From 6a0b0b6de996e2ac7eeb951e3d08f577c11c7e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 30 Nov 2014 16:05:00 +0700 Subject: tree.c: update read_tree_recursive callback to pass strbuf as base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the callback to use 'base' as a temporary buffer to quickly assemble full path "without" extra allocation. The callback has to restore it afterwards of course. Helped-by: Eric Sunshine Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- archive.c | 34 +++++++++++++++++++++------------- builtin/checkout.c | 8 ++++---- builtin/log.c | 2 +- builtin/ls-tree.c | 9 +++++---- merge-recursive.c | 15 ++++++--------- tree.c | 16 +++++++++++----- tree.h | 3 ++- 7 files changed, 50 insertions(+), 37 deletions(-) diff --git a/archive.c b/archive.c index 94a9981adf..9e30246b64 100644 --- a/archive.c +++ b/archive.c @@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, return write_entry(args, sha1, path.buf, path.len, mode); } +static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base, + const char *filename, unsigned mode, int stage, + void *context) +{ + return write_archive_entry(sha1, base->buf, base->len, + filename, mode, stage, context); +} + static void queue_directory(const unsigned char *sha1, - const char *base, int baselen, const char *filename, + struct strbuf *base, const char *filename, unsigned mode, int stage, struct archiver_context *c) { struct directory *d; - d = xmallocz(sizeof(*d) + baselen + 1 + strlen(filename)); + d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename)); d->up = c->bottom; - d->baselen = baselen; + d->baselen = base->len; d->mode = mode; d->stage = stage; c->bottom = d; - d->len = sprintf(d->path, "%.*s%s/", baselen, base, filename); + d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename); hashcpy(d->sha1, sha1); } @@ -191,28 +199,28 @@ static int write_directory(struct archiver_context *c) } static int queue_or_write_archive_entry(const unsigned char *sha1, - const char *base, int baselen, const char *filename, + struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { struct archiver_context *c = context; while (c->bottom && - !(baselen >= c->bottom->len && - !strncmp(base, c->bottom->path, c->bottom->len))) { + !(base->len >= c->bottom->len && + !strncmp(base->buf, c->bottom->path, c->bottom->len))) { struct directory *next = c->bottom->up; free(c->bottom); c->bottom = next; } if (S_ISDIR(mode)) { - queue_directory(sha1, base, baselen, filename, + queue_directory(sha1, base, filename, mode, stage, c); return READ_TREE_RECURSIVE; } if (write_directory(c)) return -1; - return write_archive_entry(sha1, base, baselen, filename, mode, + return write_archive_entry(sha1, base->buf, base->len, filename, mode, stage, context); } @@ -260,7 +268,7 @@ int write_archive_entries(struct archiver_args *args, err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec, args->pathspec.has_wildcard ? queue_or_write_archive_entry : - write_archive_entry, + write_archive_entry_buf, &context); if (err == READ_TREE_RECURSIVE) err = 0; @@ -286,14 +294,14 @@ static const struct archiver *lookup_archiver(const char *name) return NULL; } -static int reject_entry(const unsigned char *sha1, const char *base, - int baselen, const char *filename, unsigned mode, +static int reject_entry(const unsigned char *sha1, struct strbuf *base, + const char *filename, unsigned mode, int stage, void *context) { int ret = -1; if (S_ISDIR(mode)) { struct strbuf sb = STRBUF_INIT; - strbuf_addstr(&sb, base); + strbuf_addbuf(&sb, base); strbuf_addstr(&sb, filename); if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1)) ret = READ_TREE_RECURSIVE; diff --git a/builtin/checkout.c b/builtin/checkout.c index 5410dacea0..8adf48de74 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new, } -static int update_some(const unsigned char *sha1, const char *base, int baselen, +static int update_some(const unsigned char *sha1, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int len; @@ -71,11 +71,11 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen, if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; - len = baselen + strlen(pathname); + len = base->len + strlen(pathname); ce = xcalloc(1, cache_entry_size(len)); hashcpy(ce->sha1, sha1); - memcpy(ce->name, base, baselen); - memcpy(ce->name + baselen, pathname, len - baselen); + memcpy(ce->name, base->buf, base->len); + memcpy(ce->name + base->len, pathname, len - base->len); ce->ce_flags = create_ce_flags(0) | CE_UPDATE; ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); diff --git a/builtin/log.c b/builtin/log.c index 734aab3a73..f2a9f0156d 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev) } static int show_tree_object(const unsigned char *sha1, - const char *base, int baselen, + struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : ""); diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 51184dfa2e..1ab0381245 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -61,7 +61,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname) } } -static int show_tree(const unsigned char *sha1, const char *base, int baselen, +static int show_tree(const unsigned char *sha1, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int retval = 0; @@ -79,7 +79,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, */ type = commit_type; } else if (S_ISDIR(mode)) { - if (show_recursive(base, baselen, pathname)) { + if (show_recursive(base->buf, base->len, pathname)) { retval = READ_TREE_RECURSIVE; if (!(ls_options & LS_SHOW_TREES)) return retval; @@ -90,7 +90,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, return 0; if (chomp_prefix && - (baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix))) + (base->len < chomp_prefix || + memcmp(ls_tree_prefix, base->buf, chomp_prefix))) return 0; if (!(ls_options & LS_NAME_ONLY)) { @@ -112,7 +113,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, printf("%06o %s %s\t", mode, type, find_unique_abbrev(sha1, abbrev)); } - write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix, + write_name_quotedpfx(base->buf + chomp_prefix, base->len - chomp_prefix, pathname, stdout, line_termination); return retval; } diff --git a/merge-recursive.c b/merge-recursive.c index fdb7d0f10b..25c067e4a7 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o) } static int save_files_dirs(const unsigned char *sha1, - const char *base, int baselen, const char *path, + struct strbuf *base, const char *path, unsigned int mode, int stage, void *context) { - int len = strlen(path); - char *newpath = xmalloc(baselen + len + 1); + int baselen = base->len; struct merge_options *o = context; - memcpy(newpath, base, baselen); - memcpy(newpath + baselen, path, len); - newpath[baselen + len] = '\0'; + strbuf_addstr(base, path); if (S_ISDIR(mode)) - string_list_insert(&o->current_directory_set, newpath); + string_list_insert(&o->current_directory_set, base->buf); else - string_list_insert(&o->current_file_set, newpath); - free(newpath); + string_list_insert(&o->current_file_set, base->buf); + strbuf_setlen(base, baselen); return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0); } diff --git a/tree.c b/tree.c index bb02c1caa4..58ebfce1bc 100644 --- a/tree.c +++ b/tree.c @@ -30,9 +30,12 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b return add_cache_entry(ce, opt); } -static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context) +static int read_one_entry(const unsigned char *sha1, struct strbuf *base, + const char *pathname, unsigned mode, int stage, + void *context) { - return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage, + return read_one_entry_opt(sha1, base->buf, base->len, pathname, + mode, stage, ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); } @@ -40,9 +43,12 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel * This is used when the caller knows there is no existing entries at * the stage that will conflict with the entry being added. */ -static int read_one_entry_quick(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context) +static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base, + const char *pathname, unsigned mode, int stage, + void *context) { - return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage, + return read_one_entry_opt(sha1, base->buf, base->len, pathname, + mode, stage, ADD_CACHE_JUST_APPEND); } @@ -70,7 +76,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base, continue; } - switch (fn(entry.sha1, base->buf, base->len, + switch (fn(entry.sha1, base, entry.path, entry.mode, stage, context)) { case 0: continue; diff --git a/tree.h b/tree.h index d84ac63e51..d24125f84f 100644 --- a/tree.h +++ b/tree.h @@ -4,6 +4,7 @@ #include "object.h" extern const char *tree_type; +struct strbuf; struct tree { struct object object; @@ -22,7 +23,7 @@ void free_tree_buffer(struct tree *tree); struct tree *parse_tree_indirect(const unsigned char *sha1); #define READ_TREE_RECURSIVE 1 -typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int, void *); +typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *); extern int read_tree_recursive(struct tree *tree, const char *base, int baselen, -- cgit v1.2.3 From 1cf9952db243c624cc2763fa74e98adbb38537b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 30 Nov 2014 16:05:01 +0700 Subject: ls-tree: remove path filtering logic in show_tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ls-tree uses read_tree_recursive() which already does path filtering using pathspec. No need to filter one more time based on prefix only. "ls-tree ../somewhere" does not work because of this. write_name_quotedpfx() can now be retired because nobody else uses it. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/ls-tree.c | 14 +++++++------- quote.c | 21 --------------------- quote.h | 2 -- t/t3102-ls-tree-wildcards.sh | 8 ++++++++ 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 1ab0381245..053edb23a0 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -65,6 +65,7 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int retval = 0; + int baselen; const char *type = blob_type; if (S_ISGITLINK(mode)) { @@ -89,11 +90,6 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base, else if (ls_options & LS_TREE_ONLY) return 0; - if (chomp_prefix && - (base->len < chomp_prefix || - memcmp(ls_tree_prefix, base->buf, chomp_prefix))) - return 0; - if (!(ls_options & LS_NAME_ONLY)) { if (ls_options & LS_SHOW_SIZE) { char size_text[24]; @@ -113,8 +109,12 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base, printf("%06o %s %s\t", mode, type, find_unique_abbrev(sha1, abbrev)); } - write_name_quotedpfx(base->buf + chomp_prefix, base->len - chomp_prefix, - pathname, stdout, line_termination); + baselen = base->len; + strbuf_addstr(base, pathname); + write_name_quoted_relative(base->buf, + chomp_prefix ? ls_tree_prefix : NULL, + stdout, line_termination); + strbuf_setlen(base, baselen); return retval; } diff --git a/quote.c b/quote.c index 45e3db12d5..7920e18e44 100644 --- a/quote.c +++ b/quote.c @@ -274,27 +274,6 @@ void write_name_quoted(const char *name, FILE *fp, int terminator) fputc(terminator, fp); } -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); -} - void write_name_quoted_relative(const char *name, const char *prefix, FILE *fp, int terminator) { diff --git a/quote.h b/quote.h index 71dcc3aa02..99e04d34bf 100644 --- a/quote.h +++ b/quote.h @@ -56,8 +56,6 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); 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); extern void write_name_quoted_relative(const char *name, const char *prefix, FILE *fp, int terminator); diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index c286854485..83fca8df8b 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -19,4 +19,12 @@ EOF test_cmp expected actual ' +test_expect_success 'ls-tree outside prefix' ' + cat >expected <actual && + test_cmp expected actual +' + test_done -- cgit v1.2.3 From 5c6cb9888df9d21ddbb5c3478d511edcdf3cda7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 30 Nov 2014 16:05:02 +0700 Subject: ls-tree: disable negative pathspec because it's not supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/ls-tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 053edb23a0..3b04a0f082 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -174,7 +174,8 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) * cannot be lifted until it is converted to use * match_pathspec() or tree_entry_interesting() */ - parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE, + parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE | + PATHSPEC_EXCLUDE, PATHSPEC_PREFER_CWD, prefix, argv + 1); for (i = 0; i < pathspec.nr; i++) -- cgit v1.2.3 From 4be4f71f55c5677a2671894cd218e311862a98ad Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 1 Dec 2014 11:48:34 -0800 Subject: t3102: document that ls-tree does not yet support negated pathspec Signed-off-by: Junio C Hamano --- t/t3102-ls-tree-wildcards.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index 83fca8df8b..ef724200a6 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -27,4 +27,10 @@ EOF test_cmp expected actual ' +test_expect_failure 'ls-tree does not yet support negated pathspec' ' + git ls-files ":(exclude)a" "a*" >expect && + git ls-tree --name-only -r HEAD ":(exclude)a" "a*" >actual && + test_cmp expect actual +' + test_done -- cgit v1.2.3 From f1f6224c72255e17230e7347d64a2be292a9f299 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 1 Dec 2014 11:45:57 -0800 Subject: t3102: style modernization Use <<-\END_OF_HERE_DOCUMENT to allow indenting the HERE document to make it clear where each test begins and ends, and relieve readers from having to worry about variable substitution. Signed-off-by: Junio C Hamano --- t/t3102-ls-tree-wildcards.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index ef724200a6..4d4b02e760 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -12,19 +12,19 @@ test_expect_success 'setup' ' ' test_expect_success 'ls-tree a[a] matches literally' ' - cat >expected <expect <<-\EOF && + 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three + EOF git ls-tree -r HEAD "a[a]" >actual && - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'ls-tree outside prefix' ' - cat >expected <expect <<-\EOF && + 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 ../a[a]/three + EOF ( cd aa && git ls-tree -r HEAD "../a[a]"; ) >actual && - test_cmp expected actual + test_cmp expect actual ' test_expect_failure 'ls-tree does not yet support negated pathspec' ' -- cgit v1.2.3