From c4730f35cc6507bc117a08885d88668fe02b1a7d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 1 Jul 2008 00:44:47 +0100 Subject: [PATCH 1/3] Teach "git apply" to prepend a prefix with "--root=" With "git apply --root=", all file names in the patch are prepended with . If a "-p" value was given, the paths are stripped _before_ prepending . Wished for by HPA. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-apply.txt | 6 +++++- builtin-apply.c | 24 ++++++++++++++++++++++++ t/t4128-apply-root.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100755 t/t4128-apply-root.sh diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index c8347637d..63fce5369 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] [--cached] [--whitespace=] - [--exclude=PATH] [--verbose] [...] + [--exclude=PATH] [--root=] [--verbose] [...] DESCRIPTION ----------- @@ -177,6 +177,10 @@ behavior: current patch being applied will be printed. This option will cause additional information to be reported. +--root=:: + Prepend 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 c49788931..bf528966c 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -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 const char *root; +static int root_len; 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); + if (root) + strbuf_insert(&name, 0, root, root_len); 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); } + 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); } @@ -3118,6 +3130,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) 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); diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh new file mode 100755 index 000000000..80b5af2b4 --- /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 From 8ee4a6c2ec6738cfbc815dc59e44825f2a9b9f15 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 2 Jul 2008 15:28:22 -0700 Subject: [PATCH 2/3] apply --root: thinkofix. The end of a string is string[length-1], not string[length+1]. I pointed it out during the review, but I forgot about it when applying the patch. This should fix it. Signed-off-by: Junio C Hamano --- builtin-apply.c | 4 ++-- t/t4128-apply-root.sh | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index bf528966c..6c3db60b6 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3130,10 +3130,10 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) inaccurate_eof = 1; continue; } - if (!strncmp(arg, "--root=", strlen("--root="))) { + if (!prefixcmp(arg, "--root=")) { arg += strlen("--root="); root_len = strlen(arg); - if (root_len && arg[root_len + 1] != '/') { + if (root_len && arg[root_len - 1] != '/') { char *new_root; root = new_root = xmalloc(root_len + 2); strcpy(new_root, arg); diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index 80b5af2b4..b65024545 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -8,7 +8,9 @@ test_expect_success 'setup' ' mkdir -p some/sub/dir && echo Hello > some/sub/dir/file && - git add some/sub/dir/file + git add some/sub/dir/file && + git commit -m initial && + git tag initial ' @@ -21,7 +23,7 @@ diff a/bla/blub/dir/file b/bla/blub/dir/file +Bello EOF -test_expect_success 'apply --root -p --index' ' +test_expect_success 'apply --root -p (1)' ' git apply --root=some/sub -p3 --index patch && test Bello = $(git show :some/sub/dir/file) && @@ -29,4 +31,13 @@ test_expect_success 'apply --root -p --index' ' ' +test_expect_success 'apply --root -p (2) ' ' + + git reset --hard initial && + 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 From f55638874774acc1e13a046353449ebc8734ab08 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 6 Jul 2008 18:36:01 -0700 Subject: [PATCH 3/3] git-apply --directory: make --root more similar to GNU diff Applying a patch in the directory that is different from what the patch records is done with --directory option in GNU diff. The --root option we introduced previously does the same, and we can call it the same way to give users more familiar feel. Signed-off-by: Junio C Hamano --- Documentation/git-apply.txt | 8 ++++++-- builtin-apply.c | 4 ++-- t/t4128-apply-root.sh | 8 ++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index 63fce5369..3cd3179ff 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] [--cached] [--whitespace=] - [--exclude=PATH] [--root=] [--verbose] [...] + [--exclude=PATH] [--directory=] [--verbose] [...] DESCRIPTION ----------- @@ -177,9 +177,13 @@ behavior: current patch being applied will be printed. This option will cause additional information to be reported. ---root=:: +--directory=:: Prepend to all filenames. If a "-p" argument was passed, too, it is applied before prepending the new root. ++ +For example, a patch that talks about updating `a/git-gui.sh` to `b/git-gui.sh` +can be applied to the file in the working tree `modules/git-gui/git-gui.sh` by +running `git apply --directory=modules/git-gui`. Configuration ------------- diff --git a/builtin-apply.c b/builtin-apply.c index 6c3db60b6..c242bbd83 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3130,8 +3130,8 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) inaccurate_eof = 1; continue; } - if (!prefixcmp(arg, "--root=")) { - arg += strlen("--root="); + if (!prefixcmp(arg, "--directory=")) { + arg += strlen("--directory="); root_len = strlen(arg); if (root_len && arg[root_len - 1] != '/') { char *new_root; diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index b65024545..2dd0c75f9 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -23,18 +23,18 @@ diff a/bla/blub/dir/file b/bla/blub/dir/file +Bello EOF -test_expect_success 'apply --root -p (1)' ' +test_expect_success 'apply --directory -p (1)' ' - git apply --root=some/sub -p3 --index patch && + git apply --directory=some/sub -p3 --index patch && test Bello = $(git show :some/sub/dir/file) && test Bello = $(cat some/sub/dir/file) ' -test_expect_success 'apply --root -p (2) ' ' +test_expect_success 'apply --directory -p (2) ' ' git reset --hard initial && - git apply --root=some/sub/ -p3 --index patch && + git apply --directory=some/sub/ -p3 --index patch && test Bello = $(git show :some/sub/dir/file) && test Bello = $(cat some/sub/dir/file)