Skip to content

Commit bb6ac5e

Browse files
committed
Merge branch 'jc/apply-ws-prefix' into maint
* jc/apply-ws-prefix: apply: omit ws check for excluded paths apply: hoist use_patch() helper for path exclusion up apply: use the right attribute for paths in non-Git patches Conflicts: builtin/apply.c
2 parents 04cd47f + 477a08a commit bb6ac5e

File tree

3 files changed

+96
-63
lines changed

3 files changed

+96
-63
lines changed

builtin/apply.c

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,66 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
19201920
return used;
19211921
}
19221922

1923+
static void prefix_one(char **name)
1924+
{
1925+
char *old_name = *name;
1926+
if (!old_name)
1927+
return;
1928+
*name = xstrdup(prefix_filename(prefix, prefix_length, *name));
1929+
free(old_name);
1930+
}
1931+
1932+
static void prefix_patch(struct patch *p)
1933+
{
1934+
if (!prefix || p->is_toplevel_relative)
1935+
return;
1936+
prefix_one(&p->new_name);
1937+
prefix_one(&p->old_name);
1938+
}
1939+
1940+
/*
1941+
* include/exclude
1942+
*/
1943+
1944+
static struct string_list limit_by_name;
1945+
static int has_include;
1946+
static void add_name_limit(const char *name, int exclude)
1947+
{
1948+
struct string_list_item *it;
1949+
1950+
it = string_list_append(&limit_by_name, name);
1951+
it->util = exclude ? NULL : (void *) 1;
1952+
}
1953+
1954+
static int use_patch(struct patch *p)
1955+
{
1956+
const char *pathname = p->new_name ? p->new_name : p->old_name;
1957+
int i;
1958+
1959+
/* Paths outside are not touched regardless of "--include" */
1960+
if (0 < prefix_length) {
1961+
int pathlen = strlen(pathname);
1962+
if (pathlen <= prefix_length ||
1963+
memcmp(prefix, pathname, prefix_length))
1964+
return 0;
1965+
}
1966+
1967+
/* See if it matches any of exclude/include rule */
1968+
for (i = 0; i < limit_by_name.nr; i++) {
1969+
struct string_list_item *it = &limit_by_name.items[i];
1970+
if (!wildmatch(it->string, pathname, 0, NULL))
1971+
return (it->util != NULL);
1972+
}
1973+
1974+
/*
1975+
* If we had any include, a path that does not match any rule is
1976+
* not used. Otherwise, we saw bunch of exclude rules (or none)
1977+
* and such a path is used.
1978+
*/
1979+
return !has_include;
1980+
}
1981+
1982+
19231983
/*
19241984
* Read the patch text in "buffer" that extends for "size" bytes; stop
19251985
* reading after seeing a single patch (i.e. changes to a single file).
@@ -1935,9 +1995,14 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
19351995
if (offset < 0)
19361996
return offset;
19371997

1938-
patch->ws_rule = whitespace_rule(patch->new_name
1939-
? patch->new_name
1940-
: patch->old_name);
1998+
prefix_patch(patch);
1999+
2000+
if (!use_patch(patch))
2001+
patch->ws_rule = 0;
2002+
else
2003+
patch->ws_rule = whitespace_rule(patch->new_name
2004+
? patch->new_name
2005+
: patch->old_name);
19412006

19422007
patchsize = parse_single_patch(buffer + offset + hdrsize,
19432008
size - offset - hdrsize, patch);
@@ -4127,64 +4192,6 @@ static int write_out_results(struct patch *list)
41274192

41284193
static struct lock_file lock_file;
41294194

4130-
static struct string_list limit_by_name;
4131-
static int has_include;
4132-
static void add_name_limit(const char *name, int exclude)
4133-
{
4134-
struct string_list_item *it;
4135-
4136-
it = string_list_append(&limit_by_name, name);
4137-
it->util = exclude ? NULL : (void *) 1;
4138-
}
4139-
4140-
static int use_patch(struct patch *p)
4141-
{
4142-
const char *pathname = p->new_name ? p->new_name : p->old_name;
4143-
int i;
4144-
4145-
/* Paths outside are not touched regardless of "--include" */
4146-
if (0 < prefix_length) {
4147-
int pathlen = strlen(pathname);
4148-
if (pathlen <= prefix_length ||
4149-
memcmp(prefix, pathname, prefix_length))
4150-
return 0;
4151-
}
4152-
4153-
/* See if it matches any of exclude/include rule */
4154-
for (i = 0; i < limit_by_name.nr; i++) {
4155-
struct string_list_item *it = &limit_by_name.items[i];
4156-
if (!wildmatch(it->string, pathname, 0, NULL))
4157-
return (it->util != NULL);
4158-
}
4159-
4160-
/*
4161-
* If we had any include, a path that does not match any rule is
4162-
* not used. Otherwise, we saw bunch of exclude rules (or none)
4163-
* and such a path is used.
4164-
*/
4165-
return !has_include;
4166-
}
4167-
4168-
4169-
static void prefix_one(char **name)
4170-
{
4171-
char *old_name = *name;
4172-
if (!old_name)
4173-
return;
4174-
*name = xstrdup(prefix_filename(prefix, prefix_length, *name));
4175-
free(old_name);
4176-
}
4177-
4178-
static void prefix_patches(struct patch *p)
4179-
{
4180-
if (!prefix || p->is_toplevel_relative)
4181-
return;
4182-
for ( ; p; p = p->next) {
4183-
prefix_one(&p->new_name);
4184-
prefix_one(&p->old_name);
4185-
}
4186-
}
4187-
41884195
#define INACCURATE_EOF (1<<0)
41894196
#define RECOUNT (1<<1)
41904197

@@ -4210,8 +4217,6 @@ static int apply_patch(int fd, const char *filename, int options)
42104217
break;
42114218
if (apply_in_reverse)
42124219
reverse_patches(patch);
4213-
if (prefix)
4214-
prefix_patches(patch);
42154220
if (use_patch(patch)) {
42164221
patch_stats(patch);
42174222
*listp = patch;

t/t4119-apply-config.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,21 @@ test_expect_success 'same but with traditional patch input of depth 2' '
159159
check_result sub/file1
160160
'
161161

162+
test_expect_success 'in subdir with traditional patch input' '
163+
cd "$D" &&
164+
git config apply.whitespace strip &&
165+
cat >.gitattributes <<-EOF &&
166+
/* whitespace=blank-at-eol
167+
sub/* whitespace=-blank-at-eol
168+
EOF
169+
rm -f sub/file1 &&
170+
cp saved sub/file1 &&
171+
git update-index --refresh &&
172+
173+
cd sub &&
174+
git apply ../gpatch.file &&
175+
echo "B " >expect &&
176+
test_cmp expect file1
177+
'
178+
162179
test_done

t/t4124-apply-ws-rule.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,4 +512,15 @@ test_expect_success 'whitespace=fix to expand' '
512512
git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
513513
'
514514

515+
test_expect_success 'whitespace check skipped for excluded paths' '
516+
git config core.whitespace blank-at-eol &&
517+
>used &&
518+
>unused &&
519+
git add used unused &&
520+
echo "used" >used &&
521+
echo "unused " >unused &&
522+
git diff-files -p used unused >patch &&
523+
git apply --include=used --stat --whitespace=error <patch
524+
'
525+
515526
test_done

0 commit comments

Comments
 (0)