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

8 messages from 2008-06-30 to 2008-07-01. Participants: Johannes Schindelin, Junio C Hamano, H. Peter Anvin, Raimund Bauer.
Thread: https://gitlist.dev/t/14235

## Johannes Schindelin, 2008-06-30 23:44

Subject: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <alpine.DEB.1.00.0807010043440.9925@racer>
URL: https://gitlist.dev/e/alpine.DEB.1.00.0807010043440.9925%40racer

```

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

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, 2008-07-01 09:21

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <7vvdzqnemk.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vvdzqnemk.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <alpine.DEB.1.00.0807010043440.9925@racer>

```
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 ;-).

> 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, 2008-07-01 16:05

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <486A55B0.9050404@zytor.com>
URL: https://gitlist.dev/e/486A55B0.9050404%40zytor.com
In-Reply-To: <7vvdzqnemk.fsf@gitster.siamese.dyndns.org>

```
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.  ;)

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, 2008-07-01 16:34

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <alpine.LSU.1.00.0807011831130.32725@wbgn129.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/alpine.LSU.1.00.0807011831130.32725%40wbgn129.biozentrum.uni-wuerzburg.de
In-Reply-To: <7vvdzqnemk.fsf@gitster.siamese.dyndns.org>

```
Hi,

On Tue, 1 Jul 2008, Junio C Hamano wrote:

> 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".

> > 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!

> > +			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

```

## Johannes Schindelin, 2008-07-01 16:36

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <alpine.LSU.1.00.0807011835090.32725@wbgn129.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/alpine.LSU.1.00.0807011835090.32725%40wbgn129.biozentrum.uni-wuerzburg.de
In-Reply-To: <486A55B0.9050404@zytor.com>

```
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.

Ciao,
Dscho

```

## H. Peter Anvin, 2008-07-01 16:57

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <486A61E5.1070208@zytor.com>
URL: https://gitlist.dev/e/486A61E5.1070208%40zytor.com
In-Reply-To: <alpine.LSU.1.00.0807011835090.32725@wbgn129.biozentrum.uni-wuerzburg.de>

```
Johannes Schindelin wrote:
> 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, 2008-07-01 18:10

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <1214935848.6619.1.camel@doriath>
URL: https://gitlist.dev/e/1214935848.6619.1.camel%40doriath
In-Reply-To: <alpine.LSU.1.00.0807011835090.32725@wbgn129.biozentrum.uni-wuerzburg.de>

```
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

regards,
Ray

```

## H. Peter Anvin, 2008-07-01 20:27

Subject: Re: [PATCH] Teach "git apply" to prepend a prefix with "--root=<root>"
Message-ID: <486A933F.9090001@zytor.com>
URL: https://gitlist.dev/e/486A933F.9090001%40zytor.com
In-Reply-To: <1214935848.6619.1.camel@doriath>

```
Raimund Bauer wrote:
> 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

```
