Teach "git apply" to prepend a prefix with "--root=<root>"
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Mon, 30 Jun 2008 23:44:47 +0000 (00:44 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 2 Jul 2008 01:04:28 +0000 (18:04 -0700)
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>
Documentation/git-apply.txt
builtin-apply.c
t/t4128-apply-root.sh [new file with mode: 0755]
index c8347637da55e32ec4c637280d7027dc8883c264..63fce53690e35f28ebb4db049dec553fd094083f 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
          [--allow-binary-replacement | --binary] [--reject] [-z]
          [-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
          [--whitespace=<nowarn|warn|fix|error|error-all>]
          [--allow-binary-replacement | --binary] [--reject] [-z]
          [-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
          [--whitespace=<nowarn|warn|fix|error|error-all>]
-         [--exclude=PATH] [--verbose] [<patch>...]
+         [--exclude=PATH] [--root=<root>] [--verbose] [<patch>...]
 
 DESCRIPTION
 -----------
 
 DESCRIPTION
 -----------
@@ -177,6 +177,10 @@ behavior:
        current patch being applied will be printed. This option will cause
        additional information to be reported.
 
        current patch being applied will be printed. This option will cause
        additional information to be reported.
 
+--root=<root>::
+       Prepend <root> to all filenames.  If a "-p" argument was passed, too,
+       it is applied before prepending the new root.
+
 Configuration
 -------------
 
 Configuration
 -------------
 
index c4978893122bbcfd80201fe937eb8433b29e1aa0..bf528966cabd23d844add6dcc6e414a7ca32be7c 100644 (file)
@@ -57,6 +57,8 @@ static int whitespace_error;
 static int squelch_whitespace_errors = 5;
 static int applied_after_fixing_ws;
 static const char *patch_input_file;
 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)
 {
 
 static void parse_whitespace_option(const char *option)
 {
@@ -331,6 +333,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
                                 */
                                strbuf_remove(&name, 0, cp - name.buf);
                                free(def);
                                 */
                                strbuf_remove(&name, 0, cp - name.buf);
                                free(def);
+                               if (root)
+                                       strbuf_insert(&name, 0, root, root_len);
                                return strbuf_detach(&name, NULL);
                        }
                }
                                return strbuf_detach(&name, NULL);
                        }
                }
@@ -369,6 +373,14 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
                free(def);
        }
 
                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);
 }
 
        return xmemdupz(start, len);
 }
 
@@ -3118,6 +3130,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                        inaccurate_eof = 1;
                        continue;
                }
                        inaccurate_eof = 1;
                        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);
 
                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 (executable)
index 0000000..80b5af2
--- /dev/null
@@ -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