Skip to content

Commit c4730f3

Browse files
dschogitster
authored andcommitted
Teach "git apply" to prepend a prefix with "--root=<root>"
With "git apply --root=<root>", all file names in the patch are prepended with <root>. If a "-p" value was given, the paths are stripped _before_ prepending <root>. Wished for by HPA. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 6603799 commit c4730f3

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

Documentation/git-apply.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ SYNOPSIS
1414
[--allow-binary-replacement | --binary] [--reject] [-z]
1515
[-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
1616
[--whitespace=<nowarn|warn|fix|error|error-all>]
17-
[--exclude=PATH] [--verbose] [<patch>...]
17+
[--exclude=PATH] [--root=<root>] [--verbose] [<patch>...]
1818

1919
DESCRIPTION
2020
-----------
@@ -177,6 +177,10 @@ behavior:
177177
current patch being applied will be printed. This option will cause
178178
additional information to be reported.
179179

180+
--root=<root>::
181+
Prepend <root> to all filenames. If a "-p" argument was passed, too,
182+
it is applied before prepending the new root.
183+
180184
Configuration
181185
-------------
182186

builtin-apply.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static int whitespace_error;
5757
static int squelch_whitespace_errors = 5;
5858
static int applied_after_fixing_ws;
5959
static const char *patch_input_file;
60+
static const char *root;
61+
static int root_len;
6062

6163
static void parse_whitespace_option(const char *option)
6264
{
@@ -331,6 +333,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
331333
*/
332334
strbuf_remove(&name, 0, cp - name.buf);
333335
free(def);
336+
if (root)
337+
strbuf_insert(&name, 0, root, root_len);
334338
return strbuf_detach(&name, NULL);
335339
}
336340
}
@@ -369,6 +373,14 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
369373
free(def);
370374
}
371375

376+
if (root) {
377+
char *ret = xmalloc(root_len + len + 1);
378+
strcpy(ret, root);
379+
memcpy(ret + root_len, start, len);
380+
ret[root_len + len] = '\0';
381+
return ret;
382+
}
383+
372384
return xmemdupz(start, len);
373385
}
374386

@@ -3118,6 +3130,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
31183130
inaccurate_eof = 1;
31193131
continue;
31203132
}
3133+
if (!strncmp(arg, "--root=", strlen("--root="))) {
3134+
arg += strlen("--root=");
3135+
root_len = strlen(arg);
3136+
if (root_len && arg[root_len + 1] != '/') {
3137+
char *new_root;
3138+
root = new_root = xmalloc(root_len + 2);
3139+
strcpy(new_root, arg);
3140+
strcpy(new_root + root_len++, "/");
3141+
} else
3142+
root = arg;
3143+
continue;
3144+
}
31213145
if (0 < prefix_length)
31223146
arg = prefix_filename(prefix, prefix_length, arg);
31233147

t/t4128-apply-root.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/sh
2+
3+
test_description='apply same filename'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
9+
mkdir -p some/sub/dir &&
10+
echo Hello > some/sub/dir/file &&
11+
git add some/sub/dir/file
12+
13+
'
14+
15+
cat > patch << EOF
16+
diff a/bla/blub/dir/file b/bla/blub/dir/file
17+
--- a/bla/blub/dir/file
18+
+++ b/bla/blub/dir/file
19+
@@ -1,1 +1,1 @@
20+
-Hello
21+
+Bello
22+
EOF
23+
24+
test_expect_success 'apply --root -p --index' '
25+
26+
git apply --root=some/sub -p3 --index patch &&
27+
test Bello = $(git show :some/sub/dir/file) &&
28+
test Bello = $(cat some/sub/dir/file)
29+
30+
'
31+
32+
test_done

0 commit comments

Comments
 (0)