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

[PATCH] git-apply: Loosen "match_beginning" logic

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 30, 2008, 19:40 UTC
Message-ID
<7vk5dygukv.fsf_-_@gitster.siamese.dyndns.org>
In-Reply-To
<7vhc92ie44.fsf@gitster.siamese.dyndns.org>

Even after a handfle attempts, match_beginning logic still has corner cases:

    1bf1a85 (apply: treat EOF as proper context., 2006-05-23)
    65aadb9 (apply: force matching at the beginning., 2006-05-24)
    4be6096 (apply --unidiff-zero: loosen sanity checks ..., 2006-09-17)
    ee5a317 (Fix "git apply" to correctly enforce "match ..., 2008-04-06)
This is a tricky piece of code.

We still incorrectly enforce "match_beginning" for -U0 matches. I noticed this while trying out an example sequence from Clemens Buchacher:

    $ echo a >victim
    $ git add victim
    $ echo b >>victim
    $ git diff -U0 >patch
    $ cat patch
    diff --git i/victim w/victim
    index 7898192..422c2b7 100644
    --- i/victim
    +++ w/victim
    @@ -1,0 +2 @@ a
    +b
    $ git apply --cached --unidiff-zero <patch
    $ git show :victim
    b
    a

The change inserts a new line before the second line, but we insist it to be applied at the beginning. As the result, the code refuses to apply it at the original offset, and we end up adding the line at the beginning.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-apply.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git c/builtin-apply.c w/builtin-apply.c
index 2216a0b..47261e1 100644
--- c/builtin-apply.c
+++ w/builtin-apply.c
@@ -1996,6 +1996,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
 	/*
 	 * A hunk to change lines at the beginning would begin with
 	 * @@ -1,L +N,M @@
+	 * but we need to be careful.  -U0 that inserts before the second
+	 * line also has this pattern.
 	 *
 	 * And a hunk to add to an empty file would begin with
 	 * @@ -0,0 +N,M @@
@@ -2003,7 +2005,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
 	 * 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 ||
+			   (frag->oldpos == 1 && !unidiff_zero));
 
 	/*
 	 * A hunk without trailing lines must match at the end.
Previous: Junio C HamanoNext: Johannes Sixt
Message 6 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.