threads / patch / 14235

patchTeach "git apply" to prepend a prefix with "--root=<root>"

Subject: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

## tl;dr

8 messages between Jun 30, 2008 and Jul 1, 2008. Diffs are folded; open one to read it.

replies: 7people: 4as markdown or json

Johannes Schindelin· Jun 30, 2008, 23:44 UTC · lore

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>
---
	Only lightly tested.
 Documentation/git-apply.txt |    6 +++++-
 builtin-apply.c             |   24 ++++++++++++++++++++++++
 t/t4128-apply-root.sh       |   32 ++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletions(-)
 create mode 100755 t/t4128-apply-root.sh
Show changes to 3 files +60 −1

Documentation/git-apply.txt, builtin-apply.c, t/t4128-apply-root.sh

diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index c5ee636..7c51830 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -14,7 +14,7 @@ SYNOPSIS
 	  [--allow-binary-replacement | --binary] [--reject] [-z]
 	  [-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached]
 	  [--whitespace=<nowarn|warn|fix|error|error-all>]
-	  [--exclude=PATH] [--verbose] [<patch>...]
+	  [--exclude=PATH] [--root=<root>] [--verbose] [<patch>...]
 
 DESCRIPTION
 -----------
@@ -182,6 +182,10 @@ behavior:
 	by inspecting the patch (e.g. after editing the patch without
 	adjusting the hunk headers appropriately).
 
+--root=<root>::
+	Prepend <root> to all filenames.  If a "-p" argument was passed, too,
+	it is applied before prepending the new root.
+
 Configuration
 -------------
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 9fcfe39..d56d913 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -58,6 +58,8 @@ static int whitespace_error;
 static int squelch_whitespace_errors = 5;
 static int applied_after_fixing_ws;
 static const char *patch_input_file;
+static const char *root;
+static int root_len;
 
 static void parse_whitespace_option(const char *option)
 {
@@ -340,6 +342,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
 				 */
 				strbuf_remove(&name, 0, cp - name.buf);
 				free(def);
+				if (root)
+					strbuf_insert(&name, 0, root, root_len);
 				return strbuf_detach(&name, NULL);
 			}
 		}
@@ -378,6 +382,14 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
 		free(def);
 	}
 
+	if (root) {
+		char *ret = xmalloc(root_len + len + 1);
+		strcpy(ret, root);
+		memcpy(ret + root_len, start, len);
+		ret[root_len + len] = '\0';
+		return ret;
+	}
+
 	return xmemdupz(start, len);
 }
 
@@ -3240,6 +3252,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 			options |= RECOUNT;
 			continue;
 		}
+		if (!strncmp(arg, "--root=", strlen("--root="))) {
+			arg += strlen("--root=");
+			root_len = strlen(arg);
+			if (root_len && arg[root_len + 1] != '/') {
+				char *new_root;
+				root = new_root = xmalloc(root_len + 2);
+				strcpy(new_root, arg);
+				strcpy(new_root + root_len++, "/");
+			} else
+				root = arg;
+			continue;
+		}
 		if (0 < prefix_length)
 			arg = prefix_filename(prefix, prefix_length, arg);
 
diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh
new file mode 100755
index 0000000..80b5af2
--- /dev/null
+++ b/t/t4128-apply-root.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+test_description='apply same filename'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+
+	mkdir -p some/sub/dir &&
+	echo Hello > some/sub/dir/file &&
+	git add some/sub/dir/file
+
+'
+
+cat > patch << EOF
+diff a/bla/blub/dir/file b/bla/blub/dir/file
+--- a/bla/blub/dir/file
++++ b/bla/blub/dir/file
+@@ -1,1 +1,1 @@
+-Hello
++Bello
+EOF
+
+test_expect_success 'apply --root -p --index' '
+
+	git apply --root=some/sub -p3 --index patch &&
+	test Bello = $(git show :some/sub/dir/file) &&
+	test Bello = $(cat some/sub/dir/file)
+
+'
+
+test_done
-- 
1.5.6.1.297.g148d9
Junio C Hamano· Jul 1, 2008, 09:21 UTC · re: Johannes Schindelin · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 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>.
Show 8 quoted lines
> @@ -182,6 +182,10 @@ behavior:
>  	by inspecting the patch (e.g. after editing the patch without
>  	adjusting the hunk headers appropriately).
>  
> +--root=<root>::
> +	Prepend <root> to all filenames.  If a "-p" argument was passed, too,
> +	it is applied before prepending the new root.
> +

I looked for precedence of this concept outside git but did not find anything that exactly matched.

The -p<num> came from patch where it is also called --strip=num. This new option --root is about the reverse operation and it is about inserting at the beginning --- it is rerooting, in other words, but then --root is good enough and shorter. mkisofs uses the word "graft" when it allows tree shifting (enabled with --graft-points), but the word "graft" means a totally different thing to us, so we would not want to use that word.

I am not complaining (--root is fine by me), but just thinking aloud, hoping somebody's brainwave is provoked while reading this babbling and comes up with a better wording ;-).

Show 10 quoted lines
> diff --git a/builtin-apply.c b/builtin-apply.c
> index 9fcfe39..d56d913 100644
> --- a/builtin-apply.c
> +++ b/builtin-apply.c
> @@ -58,6 +58,8 @@ static int whitespace_error;
> @@ -3240,6 +3252,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
>  			options |= RECOUNT;
>  			continue;
>  		}
> +		if (!strncmp(arg, "--root=", strlen("--root="))) {
prefixcmp()?
> +			arg += strlen("--root=");
> +			root_len = strlen(arg);
> +			if (root_len && arg[root_len + 1] != '/') {

Ah, being nice not to force trailing slash on users --- how unlike you ;-) but I think you meant "arg[root_len - 1]" there...

Other than that, the change looks fine.  Thanks.
H. Peter Anvin· Jul 1, 2008, 16:05 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Junio C Hamano wrote:
Show 12 quoted lines
> 
> The -p<num> came from patch where it is also called --strip=num.  This new
> option --root is about the reverse operation and it is about inserting at
> the beginning --- it is rerooting, in other words, but then --root is good
> enough and shorter.  mkisofs uses the word "graft" when it allows tree
> shifting (enabled with --graft-points), but the word "graft" means a
> totally different thing to us, so we would not want to use that word.
> 
> I am not complaining (--root is fine by me), but just thinking aloud,
> hoping somebody's brainwave is provoked while reading this babbling and
> comes up with a better wording ;-).
> 

There is an analogous concept in patch(1), it's just implemented by cd'ing to a subdirectory first. ;)

I think --root makes sense as the root of the patch. The other alternative would be --add (by analogy with --strip); the biggest advantage there is that -a, as a short option, isn't used for anything either by git-am, git-apply, or patch.

Incidentally, has anyone talked to the patch(1) maintainers about adding support for the git extensions, like binary patches? The main reason is that patch(1) is still useful when you have to suffer though fuzzy errors.

	-hpa
Johannes Schindelin· Jul 1, 2008, 16:36 UTC · re: H. Peter Anvin · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Hi,
On Tue, 1 Jul 2008, H. Peter Anvin wrote:
Show 17 quoted lines
> Junio C Hamano wrote:
> > 
> > The -p<num> came from patch where it is also called --strip=num.  
> > This new option --root is about the reverse operation and it is about 
> > inserting at the beginning --- it is rerooting, in other words, but 
> > then --root is good enough and shorter.  mkisofs uses the word "graft" 
> > when it allows tree shifting (enabled with --graft-points), but the 
> > word "graft" means a totally different thing to us, so we would not 
> > want to use that word.
> > 
> > I am not complaining (--root is fine by me), but just thinking aloud, 
> > hoping somebody's brainwave is provoked while reading this babbling 
> > and comes up with a better wording ;-).
> > 
> 
> There is an analogous concept in patch(1), it's just implemented by 
> cd'ing to a subdirectory first.  ;)

Hey, "--cd=" is free! And it would make explaining easier why -p is applied first.

Ciao, Dscho

H. Peter Anvin· Jul 1, 2008, 16:57 UTC · re: Johannes Schindelin · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Johannes Schindelin wrote:
Show 23 quoted lines
> Hi,
> 
> On Tue, 1 Jul 2008, H. Peter Anvin wrote:
> 
>> Junio C Hamano wrote:
>>> The -p<num> came from patch where it is also called --strip=num.  
>>> This new option --root is about the reverse operation and it is about 
>>> inserting at the beginning --- it is rerooting, in other words, but 
>>> then --root is good enough and shorter.  mkisofs uses the word "graft" 
>>> when it allows tree shifting (enabled with --graft-points), but the 
>>> word "graft" means a totally different thing to us, so we would not 
>>> want to use that word.
>>>
>>> I am not complaining (--root is fine by me), but just thinking aloud, 
>>> hoping somebody's brainwave is provoked while reading this babbling 
>>> and comes up with a better wording ;-).
>>>
>> There is an analogous concept in patch(1), it's just implemented by 
>> cd'ing to a subdirectory first.  ;)
> 
> Hey, "--cd=" is free!  And it would make explaining easier why -p is 
> applied first.
> 
Although that could imply cd'ing into another git repository to some people.
	-hpa
Raimund Bauer· Jul 1, 2008, 18:10 UTC · re: Johannes Schindelin · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

On Tue, 2008-07-01 at 18:36 +0200, Johannes Schindelin wrote:
Show 5 quoted lines
> > There is an analogous concept in patch(1), it's just implemented by 
> > cd'ing to a subdirectory first.  ;)
> 
> Hey, "--cd=" is free!  And it would make explaining easier why -p is 
> applied first.
patch uses -d or --directory

regards, Ray

H. Peter Anvin· Jul 1, 2008, 20:27 UTC · re: Raimund Bauer · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Raimund Bauer wrote:
Show 7 quoted lines
> On Tue, 2008-07-01 at 18:36 +0200, Johannes Schindelin wrote:
>>> There is an analogous concept in patch(1), it's just implemented by 
>>> cd'ing to a subdirectory first.  ;)
>> Hey, "--cd=" is free!  And it would make explaining easier why -p is 
>> applied first.
> 
> patch uses -d or --directory
So it does.
	-hpa
Johannes Schindelin· Jul 1, 2008, 16:34 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"

Hi,
On Tue, 1 Jul 2008, Junio C Hamano wrote:
Show 29 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > 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>.
> 
> > @@ -182,6 +182,10 @@ behavior:
> >  	by inspecting the patch (e.g. after editing the patch without
> >  	adjusting the hunk headers appropriately).
> >  
> > +--root=<root>::
> > +	Prepend <root> to all filenames.  If a "-p" argument was passed, too,
> > +	it is applied before prepending the new root.
> > +
> 
> I looked for precedence of this concept outside git but did not find
> anything that exactly matched.
> 
> The -p<num> came from patch where it is also called --strip=num.  This 
> new option --root is about the reverse operation and it is about 
> inserting at the beginning --- it is rerooting, in other words, but then 
> --root is good enough and shorter.  mkisofs uses the word "graft" when 
> it allows tree shifting (enabled with --graft-points), but the word 
> "graft" means a totally different thing to us, so we would not want to 
> use that word.
> 
> I am not complaining (--root is fine by me), but just thinking aloud, 
> hoping somebody's brainwave is provoked while reading this babbling and 
> comes up with a better wording ;-).

Yeah, I am not too happy, but I saw you and hpa on IRC agreeing on that option name. I would have said "--prefix", but that is too ambiguous, what with "prefix" already meaning "path relative to the working directory root".

Show 12 quoted lines
> > diff --git a/builtin-apply.c b/builtin-apply.c
> > index 9fcfe39..d56d913 100644
> > --- a/builtin-apply.c
> > +++ b/builtin-apply.c
> > @@ -58,6 +58,8 @@ static int whitespace_error;
> > @@ -3240,6 +3252,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
> >  			options |= RECOUNT;
> >  			continue;
> >  		}
> > +		if (!strncmp(arg, "--root=", strlen("--root="))) {
> 
> prefixcmp()?
D'oh.
I mean, thanks!
Show 6 quoted lines
> > +			arg += strlen("--root=");
> > +			root_len = strlen(arg);
> > +			if (root_len && arg[root_len + 1] != '/') {
> 
> Ah, being nice not to force trailing slash on users --- how unlike you 
> ;-)
Seems to be the new favorite sports, Dscho bashing.
> but I think you meant "arg[root_len - 1]" there...

I did. An earlier version (as I found out by using the reflogs, as I tend to do a lot these last couple of weeks) even had a "-". Musta been late.

Ciao, Dscho

← back to recent threads