All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jeff King <peff@peff.net>, git@vger.kernel.org
Subject: [PATCH] git-apply: require -p<n> when working in a subdirectory.
Date: Mon, 19 Feb 2007 17:57:29 -0800	[thread overview]
Message-ID: <7vr6sl381i.fsf_-_@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <7vps854qf8.fsf@assigned-by-dhcp.cox.net> (Junio C. Hamano's message of "Mon, 19 Feb 2007 16:35:07 -0800")

git-apply running inside a subdirectory, with or without --index,
used to always assume that the patch is formatted in such a way
to apply with -p1 from the toplevel, but it is more useful and
consistent with the use of "GNU patch -p1" if it defaulted to
assume that its input is meant to apply at the level it is
invoked in.

This changes the behaviour.  It used to be that the patch
generated this way would apply without any trick:

	edit Documentation/Makefile
	git diff >patch.file
	cd Documentation
	git apply ../patch.file

You need to give an explicit -p2 to git-apply now.  On the other
hand, if you got a patch from somebody else who did not follow
"patch is to apply from the top with -p1" convention, the input
patch would start with:

	diff -u Makefile.old Makefile
	--- Makefile.old
	+++ Makefile

and in such a case, you can apply it with:

	git apply -p0 patch.file

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * This also makes "git apply" to honor -p<n> option even on git
   generated patches ("diff --git").

 builtin-apply.c         |   46 ++++++++++++++++++++++++++++++----------------
 t/t4119-apply-config.sh |   32 ++++++++++++++++++--------------
 2 files changed, 48 insertions(+), 30 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index 6153791..53f286e 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -238,7 +238,7 @@ static int name_terminate(const char *name, int namelen, int c, int terminate)
 	return 1;
 }
 
-static char * find_name(const char *line, char *def, int p_value, int terminate)
+static char *find_name(const char *line, char *def, int p_value, int terminate)
 {
 	int len;
 	const char *start = line;
@@ -362,7 +362,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
 static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
 {
 	if (!orig_name && !isnull)
-		return find_name(line, NULL, 1, TERM_TAB);
+		return find_name(line, NULL, p_value, TERM_TAB);
 
 	if (orig_name) {
 		int len;
@@ -372,7 +372,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
 		len = strlen(name);
 		if (isnull)
 			die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
-		another = find_name(line, NULL, 1, TERM_TAB);
+		another = find_name(line, NULL, p_value, TERM_TAB);
 		if (!another || memcmp(another, name, len))
 			die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
 		free(another);
@@ -427,28 +427,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
 static int gitdiff_copysrc(const char *line, struct patch *patch)
 {
 	patch->is_copy = 1;
-	patch->old_name = find_name(line, NULL, 0, 0);
+	patch->old_name = find_name(line, NULL, p_value-1, 0);
 	return 0;
 }
 
 static int gitdiff_copydst(const char *line, struct patch *patch)
 {
 	patch->is_copy = 1;
-	patch->new_name = find_name(line, NULL, 0, 0);
+	patch->new_name = find_name(line, NULL, p_value-1, 0);
 	return 0;
 }
 
 static int gitdiff_renamesrc(const char *line, struct patch *patch)
 {
 	patch->is_rename = 1;
-	patch->old_name = find_name(line, NULL, 0, 0);
+	patch->old_name = find_name(line, NULL, p_value-1, 0);
 	return 0;
 }
 
 static int gitdiff_renamedst(const char *line, struct patch *patch)
 {
 	patch->is_rename = 1;
-	patch->new_name = find_name(line, NULL, 0, 0);
+	patch->new_name = find_name(line, NULL, p_value-1, 0);
 	return 0;
 }
 
@@ -2394,7 +2394,7 @@ static void write_out_one_result(struct patch *patch, int phase)
 {
 	if (patch->is_delete > 0) {
 		if (phase == 0)
-			remove_file(patch);
+			remove_file(patch, 1);
 		return;
 	}
 	if (patch->is_new > 0 || patch->is_copy) {
@@ -2407,7 +2407,7 @@ static void write_out_one_result(struct patch *patch, int phase)
 	 * thing: remove the old, write the new
 	 */
 	if (phase == 0)
-		remove_file(patch);
+		remove_file(patch, 0);
 	if (phase == 1)
 		create_file(patch);
 }
@@ -2520,15 +2520,26 @@ static int use_patch(struct patch *p)
 			return 0;
 		x = x->next;
 	}
-	if (0 < prefix_length) {
-		int pathlen = strlen(pathname);
-		if (pathlen <= prefix_length ||
-		    memcmp(prefix, pathname, prefix_length))
-			return 0;
-	}
 	return 1;
 }
 
+static char *prefix_one(char *name)
+{
+	if (!name)
+		return name;
+	return xstrdup(prefix_filename(prefix, prefix_length, name));
+}
+
+static void prefix_patches(struct patch *p)
+{
+	if (!prefix)
+		return;
+	for ( ; p; p = p->next) {
+		p->new_name = prefix_one(p->new_name);
+		p->old_name = prefix_one(p->old_name);
+	}
+}
+
 static int apply_patch(int fd, const char *filename, int inaccurate_eof)
 {
 	unsigned long offset, size;
@@ -2551,11 +2562,14 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
 			break;
 		if (apply_in_reverse)
 			reverse_patches(patch);
+		if (prefix)
+			prefix_patches(patch);
 		if (use_patch(patch)) {
 			patch_stats(patch);
 			*listp = patch;
 			listp = &patch->next;
-		} else {
+		}
+		else {
 			/* perhaps free it a bit better? */
 			free(patch);
 			skipped_patch++;
diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh
index 0e8ea7e..816b5b8 100755
--- a/t/t4119-apply-config.sh
+++ b/t/t4119-apply-config.sh
@@ -10,20 +10,22 @@ test_description='git-apply --whitespace=strip and configuration file.
 . ./test-lib.sh
 
 test_expect_success setup '
-	echo A >file1 &&
-	cp file1 saved &&
-	git add file1 &&
-	echo "B " >file1 &&
+	mkdir sub &&
+	echo A >sub/file1 &&
+	cp sub/file1 saved &&
+	git add sub/file1 &&
+	echo "B " >sub/file1 &&
 	git diff >patch.file
 '
 
 test_expect_success 'apply --whitespace=strip' '
 
-	cp saved file1 &&
+	rm -f sub/file1 &&
+	cp saved sub/file1 &&
 	git update-index --refresh &&
 
 	git apply --whitespace=strip patch.file &&
-	if grep " " file1
+	if grep " " sub/file1
 	then
 		echo "Eh?"
 		false
@@ -34,12 +36,13 @@ test_expect_success 'apply --whitespace=strip' '
 
 test_expect_success 'apply --whitespace=strip from config' '
 
-	cp saved file1 &&
+	rm -f sub/file1 &&
+	cp saved sub/file1 &&
 	git update-index --refresh &&
 
 	git config apply.whitespace strip &&
 	git apply patch.file &&
-	if grep " " file1
+	if grep " " sub/file1
 	then
 		echo "Eh?"
 		false
@@ -48,19 +51,19 @@ test_expect_success 'apply --whitespace=strip from config' '
 	fi
 '
 
-mkdir sub
 D=`pwd`
 
 test_expect_success 'apply --whitespace=strip in subdir' '
 
 	cd "$D" &&
 	git config --unset-all apply.whitespace
-	cp saved file1 &&
+	rm -f sub/file1 &&
+	cp saved sub/file1 &&
 	git update-index --refresh &&
 
 	cd sub &&
-	git apply --whitespace=strip ../patch.file &&
-	if grep " " ../file1
+	git apply --whitespace=strip -p2 ../patch.file &&
+	if grep " " file1
 	then
 		echo "Eh?"
 		false
@@ -73,11 +76,12 @@ test_expect_success 'apply --whitespace=strip from config in subdir' '
 
 	cd "$D" &&
 	git config apply.whitespace strip &&
-	cp saved file1 &&
+	rm -f sub/file1 &&
+	cp saved sub/file1 &&
 	git update-index --refresh &&
 
 	cd sub &&
-	git apply ../patch.file &&
+	git apply -p2 ../patch.file &&
 	if grep " " file1
 	then
 		echo "Eh?"
-- 
1.5.0.1.555.g13b30

  parent reply	other threads:[~2007-02-20  1:57 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-17 20:37 [PATCH] Teach core.autocrlf to 'git apply' Junio C Hamano
2007-02-17 21:12 ` [PATCH] Teach 'git apply' to look at $GIT_DIR/config Junio C Hamano
2007-02-17 23:26   ` Jeff King
2007-02-17 23:31     ` Junio C Hamano
2007-02-17 23:32       ` Jeff King
2007-02-19 22:57         ` Linus Torvalds
2007-02-19 23:04           ` Shawn O. Pearce
2007-02-19 23:14           ` Junio C Hamano
2007-02-19 23:37             ` Linus Torvalds
2007-02-19 23:57               ` Junio C Hamano
2007-02-20  0:11                 ` Linus Torvalds
2007-02-20  0:35                   ` Junio C Hamano
2007-02-20  0:53                     ` Johannes Schindelin
2007-02-20  1:29                       ` Junio C Hamano
2007-02-20  1:43                         ` Johannes Schindelin
2007-02-20  1:57                     ` Junio C Hamano [this message]
2007-02-20  2:33                       ` [PATCH] apply: fix memory leak in prefix_one() Johannes Schindelin
2007-02-20  2:39                         ` Junio C Hamano
2007-02-20  2:45                           ` Johannes Schindelin
2007-02-20  1:58                     ` [PATCH] git-apply: do not lose cwd when run from a subdirectory Junio C Hamano
2007-02-20  1:28                   ` [PATCH] Teach 'git apply' to look at $GIT_DIR/config Junio C Hamano
2007-02-20  1:38                     ` Linus Torvalds
2007-02-21  5:39                   ` Daniel Barkalow
2007-02-21 11:22                     ` Junio C Hamano
2007-02-21 17:00                       ` Daniel Barkalow
2007-02-21 16:44                     ` Linus Torvalds
2007-02-21 19:35                       ` Junio C Hamano
2007-02-21 22:31                         ` [PATCH] git-apply: notice "diff --git" patch again Junio C Hamano
2007-02-22  0:24                           ` [PATCH] git-apply: guess correct -p<n> value for non-git patches Junio C Hamano
2007-02-20  0:16                 ` [PATCH] Teach 'git apply' to look at $GIT_DIR/config Johannes Schindelin
2007-02-20  0:36                 ` Simon 'corecode' Schubert
2007-02-18  0:08       ` Johannes Schindelin
2007-02-18  0:28         ` Junio C Hamano
2007-02-18  0:40           ` Johannes Schindelin
2007-02-18  1:03             ` Junio C Hamano
2007-02-18  1:15               ` Johannes Schindelin
2007-02-18  1:47                 ` Junio C Hamano
2007-02-18  2:00                   ` Johannes Schindelin
2007-02-18  2:15                     ` Junio C Hamano
2007-02-18 11:40                       ` Johannes Schindelin
2007-02-18  1:48               ` Jakub Narebski
2007-02-18  0:06     ` Johannes Schindelin
2007-02-18  0:31       ` Junio C Hamano
2007-02-18  0:53         ` Johannes Schindelin
2007-02-18  1:20           ` Junio C Hamano
2007-02-18  1:29             ` Johannes Schindelin
2007-02-18  1:48               ` Junio C Hamano
2007-02-18  2:01                 ` Johannes Schindelin
2007-02-18  2:10                   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vr6sl381i.fsf_-_@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.