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>
This commit is contained in:
Junio C Hamano 2008-08-25 01:05:31 -07:00
parent 80d12c23de
commit 6ecb1ee28a
2 changed files with 46 additions and 16 deletions

View file

@ -14,7 +14,8 @@ SYNOPSIS
[--allow-binary-replacement | --binary] [--reject] [-z]
[-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached]
[--whitespace=<nowarn|warn|fix|error|error-all>]
[--exclude=PATH] [--directory=<root>] [--verbose] [<patch>...]
[--exclude=PATH] [--include=PATH] [--directory=<root>]
[--verbose] [<patch>...]
DESCRIPTION
-----------
@ -137,6 +138,17 @@ discouraged.
be useful when importing patchsets, where you want to exclude certain
files or directories.
--include=<path-pattern>::
Apply changes to files matching the given path pattern. This can
be useful when importing patchsets, where you want to include certain
files or directories.
+
When --exclude and --include patterns are used, they are examined in the
order they appear on the command line, and the first match determines if a
patch to each path is used. 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.
--whitespace=<action>::
When applying a patch, detect a new or modified line that has
whitespace errors. What are considered whitespace errors is

View file

@ -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")) {