* [PATCH] Add a test-case for git-apply trying to add an ending line @ 2006-05-23 21:48 Catalin Marinas 2006-05-24 0:31 ` Junio C Hamano 0 siblings, 1 reply; 9+ messages in thread From: Catalin Marinas @ 2006-05-23 21:48 UTC (permalink / raw) To: git From: Catalin Marinas <catalin.marinas@gmail.com> git-apply adding an ending line doesn't seem to fail if the ending line is already present in the patched file. Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com> --- t/t4113-apply-ending.sh | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/t/t4113-apply-ending.sh b/t/t4113-apply-ending.sh new file mode 100755 index 0000000..d021ae8 --- /dev/null +++ b/t/t4113-apply-ending.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (c) 2006 Catalin Marinas +# + +test_description='git-apply trying to add an ending line. + +' +. ./test-lib.sh + +# setup + +cat >test-patch <<\EOF +diff --git a/file b/file +--- a/file ++++ b/file +@@ -1,2 +1,3 @@ + a + b ++c +EOF + +echo 'a' >file +echo 'b' >>file +echo 'c' >>file + +test_expect_success setup \ + 'git-update-index --add file' + +# test + +test_expect_failure apply \ + 'git-apply --index test-patch' + +test_done ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-23 21:48 [PATCH] Add a test-case for git-apply trying to add an ending line Catalin Marinas @ 2006-05-24 0:31 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano 0 siblings, 2 replies; 9+ messages in thread From: Junio C Hamano @ 2006-05-24 0:31 UTC (permalink / raw) To: Catalin Marinas; +Cc: git Hmmmmm. To git-apply, this patch: diff --git a/file b/file --- a/file +++ b/file @@ -1,2 +1,3 @@ a b +c currently means "I want to append a line c immediately after the lines that have a and then b". Nothing else. And applying it to a b c produces a b c c The first c is what your patch added, and the second c is what was originally there. I do not think this is necessarily a bug. You _could_ make the EOF a special case (i.e. you _could_ interpret the patch that it also says, with "@@ -1,2", that "the result of this patch _must_ end with this line I just added"), and if you are going to do that, you would also need a symmetric special case for the beginning of the file, but I do not think it is the right thing to do in general. Realistically, you would have something like this: diff --git a/apply.c b/apply.c index 0ed9d13..f99c6fe 100644 --- a/apply.c +++ b/apply.c @@ -2297,3 +2297,8 @@ int main(int argc, char **argv) return 0; /* end of main */ } + +static void this_function_is_unused(void) +{ + printf("hello, world\n"); +} You added a useless function at the end of the file. While you prepared the above patch, the upstream updated the same file to end like this: return 0; /* end of main */ } static int some_new_function(void) { return 314; } Now, git-apply would produce this file if you apply the above patch: return 0; /* end of main */ } static void this_function_is_unused(void) { printf("hello, world\n"); } static int some_new_function(void) { return 314; } I think this current behaviour is more desirable than special casing the end of file and refusing to apply. In this particular case, expecting failure like your new test does is somewhat understandable, but if you change the test case to start with this file, you would realize that your expectation is not the only valid understanding of what is really happening: echo 'a' >file echo 'b' >>file echo 'd' >>file Applying test-patch to this would result in a b c d which I think is more useful behaviour. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 0:31 ` Junio C Hamano @ 2006-05-24 1:09 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano 1 sibling, 0 replies; 9+ messages in thread From: Junio C Hamano @ 2006-05-24 1:09 UTC (permalink / raw) To: Catalin Marinas; +Cc: git Junio C Hamano <junkio@cox.net> writes: > To git-apply, this patch: > > diff --git a/file b/file > --- a/file > +++ b/file > @@ -1,2 +1,3 @@ > a > b > +c > > currently means "I want to append a line c immediately after the > lines that have a and then b". >... > I do not think this is necessarily a bug. You _could_ make the > EOF a special case (i.e. you _could_ interpret the patch that it > also says, with "@@ -1,2", that "the result of this patch _must_ > end with this line I just added"), and if you are going to do > that, you would also need a symmetric special case for the > beginning of the file, but I do not think it is the right thing > to do in general. Come to think of it, the above argument is bogus. We _would_ want to make EOF just like any other context lines. The issue is if we can reliably tell if there is such an EOF context by looking at the diff. Not having the same number of lines that starts with ' ' in the hunk is not really a nice way of doing so (you could make a unified diff that does not have trailing context at all), and I do not offhand think of a good way to do so. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 0:31 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano @ 2006-05-24 1:09 ` Junio C Hamano 2006-05-24 2:08 ` Linus Torvalds 1 sibling, 1 reply; 9+ messages in thread From: Junio C Hamano @ 2006-05-24 1:09 UTC (permalink / raw) To: Catalin Marinas; +Cc: git Junio C Hamano <junkio@cox.net> writes: > To git-apply, this patch: > > diff --git a/file b/file > --- a/file > +++ b/file > @@ -1,2 +1,3 @@ > a > b > +c > > currently means "I want to append a line c immediately after the > lines that have a and then b". >... > I do not think this is necessarily a bug. You _could_ make the > EOF a special case (i.e. you _could_ interpret the patch that it > also says, with "@@ -1,2", that "the result of this patch _must_ > end with this line I just added"), and if you are going to do > that, you would also need a symmetric special case for the > beginning of the file, but I do not think it is the right thing > to do in general. Come to think of it, the above argument is bogus. We _would_ want to make EOF just like any other context lines. The issue is if we can reliably tell if there is such an EOF context by looking at the diff. Not having the same number of lines that starts with ' ' in the hunk is not really a nice way of doing so (you could make a unified diff that does not have trailing context at all), and I do not offhand think of a good way to do so. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 1:09 ` Junio C Hamano @ 2006-05-24 2:08 ` Linus Torvalds 2006-05-24 2:17 ` Linus Torvalds 2006-05-24 4:59 ` Junio C Hamano 0 siblings, 2 replies; 9+ messages in thread From: Linus Torvalds @ 2006-05-24 2:08 UTC (permalink / raw) To: Junio C Hamano; +Cc: Catalin Marinas, git On Tue, 23 May 2006, Junio C Hamano wrote: > > Come to think of it, the above argument is bogus. We _would_ > want to make EOF just like any other context lines. > > The issue is if we can reliably tell if there is such an EOF > context by looking at the diff. Not having the same number of > lines that starts with ' ' in the hunk is not really a nice way > of doing so (you could make a unified diff that does not have > trailing context at all), and I do not offhand think of a good > way to do so. We can. Something like this should do it. (The same thing could be done for "match_beginning", perhaps). Totally untested, of course. (It might be better to pass in "match_end" to find_offset(), so that it could do the "look forwards" pass to see if it finds a better line offset that is at the end - as it is, this will _fail_ the patch if it could apply better at a non-end thing, even if it would _also_ have applied at the end of the file). Linus --- diff --git a/apply.c b/apply.c index 0ed9d13..905bf34 100644 --- a/apply.c +++ b/apply.c @@ -1333,6 +1333,7 @@ static int apply_line(char *output, cons static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag) { + int match_end; char *buf = desc->buffer; const char *patch = frag->patch; int offset, size = frag->size; @@ -1395,10 +1396,20 @@ #endif newlines = new; leading = frag->leading; trailing = frag->trailing; + + /* + * If we don't have any trailing data in the patch, + * we want to match the final ending '\0' byte in + * the file too.. + */ + match_end = !trailing; + lines = 0; pos = frag->newpos; for (;;) { offset = find_offset(buf, desc->size, oldlines, oldsize, pos, &lines); + if (match_end && offset + oldsize != desc->size) + offset = -1; if (offset >= 0) { int diff = newsize - oldsize; unsigned long size = desc->size + diff; @@ -1428,6 +1439,10 @@ #endif /* Am I at my context limits? */ if ((leading <= p_context) && (trailing <= p_context)) break; + if (match_end) { + match_end = 0; + continue; + } /* Reduce the number of context lines * Reduce both leading and trailing if they are equal * otherwise just reduce the larger context. ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 2:08 ` Linus Torvalds @ 2006-05-24 2:17 ` Linus Torvalds 2006-05-24 4:59 ` Junio C Hamano 1 sibling, 0 replies; 9+ messages in thread From: Linus Torvalds @ 2006-05-24 2:17 UTC (permalink / raw) To: Junio C Hamano; +Cc: Catalin Marinas, git On Tue, 23 May 2006, Linus Torvalds wrote: > > + /* > + * If we don't have any trailing data in the patch, > + * we want to match the final ending '\0' byte in > + * the file too.. > + */ Btw, ignore the comment. I was thinking of doing the matching differently (just make the source buffer include a '\0' at the end, and forcing that to match), but once I actually wrote it, it ended up being much easier to just check the offset/size difference. So that "final ending '\0' byte in the file" part of the comment is just nonsense. Linus ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 2:08 ` Linus Torvalds 2006-05-24 2:17 ` Linus Torvalds @ 2006-05-24 4:59 ` Junio C Hamano 2006-05-24 13:32 ` Catalin Marinas 2006-05-24 14:49 ` Linus Torvalds 1 sibling, 2 replies; 9+ messages in thread From: Junio C Hamano @ 2006-05-24 4:59 UTC (permalink / raw) To: Linus Torvalds; +Cc: Catalin Marinas, git Linus Torvalds <torvalds@osdl.org> writes: > On Tue, 23 May 2006, Junio C Hamano wrote: > >> The issue is if we can reliably tell if there is such an EOF >> context by looking at the diff. Not having the same number of >> lines that starts with ' ' in the hunk is not really a nice way >> of doing so (you could make a unified diff that does not have >> trailing context at all), and I do not offhand think of a good >> way to do so. > > We can. Something like this should do it. > > (The same thing could be done for "match_beginning", perhaps). But this is exactly what I said I had trouble with in the above. In the extreme case, wouldn't this make git apply to refuse to apply a self generated patch with 0-line context? IOW, $ git checkout -- foo ;# reset to indexed version $ edit foo $ git diff -U0 >P.diff $ git checkout -- foo ;# reset to indexed version $ git apply <P.diff would fail, even though it _should_ cleanly apply. I'd admit that trying to apply a patch without context like the above example _is_ insane, and I realize that I am making this problem unsolvable by refusing the heuristics to consider that the patch is anchored at the end when we do not see any trailing context. But somehow it feels wrong... ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 4:59 ` Junio C Hamano @ 2006-05-24 13:32 ` Catalin Marinas 2006-05-24 14:49 ` Linus Torvalds 1 sibling, 0 replies; 9+ messages in thread From: Catalin Marinas @ 2006-05-24 13:32 UTC (permalink / raw) To: Junio C Hamano; +Cc: Linus Torvalds, git On 24/05/06, Junio C Hamano <junkio@cox.net> wrote: > I'd admit that trying to apply a patch without context like the > above example _is_ insane, and I realize that I am making this > problem unsolvable by refusing the heuristics to consider that > the patch is anchored at the end when we do not see any trailing > context. But somehow it feels wrong... The reason I sent you this test is that GNU patch fails to apply the diff but git-apply succeeds (and I thought git-apply is more restrictive). When there are context lines either before or after the "+" line, it should be OK to assume that the diff has context and therefore the EOF should be considered. If there are no context lines at all, the diff is either without context or it is meant to patch an empty file. The latter is safer and probably valid for most of the cases but if you have a patch without context, you could explicitely pass the -C0 option to git-apply. -- Catalin ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add a test-case for git-apply trying to add an ending line 2006-05-24 4:59 ` Junio C Hamano 2006-05-24 13:32 ` Catalin Marinas @ 2006-05-24 14:49 ` Linus Torvalds 1 sibling, 0 replies; 9+ messages in thread From: Linus Torvalds @ 2006-05-24 14:49 UTC (permalink / raw) To: Junio C Hamano; +Cc: Catalin Marinas, git On Tue, 23 May 2006, Junio C Hamano wrote: > Linus Torvalds <torvalds@osdl.org> writes: > > > On Tue, 23 May 2006, Junio C Hamano wrote: > > > >> The issue is if we can reliably tell if there is such an EOF > >> context by looking at the diff. Not having the same number of > >> lines that starts with ' ' in the hunk is not really a nice way > >> of doing so (you could make a unified diff that does not have > >> trailing context at all), and I do not offhand think of a good > >> way to do so. > > > > We can. Something like this should do it. > > > > (The same thing could be done for "match_beginning", perhaps). > > But this is exactly what I said I had trouble with in the above. Well, not quite. You said "not the same number of lines", and I say "no ending context". Very different. My patch actually is totally self-consistent: not having any context at the end of a unified diff really means that it is the end of the file (ie, the "end of file" there _is_ the context). And if you want to apply files without context, you should use "-Cx", and my patch does that too - if you asked for "relaxed context checking", it will re-try without the "only at end" check thanks to the if (match_end) { match_end = 0; continue; } so it all should work. Not that I _tested_ it, of course ;) Linus ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-05-24 14:50 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-05-23 21:48 [PATCH] Add a test-case for git-apply trying to add an ending line Catalin Marinas 2006-05-24 0:31 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano 2006-05-24 1:09 ` Junio C Hamano 2006-05-24 2:08 ` Linus Torvalds 2006-05-24 2:17 ` Linus Torvalds 2006-05-24 4:59 ` Junio C Hamano 2006-05-24 13:32 ` Catalin Marinas 2006-05-24 14:49 ` Linus Torvalds
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).