* [PATCH 2/5] sq_quote_argv and add_to_string rework with strbuf's.
From: Pierre Habouzit @ 2007-09-18 20:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070918223947.GB4535@artemis.corp>
* sq_quote_buf is made public, and works on a strbuf.
* sq_quote_argv also works on a strbuf.
* make sq_quote_argv take a "maxlen" argument to check the buffer won't grow
too big.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
connect.c | 21 ++++++--------
git.c | 16 +++-------
quote.c | 91 ++++++++++++++++---------------------------------------------
quote.h | 9 ++----
rsh.c | 33 ++++++----------------
trace.c | 35 +++++++-----------------
6 files changed, 60 insertions(+), 145 deletions(-)
diff --git a/connect.c b/connect.c
index 1653a0e..06d279e 100644
--- a/connect.c
+++ b/connect.c
@@ -577,16 +577,13 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
if (pid < 0)
die("unable to fork");
if (!pid) {
- char command[MAX_CMD_LEN];
- char *posn = command;
- int size = MAX_CMD_LEN;
- int of = 0;
+ struct strbuf cmd;
- of |= add_to_string(&posn, &size, prog, 0);
- of |= add_to_string(&posn, &size, " ", 0);
- of |= add_to_string(&posn, &size, path, 1);
-
- if (of)
+ strbuf_init(&cmd, MAX_CMD_LEN);
+ strbuf_addstr(&cmd, prog);
+ strbuf_addch(&cmd, ' ');
+ sq_quote_buf(&cmd, path);
+ if (cmd.len >= MAX_CMD_LEN)
die("command line too long");
dup2(pipefd[1][0], 0);
@@ -606,10 +603,10 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
ssh_basename++;
if (!port)
- execlp(ssh, ssh_basename, host, command, NULL);
+ execlp(ssh, ssh_basename, host, cmd.buf, NULL);
else
execlp(ssh, ssh_basename, "-p", port, host,
- command, NULL);
+ cmd.buf, NULL);
}
else {
unsetenv(ALTERNATE_DB_ENVIRONMENT);
@@ -618,7 +615,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
unsetenv(GIT_WORK_TREE_ENVIRONMENT);
unsetenv(GRAFT_ENVIRONMENT);
unsetenv(INDEX_ENVIRONMENT);
- execlp("sh", "sh", "-c", command, NULL);
+ execlp("sh", "sh", "-c", cmd.buf, NULL);
}
die("exec failed");
}
diff --git a/git.c b/git.c
index 56ae8cc..9eaca1d 100644
--- a/git.c
+++ b/git.c
@@ -187,19 +187,13 @@ static int handle_alias(int *argcp, const char ***argv)
if (alias_string) {
if (alias_string[0] == '!') {
if (*argcp > 1) {
- int i, sz = PATH_MAX;
- char *s = xmalloc(sz), *new_alias = s;
+ struct strbuf buf;
- add_to_string(&s, &sz, alias_string, 0);
+ strbuf_init(&buf, PATH_MAX);
+ strbuf_addstr(&buf, alias_string);
+ sq_quote_argv(&buf, (*argv) + 1, *argcp - 1, PATH_MAX);
free(alias_string);
- alias_string = new_alias;
- for (i = 1; i < *argcp &&
- !add_to_string(&s, &sz, " ", 0) &&
- !add_to_string(&s, &sz, (*argv)[i], 1)
- ; i++)
- ; /* do nothing */
- if (!sz)
- die("Too many or long arguments");
+ alias_string = buf.buf;
}
trace_printf("trace: alias to shell cmd: %s => %s\n",
alias_command, alias_string + 1);
diff --git a/quote.c b/quote.c
index d88bf75..4df3262 100644
--- a/quote.c
+++ b/quote.c
@@ -20,29 +20,26 @@ static inline int need_bs_quote(char c)
return (c == '\'' || c == '!');
}
-static size_t sq_quote_buf(char *dst, size_t n, const char *src)
+void sq_quote_buf(struct strbuf *dst, const char *src)
{
- char c;
- char *bp = dst;
- size_t len = 0;
-
- EMIT('\'');
- while ((c = *src++)) {
- if (need_bs_quote(c)) {
- EMIT('\'');
- EMIT('\\');
- EMIT(c);
- EMIT('\'');
- } else {
- EMIT(c);
+ char *to_free = NULL;
+
+ if (dst->buf == src)
+ to_free = strbuf_detach(dst);
+
+ strbuf_addch(dst, '\'');
+ while (*src) {
+ size_t len = strcspn(src, "'\\");
+ strbuf_add(dst, src, len);
+ src += len;
+ while (need_bs_quote(*src)) {
+ strbuf_addstr(dst, "'\\");
+ strbuf_addch(dst, *src++);
+ strbuf_addch(dst, '\'');
}
}
- EMIT('\'');
-
- if ( n )
- *bp = 0;
-
- return len;
+ strbuf_addch(dst, '\'');
+ free(to_free);
}
void sq_quote_print(FILE *stream, const char *src)
@@ -62,11 +59,10 @@ void sq_quote_print(FILE *stream, const char *src)
fputc('\'', stream);
}
-char *sq_quote_argv(const char** argv, int count)
+void sq_quote_argv(struct strbuf *dst, const char** argv, int count,
+ size_t maxlen)
{
- char *buf, *to;
int i;
- size_t len = 0;
/* Count argv if needed. */
if (count < 0) {
@@ -74,53 +70,14 @@ char *sq_quote_argv(const char** argv, int count)
; /* just counting */
}
- /* Special case: no argv. */
- if (!count)
- return xcalloc(1,1);
-
- /* Get destination buffer length. */
- for (i = 0; i < count; i++)
- len += sq_quote_buf(NULL, 0, argv[i]) + 1;
-
- /* Alloc destination buffer. */
- to = buf = xmalloc(len + 1);
-
/* Copy into destination buffer. */
+ strbuf_grow(dst, 32 * count);
for (i = 0; i < count; ++i) {
- *to++ = ' ';
- to += sq_quote_buf(to, len, argv[i]);
+ strbuf_addch(dst, ' ');
+ sq_quote_buf(dst, argv[i]);
+ if (maxlen && dst->len > maxlen)
+ die("Too many or long arguments");
}
-
- return buf;
-}
-
-/*
- * Append a string to a string buffer, with or without shell quoting.
- * Return true if the buffer overflowed.
- */
-int add_to_string(char **ptrp, int *sizep, const char *str, int quote)
-{
- char *p = *ptrp;
- int size = *sizep;
- int oc;
- int err = 0;
-
- if (quote)
- oc = sq_quote_buf(p, size, str);
- else {
- oc = strlen(str);
- memcpy(p, str, (size <= oc) ? size - 1 : oc);
- }
-
- if (size <= oc) {
- err = 1;
- oc = size - 1;
- }
-
- *ptrp += oc;
- **ptrp = '\0';
- *sizep -= oc;
- return err;
}
char *sq_dequote(char *arg)
diff --git a/quote.h b/quote.h
index 8a59cc5..78e8d3e 100644
--- a/quote.h
+++ b/quote.h
@@ -29,13 +29,10 @@
*/
extern void sq_quote_print(FILE *stream, const char *src);
-extern char *sq_quote_argv(const char** argv, int count);
-/*
- * Append a string to a string buffer, with or without shell quoting.
- * Return true if the buffer overflowed.
- */
-extern int add_to_string(char **ptrp, int *sizep, const char *str, int quote);
+extern void sq_quote_buf(struct strbuf *, const char *src);
+extern void sq_quote_argv(struct strbuf *, const char **argv, int count,
+ size_t maxlen);
/* This unwraps what sq_quote() produces in place, but returns
* NULL if the input does not look like what sq_quote would have
diff --git a/rsh.c b/rsh.c
index 5754a23..e4ce255 100644
--- a/rsh.c
+++ b/rsh.c
@@ -7,14 +7,10 @@
int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
char *url, int rmt_argc, char **rmt_argv)
{
+ struct strbuf cmd;
char *host;
char *path;
int sv[2];
- char command[COMMAND_SIZE];
- char *posn;
- int sizen;
- int of;
- int i;
pid_t pid;
if (!strcmp(url, "-")) {
@@ -37,24 +33,13 @@ int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
return error("Bad URL: %s", url);
}
/* $GIT_RSH <host> "env GIT_DIR=<path> <remote_prog> <args...>" */
- sizen = COMMAND_SIZE;
- posn = command;
- of = 0;
- of |= add_to_string(&posn, &sizen, "env ", 0);
- of |= add_to_string(&posn, &sizen, GIT_DIR_ENVIRONMENT "=", 0);
- of |= add_to_string(&posn, &sizen, path, 1);
- of |= add_to_string(&posn, &sizen, " ", 0);
- of |= add_to_string(&posn, &sizen, remote_prog, 1);
-
- for ( i = 0 ; i < rmt_argc ; i++ ) {
- of |= add_to_string(&posn, &sizen, " ", 0);
- of |= add_to_string(&posn, &sizen, rmt_argv[i], 1);
- }
-
- of |= add_to_string(&posn, &sizen, " -", 0);
-
- if ( of )
- return error("Command line too long");
+ strbuf_init(&cmd, COMMAND_SIZE);
+ strbuf_addstr(&cmd, "env " GIT_DIR_ENVIRONMENT "=");
+ sq_quote_buf(&cmd, path);
+ strbuf_addch(&cmd, ' ');
+ sq_quote_buf(&cmd, remote_prog);
+ sq_quote_argv(&cmd, (const char **)rmt_argv, rmt_argc, COMMAND_SIZE - 2);
+ strbuf_addstr(&cmd, " -");
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv))
return error("Couldn't create socket");
@@ -74,7 +59,7 @@ int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
close(sv[1]);
dup2(sv[0], 0);
dup2(sv[0], 1);
- execlp(ssh, ssh_basename, host, command, NULL);
+ execlp(ssh, ssh_basename, host, cmd.buf, NULL);
}
close(sv[0]);
*fd_in = sv[1];
diff --git a/trace.c b/trace.c
index 7961a27..ed1cdf0 100644
--- a/trace.c
+++ b/trace.c
@@ -113,39 +113,24 @@ void trace_printf(const char *format, ...)
void trace_argv_printf(const char **argv, int count, const char *format, ...)
{
- char *argv_str, *format_str, *trace_str;
- size_t argv_len, format_len, trace_len;
- va_list rest;
+ struct strbuf trace;
+ va_list ap;
int need_close = 0;
int fd = get_trace_fd(&need_close);
if (!fd)
return;
- /* Get the argv string. */
- argv_str = sq_quote_argv(argv, count);
- argv_len = strlen(argv_str);
-
- /* Get the formated string. */
- va_start(rest, format);
- nfvasprintf(&format_str, format, rest);
- va_end(rest);
+ strbuf_init(&trace, 0);
- /* Allocate buffer for trace string. */
- format_len = strlen(format_str);
- trace_len = argv_len + format_len + 1; /* + 1 for \n */
- trace_str = xmalloc(trace_len + 1);
+ va_start(ap, format);
+ strbuf_addvf(&trace, format, ap);
+ va_end(ap);
+ sq_quote_argv(&trace, argv, count, 0);
+ strbuf_addch(&trace, '\n');
- /* Copy everything into the trace string. */
- strncpy(trace_str, format_str, format_len);
- strncpy(trace_str + format_len, argv_str, argv_len);
- strcpy(trace_str + trace_len - 1, "\n");
-
- write_or_whine_pipe(fd, trace_str, trace_len, err_msg);
-
- free(argv_str);
- free(format_str);
- free(trace_str);
+ write_or_whine_pipe(fd, trace.buf, trace.len, err_msg);
+ strbuf_release(&trace);
if (need_close)
close(fd);
--
1.5.3.1
^ permalink raw reply related
* [PATCH 3/5] Rework unquote_c_style to work on a strbuf.
From: Pierre Habouzit @ 2007-09-18 21:22 UTC (permalink / raw)
To: Junio C Hamano, Shawn O. Pearce; +Cc: git
In-Reply-To: <20070918223947.GB4535@artemis.corp>
If the gain is not obvious in the diffstat, the resulting code is more
readable, _and_ in checkout-index/update-index we now reuse the same buffer
to unquote strings instead of always freeing/mallocing.
This also is more coherent with the next patch that reworks quoting
functions.
The quoting function is also made more efficient scanning for backslashes
and treating portions of strings without a backslash at once.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-apply.c | 125 +++++++++++++++++++++++-----------------------
builtin-checkout-index.c | 27 +++++-----
builtin-update-index.c | 51 ++++++++++---------
fast-import.c | 47 ++++++++---------
mktree.c | 25 +++++----
quote.c | 92 ++++++++++++++++------------------
quote.h | 2 +-
7 files changed, 184 insertions(+), 185 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 6a5e389..cffbe52 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -231,35 +231,33 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
{
int len;
const char *start = line;
- char *name;
if (*line == '"') {
+ struct strbuf name;
+
/* Proposed "new-style" GNU patch/diff format; see
* http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
*/
- name = unquote_c_style(line, NULL);
- if (name) {
- char *cp = name;
- while (p_value) {
- cp = strchr(name, '/');
+ strbuf_init(&name, 0);
+ if (!unquote_c_style(&name, line, NULL)) {
+ char *cp;
+
+ for (cp = name.buf; p_value; p_value--) {
+ cp = strchr(name.buf, '/');
if (!cp)
break;
cp++;
- p_value--;
}
if (cp) {
/* name can later be freed, so we need
* to memmove, not just return cp
*/
- memmove(name, cp, strlen(cp) + 1);
+ strbuf_remove(&name, 0, cp - name.buf);
free(def);
- return name;
- }
- else {
- free(name);
- name = NULL;
+ return name.buf;
}
}
+ strbuf_release(&name);
}
for (;;) {
@@ -566,29 +564,30 @@ static const char *stop_at_slash(const char *line, int llen)
*/
static char *git_header_name(char *line, int llen)
{
- int len;
const char *name;
const char *second = NULL;
+ size_t len;
line += strlen("diff --git ");
llen -= strlen("diff --git ");
if (*line == '"') {
const char *cp;
- char *first = unquote_c_style(line, &second);
- if (!first)
- return NULL;
+ struct strbuf first;
+ struct strbuf sp;
+
+ strbuf_init(&first, 0);
+ strbuf_init(&sp, 0);
+
+ if (unquote_c_style(&first, line, &second))
+ goto free_and_fail1;
/* advance to the first slash */
- cp = stop_at_slash(first, strlen(first));
- if (!cp || cp == first) {
- /* we do not accept absolute paths */
- free_first_and_fail:
- free(first);
- return NULL;
- }
- len = strlen(cp+1);
- memmove(first, cp+1, len+1); /* including NUL */
+ cp = stop_at_slash(first.buf, first.len);
+ /* we do not accept absolute paths */
+ if (!cp || cp == first.buf)
+ goto free_and_fail1;
+ strbuf_remove(&first, 0, cp + 1 - first.buf);
/* second points at one past closing dq of name.
* find the second name.
@@ -597,40 +596,40 @@ static char *git_header_name(char *line, int llen)
second++;
if (line + llen <= second)
- goto free_first_and_fail;
+ goto free_and_fail1;
if (*second == '"') {
- char *sp = unquote_c_style(second, NULL);
- if (!sp)
- goto free_first_and_fail;
- cp = stop_at_slash(sp, strlen(sp));
- if (!cp || cp == sp) {
- free_both_and_fail:
- free(sp);
- goto free_first_and_fail;
- }
+ if (unquote_c_style(&sp, second, NULL))
+ goto free_and_fail1;
+ cp = stop_at_slash(sp.buf, sp.len);
+ if (!cp || cp == sp.buf)
+ goto free_and_fail1;
/* They must match, otherwise ignore */
- if (strcmp(cp+1, first))
- goto free_both_and_fail;
- free(sp);
- return first;
+ if (strcmp(cp + 1, first.buf))
+ goto free_and_fail1;
+ strbuf_release(&sp);
+ return first.buf;
}
/* unquoted second */
cp = stop_at_slash(second, line + llen - second);
if (!cp || cp == second)
- goto free_first_and_fail;
+ goto free_and_fail1;
cp++;
- if (line + llen - cp != len + 1 ||
- memcmp(first, cp, len))
- goto free_first_and_fail;
- return first;
+ if (line + llen - cp != first.len + 1 ||
+ memcmp(first.buf, cp, first.len))
+ goto free_and_fail1;
+ return first.buf;
+
+ free_and_fail1:
+ strbuf_release(&first);
+ strbuf_release(&sp);
+ return NULL;
}
/* unquoted first name */
name = stop_at_slash(line, llen);
if (!name || name == line)
return NULL;
-
name++;
/* since the first name is unquoted, a dq if exists must be
@@ -638,28 +637,30 @@ static char *git_header_name(char *line, int llen)
*/
for (second = name; second < line + llen; second++) {
if (*second == '"') {
- const char *cp = second;
+ struct strbuf sp;
const char *np;
- char *sp = unquote_c_style(second, NULL);
-
- if (!sp)
- return NULL;
- np = stop_at_slash(sp, strlen(sp));
- if (!np || np == sp) {
- free_second_and_fail:
- free(sp);
- return NULL;
- }
+
+ strbuf_init(&sp, 0);
+ if (unquote_c_style(&sp, second, NULL))
+ goto free_and_fail2;
+
+ np = stop_at_slash(sp.buf, sp.len);
+ if (!np || np == sp.buf)
+ goto free_and_fail2;
np++;
- len = strlen(np);
- if (len < cp - name &&
+
+ len = sp.buf + sp.len - np;
+ if (len < second - name &&
!strncmp(np, name, len) &&
isspace(name[len])) {
/* Good */
- memmove(sp, np, len + 1);
- return sp;
+ strbuf_remove(&sp, 0, np - sp.buf);
+ return sp.buf;
}
- goto free_second_and_fail;
+
+ free_and_fail2:
+ strbuf_release(&sp);
+ return NULL;
}
}
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index a18ecc4..e6264c4 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -270,26 +270,27 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
}
if (read_from_stdin) {
- struct strbuf buf;
+ struct strbuf buf, nbuf;
+
if (all)
die("git-checkout-index: don't mix '--all' and '--stdin'");
+
strbuf_init(&buf, 0);
- while (1) {
- char *path_name;
+ strbuf_init(&nbuf, 0);
+ while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
const char *p;
- if (strbuf_getline(&buf, stdin, line_termination) == EOF)
- break;
- if (line_termination && buf.buf[0] == '"')
- path_name = unquote_c_style(buf.buf, NULL);
- else
- path_name = buf.buf;
- p = prefix_path(prefix, prefix_length, path_name);
+ if (line_termination && buf.buf[0] == '"') {
+ strbuf_reset(&nbuf);
+ if (unquote_c_style(&nbuf, buf.buf, NULL))
+ die("line is badly quoted");
+ strbuf_swap(&buf, &nbuf);
+ }
+ p = prefix_path(prefix, prefix_length, buf.buf);
checkout_file(p, prefix_length);
- if (p < path_name || p > path_name + strlen(path_name))
+ if (p < buf.buf || p > buf.buf + buf.len)
free((char *)p);
- if (path_name != buf.buf)
- free(path_name);
}
+ strbuf_release(&nbuf);
strbuf_release(&buf);
}
diff --git a/builtin-update-index.c b/builtin-update-index.c
index acd5ab5..c76879e 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -295,8 +295,11 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
static void read_index_info(int line_termination)
{
struct strbuf buf;
+ struct strbuf uq;
+
strbuf_init(&buf, 0);
- while (1) {
+ strbuf_init(&uq, 0);
+ while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
char *ptr, *tab;
char *path_name;
unsigned char sha1[20];
@@ -320,9 +323,6 @@ static void read_index_info(int line_termination)
* This format is to put higher order stages into the
* index file and matches git-ls-files --stage output.
*/
- if (strbuf_getline(&buf, stdin, line_termination) == EOF)
- break;
-
errno = 0;
ul = strtoul(buf.buf, &ptr, 8);
if (ptr == buf.buf || *ptr != ' '
@@ -347,15 +347,17 @@ static void read_index_info(int line_termination)
if (get_sha1_hex(tab - 40, sha1) || tab[-41] != ' ')
goto bad_line;
- if (line_termination && ptr[0] == '"')
- path_name = unquote_c_style(ptr, NULL);
- else
- path_name = ptr;
+ path_name = ptr;
+ if (line_termination && path_name[0] == '"') {
+ strbuf_reset(&uq);
+ if (unquote_c_style(&uq, path_name, NULL)) {
+ die("git-update-index: bad quoting of path name");
+ }
+ path_name = uq.buf;
+ }
if (!verify_path(path_name)) {
fprintf(stderr, "Ignoring path %s\n", path_name);
- if (path_name != ptr)
- free(path_name);
continue;
}
@@ -383,6 +385,7 @@ static void read_index_info(int line_termination)
die("malformed index info %s", buf.buf);
}
strbuf_release(&buf);
+ strbuf_release(&uq);
}
static const char update_index_usage[] =
@@ -705,26 +708,26 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
free((char*)p);
}
if (read_from_stdin) {
- struct strbuf buf;
+ struct strbuf buf, nbuf;
+
strbuf_init(&buf, 0);
- while (1) {
- char *path_name;
+ strbuf_init(&nbuf, 0);
+ while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
const char *p;
- if (strbuf_getline(&buf, stdin, line_termination) == EOF)
- break;
- if (line_termination && buf.buf[0] == '"')
- path_name = unquote_c_style(buf.buf, NULL);
- else
- path_name = buf.buf;
- p = prefix_path(prefix, prefix_length, path_name);
+ if (line_termination && buf.buf[0] == '"') {
+ strbuf_reset(&nbuf);
+ if (unquote_c_style(&nbuf, buf.buf, NULL))
+ die("line is badly quoted");
+ strbuf_swap(&buf, &nbuf);
+ }
+ p = prefix_path(prefix, prefix_length, buf.buf);
update_one(p, NULL, 0);
if (set_executable_bit)
chmod_path(set_executable_bit, p);
- if (p < path_name || p > path_name + strlen(path_name))
- free((char*) p);
- if (path_name != buf.buf)
- free(path_name);
+ if (p < buf.buf || p > buf.buf + buf.len)
+ free((char *)p);
}
+ strbuf_release(&nbuf);
strbuf_release(&buf);
}
diff --git a/fast-import.c b/fast-import.c
index eddae22..a870a44 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1759,7 +1759,7 @@ static void load_branch(struct branch *b)
static void file_change_m(struct branch *b)
{
const char *p = command_buf.buf + 2;
- char *p_uq;
+ static struct strbuf uq = STRBUF_INIT;
const char *endp;
struct object_entry *oe = oe;
unsigned char sha1[20];
@@ -1797,18 +1797,20 @@ static void file_change_m(struct branch *b)
if (*p++ != ' ')
die("Missing space after SHA1: %s", command_buf.buf);
- p_uq = unquote_c_style(p, &endp);
- if (p_uq) {
+ strbuf_reset(&uq);
+ if (!unquote_c_style(&uq, p, &endp)) {
if (*endp)
die("Garbage after path in: %s", command_buf.buf);
- p = p_uq;
+ p = uq.buf;
}
if (inline_data) {
static struct strbuf buf = STRBUF_INIT;
- if (!p_uq)
- p = p_uq = xstrdup(p);
+ if (p != uq.buf) {
+ strbuf_addstr(&uq, p);
+ p = uq.buf;
+ }
read_next_command();
cmd_data(&buf);
store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0);
@@ -1826,56 +1828,54 @@ static void file_change_m(struct branch *b)
}
tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL);
- free(p_uq);
}
static void file_change_d(struct branch *b)
{
const char *p = command_buf.buf + 2;
- char *p_uq;
+ static struct strbuf uq = STRBUF_INIT;
const char *endp;
- p_uq = unquote_c_style(p, &endp);
- if (p_uq) {
+ strbuf_reset(&uq);
+ if (!unquote_c_style(&uq, p, &endp)) {
if (*endp)
die("Garbage after path in: %s", command_buf.buf);
- p = p_uq;
+ p = uq.buf;
}
tree_content_remove(&b->branch_tree, p, NULL);
- free(p_uq);
}
static void file_change_cr(struct branch *b, int rename)
{
const char *s, *d;
- char *s_uq, *d_uq;
+ static struct strbuf s_uq = STRBUF_INIT;
+ static struct strbuf d_uq = STRBUF_INIT;
const char *endp;
struct tree_entry leaf;
s = command_buf.buf + 2;
- s_uq = unquote_c_style(s, &endp);
- if (s_uq) {
+ strbuf_reset(&s_uq);
+ if (!unquote_c_style(&s_uq, s, &endp)) {
if (*endp != ' ')
die("Missing space after source: %s", command_buf.buf);
- }
- else {
+ } else {
endp = strchr(s, ' ');
if (!endp)
die("Missing space after source: %s", command_buf.buf);
- s_uq = xmemdupz(s, endp - s);
+ strbuf_add(&s_uq, s, endp - s);
}
- s = s_uq;
+ s = s_uq.buf;
endp++;
if (!*endp)
die("Missing dest: %s", command_buf.buf);
d = endp;
- d_uq = unquote_c_style(d, &endp);
- if (d_uq) {
+ strbuf_reset(&d_uq);
+ if (!unquote_c_style(&d_uq, d, &endp)) {
if (*endp)
die("Garbage after dest in: %s", command_buf.buf);
- d = d_uq;
+ d = d_uq.buf;
}
memset(&leaf, 0, sizeof(leaf));
@@ -1889,9 +1889,6 @@ static void file_change_cr(struct branch *b, int rename)
leaf.versions[1].sha1,
leaf.versions[1].mode,
leaf.tree);
-
- free(s_uq);
- free(d_uq);
}
static void file_change_deleteall(struct branch *b)
diff --git a/mktree.c b/mktree.c
index 9c137de..e0da110 100644
--- a/mktree.c
+++ b/mktree.c
@@ -66,6 +66,7 @@ static const char mktree_usage[] = "git-mktree [-z]";
int main(int ac, char **av)
{
struct strbuf sb;
+ struct strbuf p_uq;
unsigned char sha1[20];
int line_termination = '\n';
@@ -82,14 +83,13 @@ int main(int ac, char **av)
}
strbuf_init(&sb, 0);
- while (1) {
+ strbuf_init(&p_uq, 0);
+ while (strbuf_getline(&sb, stdin, line_termination) != EOF) {
char *ptr, *ntr;
unsigned mode;
enum object_type type;
char *path;
- if (strbuf_getline(&sb, stdin, line_termination) == EOF)
- break;
ptr = sb.buf;
/* Input is non-recursive ls-tree output format
* mode SP type SP sha1 TAB name
@@ -109,18 +109,21 @@ int main(int ac, char **av)
*ntr++ = 0; /* now at the beginning of SHA1 */
if (type != type_from_string(ptr))
die("object type %s mismatch (%s)", ptr, typename(type));
- ntr += 41; /* at the beginning of name */
- if (line_termination && ntr[0] == '"')
- path = unquote_c_style(ntr, NULL);
- else
- path = ntr;
- append_to_tree(mode, sha1, path);
+ path = ntr + 41; /* at the beginning of name */
+ if (line_termination && path[0] == '"') {
+ strbuf_reset(&p_uq);
+ if (unquote_c_style(&p_uq, path, NULL)) {
+ die("invalid quoting");
+ }
+ path = p_uq.buf;
+ }
- if (path != ntr)
- free(path);
+ append_to_tree(mode, sha1, path);
}
+ strbuf_release(&p_uq);
strbuf_release(&sb);
+
write_tree(sha1);
puts(sha1_to_hex(sha1));
exit(0);
diff --git a/quote.c b/quote.c
index 4df3262..67c6527 100644
--- a/quote.c
+++ b/quote.c
@@ -201,68 +201,62 @@ int quote_c_style(const char *name, char *outbuf, FILE *outfp, int no_dq)
* should free when done. Updates endp pointer to point at
* one past the ending double quote if given.
*/
-
-char *unquote_c_style(const char *quoted, const char **endp)
+int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
{
- const char *sp;
- char *name = NULL, *outp = NULL;
- int count = 0, ch, ac;
-
-#undef EMIT
-#define EMIT(c) (outp ? (*outp++ = (c)) : (count++))
+ size_t oldlen = sb->len, len;
+ int ch, ac;
if (*quoted++ != '"')
- return NULL;
+ return -1;
+
+ for (;;) {
+ len = strcspn(quoted, "\"\\");
+ strbuf_add(sb, quoted, len);
+ quoted += len;
+
+ switch (*quoted++) {
+ case '"':
+ if (endp)
+ *endp = quoted + 1;
+ return 0;
+ case '\\':
+ break;
+ default:
+ goto error;
+ }
+
+ switch ((ch = *quoted++)) {
+ case 'a': ch = '\a'; break;
+ case 'b': ch = '\b'; break;
+ case 'f': ch = '\f'; break;
+ case 'n': ch = '\n'; break;
+ case 'r': ch = '\r'; break;
+ case 't': ch = '\t'; break;
+ case 'v': ch = '\v'; break;
- while (1) {
- /* first pass counts and allocates, second pass fills */
- for (sp = quoted; (ch = *sp++) != '"'; ) {
- if (ch == '\\') {
- switch (ch = *sp++) {
- case 'a': ch = '\a'; break;
- case 'b': ch = '\b'; break;
- case 'f': ch = '\f'; break;
- case 'n': ch = '\n'; break;
- case 'r': ch = '\r'; break;
- case 't': ch = '\t'; break;
- case 'v': ch = '\v'; break;
-
- case '\\': case '"':
- break; /* verbatim */
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /* octal */
+ case '\\': case '"':
+ break; /* verbatim */
+
+ /* octal values with first digit over 4 overflow */
+ case '0': case '1': case '2': case '3':
ac = ((ch - '0') << 6);
- if ((ch = *sp++) < '0' || '7' < ch)
- return NULL;
+ if ((ch = *quoted++) < '0' || '7' < ch)
+ goto error;
ac |= ((ch - '0') << 3);
- if ((ch = *sp++) < '0' || '7' < ch)
- return NULL;
+ if ((ch = *quoted++) < '0' || '7' < ch)
+ goto error;
ac |= (ch - '0');
ch = ac;
break;
default:
- return NULL; /* malformed */
- }
+ goto error;
}
- EMIT(ch);
+ strbuf_addch(sb, ch);
}
- if (name) {
- *outp = 0;
- if (endp)
- *endp = sp;
- return name;
- }
- outp = name = xmalloc(count + 1);
- }
+ error:
+ strbuf_setlen(sb, oldlen);
+ return -1;
}
void write_name_quoted(const char *prefix, int prefix_len,
diff --git a/quote.h b/quote.h
index 78e8d3e..6407c4d 100644
--- a/quote.h
+++ b/quote.h
@@ -40,9 +40,9 @@ extern void sq_quote_argv(struct strbuf *, const char **argv, int count,
*/
extern char *sq_dequote(char *);
+extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp);
extern int quote_c_style(const char *name, char *outbuf, FILE *outfp,
int nodq);
-extern char *unquote_c_style(const char *quoted, const char **endp);
extern void write_name_quoted(const char *prefix, int prefix_len,
const char *name, int quote, FILE *out);
--
1.5.3.1
^ permalink raw reply related
* [PATCH 5/5] Avoid duplicating memory, and use xmemdupz instead of xstrdup.
From: Pierre Habouzit @ 2007-09-18 21:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070918223947.GB4535@artemis.corp>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
fetch.c | 23 +++++++++--------------
1 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/fetch.c b/fetch.c
index b1c1f07..479ec02 100644
--- a/fetch.c
+++ b/fetch.c
@@ -218,24 +218,19 @@ int pull_targets_stdin(char ***target, const char ***write_ref)
struct strbuf buf;
*target = NULL; *write_ref = NULL;
strbuf_init(&buf, 0);
- while (1) {
- char *rf_one = NULL;
- char *tg_one;
-
- if (strbuf_getline(&buf, stdin, '\n') == EOF)
- break;
- tg_one = buf.buf;
- rf_one = strchr(tg_one, '\t');
- if (rf_one)
- *rf_one++ = 0;
+ while (strbuf_getline(&buf, stdin, '\n') != EOF) {
+ char *rf_one = memchr(buf.buf, '\t', buf.len);
if (targets >= targets_alloc) {
- targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
- *target = xrealloc(*target, targets_alloc * sizeof(**target));
+ ALLOC_GROW(target, targets, targets_alloc);
*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
}
- (*target)[targets] = xstrdup(tg_one);
- (*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;
+ if (rf_one) {
+ (*write_ref)[targets] = xmemdupz(rf_one, buf.len - (rf_one - buf.buf));
+ } else {
+ (*write_ref)[targets] = NULL;
+ }
+ (*target)[targets] = strbuf_detach(&buf);
targets++;
}
strbuf_release(&buf);
--
1.5.3.1
^ permalink raw reply related
* [PATCH 4/5] Full rework of quote_c_style and write_name_quoted.
From: Pierre Habouzit @ 2007-09-18 22:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070918223947.GB4535@artemis.corp>
* quote_c_style works on a strbuf instead of a wild buffer.
* quote_c_style is now clever enough to not add double quotes if not needed.
* write_name_quoted inherits those advantages, but also take a different
set of arguments. Now instead of asking for quotes or not, you pass a
"terminator". If it's \0 then we assume you don't want to escape, else C
escaping is performed. In any case, the terminator is also appended to the
stream. It also no longer takes the prefix/prefix_len arguments, as it's
seldomly used, and makes some optimizations harder.
* write_name_quotedpfx is created to work like write_name_quoted and take
the prefix/prefix_len arguments.
Thanks to those API changes, diff.c has somehow lost weight, thanks to the
removal of functions that were wrappers around the old write_name_quoted
trying to give it a semantics like the new one, but performing a lot of
allocations for this goal. Now we always write directly to the stream, no
intermediate allocation is performed.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-apply.c | 83 +++++--------
builtin-blame.c | 3 +-
builtin-check-attr.c | 2 +-
builtin-checkout-index.c | 4 +-
builtin-ls-files.c | 13 +--
builtin-ls-tree.c | 6 +-
combine-diff.c | 16 +--
diff.c | 303 +++++++++++++++++-----------------------------
quote.c | 198 +++++++++++++++++-------------
quote.h | 8 +-
10 files changed, 268 insertions(+), 368 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index cffbe52..0328863 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -163,15 +163,14 @@ static void say_patch_name(FILE *output, const char *pre, struct patch *patch, c
fputs(pre, output);
if (patch->old_name && patch->new_name &&
strcmp(patch->old_name, patch->new_name)) {
- write_name_quoted(NULL, 0, patch->old_name, 1, output);
+ quote_c_style(patch->old_name, NULL, output, 0);
fputs(" => ", output);
- write_name_quoted(NULL, 0, patch->new_name, 1, output);
- }
- else {
+ quote_c_style(patch->new_name, NULL, output, 0);
+ } else {
const char *n = patch->new_name;
if (!n)
n = patch->old_name;
- write_name_quoted(NULL, 0, n, 1, output);
+ quote_c_style(n, NULL, output, 0);
}
fputs(post, output);
}
@@ -1378,61 +1377,50 @@ static const char minuses[]= "--------------------------------------------------
static void show_stats(struct patch *patch)
{
- const char *prefix = "";
- char *name = patch->new_name;
- char *qname = NULL;
- int len, max, add, del, total;
-
- if (!name)
- name = patch->old_name;
+ struct strbuf qname;
+ char *cp = patch->new_name ? patch->new_name : patch->old_name;
+ int max, add, del;
- if (0 < (len = quote_c_style(name, NULL, NULL, 0))) {
- qname = xmalloc(len + 1);
- quote_c_style(name, qname, NULL, 0);
- name = qname;
- }
+ strbuf_init(&qname, 0);
+ quote_c_style(cp, &qname, NULL, 0);
/*
* "scale" the filename
*/
- len = strlen(name);
max = max_len;
if (max > 50)
max = 50;
- if (len > max) {
- char *slash;
- prefix = "...";
- max -= 3;
- name += len - max;
- slash = strchr(name, '/');
- if (slash)
- name = slash;
+
+ if (qname.len > max) {
+ cp = strchr(qname.buf + qname.len + 3 - max, '/');
+ if (cp)
+ cp = qname.buf + qname.len + 3 - max;
+ strbuf_splice(&qname, 0, cp - qname.buf, "...", 3);
+ }
+
+ if (patch->is_binary) {
+ printf(" %-*s | Bin\n", max, qname.buf);
+ strbuf_release(&qname);
+ return;
}
- len = max;
+
+ printf(" %-*s |", max, qname.buf);
+ strbuf_release(&qname);
/*
* scale the add/delete
*/
- max = max_change;
- if (max + len > 70)
- max = 70 - len;
-
+ max = max + max_change > 70 ? 70 - max : max_change;
add = patch->lines_added;
del = patch->lines_deleted;
- total = add + del;
if (max_change > 0) {
- total = (total * max + max_change / 2) / max_change;
+ int total = ((add + del) * max + max_change / 2) / max_change;
add = (add * max + max_change / 2) / max_change;
del = total - add;
}
- if (patch->is_binary)
- printf(" %s%-*s | Bin\n", prefix, len, name);
- else
- printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
- len, name, patch->lines_added + patch->lines_deleted,
- add, pluses, del, minuses);
- free(qname);
+ printf("%5d %.*s%.*s\n", patch->lines_added + patch->lines_deleted,
+ add, pluses, del, minuses);
}
static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)
@@ -2197,11 +2185,7 @@ static void show_index_list(struct patch *list)
sha1_ptr = sha1;
printf("%06o %s ",patch->old_mode, sha1_to_hex(sha1_ptr));
- if (line_termination && quote_c_style(name, NULL, NULL, 0))
- quote_c_style(name, NULL, stdout, 0);
- else
- fputs(name, stdout);
- putchar(line_termination);
+ write_name_quoted(name, stdout, line_termination);
}
}
@@ -2227,13 +2211,8 @@ static void numstat_patch_list(struct patch *patch)
if (patch->is_binary)
printf("-\t-\t");
else
- printf("%d\t%d\t",
- patch->lines_added, patch->lines_deleted);
- if (line_termination && quote_c_style(name, NULL, NULL, 0))
- quote_c_style(name, NULL, stdout, 0);
- else
- fputs(name, stdout);
- putchar(line_termination);
+ printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
+ write_name_quoted(name, stdout, line_termination);
}
}
diff --git a/builtin-blame.c b/builtin-blame.c
index e364b6c..16c0ca8 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1430,8 +1430,7 @@ static void get_commit_info(struct commit *commit,
static void write_filename_info(const char *path)
{
printf("filename ");
- write_name_quoted(NULL, 0, path, 1, stdout);
- putchar('\n');
+ write_name_quoted(path, stdout, '\n');
}
/*
diff --git a/builtin-check-attr.c b/builtin-check-attr.c
index d949733..6afdfa1 100644
--- a/builtin-check-attr.c
+++ b/builtin-check-attr.c
@@ -56,7 +56,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
else if (ATTR_UNSET(value))
value = "unspecified";
- write_name_quoted("", 0, argv[i], 1, stdout);
+ quote_c_style(argv[i], NULL, stdout, 0);
printf(": %s: %s\n", argv[j+1], value);
}
}
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index e6264c4..70d619d 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -66,9 +66,7 @@ static void write_tempfile_record(const char *name, int prefix_length)
fputs(topath[checkout_stage], stdout);
putchar('\t');
- write_name_quoted("", 0, name + prefix_length,
- line_termination, stdout);
- putchar(line_termination);
+ write_name_quoted(name + prefix_length, stdout, line_termination);
for (i = 0; i < 4; i++) {
topath[i][0] = 0;
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 48dd3f7..2e6f43b 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -84,8 +84,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
return;
fputs(tag, stdout);
- write_name_quoted("", 0, ent->name + offset, line_terminator, stdout);
- putchar(line_terminator);
+ write_name_quoted(ent->name + offset, stdout, line_terminator);
}
static void show_other_files(struct dir_struct *dir)
@@ -208,21 +207,15 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
if (!show_stage) {
fputs(tag, stdout);
- write_name_quoted("", 0, ce->name + offset,
- line_terminator, stdout);
- putchar(line_terminator);
- }
- else {
+ } else {
printf("%s%06o %s %d\t",
tag,
ntohl(ce->ce_mode),
abbrev ? find_unique_abbrev(ce->sha1,abbrev)
: sha1_to_hex(ce->sha1),
ce_stage(ce));
- write_name_quoted("", 0, ce->name + offset,
- line_terminator, stdout);
- putchar(line_terminator);
}
+ write_name_quoted(ce->name + offset, stdout, line_terminator);
}
static void show_files(struct dir_struct *dir, const char *prefix)
diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c
index cb4be4f..7abe333 100644
--- a/builtin-ls-tree.c
+++ b/builtin-ls-tree.c
@@ -112,10 +112,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
abbrev ? find_unique_abbrev(sha1, abbrev)
: sha1_to_hex(sha1));
}
- write_name_quoted(base + chomp_prefix, baselen - chomp_prefix,
- pathname,
- line_termination, stdout);
- putchar(line_termination);
+ write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
+ pathname, stdout, line_termination);
return retval;
}
diff --git a/combine-diff.c b/combine-diff.c
index ef62234..fe5a2a1 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -650,10 +650,7 @@ static void dump_quoted_path(const char *prefix, const char *path,
const char *c_meta, const char *c_reset)
{
printf("%s%s", c_meta, prefix);
- if (quote_c_style(path, NULL, NULL, 0))
- quote_c_style(path, NULL, stdout, 0);
- else
- printf("%s", path);
+ quote_c_style(path, NULL, stdout, 0);
printf("%s\n", c_reset);
}
@@ -900,16 +897,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re
putchar(inter_name_termination);
}
- if (line_termination) {
- if (quote_c_style(p->path, NULL, NULL, 0))
- quote_c_style(p->path, NULL, stdout, 0);
- else
- printf("%s", p->path);
- putchar(line_termination);
- }
- else {
- printf("%s%c", p->path, line_termination);
- }
+ write_name_quoted(p->path, stdout, line_termination);
}
void show_combined_diff(struct combine_diff_path *p,
diff --git a/diff.c b/diff.c
index 2216d75..fb6d077 100644
--- a/diff.c
+++ b/diff.c
@@ -181,44 +181,23 @@ int git_diff_ui_config(const char *var, const char *value)
return git_default_config(var, value);
}
-static char *quote_one(const char *str)
-{
- int needlen;
- char *xp;
-
- if (!str)
- return NULL;
- needlen = quote_c_style(str, NULL, NULL, 0);
- if (!needlen)
- return xstrdup(str);
- xp = xmalloc(needlen + 1);
- quote_c_style(str, xp, NULL, 0);
- return xp;
-}
-
static char *quote_two(const char *one, const char *two)
{
int need_one = quote_c_style(one, NULL, NULL, 1);
int need_two = quote_c_style(two, NULL, NULL, 1);
- char *xp;
+ struct strbuf res;
+ strbuf_init(&res, 0);
if (need_one + need_two) {
- if (!need_one) need_one = strlen(one);
- if (!need_two) need_one = strlen(two);
-
- xp = xmalloc(need_one + need_two + 3);
- xp[0] = '"';
- quote_c_style(one, xp + 1, NULL, 1);
- quote_c_style(two, xp + need_one + 1, NULL, 1);
- strcpy(xp + need_one + need_two + 1, "\"");
- return xp;
+ strbuf_addch(&res, '"');
+ quote_c_style(one, &res, NULL, 1);
+ quote_c_style(two, &res, NULL, 1);
+ strbuf_addch(&res, '"');
+ } else {
+ strbuf_addstr(&res, one);
+ strbuf_addstr(&res, two);
}
- need_one = strlen(one);
- need_two = strlen(two);
- xp = xmalloc(need_one + need_two + 1);
- strcpy(xp, one);
- strcpy(xp + need_one, two);
- return xp;
+ return res.buf;
}
static const char *external_diff(void)
@@ -670,27 +649,20 @@ static char *pprint_rename(const char *a, const char *b)
{
const char *old = a;
const char *new = b;
- char *name = NULL;
+ struct strbuf name;
int pfx_length, sfx_length;
int len_a = strlen(a);
int len_b = strlen(b);
+ int a_midlen, b_midlen;
int qlen_a = quote_c_style(a, NULL, NULL, 0);
int qlen_b = quote_c_style(b, NULL, NULL, 0);
+ strbuf_init(&name, 0);
if (qlen_a || qlen_b) {
- if (qlen_a) len_a = qlen_a;
- if (qlen_b) len_b = qlen_b;
- name = xmalloc( len_a + len_b + 5 );
- if (qlen_a)
- quote_c_style(a, name, NULL, 0);
- else
- memcpy(name, a, len_a);
- memcpy(name + len_a, " => ", 4);
- if (qlen_b)
- quote_c_style(b, name + len_a + 4, NULL, 0);
- else
- memcpy(name + len_a + 4, b, len_b + 1);
- return name;
+ quote_c_style(a, &name, NULL, 0);
+ strbuf_addstr(&name, " => ");
+ quote_c_style(b, &name, NULL, 0);
+ return name.buf;
}
/* Find common prefix */
@@ -719,24 +691,26 @@ static char *pprint_rename(const char *a, const char *b)
* pfx{sfx-a => sfx-b}
* name-a => name-b
*/
+ a_midlen = len_a - pfx_length - sfx_length;
+ b_midlen = len_b - pfx_length - sfx_length;
+ if (a_midlen < 0)
+ a_midlen = 0;
+ if (b_midlen < 0)
+ b_midlen = 0;
+
+ strbuf_grow(&name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
if (pfx_length + sfx_length) {
- int a_midlen = len_a - pfx_length - sfx_length;
- int b_midlen = len_b - pfx_length - sfx_length;
- if (a_midlen < 0) a_midlen = 0;
- if (b_midlen < 0) b_midlen = 0;
-
- name = xmalloc(pfx_length + a_midlen + b_midlen + sfx_length + 7);
- sprintf(name, "%.*s{%.*s => %.*s}%s",
- pfx_length, a,
- a_midlen, a + pfx_length,
- b_midlen, b + pfx_length,
- a + len_a - sfx_length);
+ strbuf_add(&name, a, pfx_length);
+ strbuf_addch(&name, '{');
}
- else {
- name = xmalloc(len_a + len_b + 5);
- sprintf(name, "%s => %s", a, b);
+ strbuf_add(&name, a + pfx_length, a_midlen);
+ strbuf_addstr(&name, " => ");
+ strbuf_add(&name, b + pfx_length, b_midlen);
+ if (pfx_length + sfx_length) {
+ strbuf_addch(&name, '}');
+ strbuf_add(&name, a + len_a - sfx_length, sfx_length);
}
- return name;
+ return name.buf;
}
struct diffstat_t {
@@ -849,12 +823,13 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
int change = file->added + file->deleted;
if (!file->is_renamed) { /* renames are already quoted by pprint_rename */
- len = quote_c_style(file->name, NULL, NULL, 0);
- if (len) {
- char *qname = xmalloc(len + 1);
- quote_c_style(file->name, qname, NULL, 0);
+ struct strbuf buf;
+ strbuf_init(&buf, 0);
+ if (quote_c_style(file->name, &buf, NULL, 0)) {
free(file->name);
- file->name = qname;
+ file->name = buf.buf;
+ } else {
+ strbuf_release(&buf);
}
}
@@ -992,12 +967,12 @@ static void show_numstat(struct diffstat_t* data, struct diff_options *options)
printf("-\t-\t");
else
printf("%d\t%d\t", file->added, file->deleted);
- if (options->line_termination && !file->is_renamed &&
- quote_c_style(file->name, NULL, NULL, 0))
- quote_c_style(file->name, NULL, stdout, 0);
- else
+ if (!file->is_renamed) {
+ write_name_quoted(file->name, stdout, options->line_termination);
+ } else {
fputs(file->name, stdout);
- putchar(options->line_termination);
+ putchar(options->line_termination);
+ }
}
}
@@ -1941,50 +1916,46 @@ static int similarity_index(struct diff_filepair *p)
static void run_diff(struct diff_filepair *p, struct diff_options *o)
{
const char *pgm = external_diff();
- char msg[PATH_MAX*2+300], *xfrm_msg;
- struct diff_filespec *one;
- struct diff_filespec *two;
+ struct strbuf msg;
+ char *xfrm_msg;
+ struct diff_filespec *one = p->one;
+ struct diff_filespec *two = p->two;
const char *name;
const char *other;
- char *name_munged, *other_munged;
int complete_rewrite = 0;
- int len;
+
if (DIFF_PAIR_UNMERGED(p)) {
- /* unmerged */
run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, o, 0);
return;
}
- name = p->one->path;
+ name = p->one->path;
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
- name_munged = quote_one(name);
- other_munged = quote_one(other);
- one = p->one; two = p->two;
-
diff_fill_sha1_info(one);
diff_fill_sha1_info(two);
- len = 0;
+ strbuf_init(&msg, PATH_MAX * 2 + 300);
switch (p->status) {
case DIFF_STATUS_COPIED:
- len += snprintf(msg + len, sizeof(msg) - len,
- "similarity index %d%%\n"
- "copy from %s\n"
- "copy to %s\n",
- similarity_index(p), name_munged, other_munged);
+ strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
+ strbuf_addstr(&msg, "\ncopy from ");
+ quote_c_style(name, &msg, NULL, 0);
+ strbuf_addstr(&msg, "\ncopy to ");
+ quote_c_style(other, &msg, NULL, 0);
+ strbuf_addch(&msg, '\n');
break;
case DIFF_STATUS_RENAMED:
- len += snprintf(msg + len, sizeof(msg) - len,
- "similarity index %d%%\n"
- "rename from %s\n"
- "rename to %s\n",
- similarity_index(p), name_munged, other_munged);
+ strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
+ strbuf_addstr(&msg, "\nrename from ");
+ quote_c_style(name, &msg, NULL, 0);
+ strbuf_addstr(&msg, "\nrename to ");
+ quote_c_style(other, &msg, NULL, 0);
+ strbuf_addch(&msg, '\n');
break;
case DIFF_STATUS_MODIFIED:
if (p->score) {
- len += snprintf(msg + len, sizeof(msg) - len,
- "dissimilarity index %d%%\n",
+ strbuf_addf(&msg, "dissimilarity index %d%%\n",
similarity_index(p));
complete_rewrite = 1;
break;
@@ -2004,19 +1975,17 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
abbrev = 40;
}
- len += snprintf(msg + len, sizeof(msg) - len,
- "index %.*s..%.*s",
+ strbuf_addf(&msg, "index %.*s..%.*s",
abbrev, sha1_to_hex(one->sha1),
abbrev, sha1_to_hex(two->sha1));
if (one->mode == two->mode)
- len += snprintf(msg + len, sizeof(msg) - len,
- " %06o", one->mode);
- len += snprintf(msg + len, sizeof(msg) - len, "\n");
+ strbuf_addf(&msg, " %06o", one->mode);
+ strbuf_addch(&msg, '\n');
}
- if (len)
- msg[--len] = 0;
- xfrm_msg = len ? msg : NULL;
+ if (msg.len)
+ strbuf_setlen(&msg, msg.len - 1);
+ xfrm_msg = msg.len ? msg.buf : NULL;
if (!pgm &&
DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
@@ -2035,8 +2004,7 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
run_diff_cmd(pgm, name, other, one, two, xfrm_msg, o,
complete_rewrite);
- free(name_munged);
- free(other_munged);
+ strbuf_release(&msg);
}
static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
@@ -2492,72 +2460,30 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len)
return sha1_to_hex(sha1);
}
-static void diff_flush_raw(struct diff_filepair *p,
- struct diff_options *options)
+static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt)
{
- int two_paths;
- char status[10];
- int abbrev = options->abbrev;
- const char *path_one, *path_two;
- int inter_name_termination = '\t';
- int line_termination = options->line_termination;
-
- if (!line_termination)
- inter_name_termination = 0;
+ int line_termination = opt->line_termination;
+ int inter_name_termination = line_termination ? '\t' : '\0';
- path_one = p->one->path;
- path_two = p->two->path;
- if (line_termination) {
- path_one = quote_one(path_one);
- path_two = quote_one(path_two);
+ if (!(opt->output_format & DIFF_FORMAT_NAME_STATUS)) {
+ printf(":%06o %06o %s ", p->one->mode, p->two->mode,
+ diff_unique_abbrev(p->one->sha1, opt->abbrev));
+ printf("%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev));
}
-
- if (p->score)
- sprintf(status, "%c%03d", p->status, similarity_index(p));
- else {
- status[0] = p->status;
- status[1] = 0;
- }
- switch (p->status) {
- case DIFF_STATUS_COPIED:
- case DIFF_STATUS_RENAMED:
- two_paths = 1;
- break;
- case DIFF_STATUS_ADDED:
- case DIFF_STATUS_DELETED:
- two_paths = 0;
- break;
- default:
- two_paths = 0;
- break;
- }
- if (!(options->output_format & DIFF_FORMAT_NAME_STATUS)) {
- printf(":%06o %06o %s ",
- p->one->mode, p->two->mode,
- diff_unique_abbrev(p->one->sha1, abbrev));
- printf("%s ",
- diff_unique_abbrev(p->two->sha1, abbrev));
+ if (p->score) {
+ printf("%c%03d%c", p->status, similarity_index(p),
+ inter_name_termination);
+ } else {
+ printf("%c%c", p->status, inter_name_termination);
}
- printf("%s%c%s", status, inter_name_termination,
- two_paths || p->one->mode ? path_one : path_two);
- if (two_paths)
- printf("%c%s", inter_name_termination, path_two);
- putchar(line_termination);
- if (path_one != p->one->path)
- free((void*)path_one);
- if (path_two != p->two->path)
- free((void*)path_two);
-}
-static void diff_flush_name(struct diff_filepair *p, struct diff_options *opt)
-{
- char *path = p->two->path;
-
- if (opt->line_termination)
- path = quote_one(p->two->path);
- printf("%s%c", path, opt->line_termination);
- if (p->two->path != path)
- free(path);
+ if (p->status == DIFF_STATUS_COPIED || p->status == DIFF_STATUS_RENAMED) {
+ write_name_quoted(p->one->path, stdout, inter_name_termination);
+ write_name_quoted(p->two->path, stdout, line_termination);
+ } else {
+ const char *path = p->one->mode ? p->one->path : p->two->path;
+ write_name_quoted(path, stdout, line_termination);
+ }
}
int diff_unmodified_pair(struct diff_filepair *p)
@@ -2567,14 +2493,11 @@ int diff_unmodified_pair(struct diff_filepair *p)
* let transformers to produce diff_filepairs any way they want,
* and filter and clean them up here before producing the output.
*/
- struct diff_filespec *one, *two;
+ struct diff_filespec *one = p->one, *two = p->two;
if (DIFF_PAIR_UNMERGED(p))
return 0; /* unmerged is interesting */
- one = p->one;
- two = p->two;
-
/* deletion, addition, mode or type change
* and rename are all interesting.
*/
@@ -2763,32 +2686,27 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt)
else if (fmt & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME_STATUS))
diff_flush_raw(p, opt);
else if (fmt & DIFF_FORMAT_NAME)
- diff_flush_name(p, opt);
+ write_name_quoted(p->two->path, stdout, opt->line_termination);
}
static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
{
- char *name = quote_one(fs->path);
if (fs->mode)
- printf(" %s mode %06o %s\n", newdelete, fs->mode, name);
+ printf(" %s mode %06o ", newdelete, fs->mode);
else
- printf(" %s %s\n", newdelete, name);
- free(name);
+ printf(" %s ", newdelete);
+ write_name_quoted(fs->path, stdout, '\n');
}
static void show_mode_change(struct diff_filepair *p, int show_name)
{
if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {
+ printf(" mode change %06o => %06o%c", p->one->mode, p->two->mode,
+ show_name ? ' ' : '\n');
if (show_name) {
- char *name = quote_one(p->two->path);
- printf(" mode change %06o => %06o %s\n",
- p->one->mode, p->two->mode, name);
- free(name);
+ write_name_quoted(p->two->path, stdout, '\n');
}
- else
- printf(" mode change %06o => %06o\n",
- p->one->mode, p->two->mode);
}
}
@@ -2818,12 +2736,11 @@ static void diff_summary(struct diff_filepair *p)
break;
default:
if (p->score) {
- char *name = quote_one(p->two->path);
- printf(" rewrite %s (%d%%)\n", name,
- similarity_index(p));
- free(name);
- show_mode_change(p, 0);
- } else show_mode_change(p, 1);
+ puts(" rewrite ");
+ write_name_quoted(p->two->path, stdout, ' ');
+ printf("(%d%%)\n", similarity_index(p));
+ }
+ show_mode_change(p, !p->score);
break;
}
}
@@ -2837,14 +2754,14 @@ struct patch_id_t {
static int remove_space(char *line, int len)
{
int i;
- char *dst = line;
- unsigned char c;
+ char *dst = line;
+ unsigned char c;
- for (i = 0; i < len; i++)
- if (!isspace((c = line[i])))
- *dst++ = c;
+ for (i = 0; i < len; i++)
+ if (!isspace((c = line[i])))
+ *dst++ = c;
- return dst - line;
+ return dst - line;
}
static void patch_id_consume(void *priv, char *line, unsigned long len)
diff --git a/quote.c b/quote.c
index 67c6527..a8a755a 100644
--- a/quote.c
+++ b/quote.c
@@ -114,83 +114,142 @@ char *sq_dequote(char *arg)
}
}
+/* 1 means: quote as octal
+ * 0 means: quote as octal if (quote_path_fully)
+ * -1 means: never quote
+ * c: quote as "\\c"
+ */
+#define X8(x) x, x, x, x, x, x, x, x
+#define X16(x) X8(x), X8(x)
+static signed char const sq_lookup[256] = {
+ /* 0 1 2 3 4 5 6 7 */
+ /* 0x00 */ 1, 1, 1, 1, 1, 1, 'a', 1,
+ /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r', 1, 1,
+ /* 0x10 */ X16(1),
+ /* 0x20 */ -1, -1, '"', -1, -1, -1, -1, -1,
+ /* 0x28 */ X16(-1), X16(-1), X16(-1),
+ /* 0x58 */ -1, -1, -1, -1,'\\', -1, -1, -1,
+ /* 0x60 */ X16(-1), X16(-1),
+ /* 0x80 */ /* set to 0 */
+};
+
+static inline int sq_must_quote(char c) {
+ return sq_lookup[(unsigned char)c] + quote_path_fully > 0;
+}
+
+/* returns the longest prefix not needing a quote up to maxlen if positive.
+ This stops at the first \0 because it's marked as a character needing an
+ escape */
+static size_t next_quote_pos(const char *s, ssize_t maxlen)
+{
+ size_t len;
+ if (maxlen < 0) {
+ for (len = 0; !sq_must_quote(s[len]); len++);
+ } else {
+ for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++);
+ }
+ return len;
+}
+
/*
* C-style name quoting.
*
- * Does one of three things:
- *
* (1) if outbuf and outfp are both NULL, inspect the input name and
* counts the number of bytes that are needed to hold c_style
* quoted version of name, counting the double quotes around
* it but not terminating NUL, and returns it. However, if name
* does not need c_style quoting, it returns 0.
*
- * (2) if outbuf is not NULL, it must point at a buffer large enough
- * to hold the c_style quoted version of name, enclosing double
- * quotes, and terminating NUL. Fills outbuf with c_style quoted
- * version of name enclosed in double-quote pair. Return value
- * is undefined.
- *
- * (3) if outfp is not NULL, outputs c_style quoted version of name,
- * but not enclosed in double-quote pair. Return value is undefined.
+ * (2) if sb or fp are not NULL, it emits the c_style quoted version
+ * of name, enclosed with double quotes if asked and needed only.
+ * Return value is the same as in (1).
*/
-
-static int quote_c_style_counted(const char *name, int namelen,
- char *outbuf, FILE *outfp, int no_dq)
+static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
+ struct strbuf *sb, FILE *fp, int no_dq)
{
#undef EMIT
-#define EMIT(c) \
- (outbuf ? (*outbuf++ = (c)) : outfp ? fputc(c, outfp) : (count++))
+#define EMIT(c) \
+ do { \
+ if (sb) strbuf_addch(sb, (c)); \
+ if (fp) fputc((c), fp); \
+ count++; \
+ } while (0)
+#define EMITBUF(s, l) \
+ do { \
+ if (sb) strbuf_add(sb, (s), (l)); \
+ if (fp) fwrite((s), (l), 1, fp); \
+ count += (l); \
+ } while (0)
+
+ size_t len, count = 0;
+ const char *p = name;
-#define EMITQ() EMIT('\\')
-
- const char *sp;
- unsigned char ch;
- int count = 0, needquote = 0;
+ for (;;) {
+ int ch;
- if (!no_dq)
- EMIT('"');
- for (sp = name; sp < name + namelen; sp++) {
- ch = *sp;
- if (!ch)
+ len = next_quote_pos(p, maxlen);
+ if (len == maxlen || !p[len])
break;
- if ((ch < ' ') || (ch == '"') || (ch == '\\') ||
- (quote_path_fully && (ch >= 0177))) {
- needquote = 1;
- switch (ch) {
- case '\a': EMITQ(); ch = 'a'; break;
- case '\b': EMITQ(); ch = 'b'; break;
- case '\f': EMITQ(); ch = 'f'; break;
- case '\n': EMITQ(); ch = 'n'; break;
- case '\r': EMITQ(); ch = 'r'; break;
- case '\t': EMITQ(); ch = 't'; break;
- case '\v': EMITQ(); ch = 'v'; break;
-
- case '\\': /* fallthru */
- case '"': EMITQ(); break;
- default:
- /* octal */
- EMITQ();
- EMIT(((ch >> 6) & 03) + '0');
- EMIT(((ch >> 3) & 07) + '0');
- ch = (ch & 07) + '0';
- break;
- }
+
+ if (!no_dq && p == name)
+ EMIT('"');
+
+ EMITBUF(p, len);
+ EMIT('\\');
+ p += len;
+ ch = (unsigned char)*p++;
+ if (sq_lookup[ch] >= ' ') {
+ EMIT(sq_lookup[ch]);
+ } else {
+ EMIT(((ch >> 6) & 03) + '0');
+ EMIT(((ch >> 3) & 07) + '0');
+ EMIT(((ch >> 0) & 07) + '0');
}
- EMIT(ch);
}
+
+ EMITBUF(p, len);
+ if (p == name) /* no ending quote needed */
+ return 0;
+
if (!no_dq)
EMIT('"');
- if (outbuf)
- *outbuf = 0;
+ return count;
+}
- return needquote ? count : 0;
+size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq)
+{
+ return quote_c_style_counted(name, -1, sb, fp, nodq);
}
-int quote_c_style(const char *name, char *outbuf, FILE *outfp, int no_dq)
+void write_name_quoted(const char *name, FILE *fp, int terminator)
{
- int cnt = strlen(name);
- return quote_c_style_counted(name, cnt, outbuf, outfp, no_dq);
+ if (terminator) {
+ quote_c_style(name, NULL, fp, 0);
+ } else {
+ fputs(name, fp);
+ }
+ fputc(terminator, fp);
+}
+
+extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
+ const char *name, FILE *fp, int terminator)
+{
+ int needquote = 0;
+
+ if (terminator) {
+ needquote = next_quote_pos(pfx, pfxlen) < pfxlen
+ || name[next_quote_pos(name, -1)];
+ }
+ if (needquote) {
+ fputc('"', fp);
+ quote_c_style_counted(pfx, pfxlen, NULL, fp, 1);
+ quote_c_style(name, NULL, fp, 1);
+ fputc('"', fp);
+ } else {
+ fwrite(pfx, pfxlen, 1, fp);
+ fputs(name, fp);
+ }
+ fputc(terminator, fp);
}
/*
@@ -259,37 +318,6 @@ int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
return -1;
}
-void write_name_quoted(const char *prefix, int prefix_len,
- const char *name, int quote, FILE *out)
-{
- int needquote;
-
- if (!quote) {
- no_quote:
- if (prefix_len)
- fprintf(out, "%.*s", prefix_len, prefix);
- fputs(name, out);
- return;
- }
-
- needquote = 0;
- if (prefix_len)
- needquote = quote_c_style_counted(prefix, prefix_len,
- NULL, NULL, 0);
- if (!needquote)
- needquote = quote_c_style(name, NULL, NULL, 0);
- if (needquote) {
- fputc('"', out);
- if (prefix_len)
- quote_c_style_counted(prefix, prefix_len,
- NULL, out, 1);
- quote_c_style(name, NULL, out, 1);
- fputc('"', out);
- }
- else
- goto no_quote;
-}
-
/* quoting as a string literal for other languages */
void perl_quote_print(FILE *stream, const char *src)
diff --git a/quote.h b/quote.h
index 6407c4d..4287990 100644
--- a/quote.h
+++ b/quote.h
@@ -41,11 +41,11 @@ extern void sq_quote_argv(struct strbuf *, const char **argv, int count,
extern char *sq_dequote(char *);
extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp);
-extern int quote_c_style(const char *name, char *outbuf, FILE *outfp,
- int nodq);
+extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq);
-extern void write_name_quoted(const char *prefix, int prefix_len,
- const char *name, int quote, FILE *out);
+extern void write_name_quoted(const char *name, FILE *, int terminator);
+extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
+ const char *name, FILE *, int terminator);
/* quoting as a string literal for other languages */
extern void perl_quote_print(FILE *stream, const char *src);
--
1.5.3.1
^ permalink raw reply related
* Re: Problem with merge when renaming
From: David Euresti @ 2007-09-18 22:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7imnvca0.fsf@gitster.siamese.dyndns.org>
1) git version 1.5.2.5 and 1.5.3.1.139.g9346b
2)
$ git-merge -s resolve branch-a
$ git-merge -s resolve branch-b
Trying really trivial in-index merge...
fatal: Merge requires file-level merging
Nope.
Trying simple merge.
Simple merge failed, trying Automatic merge.
fatal: merge program failed
Automatic merge failed; fix conflicts and then commit the result.
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: bar.txt
# new file: foo.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# unmerged: dir/foo
# unmerged: dir/foo/foo.bin
# modified: dir/foo/foo.bin
#
But if I do it in the other order I get this:
$ git-merge -s resolve branch-b
$ git-merge -s resolve branch-a
Trying really trivial in-index merge...
fatal: Merge requires file-level merging
Nope.
Trying simple merge.
Simple merge failed, trying Automatic merge.
Removing dir/foo
Adding dir/foo/foo.bin
ERROR: untracked dir/foo/foo.bin is overwritten by the merge.
fatal: merge program failed
Automatic merge failed; fix conflicts and then commit the result.
deuresti@deuresti-lnx /tmp/scm-rename-test/git-repo
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: dir/foo
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# unmerged: dir/foo/foo.bin
#
Thanks,
David
On 9/18/07, Junio C Hamano <gitster@pobox.com> wrote:
> "David Euresti" <evelio@gmail.com> writes:
>
> > I think I found a problem when you move a file into a directory of the
> > same name. Here's what I did.
>
> Two questions.
>
> (1) git --version?
>
> (2) if you do "git merge -s resolve" instead of just "git
> merge", do you see a difference?
>
^ permalink raw reply
* Re: Problem with merge when renaming
From: Alex Riesen @ 2007-09-18 22:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: David Euresti, git
In-Reply-To: <7v7imnvca0.fsf@gitster.siamese.dyndns.org>
Junio C Hamano, Wed, Sep 19, 2007 00:28:39 +0200:
> "David Euresti" <evelio@gmail.com> writes:
>
> > I think I found a problem when you move a file into a directory of the
> > same name. Here's what I did.
>
> Two questions.
>
> (1) git --version?
it happens with very recent git (as of today)
> (2) if you do "git merge -s resolve" instead of just "git
> merge", do you see a difference?
yes: it has more error output.
Trying really trivial in-index merge...
warning: Merge requires file-level merging
Nope, a really trivial in-index merge not possible
Trying simple merge.
Simple merge failed, trying Automatic merge.
error: init: is a directory - add individual files instead
fatal: Unable to process path init
fatal: merge program failed
Automatic merge failed; fix conflicts and then commit the result.
^ permalink raw reply
* Re: [PATCH] git-merge: add option --no-ff
From: Peter Baumann @ 2007-09-18 22:51 UTC (permalink / raw)
To: Lars Hjemli; +Cc: git
In-Reply-To: <11900461843997-git-send-email-hjemli@gmail.com>
On Mon, Sep 17, 2007 at 06:23:04PM +0200, Lars Hjemli wrote:
> This option forces fast-forward merges to create a "true" merge commit,
> i.e. a commit with multiple parents.
>
> Although a fast-forward merge would normally be the right thing to do with
> git branches, it is suboptimal when operating on git-svn branches since it
> makes 'git-svn dcommit' fail to recognize the correct upstream subversion
> branch. But performing such a merge with --no-ff specified will both make
> git-svn dcommit recognize the correct upstream and create the logically
> correct history in subversion (the merge performed in git will be recorded
> as a single revision in subversion, not as a series of revisions seemingly
> cherry-picked from the merged branch).
>
> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
> ---
>
> When updating git-svn.txt, I noticed that we might want to update the
> section "DESIGN PHILOSOPHY". Eric?
>
>
> Documentation/git-svn.txt | 13 +++++++++++++
> Documentation/merge-options.txt | 5 +++++
> git-merge.sh | 13 +++++++++++--
> t/t6028-merge-up-to-date.sh | 25 +++++++++++++++++++++++++
> 4 files changed, 54 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
> index be2e34e..c510c21 100644
> --- a/Documentation/git-svn.txt
> +++ b/Documentation/git-svn.txt
> @@ -475,6 +475,19 @@ use 'git-svn rebase' to update your work branch instead of 'git pull' or
> when committing into SVN, which can lead to merge commits reversing
> previous commits in SVN.
>
> +If you use 'git-svn dcommit' to commit your local work to the upstream
> +subversion branch, merge commits are usually handled correctly, i.e.
> +git-svn will only follow the first parent of each merge commit and create
> +a single subversion revision for each of them. An exception is when two
> +subversion branches has been merged locally and the merge ended up as a
> +fast-forward operation. This will make git-svn belive that there are no
> +local changes to dcommit. To work around this issue, one can redo the
> +merge using the --no-ff option:
> +
> + $ git reset --hard HEAD@{1} ## undo the fast-forward merge
> + $ git merge --no-ff <branch>
> +
> +
> DESIGN PHILOSOPHY
> -----------------
> Merge tracking in Subversion is lacking and doing branched development
> diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
> index d64c259..b34b888 100644
> --- a/Documentation/merge-options.txt
> +++ b/Documentation/merge-options.txt
> @@ -25,3 +25,8 @@
> If there is no `-s` option, a built-in list of strategies
> is used instead (`git-merge-recursive` when merging a single
> head, `git-merge-octopus` otherwise).
> +
> +--no-ff::
> + Force the creation of a merge commit even when the merge would
> + have resolved as a fast-forward operation. See gitlink:git-svn[1]
> + for a use-case for this option.
> diff --git a/git-merge.sh b/git-merge.sh
> index 3a01db0..13b98e6 100755
> --- a/git-merge.sh
> +++ b/git-merge.sh
> @@ -3,7 +3,7 @@
> # Copyright (c) 2005 Junio C Hamano
> #
>
> -USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
> +USAGE='[-n] [--summary] [--no-commit] [--no-ff] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
>
> SUBDIRECTORY_OK=Yes
> . git-sh-setup
> @@ -165,6 +165,10 @@ do
> merge_msg="$1"
> have_message=t
> ;;
> + --no-ff)
> + no_ff=t
> + no_fast_forward_strategies=$all_strategies
> + ;;
> -*) usage ;;
> *) break ;;
> esac
> @@ -444,7 +448,12 @@ done
> # auto resolved the merge cleanly.
> if test '' != "$result_tree"
> then
> - parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
> + if test $no_ff = 't'
This should be quoted, e.g.
+ if test "$no_ff" = 't'
Otherwise I get an error like the following:
xp:/tmp/va (a)$ git merge b
Renamed msg.cc->common/msg.cc
Auto-merged common/msg.cc
Renamed msg.h->common/msg.h
Auto-merged common/msg.h
Renamed sampler/ConcurrentQueue.h->common/ConcurrentQueue.h
Auto-merged common/ConcurrentQueue.h
Renamed sampler/TimeoutSemaphore.h->common/TimeoutSemaphore.h
Auto-merged common/TimeoutSemaphore.h
/home/peter/usr/bin/git-merge: line 451: test: =: unary operator expected
Merge made by recursive.
> + then
> + parents=$(git rev-parse "$head" "$@" | sed -e 's/^/-p /')
> + else
> + parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
> + fi
> result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit
> finish "$result_commit" "Merge made by $wt_strategy."
> dropsave
-Peter
^ permalink raw reply
* Re: [PATCH 4/4] Make git-pull give hints on what to do when there is no branch to merge from
From: Junio C Hamano @ 2007-09-18 23:00 UTC (permalink / raw)
To: Federico Mena Quintero; +Cc: git
In-Reply-To: <1190077948.22387.66.camel@cacharro.xalalinux.org>
Federico Mena Quintero <federico@novell.com> writes:
> Signed-off-by: Federico Mena Quintero <federico@gnu.org>
> ---
> git-pull.sh | 6 +++++-
> 1 files changed, 5 insertions(+), 1 deletions(-)
>
> diff --git a/git-pull.sh b/git-pull.sh
> index 5e96d1f..7beef4d 100755
> --- a/git-pull.sh
> +++ b/git-pull.sh
> @@ -98,7 +98,11 @@ case "$merge_head" in
> curr_branch=${curr_branch#refs/heads/}
>
> echo >&2 "Warning: No merge candidate found because value of config option
> - \"branch.${curr_branch}.merge\" does not match any remote branch fetched."
> + \"branch.${curr_branch}.merge\" does not match any remote branch fetched.
> + This branch is not set up to track any other branches. Please name which
> + branch you want to merge from on the command line, or if you almost always
> + want to merge from the same branch, then set this up with
> + \"git branch --track\"."
This is a nice attempt, but can you use "git branch --track" to
set this? What does the command line look like?
This error can come when branch.<foo>.merge does not match what
remote.<bar>.fetch says (where branch.<foo>.remote is <bar>),
but it is my understanding that the builtin-fetch work by Daniel
and Shawn would fetch branch.<foo>.merge as well to reduce this
error. Another possibility is when the user does not have any
branch.<foo>.merge.
I am inclined to suggest rewording the message like this, and
make this condition an error (i.e. "exit 1"):
You asked me to pull without telling me which branch you
want to merge with, and 'branch.${curr_branch}.merge' in
your configuration file does not tell me either. Please
name which branch you want to merge on the command line and
try again.
If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:
branch.${curr_branch}.remote = <nickname>
branch.${curr_branch}.merge = <remote-ref>
remote.<nickname>.url = <url>
remote.<nickname>.fetch = <refspec>
See git-config(1) for details.
^ permalink raw reply
* Re: Latest builtin-commit series
From: Kristian Høgsberg @ 2007-09-18 23:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <7vbqbzvcf4.fsf@gitster.siamese.dyndns.org>
On Tue, 2007-09-18 at 15:25 -0700, Junio C Hamano wrote:
> Kristian Høgsberg <krh@redhat.com> writes:
>
> > Better late than never:
> >
> > * rebase to Pierres strbuf changes. Note, there is still some
> > strbuf tweaking required, to let stripspace work on a strbuf.
> > Also, I changed the semantics of stripspace to always add a
> > newline if the last line doesn't have one. I believe the
> > current odd semantics (always remove the last newline) comes
> > from not being able to easily add a newline, but now that it's a
> > strbuf, that's easy.
>
> I do not find the "remove trailing newline" so odd. Didn't it
> come because you sometimes needed to _not_ add it?
All users add a trailing newline if it's not present after stripping.
> > * Set the test suite default editor to '/bin/true' instead of ':'.
> > Since we're not exec'ing the editor from shell anymore, ':'
> > won't work. Maybe we should special case ':' in launch_editor
> > or perhaps make launch_editor use system(3). Not sure.
>
> We've had a few threads on the list about what to do with:
>
> GIT_EDITOR='emacs -nw'
>
> I think David's 08874658b450600e72bb7cb0d0747c1ec4b0bfe1
> (git-sh-setup.sh: make GIT_EDITOR/core.editor/VISUAL/EDITOR
> accept commands) is a sensible to deal with this issue, and
> prefer to see the same semantics kept in the C version.
Ok, I'll take a look at that commit.
Kristian
^ permalink raw reply
* Re: [PATCH] instaweb: added support Ruby's WEBrick server
From: Junio C Hamano @ 2007-09-18 23:15 UTC (permalink / raw)
To: mike dalessio; +Cc: git, normalperson
In-Reply-To: <20070918121634.E8EFF814635@cyrano>
mike@csa.net (mike dalessio) writes:
> diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
> index cec60ee..914fc4c 100644
> --- a/Documentation/git-instaweb.txt
> +++ b/Documentation/git-instaweb.txt
> @@ -27,7 +27,8 @@ OPTIONS
> The HTTP daemon command-line that will be executed.
> Command-line options may be specified here, and the
> configuration file will be added at the end of the command-line.
> - Currently, lighttpd and apache2 are the only supported servers.
> + Currently, lighttpd, apache2 and webrick are the only supported
> + servers.
> (Default: lighttpd)
Perhaps we can start thinking about rewording "are the only
suported servers" to "are supported".
> diff --git a/git-instaweb.sh b/git-instaweb.sh
> index b79c6b6..803a754 100755
> --- a/git-instaweb.sh
> +++ b/git-instaweb.sh
> @@ -37,7 +37,9 @@ start_httpd () {
> else
> # many httpds are installed in /usr/sbin or /usr/local/sbin
> # these days and those are not in most users $PATHs
> - for i in /usr/local/sbin /usr/sbin
> + # in addition, we may have generated a server script
> + # in $fqgitdir/gitweb.
> + for i in /usr/local/sbin /usr/sbin $fqgitdir/gitweb
> do
> if test -x "$i/$httpd_only"
> then
I do not think this hunk belongs to this patch. It alone would
be a useful addition to the program even without the rest of
your patch, wouldn't it? Imagine a case where I automatically
would reject all patches that have "Ruby" in it for some unknown
reason. Do we want to drop this hunk in such a case?
> + # generate a shell script to invoke the above ruby script,
> + # which assumes _ruby_ is in the user's $PATH. that's _one_
> + # portable way to run ruby, which could be installed anywhere,
> + # really.
No games with env, type, nor which. Good.
Just a few style things (-) and one concern (+):
> + cat > "$fqgitdir/gitweb/$httpd" <<EOF
> +#! /bin/sh
> +ruby $fqgitdir/gitweb/$httpd.rb \$*
> +EOF
- I do not like extra whitespace between she-bang #! and the
path. Looks very ugly.
- I do not like extra whitespace between redirection > and
redirected filename either. Looks very ugly.
- I prefer such wrapper to exec the command, like this:
#!/bin/sh
exec ruby ...
+ fqgitdir and httpd need to be shell quoted. I do not think
anybody is stupid enough to have his GIT_DIR set to something
like "/opt/funny/; rm -f / nuke-me/.git/" but you would see
spaces and single quotes in pathnames in odd environments.
I wonder how popular instaweb is and how widely it is used.
I've actually wondering if we should demote it to contrib/
somewhere, but it gets occasional updates so people must be
using it...
^ permalink raw reply
* Re: State of Perforce importing.
From: David Brown @ 2007-09-18 23:19 UTC (permalink / raw)
To: Reece Dunn; +Cc: Sam Vilain, Git
In-Reply-To: <3f4fd2640709181053t70b7abcdi2c4eaf67e7b75338@mail.gmail.com>
On Tue, Sep 18, 2007 at 06:53:45PM +0100, Reece Dunn wrote:
>The main issues with using client workspaces is that they require you
>to use `p4 sync`, whereas git-p4 uses `p4 print` and that they may
>change as the repository changes, but Perforce does not track these
>changes.
Unfortunately, we have one project that heavily abuses P4 client specs.
For every release, someone creates a >900 line client spec and labels the
files in it. Those are the versions that need to get checked in, and
without rewriting much of what P4 does, I'm going to have to let P4 do the
syncing and checking out.
>I would not do that. It is a good idea to keep the original log
>messages, even if it does make for an uninformative shortlog. Look at
>some of the CVS/SVN imported logs!
I think what I want then is something to filter between 'git log' and 'git
shortlog' that would find a summary line in the commit message and copy it
to the top. It wouldn't change the history, but clean it up for shortlog's
purpose.
David
^ permalink raw reply
* Re: Problem with merge when renaming
From: Junio C Hamano @ 2007-09-18 23:27 UTC (permalink / raw)
To: Alex Riesen; +Cc: David Euresti, git
In-Reply-To: <20070918224447.GC14488@steel.home>
Alex Riesen <raa.lkml@gmail.com> writes:
> Junio C Hamano, Wed, Sep 19, 2007 00:28:39 +0200:
>> "David Euresti" <evelio@gmail.com> writes:
>>
>> > I think I found a problem when you move a file into a directory of the
>> > same name. Here's what I did.
>>
>> Two questions.
>>
>> (1) git --version?
>
> it happens with very recent git (as of today)
>
>> (2) if you do "git merge -s resolve" instead of just "git
>> merge", do you see a difference?
>
> yes: it has more error output.
>
> Trying really trivial in-index merge...
> warning: Merge requires file-level merging
> Nope, a really trivial in-index merge not possible
> Trying simple merge.
> Simple merge failed, trying Automatic merge.
> error: init: is a directory - add individual files instead
> fatal: Unable to process path init
> fatal: merge program failed
> Automatic merge failed; fix conflicts and then commit the result.
Isn't this the same as the known issue here?
<http://permalink.gmane.org/gmane.comp.version-control.git/53402>
^ permalink raw reply
* Re: State of Perforce importing.
From: David Brown @ 2007-09-18 23:37 UTC (permalink / raw)
To: Git
In-Reply-To: <20070917193027.GA24282@old.davidb.org>
On Mon, Sep 17, 2007 at 12:30:28PM -0700, David Brown wrote:
> I'd like to track a lot of code living in a Perforce repository, so I've
> been playing with 'git-p4.py'. Is the one in the contrib/fast-import
> directory the latest version, or is there a better place.
>
> So far, it is having a couple of problems:
>
> - The commit comment is empty. It doesn't seem to grab the Perforce
> description, and the user seems to be <a@b>.
>
> - Every revision seems to check every file out of Perforce. This means
> that for the directory I want, every revision is going to take about 20
> minutes.
An additional problem:
- git-p4 doesn't preserve the execute permission bit from Perforce.
David
^ permalink raw reply
* [PATCH] Documentation/git-svn: updated design philosophy notes
From: Eric Wong @ 2007-09-18 23:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Lars Hjemli, git
This section has not been updated in a while and
--branches/--tags/--trunk options are commonly used nowadays.
Noticed-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
Documentation/git-svn.txt | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
Eric Wong <normalperson@yhbt.net> wrote:
> Lars Hjemli <hjemli@gmail.com> wrote:
> > When updating git-svn.txt, I noticed that we might want to update the
> > section "DESIGN PHILOSOPHY". Eric?
>
> Yeah. That's very much out of date. I'll update it in a bit.
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index be2e34e..e157c6a 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -478,11 +478,12 @@ previous commits in SVN.
DESIGN PHILOSOPHY
-----------------
Merge tracking in Subversion is lacking and doing branched development
-with Subversion is cumbersome as a result. git-svn does not do
-automated merge/branch tracking by default and leaves it entirely up to
-the user on the git side. git-svn does however follow copy
-history of the directory that it is tracking, however (much like
-how 'svn log' works).
+with Subversion can be cumbersome as a result. While git-svn can track
+copy history (including branches and tags) for repositories adopting a
+standard layout, it cannot yet represent merge history that happened
+inside git back upstream to SVN users. Therefore it is advised that
+users keep history as linear as possible inside git to ease
+compatibility with SVN (see the CAVEATS section below).
CAVEATS
-------
--
Eric Wong
^ permalink raw reply related
* Re: [PATCH 4/5] Full rework of quote_c_style and write_name_quoted.
From: Pierre Habouzit @ 2007-09-19 0:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070918224122.2B55D344AB3@madism.org>
[-- Attachment #1: Type: text/plain, Size: 461 bytes --]
On Tue, Sep 18, 2007 at 10:00:51PM +0000, Pierre Habouzit wrote:
> + cp = strchr(qname.buf + qname.len + 3 - max, '/');
> + if (cp)
> + cp = qname.buf + qname.len + 3 - max;
OMG, this is supposed to be if (!cp) of course...
I wonder how this passed the testsuite.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 3/5] Rework unquote_c_style to work on a strbuf.
From: Pierre Habouzit @ 2007-09-19 0:14 UTC (permalink / raw)
To: Junio C Hamano, Shawn O. Pearce; +Cc: git
In-Reply-To: <20070918224121.24C3B344AB3@madism.org>
[-- Attachment #1: Type: text/plain, Size: 436 bytes --]
On Tue, Sep 18, 2007 at 09:22:47PM +0000, Pierre Habouzit wrote:
> + for (cp = name.buf; p_value; p_value--) {
> + cp = strchr(name.buf, '/');
And I forgot to fix this, as cp = strchr(cp...) like the patch I
proposed for integration in maint.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: State of Perforce importing.
From: Sam Vilain @ 2007-09-19 0:20 UTC (permalink / raw)
To: Reece Dunn; +Cc: Git
In-Reply-To: <20070918231921.GA17652@old.davidb.org>
David Brown wrote:
> On Tue, Sep 18, 2007 at 06:53:45PM +0100, Reece Dunn wrote:
>
>> The main issues with using client workspaces is that they require you
>> to use `p4 sync`, whereas git-p4 uses `p4 print` and that they may
>> change as the repository changes, but Perforce does not track these
>> changes.
>
> Unfortunately, we have one project that heavily abuses P4 client specs.
> For every release, someone creates a >900 line client spec and labels the
> files in it. Those are the versions that need to get checked in, and
> without rewriting much of what P4 does, I'm going to have to let P4 do the
> syncing and checking out.
If you can get a hold of the "checkpoint" and "journal" files, you could
probably throw the client spec data into a few Pg tables, chuck a couple
of constraints on it to confirm that it works the way you thought, and
then get the information on what's where using a SQL query. The file
images themselves can come from wherever, it doesn't really matter
because there are MD5 hashes in the data tables you can use to confirm
you got the right file.
I haven't looked at importing the client spec because it's not important
for the project I'm importing. But I'd be happy to provide pointers.
>> I would not do that. It is a good idea to keep the original log
>> messages, even if it does make for an uninformative shortlog. Look at
>> some of the CVS/SVN imported logs!
> I think what I want then is something to filter between 'git log' and 'git
> shortlog' that would find a summary line in the commit message and copy it
> to the top. It wouldn't change the history, but clean it up for shortlog's
> purpose.
Sounds like a job for a templating git-log porcelain.
Sam.
^ permalink raw reply
* Re: State of Perforce importing.
From: Sam Vilain @ 2007-09-19 0:23 UTC (permalink / raw)
To: David Brown; +Cc: Git
In-Reply-To: <20070918233749.GA19533@old.davidb.org>
David Brown wrote:
>
> An additional problem:
>
> - git-p4 doesn't preserve the execute permission bit from Perforce.
FWIW I found that bit on bit 9 of the 'file type' flag in the db, which
is the third column in the "db.rev" table. It's used to come up with
the silly names like "text" vs "xtext" (difference? well, one's
executable of course).
Sam.
^ permalink raw reply
* Re: State of Perforce importing.
From: Sam Vilain @ 2007-09-19 0:23 UTC (permalink / raw)
To: Reece Dunn; +Cc: Git
In-Reply-To: <3f4fd2640709181053t70b7abcdi2c4eaf67e7b75338@mail.gmail.com>
Reece Dunn wrote:
> There is no need to create yet another Perforce importing tool, git-p4
> works well in most cases. If we focus on improving git-p4, extending
> it to support the functionality mentioned here, fix the issues that
> there are with it, then that will be more beneficial to the community
> as they will not have to learn another tool with a different set of
> bugs and issues.
I like my approach; it's clean and I think shows a tasteful level of
distrust towards the sanity and integrity of the data held by Perforce.
Actually it really helped me understand what was really going on;
because the information as displayed by for instance "p4 integrate" is
a lot more confusing than the underlying tables (IMHO).
Sam.
^ permalink raw reply
* Re: State of Perforce importing.
From: David Brown @ 2007-09-19 0:26 UTC (permalink / raw)
To: Sam Vilain; +Cc: Reece Dunn, Git
In-Reply-To: <46F06B5C.2050207@vilain.net>
On Wed, Sep 19, 2007 at 12:20:44PM +1200, Sam Vilain wrote:
>If you can get a hold of the "checkpoint" and "journal" files, you could
>probably throw the client spec data into a few Pg tables, chuck a couple
>of constraints on it to confirm that it works the way you thought, and
>then get the information on what's where using a SQL query. The file
>images themselves can come from wherever, it doesn't really matter
>because there are MD5 hashes in the data tables you can use to confirm
>you got the right file.
In my instance, I don't have an account on the P4 server, so I'm going to
have to deal with this through P4's normal client.
I don't have much confidence that P4 really knows what it is doing when it
comes to integrate, so I'm not much worried about branches. But, I do want
to accurately get the history of a particular branch.
So far, the only thing that isn't working is the execute bit doesn't get
set on files that should have it.
Dave
^ permalink raw reply
* Re: State of Perforce importing.
From: David Brown @ 2007-09-19 0:27 UTC (permalink / raw)
To: Sam Vilain; +Cc: Git
In-Reply-To: <46F06C0C.8090201@vilain.net>
On Wed, Sep 19, 2007 at 12:23:40PM +1200, Sam Vilain wrote:
>David Brown wrote:
>>
>> An additional problem:
>>
>> - git-p4 doesn't preserve the execute permission bit from Perforce.
>
>FWIW I found that bit on bit 9 of the 'file type' flag in the db, which
>is the third column in the "db.rev" table. It's used to come up with
>the silly names like "text" vs "xtext" (difference? well, one's
>executable of course).
It does come back in the 'kind' field when it asks the client for the file
type. I'll look into using that information to set the execute bit in the
mode it sends off.
Dave
^ permalink raw reply
* Re: [PATCH] instaweb: added support Ruby's WEBrick server
From: David Symonds @ 2007-09-19 0:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: mike dalessio, git, normalperson
In-Reply-To: <7vodfztviv.fsf@gitster.siamese.dyndns.org>
On 19/09/2007, Junio C Hamano <gitster@pobox.com> wrote:
> - I do not like extra whitespace between she-bang #! and the
> path. Looks very ugly.
At least according to the Autoconf manual, there are some UNIXes that
require a space after the shebang. Not that I've seen such a system.
Personally, I find it easier to read with the space.
Dave.
^ permalink raw reply
* Re: [PATCH 4/5] Full rework of quote_c_style and write_name_quoted.
From: Junio C Hamano @ 2007-09-19 0:55 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <20070919000757.GC4535@artemis.corp>
Pierre Habouzit <madcoder@debian.org> writes:
> On Tue, Sep 18, 2007 at 10:00:51PM +0000, Pierre Habouzit wrote:
>> + cp = strchr(qname.buf + qname.len + 3 - max, '/');
>> + if (cp)
>> + cp = qname.buf + qname.len + 3 - max;
>
> OMG, this is supposed to be if (!cp) of course...
>
> I wonder how this passed the testsuite.
You would need a new test, I guess, before a huge rewrite.
^ permalink raw reply
* Re: Git tree for old kernels from before the current tree
From: Oleg Verych @ 2007-09-19 1:19 UTC (permalink / raw)
To: Linus Torvalds
Cc: Nicolas Pitre, H. Peter Anvin, Jan Engelhardt, Paul Mundt,
Jon Smirl, Git Mailing List, lkml
In-Reply-To: <alpine.LFD.0.999.0707231057480.3607@woody.linux-foundation.org>
* Mon, 23 Jul 2007 11:02:39 -0700 (PDT)
>
> On Mon, 23 Jul 2007, Nicolas Pitre wrote:
>>
>> I started this once.
>>
>> I have (sort of) a GIT tree with all Linux revisions that I could find
>> from v0.01 up to v1.0.9. But the most interesting information and also
>> what is the most time consuming is the retrieval of announcement
>> messages for those releases in old mailing list or newsgroup archives to
>> serve as commit log data. It seems to be even arder to find for post
>> v1.0 releases.
>
> Yes, I agree. Google finds some of them, but (a) I was never very good
> about announcements anyway and (b) there's nothing really good to search
> for, so it's very hit-and-miss.
>
> Some of the really early release notes are easy to find, just because I
> made them available with the sources, but mostly I'd just have posten to
> the newsgroup/mailing lists.
Maybe this can be useful somehow: ftp://ftp.shout.net/pub/users/mec/kcs
____
^ permalink raw reply
* Re: [PATCH 4/5] Full rework of quote_c_style and write_name_quoted.
From: Pierre Habouzit @ 2007-09-19 1:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vabrjtqw7.fsf@gitster.siamese.dyndns.org>
[-- Attachment #1: Type: text/plain, Size: 846 bytes --]
On Wed, Sep 19, 2007 at 12:55:52AM +0000, Junio C Hamano wrote:
> Pierre Habouzit <madcoder@debian.org> writes:
>
> > On Tue, Sep 18, 2007 at 10:00:51PM +0000, Pierre Habouzit wrote:
> >> + cp = strchr(qname.buf + qname.len + 3 - max, '/');
> >> + if (cp)
> >> + cp = qname.buf + qname.len + 3 - max;
> >
> > OMG, this is supposed to be if (!cp) of course...
> >
> > I wonder how this passed the testsuite.
>
> You would need a new test, I guess, before a huge rewrite.
OTOH this is in the code that generates the diffstats, it's not _that_
surprising that we don't have extensive tests about that, as it's not
critical in git afaict ;)
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox