{"thread":{"id":"11650","subject":"git apply behaves differently from patch(1)","startedAt":"2008-01-16T22:58:48Z","lastAt":"2008-01-17T19:58:41Z","messageCount":3,"participants":["Thomas Zander","Johannes Sixt","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"65621","messageId":"200801162358.48723.zander@kde.org","threadId":"11650","inReplyTo":null,"subject":"git apply behaves differently from patch(1)","fromName":"Thomas Zander","fromEmail":"zander@kde.org","sentAt":"2008-01-16T22:58:48Z","receivedAt":"2008-01-16T22:58:48Z","isPatch":false,"sender":{"key":"zander@kde.org","avatar":null},"body":"In the following usecase git apply (git version 1.5.4.rc3.15.g785f9) \ndoesn't do what I expect it should do. I expect it to do the same as \npatch does in the same situation.\n\nTo reproduce;\nCreate a file 'test' with a number on each line.  Numbers 1 though 10.\n$ for i in 1 2 3 4 5 6 7 8 9 10; do echo $i >> test; done\n$ git add test\n$ git commit test\n\n$ rm test\n$ for i in 1 3 4 5 6 7 10; do echo $i >> test; done\n$ git diff-index -p --unified=0 HEAD test | tee mypatch\n\nNow use your editor to edit 'mypatch' and remove the first hunk; the end \nresult (after your editing) should be something like this;\n$ cat mypatch\ndiff --git a/test b/test\nindex f00c965..319869c 100644\n--- a/test\n+++ b/test\n@@ -8,2 +6,0 @@\n-8\n-9\n\napply revert this patch;\n$ git apply -R --unidiff-zero --apply mypatch\n$ git diff\n\nWhat I expect (and what I get if I replace git apply with a 'patch -R -p1 \n< mypatch') is that the diff shows line \"2\" is still missing.\n\nWhat I get instead is that \"2\" is missing but also that \"10\" moved 2 lines \nup.\nI conclude that git somehow doesn't like the patch to be removed, while \npatch(1) has no problem with that.\n\nI hope you agree its a bug and fix it in an upcoming version, it would be \ngreat if I can avoid using patch(1) or worse.\nIf you have any questions feel free to ask; but please cc me as I am not \nsubscribed.\n-- \nThomas Zander\n"},{"id":"65696","messageId":"478F0DC0.9030107@viscovery.net","threadId":"11650","inReplyTo":"200801162358.48723.zander@kde.org","subject":"Re: git apply behaves differently from patch(1)","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-01-17T08:11:44Z","receivedAt":"2008-01-17T08:11:44Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Thomas Zander schrieb:\n> In the following usecase git apply (git version 1.5.4.rc3.15.g785f9) \n> doesn't do what I expect it should do. I expect it to do the same as \n> patch does in the same situation.\n> \n> To reproduce;\n\n[... hand-edit a patch without context ...]\n\n> What I expect (and what I get if I replace git apply with a 'patch -R -p1 \n> < mypatch') is that the diff shows line \"2\" is still missing.\n> \n> What I get instead is that \"2\" is missing but also that \"10\" moved 2 lines \n> up.\n> I conclude that git somehow doesn't like the patch to be removed, while \n> patch(1) has no problem with that.\n> \n> I hope you agree its a bug and fix it in an upcoming version, it would be \n> great if I can avoid using patch(1) or worse.\n\nIt's not exactly a bug. The behavior of zero-context patches is simply not\nwell-defined. You have just been lucky that patch worked in the way that\nyou expected. Don't use zero-context patches.\n\nThat said git-apply can certainly be modified to behave like patch in this\ncase. I tried, but gave up - it's too much code that is new to me. :(\n\n-- Hannes\n"},{"id":"65770","messageId":"alpine.LFD.1.00.0801171142230.14959@woody.linux-foundation.org","threadId":"11650","inReplyTo":"200801162358.48723.zander@kde.org","subject":"Re: git apply behaves differently from patch(1)","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-01-17T19:58:41Z","receivedAt":"2008-01-17T19:58:41Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 16 Jan 2008, Thomas Zander wrote:\n>\n> In the following usecase git apply (git version 1.5.4.rc3.15.g785f9) \n> doesn't do what I expect it should do. I expect it to do the same as \n> patch does in the same situation.\n\nThere's actually a lot of cases where git-apply doesn't really do what \npatch does.\n\nThere's one really obvious difference, in that git-apply only does unified \ndiffs and doesn't support any of the traditional ones: that may be seen as \na downside, but I was never interested in them, so it's a \"limitation\" \nonly in the sense that git-apply just doesn't do the ass-backwards old \nformats.\n\nBut this definitely means that \"git-apply\" doesn't really _replace_ patch \nper se.\n\nThere's also the very explicit differences, ie git-apply has all the \nextensions for renaming etc.\n\nBut in addition to those limitations and extensions there are the much \nsubtler ones, which tend to come down to different interpretations of what \nis \"safe\".\n\nWhat you hit is one such difference. There are others. They all boil down \nto \"I'm not sure enough I can apply this correctly, so I won't\":\n\n - (the one you hit): zero context at the end means \"end-of-file\"\n\n   There's no other valid reason to have zero context in git-apply's \n   opinion, because without the context, there's no way to verify that \n   we're applying things in the right place.\n\n - git doesn't guess how deep the path is by default.\n\n - git does not accept any fuzz by default\n\nIn other words, git-apply simply doesn't want to apply unsafe patches. \nYes, they often (probably 99% of the time) would apply in the right place, \nbut partly *because* they often work, people are so used to doing them \nthat then the few cases where they silently apply incorrectly are even \nmore painful and often aren't noticed.\n\nSo no, git-apply really isn't a straight replacement for GNU patch. \n\nYou can't really get exactly the same behaviour with any flags (there is \nno \"guess filename path depth\" mode at all, for example), but you can get \nfairly close with\n\n\tgit-apply -C1 --unidiff-zero\n\nwhere that -C1 matches GNU patches (INSANE!) default fuzz of 2, and the \n--unidiff-zero thing disables the stricter git-apply rules for no context.\n\nI would actually suggest you go the other way: rather than try to make \ngit-apply mimic the unsafe defaults of GNU patch, try to teach yourself to \nuse the stricter rules. It's not always practical, but generally, the \nthings git-apply refuses to do by default really *are* rather likely to \nmis-apply a patch occasionally.\n\n(Even with git-apply's strict defaults, there is obviously no *guarantee* \nthat a patch will always apply correctly, but at least git-apply will \nstrictly check as much of the information that is available in the patch)\n\n\t\t\tLinus\n"}]}