{"thread":{"id":"25280","subject":"[PATCH 1/6] Add struct pathspec","startedAt":"2010-09-28T12:00:23Z","lastAt":"2010-09-28T12:00:29Z","messageCount":7,"participants":["Nguyễn Thái Ngọc Duy"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"151976","messageId":"1285675229-28019-1-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":null,"subject":"[PATCH v2 0/6] Introduct pathspec struct","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:23Z","receivedAt":"2010-09-28T12:00:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Just minor changes from Junio's comments. A comment managed to\nsneak in cache.h, to briefly explain \"raw\" field.\n\nNguyễn Thái Ngọc Duy (6):\n  Add struct pathspec\n  diff-no-index: use diff_tree_setup_paths()\n  pathspec: cache string length when initializing pathspec\n  Convert struct diff_options to use struct pathspec\n  tree_entry_interesting(): remove dependency on struct diff_options\n  Move tree_entry_interesting() to tree-walk.c and export it\n\n builtin/diff-files.c |    2 +-\n builtin/diff.c       |    4 +-\n builtin/log.c        |    2 +-\n cache.h              |   10 +++\n diff-lib.c           |    2 +-\n diff-no-index.c      |   13 ++--\n diff.h               |    4 +-\n dir.c                |   29 +++++++++\n revision.c           |    6 +--\n tree-diff.c          |  157 +++-----------------------------------------------\n tree-walk.c          |  111 +++++++++++++++++++++++++++++++++++\n tree-walk.h          |    2 +\n 12 files changed, 175 insertions(+), 167 deletions(-)\n"},{"id":"151974","messageId":"1285675229-28019-2-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 1/6] Add struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:24Z","receivedAt":"2010-09-28T12:00:24Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This struct for now is just a wrapper for the current pathspec form:\nconst char **. It is intended to be extended with more useful\npathspec-related information over time.\n\nThe data structure for passing pathspec around remains const char **,\nstruct pathspec will be initialized locally to be used and destroyed.\nHopefully all pathspec related code will be gradually migrated to pass\nthis struct instead.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h |    7 +++++++\n dir.c   |   18 ++++++++++++++++++\n 2 files changed, 25 insertions(+), 0 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex eb77e1d..a3029fd 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -492,6 +492,13 @@ extern int index_name_is_other(const struct index_state *, const char *, int);\n extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);\n extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);\n \n+struct pathspec {\n+\tconst char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n+\tint nr;\n+};\n+\n+extern int init_pathspec(struct pathspec *, const char **);\n+extern void free_pathspec(struct pathspec *);\n extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);\n extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);\n extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);\ndiff --git a/dir.c b/dir.c\nindex 133f472..205adc4 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1071,3 +1071,21 @@ int remove_path(const char *name)\n \treturn 0;\n }\n \n+int init_pathspec(struct pathspec *pathspec, const char **paths)\n+{\n+\tconst char **p = paths;\n+\n+\tmemset(pathspec, 0, sizeof(*pathspec));\n+\tif (!p)\n+\t\treturn 0;\n+\twhile (*p)\n+\t\tp++;\n+\tpathspec->raw = paths;\n+\tpathspec->nr = p - paths;\n+\treturn 0;\n+}\n+\n+void free_pathspec(struct pathspec *pathspec)\n+{\n+\t; /* do nothing */\n+}\n-- \n1.7.1.rc1.70.g788ca\n"},{"id":"151975","messageId":"1285675229-28019-3-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/6] diff-no-index: use diff_tree_setup_paths()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:25Z","receivedAt":"2010-09-28T12:00:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"diff_options.{paths,nr_paths} will be removed later. Do not\nmodify them directly.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n diff-no-index.c |    9 +++++----\n 1 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex ce9e783..e48ab92 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -231,8 +231,9 @@ void diff_no_index(struct rev_info *revs,\n \n \tif (prefix) {\n \t\tint len = strlen(prefix);\n+\t\tconst char *paths[3];\n+\t\tmemset(paths, 0, sizeof(paths));\n \n-\t\trevs->diffopt.paths = xcalloc(2, sizeof(char *));\n \t\tfor (i = 0; i < 2; i++) {\n \t\t\tconst char *p = argv[argc - 2 + i];\n \t\t\t/*\n@@ -242,12 +243,12 @@ void diff_no_index(struct rev_info *revs,\n \t\t\tp = (strcmp(p, \"-\")\n \t\t\t     ? xstrdup(prefix_filename(prefix, len, p))\n \t\t\t     : p);\n-\t\t\trevs->diffopt.paths[i] = p;\n+\t\t\tpaths[i] = p;\n \t\t}\n+\t\tdiff_tree_setup_paths(paths, &revs->diffopt);\n \t}\n \telse\n-\t\trevs->diffopt.paths = argv + argc - 2;\n-\trevs->diffopt.nr_paths = 2;\n+\t\tdiff_tree_setup_paths(argv + argc - 2, &revs->diffopt);\n \trevs->diffopt.skip_stat_unmatch = 1;\n \tif (!revs->diffopt.output_format)\n \t\trevs->diffopt.output_format = DIFF_FORMAT_PATCH;\n-- \n1.7.1.rc1.70.g788ca\n"},{"id":"151977","messageId":"1285675229-28019-4-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 3/6] pathspec: cache string length when initializing pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:26Z","receivedAt":"2010-09-28T12:00:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This field will be used when tree_entry_interesting() is converted to\nuse struct pathspec. Currently it uses pathlens[] in struct\ndiff_options to avoid calculating string over and over again.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h |    3 +++\n dir.c   |   13 ++++++++++++-\n 2 files changed, 15 insertions(+), 1 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex a3029fd..d4d9bc5 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -495,6 +495,9 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct\n struct pathspec {\n \tconst char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n \tint nr;\n+\tstruct pathspec_item {\n+\t\tint len;\n+\t} *items;\n };\n \n extern int init_pathspec(struct pathspec *, const char **);\ndiff --git a/dir.c b/dir.c\nindex 205adc4..646c79f 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1074,6 +1074,7 @@ int remove_path(const char *name)\n int init_pathspec(struct pathspec *pathspec, const char **paths)\n {\n \tconst char **p = paths;\n+\tint i;\n \n \tmemset(pathspec, 0, sizeof(*pathspec));\n \tif (!p)\n@@ -1082,10 +1083,20 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)\n \t\tp++;\n \tpathspec->raw = paths;\n \tpathspec->nr = p - paths;\n+\tif (!pathspec->nr)\n+\t\treturn 0;\n+\n+\tpathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr);\n+\tfor (i = 0; i < pathspec->nr; i++) {\n+\t\tstruct pathspec_item *item = pathspec->items+i;\n+\n+\t\titem->len = strlen(paths[i]);\n+\t}\n \treturn 0;\n }\n \n void free_pathspec(struct pathspec *pathspec)\n {\n-\t; /* do nothing */\n+\tfree(pathspec->items);\n+\tpathspec->items = NULL;\n }\n-- \n1.7.1.rc1.70.g788ca\n"},{"id":"151978","messageId":"1285675229-28019-5-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 4/6] Convert struct diff_options to use struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:27Z","receivedAt":"2010-09-28T12:00:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/diff-files.c |    2 +-\n builtin/diff.c       |    4 ++--\n builtin/log.c        |    2 +-\n diff-lib.c           |    2 +-\n diff-no-index.c      |    4 ++--\n diff.h               |    4 +---\n revision.c           |    6 +-----\n tree-diff.c          |   46 +++++++++++-----------------------------------\n 8 files changed, 20 insertions(+), 50 deletions(-)\n\ndiff --git a/builtin/diff-files.c b/builtin/diff-files.c\nindex 951c7c8..46085f8 100644\n--- a/builtin/diff-files.c\n+++ b/builtin/diff-files.c\n@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)\n \t    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))\n \t\trev.combine_merges = rev.dense_combined_merges = 1;\n \n-\tif (read_cache_preload(rev.diffopt.paths) < 0) {\n+\tif (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {\n \t\tperror(\"read_cache_preload\");\n \t\treturn -1;\n \t}\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex a43d326..76c42d8 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -135,7 +135,7 @@ static int builtin_diff_index(struct rev_info *revs,\n \t    revs->max_count != -1 || revs->min_age != -1 ||\n \t    revs->max_age != -1)\n \t\tusage(builtin_diff_usage);\n-\tif (read_cache_preload(revs->diffopt.paths) < 0) {\n+\tif (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {\n \t\tperror(\"read_cache_preload\");\n \t\treturn -1;\n \t}\n@@ -237,7 +237,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv\n \t\trevs->combine_merges = revs->dense_combined_merges = 1;\n \n \tsetup_work_tree();\n-\tif (read_cache_preload(revs->diffopt.paths) < 0) {\n+\tif (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {\n \t\tperror(\"read_cache_preload\");\n \t\treturn -1;\n \t}\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 08b8722..d78744f 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -89,7 +89,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,\n \t\trev->always_show_header = 0;\n \tif (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {\n \t\trev->always_show_header = 0;\n-\t\tif (rev->diffopt.nr_paths != 1)\n+\t\tif (rev->diffopt.pathspec.nr != 1)\n \t\t\tusage(\"git logs can only follow renames on one pathname at a time\");\n \t}\n \tfor (i = 1; i < argc; i++) {\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 392ce2b..3b809f2 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -501,7 +501,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n \tactive_nr = dst - active_cache;\n \n \tinit_revisions(&revs, NULL);\n-\trevs.prune_data = opt->paths;\n+\trevs.prune_data = opt->pathspec.raw;\n \ttree = parse_tree_indirect(tree_sha1);\n \tif (!tree)\n \t\tdie(\"bad tree object %s\", sha1_to_hex(tree_sha1));\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex e48ab92..3a36144 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -260,8 +260,8 @@ void diff_no_index(struct rev_info *revs,\n \tif (diff_setup_done(&revs->diffopt) < 0)\n \t\tdie(\"diff_setup_done failed\");\n \n-\tif (queue_diff(&revs->diffopt, revs->diffopt.paths[0],\n-\t\t       revs->diffopt.paths[1]))\n+\tif (queue_diff(&revs->diffopt, revs->diffopt.pathspec.raw[0],\n+\t\t       revs->diffopt.pathspec.raw[1]))\n \t\texit(1);\n \tdiff_set_mnemonic_prefix(&revs->diffopt, \"1/\", \"2/\");\n \tdiffcore_std(&revs->diffopt);\ndiff --git a/diff.h b/diff.h\nindex bf2f44d..6497b71 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -133,9 +133,7 @@ struct diff_options {\n \tFILE *file;\n \tint close_file;\n \n-\tint nr_paths;\n-\tconst char **paths;\n-\tint *pathlens;\n+\tstruct pathspec pathspec;\n \tchange_fn_t change;\n \tadd_remove_fn_t add_remove;\n \tdiff_format_fn_t format_callback;\ndiff --git a/revision.c b/revision.c\nindex b1c1890..b2a5867 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -553,11 +553,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)\n \n \tleft_first = left_count < right_count;\n \tinit_patch_ids(&ids);\n-\tif (revs->diffopt.nr_paths) {\n-\t\tids.diffopts.nr_paths = revs->diffopt.nr_paths;\n-\t\tids.diffopts.paths = revs->diffopt.paths;\n-\t\tids.diffopts.pathlens = revs->diffopt.pathlens;\n-\t}\n+\tids.diffopts.pathspec = revs->diffopt.pathspec;\n \n \t/* Compute patch-ids for one side */\n \tfor (p = list; p; p = p->next) {\ndiff --git a/tree-diff.c b/tree-diff.c\nindex cd659c6..986c0f4 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -100,16 +100,16 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int\n \tint pathlen;\n \tint never_interesting = -1;\n \n-\tif (!opt->nr_paths)\n+\tif (!opt->pathspec.nr)\n \t\treturn 1;\n \n \tsha1 = tree_entry_extract(desc, &path, &mode);\n \n \tpathlen = tree_entry_len(path, sha1);\n \n-\tfor (i = 0; i < opt->nr_paths; i++) {\n-\t\tconst char *match = opt->paths[i];\n-\t\tint matchlen = opt->pathlens[i];\n+\tfor (i = 0; i < opt->pathspec.nr; i++) {\n+\t\tconst char *match = opt->pathspec.raw[i];\n+\t\tint matchlen = opt->pathspec.items[i].len;\n \t\tint m = -1; /* signals that we haven't called strncmp() */\n \n \t\tif (baselen >= matchlen) {\n@@ -289,7 +289,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru\n \t\tif (DIFF_OPT_TST(opt, QUICK) &&\n \t\t    DIFF_OPT_TST(opt, HAS_CHANGES))\n \t\t\tbreak;\n-\t\tif (opt->nr_paths) {\n+\t\tif (opt->pathspec.nr) {\n \t\t\tskip_uninteresting(t1, base, baselen, opt);\n \t\t\tskip_uninteresting(t2, base, baselen, opt);\n \t\t}\n@@ -348,7 +348,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co\n \tDIFF_OPT_SET(&diff_opts, RECURSIVE);\n \tDIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);\n \tdiff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;\n-\tdiff_opts.single_follow = opt->paths[0];\n+\tdiff_opts.single_follow = opt->pathspec.raw[0];\n \tdiff_opts.break_opt = opt->break_opt;\n \tpaths[0] = NULL;\n \tdiff_tree_setup_paths(paths, &diff_opts);\n@@ -368,15 +368,15 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co\n \t\t * diff_queued_diff, we will also use that as the path in\n \t\t * the future!\n \t\t */\n-\t\tif ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->paths[0])) {\n+\t\tif ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->pathspec.raw[0])) {\n \t\t\t/* Switch the file-pairs around */\n \t\t\tq->queue[i] = choice;\n \t\t\tchoice = p;\n \n \t\t\t/* Update the path we use from now on.. */\n \t\t\tdiff_tree_release_paths(opt);\n-\t\t\topt->paths[0] = xstrdup(p->one->path);\n-\t\t\tdiff_tree_setup_paths(opt->paths, opt);\n+\t\t\topt->pathspec.raw[0] = xstrdup(p->one->path);\n+\t\t\tdiff_tree_setup_paths(opt->pathspec.raw, opt);\n \n \t\t\t/*\n \t\t\t * The caller expects us to return a set of vanilla\n@@ -451,36 +451,12 @@ int diff_root_tree_sha1(const unsigned char *new, const char *base, struct diff_\n \treturn retval;\n }\n \n-static int count_paths(const char **paths)\n-{\n-\tint i = 0;\n-\twhile (*paths++)\n-\t\ti++;\n-\treturn i;\n-}\n-\n void diff_tree_release_paths(struct diff_options *opt)\n {\n-\tfree(opt->pathlens);\n+\tfree_pathspec(&opt->pathspec);\n }\n \n void diff_tree_setup_paths(const char **p, struct diff_options *opt)\n {\n-\topt->nr_paths = 0;\n-\topt->pathlens = NULL;\n-\topt->paths = NULL;\n-\n-\tif (p) {\n-\t\tint i;\n-\n-\t\topt->paths = p;\n-\t\topt->nr_paths = count_paths(p);\n-\t\tif (opt->nr_paths == 0) {\n-\t\t\topt->pathlens = NULL;\n-\t\t\treturn;\n-\t\t}\n-\t\topt->pathlens = xmalloc(opt->nr_paths * sizeof(int));\n-\t\tfor (i=0; i < opt->nr_paths; i++)\n-\t\t\topt->pathlens[i] = strlen(p[i]);\n-\t}\n+\tinit_pathspec(&opt->pathspec, p);\n }\n-- \n1.7.1.rc1.70.g788ca\n"},{"id":"151979","messageId":"1285675229-28019-6-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 5/6] tree_entry_interesting(): remove dependency on struct diff_options","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:28Z","receivedAt":"2010-09-28T12:00:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This function can be potentially used in more places than just\ntree-diff.c. \"struct diff_options\" does not make much sense outside\ndiff_tree_sha1().\n\nWhile removing the use of diff_options, it also removes\ntree_entry_extract() call. This means S_ISDIR() uses the entry->mode\ndirectly, without being filtered by canon_mode() (called internally\ninside tree_entry_extract)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n tree-diff.c |   28 +++++++++++-----------------\n 1 files changed, 11 insertions(+), 17 deletions(-)\n\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 986c0f4..822d45e 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -91,25 +91,20 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const\n  *  - zero for no\n  *  - negative for \"no, and no subsequent entries will be either\"\n  */\n-static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)\n+static int tree_entry_interesting(const struct name_entry *entry, const char *base, int baselen, const struct pathspec *ps)\n {\n-\tconst char *path;\n-\tconst unsigned char *sha1;\n-\tunsigned mode;\n \tint i;\n \tint pathlen;\n \tint never_interesting = -1;\n \n-\tif (!opt->pathspec.nr)\n+\tif (!ps || !ps->nr)\n \t\treturn 1;\n \n-\tsha1 = tree_entry_extract(desc, &path, &mode);\n-\n-\tpathlen = tree_entry_len(path, sha1);\n+\tpathlen = tree_entry_len(entry->path, entry->sha1);\n \n-\tfor (i = 0; i < opt->pathspec.nr; i++) {\n-\t\tconst char *match = opt->pathspec.raw[i];\n-\t\tint matchlen = opt->pathspec.items[i].len;\n+\tfor (i = 0; i < ps->nr; i++) {\n+\t\tconst char *match = ps->raw[i];\n+\t\tint matchlen = ps->items[i].len;\n \t\tint m = -1; /* signals that we haven't called strncmp() */\n \n \t\tif (baselen >= matchlen) {\n@@ -147,7 +142,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int\n \t\t\t * Does match sort strictly earlier than path\n \t\t\t * with their common parts?\n \t\t\t */\n-\t\t\tm = strncmp(match, path,\n+\t\t\tm = strncmp(match, entry->path,\n \t\t\t\t    (matchlen < pathlen) ? matchlen : pathlen);\n \t\t\tif (m < 0)\n \t\t\t\tcontinue;\n@@ -174,7 +169,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int\n \t\tif (matchlen > pathlen) {\n \t\t\tif (match[pathlen] != '/')\n \t\t\t\tcontinue;\n-\t\t\tif (!S_ISDIR(mode))\n+\t\t\tif (!S_ISDIR(entry->mode))\n \t\t\t\tcontinue;\n \t\t}\n \n@@ -183,7 +178,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int\n \t\t\t * we cheated and did not do strncmp(), so we do\n \t\t\t * that here.\n \t\t\t */\n-\t\t\tm = strncmp(match, path, pathlen);\n+\t\t\tm = strncmp(match, entry->path, pathlen);\n \n \t\t/*\n \t\t * If common part matched earlier then it is a hit,\n@@ -206,8 +201,7 @@ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_\n \t\tif (all_interesting)\n \t\t\tshow = 1;\n \t\telse {\n-\t\t\tshow = tree_entry_interesting(desc, base, baselen,\n-\t\t\t\t\t\t      opt);\n+\t\t\tshow = tree_entry_interesting(&desc->entry, base, baselen, &opt->pathspec);\n \t\t\tif (show == 2)\n \t\t\t\tall_interesting = 1;\n \t\t}\n@@ -266,7 +260,7 @@ static void skip_uninteresting(struct tree_desc *t, const char *base, int basele\n \t\tif (all_interesting)\n \t\t\tshow = 1;\n \t\telse {\n-\t\t\tshow = tree_entry_interesting(t, base, baselen, opt);\n+\t\t\tshow = tree_entry_interesting(&t->entry, base, baselen, &opt->pathspec);\n \t\t\tif (show == 2)\n \t\t\t\tall_interesting = 1;\n \t\t}\n-- \n1.7.1.rc1.70.g788ca\n"},{"id":"151980","messageId":"1285675229-28019-7-git-send-email-pclouds@gmail.com","threadId":"25280","inReplyTo":"1285675229-28019-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 6/6] Move tree_entry_interesting() to tree-walk.c and export it","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-09-28T12:00:29Z","receivedAt":"2010-09-28T12:00:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n tree-diff.c |  109 ---------------------------------------------------------\n tree-walk.c |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tree-walk.h |    2 +\n 3 files changed, 113 insertions(+), 109 deletions(-)\n\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 822d45e..50d7e6d 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -82,115 +82,6 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const\n \treturn 0;\n }\n \n-/*\n- * Is a tree entry interesting given the pathspec we have?\n- *\n- * Return:\n- *  - 2 for \"yes, and all subsequent entries will be\"\n- *  - 1 for yes\n- *  - zero for no\n- *  - negative for \"no, and no subsequent entries will be either\"\n- */\n-static int tree_entry_interesting(const struct name_entry *entry, const char *base, int baselen, const struct pathspec *ps)\n-{\n-\tint i;\n-\tint pathlen;\n-\tint never_interesting = -1;\n-\n-\tif (!ps || !ps->nr)\n-\t\treturn 1;\n-\n-\tpathlen = tree_entry_len(entry->path, entry->sha1);\n-\n-\tfor (i = 0; i < ps->nr; i++) {\n-\t\tconst char *match = ps->raw[i];\n-\t\tint matchlen = ps->items[i].len;\n-\t\tint m = -1; /* signals that we haven't called strncmp() */\n-\n-\t\tif (baselen >= matchlen) {\n-\t\t\t/* If it doesn't match, move along... */\n-\t\t\tif (strncmp(base, match, matchlen))\n-\t\t\t\tcontinue;\n-\n-\t\t\t/*\n-\t\t\t * If the base is a subdirectory of a path which\n-\t\t\t * was specified, all of them are interesting.\n-\t\t\t */\n-\t\t\tif (!matchlen ||\n-\t\t\t    base[matchlen] == '/' ||\n-\t\t\t    match[matchlen - 1] == '/')\n-\t\t\t\treturn 2;\n-\n-\t\t\t/* Just a random prefix match */\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\t/* Does the base match? */\n-\t\tif (strncmp(base, match, baselen))\n-\t\t\tcontinue;\n-\n-\t\tmatch += baselen;\n-\t\tmatchlen -= baselen;\n-\n-\t\tif (never_interesting) {\n-\t\t\t/*\n-\t\t\t * We have not seen any match that sorts later\n-\t\t\t * than the current path.\n-\t\t\t */\n-\n-\t\t\t/*\n-\t\t\t * Does match sort strictly earlier than path\n-\t\t\t * with their common parts?\n-\t\t\t */\n-\t\t\tm = strncmp(match, entry->path,\n-\t\t\t\t    (matchlen < pathlen) ? matchlen : pathlen);\n-\t\t\tif (m < 0)\n-\t\t\t\tcontinue;\n-\n-\t\t\t/*\n-\t\t\t * If we come here even once, that means there is at\n-\t\t\t * least one pathspec that would sort equal to or\n-\t\t\t * later than the path we are currently looking at.\n-\t\t\t * In other words, if we have never reached this point\n-\t\t\t * after iterating all pathspecs, it means all\n-\t\t\t * pathspecs are either outside of base, or inside the\n-\t\t\t * base but sorts strictly earlier than the current\n-\t\t\t * one.  In either case, they will never match the\n-\t\t\t * subsequent entries.  In such a case, we initialized\n-\t\t\t * the variable to -1 and that is what will be\n-\t\t\t * returned, allowing the caller to terminate early.\n-\t\t\t */\n-\t\t\tnever_interesting = 0;\n-\t\t}\n-\n-\t\tif (pathlen > matchlen)\n-\t\t\tcontinue;\n-\n-\t\tif (matchlen > pathlen) {\n-\t\t\tif (match[pathlen] != '/')\n-\t\t\t\tcontinue;\n-\t\t\tif (!S_ISDIR(entry->mode))\n-\t\t\t\tcontinue;\n-\t\t}\n-\n-\t\tif (m == -1)\n-\t\t\t/*\n-\t\t\t * we cheated and did not do strncmp(), so we do\n-\t\t\t * that here.\n-\t\t\t */\n-\t\t\tm = strncmp(match, entry->path, pathlen);\n-\n-\t\t/*\n-\t\t * If common part matched earlier then it is a hit,\n-\t\t * because we rejected the case where path is not a\n-\t\t * leading directory and is shorter than match.\n-\t\t */\n-\t\tif (!m)\n-\t\t\treturn 1;\n-\t}\n-\treturn never_interesting; /* No matches */\n-}\n-\n /* A whole sub-tree went away or appeared */\n static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen)\n {\ndiff --git a/tree-walk.c b/tree-walk.c\nindex a9bbf4e..01168ea 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -455,3 +455,114 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch\n \tfree(tree);\n \treturn retval;\n }\n+\n+/*\n+ * Is a tree entry interesting given the pathspec we have?\n+ *\n+ * Return:\n+ *  - 2 for \"yes, and all subsequent entries will be\"\n+ *  - 1 for yes\n+ *  - zero for no\n+ *  - negative for \"no, and no subsequent entries will be either\"\n+ */\n+int tree_entry_interesting(const struct name_entry *entry,\n+\t\t\t   const char *base, int baselen,\n+\t\t\t   const struct pathspec *ps)\n+{\n+\tint i;\n+\tint pathlen;\n+\tint never_interesting = -1;\n+\n+\tif (!ps || !ps->nr)\n+\t\treturn 1;\n+\n+\tpathlen = tree_entry_len(entry->path, entry->sha1);\n+\n+\tfor (i = 0; i < ps->nr; i++) {\n+\t\tconst char *match = ps->raw[i];\n+\t\tint matchlen = ps->items[i].len;\n+\t\tint m = -1; /* signals that we haven't called strncmp() */\n+\n+\t\tif (baselen >= matchlen) {\n+\t\t\t/* If it doesn't match, move along... */\n+\t\t\tif (strncmp(base, match, matchlen))\n+\t\t\t\tcontinue;\n+\n+\t\t\t/*\n+\t\t\t * If the base is a subdirectory of a path which\n+\t\t\t * was specified, all of them are interesting.\n+\t\t\t */\n+\t\t\tif (!matchlen ||\n+\t\t\t    base[matchlen] == '/' ||\n+\t\t\t    match[matchlen - 1] == '/')\n+\t\t\t\treturn 2;\n+\n+\t\t\t/* Just a random prefix match */\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Does the base match? */\n+\t\tif (strncmp(base, match, baselen))\n+\t\t\tcontinue;\n+\n+\t\tmatch += baselen;\n+\t\tmatchlen -= baselen;\n+\n+\t\tif (never_interesting) {\n+\t\t\t/*\n+\t\t\t * We have not seen any match that sorts later\n+\t\t\t * than the current path.\n+\t\t\t */\n+\n+\t\t\t/*\n+\t\t\t * Does match sort strictly earlier than path\n+\t\t\t * with their common parts?\n+\t\t\t */\n+\t\t\tm = strncmp(match, entry->path,\n+\t\t\t\t    (matchlen < pathlen) ? matchlen : pathlen);\n+\t\t\tif (m < 0)\n+\t\t\t\tcontinue;\n+\n+\t\t\t/*\n+\t\t\t * If we come here even once, that means there is at\n+\t\t\t * least one pathspec that would sort equal to or\n+\t\t\t * later than the path we are currently looking at.\n+\t\t\t * In other words, if we have never reached this point\n+\t\t\t * after iterating all pathspecs, it means all\n+\t\t\t * pathspecs are either outside of base, or inside the\n+\t\t\t * base but sorts strictly earlier than the current\n+\t\t\t * one.  In either case, they will never match the\n+\t\t\t * subsequent entries.  In such a case, we initialized\n+\t\t\t * the variable to -1 and that is what will be\n+\t\t\t * returned, allowing the caller to terminate early.\n+\t\t\t */\n+\t\t\tnever_interesting = 0;\n+\t\t}\n+\n+\t\tif (pathlen > matchlen)\n+\t\t\tcontinue;\n+\n+\t\tif (matchlen > pathlen) {\n+\t\t\tif (match[pathlen] != '/')\n+\t\t\t\tcontinue;\n+\t\t\tif (!S_ISDIR(entry->mode))\n+\t\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (m == -1)\n+\t\t\t/*\n+\t\t\t * we cheated and did not do strncmp(), so we do\n+\t\t\t * that here.\n+\t\t\t */\n+\t\t\tm = strncmp(match, entry->path, pathlen);\n+\n+\t\t/*\n+\t\t * If common part matched earlier then it is a hit,\n+\t\t * because we rejected the case where path is not a\n+\t\t * leading directory and is shorter than match.\n+\t\t */\n+\t\tif (!m)\n+\t\t\treturn 1;\n+\t}\n+\treturn never_interesting; /* No matches */\n+}\ndiff --git a/tree-walk.h b/tree-walk.h\nindex 88ea7e9..c3d0684 100644\n--- a/tree-walk.h\n+++ b/tree-walk.h\n@@ -57,4 +57,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru\n \treturn info->pathlen + tree_entry_len(n->path, n->sha1);\n }\n \n+extern int tree_entry_interesting(const struct name_entry *, const char *, int, const struct pathspec *ps);\n+\n #endif\n-- \n1.7.1.rc1.70.g788ca\n"}]}