diff options
author | Junio C Hamano <gitster@pobox.com> | 2008-08-25 01:05:31 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-09-06 18:56:44 -0700 |
commit | 6ecb1ee28a9479af1d39cfab170b5d93e238c277 (patch) | |
tree | 7b8dfdec19e5b2117f8928916da9ca6e56907917 /builtin-apply.c | |
parent | 80d12c23de4fbddfaee2f9bf7fe809f57d02e171 (diff) | |
download | git-6ecb1ee28a9479af1d39cfab170b5d93e238c277.tar.gz |
git-apply:--include=pathspec
This allows --include=pathspec, similar to --exclude=pathspec.
The rule when one or both of these are used is that the include/exclude
patterns are examined in the order they are given on the command line, and
the first match determines if a patch to each path is used or not. Hence:
$ git apply --include='specific.h' --exclude='*.h' <diff
would apply the patch to specific.h header file, but all other patches in
the input file to other header files are ignored. A patch to a path that
does not match any include/exclude pattern is used by default if there is
no include pattern on the command line, and ignored if there is any
include pattern.
This originally came from Joe Perches, but both the design of the
semantics and the implementation have been redone complately.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-apply.c')
-rw-r--r-- | builtin-apply.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/builtin-apply.c b/builtin-apply.c index 20bef1f21d..2ab4aba5a0 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2994,29 +2994,45 @@ static int write_out_results(struct patch *list, int skipped_patch) static struct lock_file lock_file; -static struct excludes { - struct excludes *next; - const char *path; -} *excludes; +static struct string_list limit_by_name; +static int has_include; +static void add_name_limit(const char *name, int exclude) +{ + struct string_list_item *it; + + it = string_list_append(name, &limit_by_name); + it->util = exclude ? NULL : (void *) 1; +} static int use_patch(struct patch *p) { const char *pathname = p->new_name ? p->new_name : p->old_name; - struct excludes *x = excludes; - while (x) { - if (fnmatch(x->path, pathname, 0) == 0) - return 0; - x = x->next; - } + int i; + + /* Paths outside are not touched regardless of "--include" */ if (0 < prefix_length) { int pathlen = strlen(pathname); if (pathlen <= prefix_length || memcmp(prefix, pathname, prefix_length)) return 0; } - return 1; + + /* See if it matches any of exclude/include rule */ + for (i = 0; i < limit_by_name.nr; i++) { + struct string_list_item *it = &limit_by_name.items[i]; + if (!fnmatch(it->string, pathname, 0)) + return (it->util != NULL); + } + + /* + * If we had any include, a path that does not match any rule is + * not used. Otherwise, we saw bunch of exclude rules (or none) + * and such a path is used. + */ + return !has_include; } + static void prefix_one(char **name) { char *old_name = *name; @@ -3157,10 +3173,12 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) continue; } if (!prefixcmp(arg, "--exclude=")) { - struct excludes *x = xmalloc(sizeof(*x)); - x->path = arg + 10; - x->next = excludes; - excludes = x; + add_name_limit(arg + 10, 1); + continue; + } + if (!prefixcmp(arg, "--include=")) { + add_name_limit(arg + 10, 0); + has_include = 1; continue; } if (!prefixcmp(arg, "-p")) { |