Clemens Buchacher venit, vidit, dixit 29.07.2011 15:35: > In order to do partial commits, git-commit overlays a tree on the > cache and checks pathspecs against the result. Currently, the overlaying > is done using "prefix" which prevents relative pathspecs with ".." and > absolute pathspec from matching when they refer to files not under > "prefix" and absent from the index, but still in the tree (i.e. files > staged for removal). > > Instead, determine the maximal common prefix for all specified > paths using the pathspec_prefix() routine from ls-files.c. Any use > of global variables is removed from pathspec_prefix() so that it > can be called from commit.c. > > Reported-by: Reuben Thomas <rrt@xxxxxxxx> > Analyzed-by: Michael J Gruber <git@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Clemens Buchacher <drizzd@xxxxxx> > > On Mon, Jul 25, 2011 at 09:42:10AM +0200, Michael J Gruber wrote: >> >> Overlay the full tree instead. > > That is one option. On the other hand, ls-files already provides > the function we need to do this properly. > How is this huge patch more "proper" then what I proposed? > With your permission I am stealing your commit message. I don't care about the message but don't see the point of this patch. Using the same message certainly won't explain the difference... > > Clemens > --- > builtin/commit.c | 6 ++++-- > builtin/ls-files.c | 38 ++------------------------------------ > cache.h | 1 + > setup.c | 32 ++++++++++++++++++++++++++++++++ > 4 files changed, 39 insertions(+), 38 deletions(-) > > diff --git a/builtin/commit.c b/builtin/commit.c > index a16d00b..c2db12a 100644 > --- a/builtin/commit.c > +++ b/builtin/commit.c > @@ -256,8 +256,10 @@ static int list_paths(struct string_list *list, const char *with_tree, > ; > m = xcalloc(1, i); > > - if (with_tree) > - overlay_tree_on_cache(with_tree, prefix); > + if (with_tree) { > + const char *max_prefix = pathspec_prefix(prefix, pattern); > + overlay_tree_on_cache(with_tree, max_prefix); > + } > > for (i = 0; i < active_nr; i++) { > struct cache_entry *ce = active_cache[i]; > diff --git a/builtin/ls-files.c b/builtin/ls-files.c > index 72b986f..fef5642 100644 > --- a/builtin/ls-files.c > +++ b/builtin/ls-files.c > @@ -276,41 +276,6 @@ static void prune_cache(const char *prefix) > active_nr = last; > } > > -static const char *pathspec_prefix(const char *prefix) > -{ > - const char **p, *n, *prev; > - unsigned long max; > - > - if (!pathspec) { > - max_prefix_len = prefix ? strlen(prefix) : 0; > - return prefix; > - } > - > - prev = NULL; > - max = PATH_MAX; > - for (p = pathspec; (n = *p) != NULL; p++) { > - int i, len = 0; > - for (i = 0; i < max; i++) { > - char c = n[i]; > - if (prev && prev[i] != c) > - break; > - if (!c || c == '*' || c == '?') > - break; > - if (c == '/') > - len = i+1; > - } > - prev = n; > - if (len < max) { > - max = len; > - if (!max) > - break; > - } > - } > - > - max_prefix_len = max; > - return max ? xmemdupz(prev, max) : NULL; > -} > - > static void strip_trailing_slash_from_submodules(void) > { > const char **p; > @@ -581,7 +546,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) > strip_trailing_slash_from_submodules(); > > /* Find common prefix for all pathspec's */ > - max_prefix = pathspec_prefix(prefix); > + max_prefix = pathspec_prefix(prefix, pathspec); > + max_prefix_len = max_prefix ? strlen(max_prefix) : 0; > > /* Treat unmatching pathspec elements as errors */ > if (pathspec && error_unmatch) { > diff --git a/cache.h b/cache.h > index 86518fb..dd3edaa 100644 > --- a/cache.h > +++ b/cache.h > @@ -441,6 +441,7 @@ extern void set_git_work_tree(const char *tree); > #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" > > extern const char **get_pathspec(const char *prefix, const char **pathspec); > +extern const char *pathspec_prefix(const char *prefix, const char **pathspec); > extern void setup_work_tree(void); > extern const char *setup_git_directory_gently(int *); > extern const char *setup_git_directory(void); > diff --git a/setup.c b/setup.c > index 5ea5502..2c51a9a 100644 > --- a/setup.c > +++ b/setup.c > @@ -264,6 +264,38 @@ const char **get_pathspec(const char *prefix, const char **pathspec) > return pathspec; > } > > +const char *pathspec_prefix(const char *prefix, const char **pathspec) > +{ > + const char **p, *n, *prev; > + unsigned long max; > + > + if (!pathspec) > + return prefix ? xmemdupz(prefix, strlen(prefix)) : NULL; > + > + prev = NULL; > + max = PATH_MAX; > + for (p = pathspec; (n = *p) != NULL; p++) { > + int i, len = 0; > + for (i = 0; i < max; i++) { > + char c = n[i]; > + if (prev && prev[i] != c) > + break; > + if (!c || c == '*' || c == '?') > + break; > + if (c == '/') > + len = i+1; > + } > + prev = n; > + if (len < max) { > + max = len; > + if (!max) > + break; > + } > + } > + > + return max ? xmemdupz(prev, max) : NULL; > +} > + > /* > * Test if it looks like we're at a git directory. > * We want to see: -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html