git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git apply: do not match beginning in special unidiff-zero case

From
Clemens Buchacher <drizzd@aon.at>
Date
Aug 30, 2008, 19:03 UTC
Message-ID
<20080830190302.GA29851@localhost>
In-Reply-To
<7vhc92ie44.fsf@gitster.siamese.dyndns.org>

If a unidiff patch without any context modifies the second line, it does not match the beginning, even though oldpos == 1.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
---
On Sat, Aug 30, 2008 at 10:53:15AM -0700, Junio C Hamano wrote:
Show 10 quoted lines
> Clemens Buchacher <drizzd@aon.at> writes:
> 
> > echo a > victim
> > git add victim
> > echo b >> victim
> > git diff -U0 | git apply --cached --unidiff-zero
> > git diff
> 
> I think "diff -U0" there would say "@@ -1,0 +2 @@", iow "add this one line
> after the first line", and "apply" has an off-by-one in this case.

Indeed. This appears to fix problems with staging hunks in git gui, even with zero context lines. Staging individual lines still doesn't work, though.

Clemens
 builtin-apply.c           |    9 ++++-----
 t/t4104-apply-boundary.sh |   15 ++++++++++++---
 2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 2216a0b..8402f9d 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1994,16 +1994,15 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
 	trailing = frag->trailing;
 
 	/*
-	 * A hunk to change lines at the beginning would begin with
+	 * Unless the patch was generated with unidiff without any context, a
+	 * hunk to change lines at the beginning would begin with
 	 * @@ -1,L +N,M @@
 	 *
 	 * And a hunk to add to an empty file would begin with
 	 * @@ -0,0 +N,M @@
-	 *
-	 * In other words, a hunk that is (frag->oldpos <= 1) with or
-	 * without leading context must match at the beginning.
 	 */
-	match_beginning = frag->oldpos <= 1;
+	match_beginning = frag->oldpos == 0 ||
+		(!unidiff_zero && frag->oldpos == 1);
 
 	/*
 	 * A hunk without trailing lines must match at the end.
diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh
index e7e2913..0e3ce36 100755
--- a/t/t4104-apply-boundary.sh
+++ b/t/t4104-apply-boundary.sh
@@ -27,6 +27,15 @@ test_expect_success setup '
 	git diff victim >add-a-patch.with &&
 	git diff --unified=0 >add-a-patch.without &&
 
+	: insert at line two
+	for i in b a '"$L"' y
+	do
+		echo $i
+	done >victim &&
+	cat victim >insert-a-expect &&
+	git diff victim >insert-a-patch.with &&
+	git diff --unified=0 >insert-a-patch.without &&
+
 	: modify at the head
 	for i in a '"$L"' y
 	do
@@ -55,7 +64,7 @@ test_expect_success setup '
 	git diff --unified=0 >add-z-patch.without &&
 
 	: modify at the tail
-	for i in a '"$L"' y
+	for i in b '"$L"' z
 	do
 		echo $i
 	done >victim &&
@@ -81,7 +90,7 @@ do
 	with) u= ;;
 	without) u='--unidiff-zero ' ;;
 	esac
-	for kind in add-a add-z mod-a mod-z del-a del-z
+	for kind in add-a add-z insert-a mod-a mod-z del-a del-z
 	do
 		test_expect_success "apply $kind-patch $with context" '
 			cat original >victim &&
@@ -95,7 +104,7 @@ do
 	done
 done
 
-for kind in add-a add-z mod-a mod-z del-a del-z
+for kind in add-a add-z insert-a mod-a mod-z del-a del-z
 do
 	rm -f $kind-ng.without
 	sed	-e "s/^diff --git /diff /" \
-- 
1.6.0
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 17 in “git gui: show diffs with a minimum of 1 context line”
  1. git gui: show diffs with a minimum of 1 context lineClemens Buchacher, Aug 30, 2008
  2. git gui: use apply --unidiff-zero when staging hunks without contextClemens Buchacher, Aug 30, 2008
  3. Junio C HamanoAug 30, 2008
  4. git apply: do not match beginning in special unidiff-zero caseClemens Buchacher, Aug 30, 2008
  5. Junio C HamanoAug 30, 2008
  6. git-apply: Loosen "match_beginning" logicJunio C Hamano, Aug 30, 2008
  7. Johannes SixtAug 30, 2008
  8. Clemens BuchacherAug 30, 2008
  9. Junio C HamanoAug 30, 2008
  10. Clemens BuchacherAug 30, 2008
  11. Shawn O. PearceSep 1, 2008
  12. Junio C HamanoAug 30, 2008
  13. Junio C HamanoAug 30, 2008
  14. git gui: show diffs with a minimum of 1 context lineClemens Buchacher, Aug 30, 2008
  15. Shawn O. PearceSep 1, 2008
  16. Clemens BuchacherSep 1, 2008
  17. Shawn O. PearceSep 1, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.