git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bug in git-apply
@ 2008-04-06 23:53 Karl Hasselström
  2008-04-07  1:11 ` Junio C Hamano
  0 siblings, 1 reply; 4+ messages in thread
From: Karl Hasselström @ 2008-04-06 23:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Catalin Marinas

StGit's test suite has started failing, and it's due to a change in
git that I'm pretty sure is a bug. I built a small test case using
just git for easier testing:

  mkdir foo
  cd foo

  git init
  touch xx
  git add xx
  git commit -m 'first'

  git checkout -b branch

  echo aaa >> xx
  git add xx
  git commit -m 'second'

  git checkout master

  echo bbb >> xx
  git add xx
  git commit -m 'third'

  git diff branch^ branch > p
  git apply < p && echo "this should not succeed!"

Basically, we have a file containing "aaa\n", and a patch that tries
to take the file from "" to "bbb\n". A recent enough git-apply will
accept this patch without complaining, and put "aaa\nbbb\n" in the
file.

I bisected, and the culprit was this commit:

commit dc41976a3eed1d9c93fdc08c448bab969db4e0ec
Author: Junio C Hamano <gitster@pobox.com>
Date:   Sat Jan 19 01:58:34 2008 -0800

    builtin-apply.c: push match-beginning/end logic down

    This moves the logic to force match at the beginning and/or at
    the end of the buffer to the actual function that finds the
    match from its caller.  This is a necessary preparation for the
    next step to allow matching disregarding certain differences,
    such as whitespace changes.

    We probably could optimize this even more by taking advantage of
    the fact that match_beginning and match_end forces the match to
    be at an exact location (anchored at the beginning and/or the
    end), but that's for another commit.

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: bug in git-apply
  2008-04-06 23:53 bug in git-apply Karl Hasselström
@ 2008-04-07  1:11 ` Junio C Hamano
  2008-04-07  7:04   ` Karl Hasselström
  0 siblings, 1 reply; 4+ messages in thread
From: Junio C Hamano @ 2008-04-07  1:11 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git, Catalin Marinas, Linus Torvalds

Karl Hasselström <kha@treskal.com> writes:

> I bisected, and the culprit was this commit:
>
> commit dc41976a3eed1d9c93fdc08c448bab969db4e0ec

I think the issue is much older than that.  The faulty one is 4be6096
(apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches,
2006-09-17), which incorrectly loosened the match_beginning/match_end
computation too much, whose botch may have been hidden by what the
surrounding code did.

And 65aadb9 (apply: force matching at the beginning., 2006-05-24) is
equally wrong in that it tried to take hints from leading context lines,
to decide if the hunk must match at the beginning, but in this case we
can just look at the line number in the hunk to decide.

How about doing this?


 builtin-apply.c           |   29 ++++++++++++++++-------------
 t/t4104-apply-boundary.sh |   13 +++++++++++++
 2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index b5f78ac..abe73a0 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1937,21 +1937,24 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
 	trailing = frag->trailing;
 
 	/*
-	 * If we don't have any leading/trailing data in the patch,
-	 * we want it to match at the beginning/end of the file.
+	 * A hunk to change lines at the beginning would begin with
+	 * @@ -1,L +N,M @@
 	 *
-	 * But that would break if the patch is generated with
-	 * --unified=0; sane people wouldn't do that to cause us
-	 * trouble, but we try to please not so sane ones as well.
+	 * 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.
 	 */
-	if (unidiff_zero) {
-		match_beginning = (!leading && !frag->oldpos);
-		match_end = 0;
-	}
-	else {
-		match_beginning = !leading && (frag->oldpos == 1);
-		match_end = !trailing;
-	}
+	match_beginning = frag->oldpos <= 1;
+
+	/*
+	 * A hunk without trailing lines must match at the end.
+	 * However, we simply cannot tell if a hunk must match end
+	 * from the lack of trailing lines if the patch was generated
+	 * with unidiff without any context.
+	 */
+	match_end = !unidiff_zero && !trailing;
 
 	pos = frag->newpos ? (frag->newpos - 1) : 0;
 	preimage.buf = oldlines;
diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh
index 64f34e3..0007535 100755
--- a/t/t4104-apply-boundary.sh
+++ b/t/t4104-apply-boundary.sh
@@ -112,4 +112,17 @@ do
 	'
 done
 
+test_expect_success 'two lines' '
+
+	>file &&
+	git add file &&
+	echo aaa >file &&
+	git diff >patch &&
+	git add file &&
+	echo bbb >file &&
+	git add file &&
+	test_must_fail git apply patch
+
+'
+
 test_done

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: bug in git-apply
  2008-04-07  1:11 ` Junio C Hamano
@ 2008-04-07  7:04   ` Karl Hasselström
  2008-04-07  7:12     ` Junio C Hamano
  0 siblings, 1 reply; 4+ messages in thread
From: Karl Hasselström @ 2008-04-07  7:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Catalin Marinas, Linus Torvalds

On 2008-04-06 18:11:13 -0700, Junio C Hamano wrote:

> How about doing this?

Well, it does fix the stgit test suite failure, so I'm all for it!
(Though I see you've already pushed it to master.) Thanks.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: bug in git-apply
  2008-04-07  7:04   ` Karl Hasselström
@ 2008-04-07  7:12     ` Junio C Hamano
  0 siblings, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2008-04-07  7:12 UTC (permalink / raw)
  To: git; +Cc: Catalin Marinas, Linus Torvalds

Karl Hasselström <kha@treskal.com> writes:

> On 2008-04-06 18:11:13 -0700, Junio C Hamano wrote:
>
>> How about doing this?
>
> Well, it does fix the stgit test suite failure, so I'm all for it!
> (Though I see you've already pushed it to master.) Thanks.

This actually is a fix for maint; even though your test case does not
let you observe the breakage directly, only because must-match-at-end
check prevents the single-liner test hunk from applying cleanly.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-04-07  7:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-06 23:53 bug in git-apply Karl Hasselström
2008-04-07  1:11 ` Junio C Hamano
2008-04-07  7:04   ` Karl Hasselström
2008-04-07  7:12     ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).