{"thread":{"id":"16256","subject":"[PATCH] 3-way merge with file move fails when diff.renames = copies","startedAt":"2008-11-10T22:26:10Z","lastAt":"2010-07-24T21:59:10Z","messageCount":22,"participants":["David D. Kilzer","Johannes Schindelin","Junio C Hamano","Jonathan Nieder","Sverre Rabbelier"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"95396","messageId":"1226355970-2542-1-git-send-email-ddkilzer@kilzer.net","threadId":"16256","inReplyTo":null,"subject":"[PATCH] 3-way merge with file move fails when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2008-11-10T22:26:10Z","receivedAt":"2008-11-10T22:26:10Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"With diff.renames = copies, a 3-way merge (e.g. \"git rebase\") would\nfail with the following error:\n\n    fatal: mode change for <file>, which is not in current HEAD\n    Repository lacks necessary blobs to fall back on 3-way merge.\n    Cannot fall back to three-way merge.\n    Patch failed at 0001.\n\nThe bug is a logic error added in ece7b749, which attempts to find\nan sha1 for a patch with no index line in build_fake_ancestor().\nInstead of failing unless an sha1 is found for both the old file and\nthe new file, a failure should only be reported if neither the old\nfile nor the new file is found.\n\nSigned-off-by: David D. Kilzer <ddkilzer@kilzer.net>\n---\n builtin-apply.c   |    2 +-\n t/t3400-rebase.sh |   17 +++++++++++++++++\n 2 files changed, 18 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 4c4d1e1..cfeb6cc 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2573,7 +2573,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \t\telse if (get_sha1(patch->old_sha1_prefix, sha1))\n \t\t\t/* git diff has no index line for mode/type changes */\n \t\t\tif (!patch->lines_added && !patch->lines_deleted) {\n-\t\t\t\tif (get_current_sha1(patch->new_name, sha1) ||\n+\t\t\t\tif (get_current_sha1(patch->new_name, sha1) &&\n \t\t\t\t    get_current_sha1(patch->old_name, sha1))\n \t\t\t\t\tdie(\"mode change for %s, which is not \"\n \t\t\t\t\t\t\"in current HEAD\", name);\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex b7a670e..a156850 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -84,4 +84,21 @@ test_expect_success 'rebase a single mode change' '\n      GIT_TRACE=1 git rebase master\n '\n \n+test_expect_success 'rebase a single file move with diff.renames = copies' '\n+     git config diff.renames copies &&\n+     git checkout master &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     test_tick &&\n+     git commit -m \"prepare file move\" &&\n+     git checkout -b filemove HEAD^ &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     mkdir D &&\n+     git mv A D/A &&\n+     test_tick &&\n+     git commit -m filemove &&\n+     GIT_TRACE=1 git rebase master\n+'\n+\n test_done\n-- \n1.6.0\n"},{"id":"95404","messageId":"alpine.DEB.1.00.0811110039280.30769@pacific.mpi-cbg.de","threadId":"16256","inReplyTo":"1226355970-2542-1-git-send-email-ddkilzer@kilzer.net","subject":"Re: [PATCH] 3-way merge with file move fails when diff.renames = copies","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-11-10T23:41:01Z","receivedAt":"2008-11-10T23:41:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nexcept for the commit subject I like it, especially the commit body. So:\n\ns/(3-way.*) fails/Fix &/\n\nCiao,\nDscho\n"},{"id":"95408","messageId":"7v63mv3zww.fsf@gitster.siamese.dyndns.org","threadId":"16256","inReplyTo":"1226355970-2542-1-git-send-email-ddkilzer@kilzer.net","subject":"Re: [PATCH] 3-way merge with file move fails when diff.renames = copies","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-11-10T23:49:03Z","receivedAt":"2008-11-10T23:49:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"David D. Kilzer\" <ddkilzer@kilzer.net> writes:\n\n> With diff.renames = copies, a 3-way merge (e.g. \"git rebase\") would\n> fail with the following error:\n>\n>     fatal: mode change for <file>, which is not in current HEAD\n>     Repository lacks necessary blobs to fall back on 3-way merge.\n>     Cannot fall back to three-way merge.\n>     Patch failed at 0001.\n>\n> The bug is a logic error added in ece7b749, which attempts to find\n> an sha1 for a patch with no index line in build_fake_ancestor().\n> Instead of failing unless an sha1 is found for both the old file and\n> the new file, a failure should only be reported if neither the old\n> file nor the new file is found.\n>\n> Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net>\n> ---\n>  builtin-apply.c   |    2 +-\n>  t/t3400-rebase.sh |   17 +++++++++++++++++\n>  2 files changed, 18 insertions(+), 1 deletions(-)\n>\n> diff --git a/builtin-apply.c b/builtin-apply.c\n> index 4c4d1e1..cfeb6cc 100644\n> --- a/builtin-apply.c\n> +++ b/builtin-apply.c\n> @@ -2573,7 +2573,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n>  \t\telse if (get_sha1(patch->old_sha1_prefix, sha1))\n>  \t\t\t/* git diff has no index line for mode/type changes */\n>  \t\t\tif (!patch->lines_added && !patch->lines_deleted) {\n> -\t\t\t\tif (get_current_sha1(patch->new_name, sha1) ||\n> +\t\t\t\tif (get_current_sha1(patch->new_name, sha1) &&\n>  \t\t\t\t    get_current_sha1(patch->old_name, sha1))\n>  \t\t\t\t\tdie(\"mode change for %s, which is not \"\n>  \t\t\t\t\t\t\"in current HEAD\", name);\n\nHmm.\n\nThe logic introduced by the blamed commit makes the --index-info\nunreliable (I'd rather see it fail reliably if it does not have enough\ninformation rather than pretending everything is Ok), and I think the\npatch makes it slightly more so.\n\nIf new_name that is not related at all to old_name happens to exist in the\ncurrent tree you are applying the patch to, you can grab the contents of\nthe unrelated file as the preimage and try to merge the changes in.\n\nWhen running --index-info for the purpose of \"am -3\" (hence rebase), the\nexpectation is that the tree you are applying the changes to is _similar_\nto the preimage of the change, i.e. old_name.  Shouldn't missing old_name\nbe treated as a fatal condition?  new_name does not have to even exist\nbecause otherwise you cannot accept a patch that creates the path.\n\nWouldn't this be a better patch, I wonder...\n\n builtin-apply.c |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git i/builtin-apply.c w/builtin-apply.c\nindex 4c4d1e1..7de70e9 100644\n--- i/builtin-apply.c\n+++ w/builtin-apply.c\n@@ -2573,8 +2573,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \t\telse if (get_sha1(patch->old_sha1_prefix, sha1))\n \t\t\t/* git diff has no index line for mode/type changes */\n \t\t\tif (!patch->lines_added && !patch->lines_deleted) {\n-\t\t\t\tif (get_current_sha1(patch->new_name, sha1) ||\n-\t\t\t\t    get_current_sha1(patch->old_name, sha1))\n+\t\t\t\tif (get_current_sha1(patch->old_name, sha1))\n \t\t\t\t\tdie(\"mode change for %s, which is not \"\n \t\t\t\t\t\t\"in current HEAD\", name);\n \t\t\t\tsha1_ptr = sha1;\n"},{"id":"95409","messageId":"1226361207-7491-1-git-send-email-ddkilzer@kilzer.net","threadId":"16256","inReplyTo":"alpine.DEB.1.00.0811110039280.30769@pacific.mpi-cbg.de","subject":"[PATCH] Fix 3-way merge with file move when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2008-11-10T23:53:27Z","receivedAt":"2008-11-10T23:53:27Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"With diff.renames = copies, a 3-way merge (e.g. \"git rebase\") with a\nfile move would fail with the following error:\n\n    fatal: mode change for <file>, which is not in current HEAD\n    Repository lacks necessary blobs to fall back on 3-way merge.\n    Cannot fall back to three-way merge.\n    Patch failed at 0001.\n\nThe bug is a logic error added in ece7b749, which attempts to find\nan sha1 for a patch with no index line in build_fake_ancestor().\nInstead of failing unless an sha1 is found for both the old file and\nthe new file, a failure should only be reported if neither the old\nfile nor the new file is found.\n\nSigned-off-by: David D. Kilzer <ddkilzer@kilzer.net>\n---\nSame as \"[PATCH] 3-way merge with file move fails when diff.renames = copies\"\nbut with an updated subject and initial sentence (added \"with a file move\").\n\n builtin-apply.c   |    2 +-\n t/t3400-rebase.sh |   17 +++++++++++++++++\n 2 files changed, 18 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 4c4d1e1..cfeb6cc 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2573,7 +2573,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \t\telse if (get_sha1(patch->old_sha1_prefix, sha1))\n \t\t\t/* git diff has no index line for mode/type changes */\n \t\t\tif (!patch->lines_added && !patch->lines_deleted) {\n-\t\t\t\tif (get_current_sha1(patch->new_name, sha1) ||\n+\t\t\t\tif (get_current_sha1(patch->new_name, sha1) &&\n \t\t\t\t    get_current_sha1(patch->old_name, sha1))\n \t\t\t\t\tdie(\"mode change for %s, which is not \"\n \t\t\t\t\t\t\"in current HEAD\", name);\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex b7a670e..a156850 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -84,4 +84,21 @@ test_expect_success 'rebase a single mode change' '\n      GIT_TRACE=1 git rebase master\n '\n \n+test_expect_success 'rebase a single file move with diff.renames = copies' '\n+     git config diff.renames copies &&\n+     git checkout master &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     test_tick &&\n+     git commit -m \"prepare file move\" &&\n+     git checkout -b filemove HEAD^ &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     mkdir D &&\n+     git mv A D/A &&\n+     test_tick &&\n+     git commit -m filemove &&\n+     GIT_TRACE=1 git rebase master\n+'\n+\n test_done\n-- \n1.6.0\n"},{"id":"95417","messageId":"953073.59787.qm@web52406.mail.re2.yahoo.com","threadId":"16256","inReplyTo":"7v63mv3zww.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] 3-way merge with file move fails when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2008-11-11T00:06:04Z","receivedAt":"2008-11-11T00:06:04Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> If new_name that is not related at all to old_name happens to exist in the\n> current tree you are applying the patch to, you can grab the contents of\n> the unrelated file as the preimage and try to merge the changes in.\n> \n> When running --index-info for the purpose of \"am -3\" (hence rebase), the\n> expectation is that the tree you are applying the changes to is _similar_\n> to the preimage of the change, i.e. old_name.  Shouldn't missing old_name\n> be treated as a fatal condition?  new_name does not have to even exist\n> because otherwise you cannot accept a patch that creates the path.\n> \n> Wouldn't this be a better patch, I wonder...\n> \n> builtin-apply.c |    3 +--\n> 1 files changed, 1 insertions(+), 2 deletions(-)\n> \n> diff --git i/builtin-apply.c w/builtin-apply.c\n> index 4c4d1e1..7de70e9 100644\n> --- i/builtin-apply.c\n> +++ w/builtin-apply.c\n> @@ -2573,8 +2573,7 @@ static void build_fake_ancestor(struct patch *list, const \n> char *filename)\n>         else if (get_sha1(patch->old_sha1_prefix, sha1))\n>             /* git diff has no index line for mode/type changes */\n>             if (!patch->lines_added && !patch->lines_deleted) {\n> -                if (get_current_sha1(patch->new_name, sha1) ||\n> -                    get_current_sha1(patch->old_name, sha1))\n> +                if (get_current_sha1(patch->old_name, sha1))\n>                     die(\"mode change for %s, which is not \"\n>                         \"in current HEAD\", name);\n>                 sha1_ptr = sha1;\n\n\nYes, this change makes more sense to me, but I'll defer to Johannes' opinion before submitting another patch.\n\nDave\n"},{"id":"95419","messageId":"7vwsfb2k3u.fsf@gitster.siamese.dyndns.org","threadId":"16256","inReplyTo":"7v63mv3zww.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] 3-way merge with file move fails when diff.renames = copies","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-11-11T00:15:49Z","receivedAt":"2008-11-11T00:15:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"David D. Kilzer\" <ddkilzer@kilzer.net> writes:\n>\n>> With diff.renames = copies, a 3-way merge (e.g. \"git rebase\") would\n>> fail with the following error:\n\nBy the way, I think the real issue with this one is that we currently do\nnot disable diff.renames configuration while rebase internally runs\n\"format-patch\" to feed \"am -3\".\n\nThe end user configuration for \"diff\" should not affect the result\nproduced by the higher level command that is related to \"diff\" only\nbecause internally it is implemented in terms of it.\n\nFor that matter, I have a feeling that format-patch should not even look\nat diff.renames, but we seem to have been doing this for a long time so\nthere is no easy way to fix this thinko.\n\nIn any case, here is a much straightforward fix for \"rebase\".  \n\nRunning \"am -3\" on a copying patch would still need a patch to the\nindex-info codepath, and my earlier comment on it still stands, but it is\nirrelevant/orthogonal to your particular test script.\n\n git-rebase.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git c/git-rebase.sh w/git-rebase.sh\nindex 023a6dc..159ccb3 100755\n--- c/git-rebase.sh\n+++ w/git-rebase.sh\n@@ -429,7 +429,7 @@ fi\n if test -z \"$do_merge\"\n then\n \tgit format-patch -k --stdout --full-index --ignore-if-in-upstream \\\n-\t\t\"$upstream..$orig_head\" |\n+\t\t--no-renames \"$upstream..$orig_head\" |\n \tgit am $git_am_opt --rebasing --resolvemsg=\"$RESOLVEMSG\" &&\n \tmove_to_original_branch\n \tret=$?\n"},{"id":"145954","messageId":"1279742303-29817-1-git-send-email-ddkilzer@kilzer.net","threadId":"16256","inReplyTo":"7vwsfb2k3u.fsf@gitster.siamese.dyndns.org","subject":"[PATCH] Fix rebase with file move when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2010-07-21T19:58:23Z","receivedAt":"2010-07-21T19:58:23Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"With diff.renames = copies, a rebase with a file move will fail with\nthe following error:\n\n    fatal: mode change for <file>, which is not in current HEAD\n    Repository lacks necessary blobs to fall back on 3-way merge.\n    Cannot fall back to three-way merge.\n    Patch failed at 0001.\n\nThe bug is that git rebase does not disable diff.renames when it runs\nformat-patch internally to feed into \"am -3\".  The fix is simply to\ninclude a --no-renames argument to format-patch to override any local\ndiff.renames setting.\n\nFix by Junio C Hamano.  Test case by David D. Kilzer.\n\nSigned-off-by: David D. Kilzer <ddkilzer@kilzer.net>\n---\n git-rebase.sh     |    2 +-\n t/t3400-rebase.sh |   17 +++++++++++++++++\n 2 files changed, 18 insertions(+), 1 deletions(-)\n\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex 6ec155c..0718caf 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -514,7 +514,7 @@ fi\n if test -z \"$do_merge\"\n then\n \tgit format-patch -k --stdout --full-index --ignore-if-in-upstream \\\n-\t\t$root_flag \"$revisions\" |\n+\t\t--no-renames $root_flag \"$revisions\" |\n \tgit am $git_am_opt --rebasing --resolvemsg=\"$RESOLVEMSG\" &&\n \tmove_to_original_branch\n \tret=$?\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 4e6a44b..6d2ec91 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -155,4 +155,21 @@ test_expect_success 'Rebase a commit that sprinkles CRs in' '\n \tgit diff --exit-code file-with-cr:CR HEAD:CR\n '\n \n+test_expect_success 'rebase a single file move with diff.renames = copies' '\n+     git config diff.renames copies &&\n+     git checkout master &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     test_tick &&\n+     git commit -m \"prepare file move\" &&\n+     git checkout -b filemove HEAD^ &&\n+     echo 1 > Y &&\n+     git add Y &&\n+     mkdir D &&\n+     git mv A D/A &&\n+     test_tick &&\n+     git commit -m filemove &&\n+     GIT_TRACE=1 git rebase master\n+'\n+\n test_done\n-- \n1.7.1\n"},{"id":"145963","messageId":"7vpqygijqt.fsf@alter.siamese.dyndns.org","threadId":"16256","inReplyTo":"1279742303-29817-1-git-send-email-ddkilzer@kilzer.net","subject":"Re: [PATCH] Fix rebase with file move when diff.renames = copies","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-07-21T21:54:18Z","receivedAt":"2010-07-21T21:54:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"David D. Kilzer\" <ddkilzer@kilzer.net> writes:\n\n> The bug is that git rebase does not disable diff.renames when it runs\n> format-patch internally to feed into \"am -3\".  The fix is simply to\n> include a --no-renames argument to format-patch to override any local\n> diff.renames setting.\n>\n> Fix by Junio C Hamano.  Test case by David D. Kilzer.\n>\n> Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net>\n\nHmm, I actully do not recall doing this patch, even though I think what it\ndoes probably makes sense.\n"},{"id":"145975","messageId":"76360.2655.qm@web30004.mail.mud.yahoo.com","threadId":"16256","inReplyTo":"7vpqygijqt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Fix rebase with file move when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2010-07-22T00:22:08Z","receivedAt":"2010-07-22T00:22:08Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"On Wed, July 21, 2010 at 2:54:18 PM, Junio C Hamano wrote:\n\n> \"David D. Kilzer\" <ddkilzer@kilzer.net>  writes:\n> \n> > The bug is that git rebase does not disable diff.renames  when it runs\n> > format-patch internally to feed into \"am -3\".  The fix  is simply to\n> > include a --no-renames argument to format-patch to override  any local\n> > diff.renames setting.\n> >\n> > Fix by Junio C  Hamano.  Test case by David D. Kilzer.\n> >\n> > Signed-off-by: David  D. Kilzer <ddkilzer@kilzer.net>\n> \n> Hmm, I  actully do not recall doing this patch, even though I think what it\n> does  probably makes sense.\n\n\nYeah, it was a while ago (Nov 11, 2008):\n\n<http://marc.info/?l=git&m=122636263923046&w=2>\n\nSorry for the delay, but the issue still affects me.  :)\n\nDave\n"},{"id":"145982","messageId":"20100722075133.GA9292@burratino","threadId":"16256","inReplyTo":"1279742303-29817-1-git-send-email-ddkilzer@kilzer.net","subject":"Re: [PATCH] Fix rebase with file move when diff.renames = copies","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-22T07:51:33Z","receivedAt":"2010-07-22T07:51:33Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"David D. Kilzer wrote:\n\n> With diff.renames = copies, a rebase with a file move will fail with\n> the following error:\n>\n>     fatal: mode change for <file>, which is not in current HEAD\n>     Repository lacks necessary blobs to fall back on 3-way merge.\n>     Cannot fall back to three-way merge.\n>     Patch failed at 0001.\n\nI would think that the following works fine:\n\n\tgit init test-repo &&\n\tcd test-repo &&\n\techo hello >greeting.txt &&\n\tgit add greeting.txt &&\n\tgit commit -m base &&\n\tgit checkout -b move &&\n\tgit mv greeting.txt moved.txt &&\n\tgit commit -m move &&\n\tgit checkout master &&\n\techo hi >greeting.txt &&\n\tgit add greeting.txt &&\n\tgit commit -m change &&\n\tgit checkout move &&\n\techo '[diff] renames = copies' >>.git/config &&\n\tgit rebase master\n\nWhat am I doing wrong?\n\nOn the other hand I find Junio’s explanation[1] compelling\nalready on its own.\n\n The end user configuration for \"diff\" should not affect the\n result produced by the higher level command that is related to\n \"diff\" only because internally it is implemented in terms of\n it.\n\nIn cases where a patch copies a file that was then removed on the\nmainline, my intuition says ‘rebase’ without some extra flag should\naccept the change without complaint.  Of course, this intuition is\ntotally warped --- I tend to think of rebase as diff + apply.\n\nPatch does not apply to master or maint, due to conflict with\nv1.7.1-rc0~37^2~5 (rebase: support automatic notes copying,\n2010-03-12).  One sneaky way to avoid this kind of thing would be to\ninsert new tests at some logical point in the middle of a test script.\n\nTest nitpicks:\n\n> +++ b/t/t3400-rebase.sh\n> @@ -155,4 +155,21 @@ test_expect_success 'Rebase a commit that sprinkles CRs in' '\n>  \tgit diff --exit-code file-with-cr:CR HEAD:CR\n>  '\n>  \n> +test_expect_success 'rebase a single file move with diff.renames = copies' '\n> +     git config diff.renames copies &&\n\nUse\n\n\ttest_when_finished \"git config --unset diff.renames\" &&\n\nto shelter future tests from the effect of this one.\n\n> +     git checkout master &&\n> +     echo 1 > Y &&\n> +     git add Y &&\n> +     test_tick &&\n> +     git commit -m \"prepare file move\" &&\n\ncommit: new file Y.\n\n> +     git checkout -b filemove HEAD^ &&\n> +     echo 1 > Y &&\n> +     git add Y &&\n> +     mkdir D &&\n> +     git mv A D/A &&\n> +     test_tick &&\n> +     git commit -m filemove &&\n\ncommit: new file Y, rename A to D/A.\n\n> +     GIT_TRACE=1 git rebase master\n\nThis wants to notice that Y was already added so the top patch can be\nsimplified to include only a rename.\n\nCan you explain why this test will fail without your patch?\n\nThanks,\nJonathan\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/100583/focus=100606\n"},{"id":"146026","messageId":"681325.9577.qm@web30002.mail.mud.yahoo.com","threadId":"16256","inReplyTo":"20100722075133.GA9292@burratino","subject":"Re: [PATCH] Fix rebase with file move when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2010-07-22T21:59:49Z","receivedAt":"2010-07-22T21:59:49Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"On Jonathan Nieder wrote:\n\n> David D. Kilzer wrote:\n> \n> > With diff.renames = copies, a rebase with a  file move will fail with\n> > the following error:\n> >\n> >      fatal: mode change for <file>, which is not in current  HEAD\n> >     Repository lacks necessary blobs to fall back on  3-way merge.\n> >     Cannot fall back to three-way  merge.\n> >     Patch failed at 0001.\n> \n> I would think that the  following works fine:\n> \n>     git init test-repo  &&\n>     cd test-repo &&\n>      echo hello >greeting.txt &&\n>     git add  greeting.txt &&\n>     git commit -m base  &&\n>     git checkout -b move  &&\n>     git mv greeting.txt moved.txt  &&\n>     git commit -m move  &&\n>     git checkout master  &&\n>     echo hi >greeting.txt  &&\n>     git add greeting.txt  &&\n>     git commit -m change  &&\n>     git checkout move  &&\n>     echo '[diff] renames = copies'  >>.git/config &&\n>     git rebase  master\n> \n> What am I doing wrong?\n\n\nGiven the following tree:\n\n      B' topic\n     /\n    A---B master\n\nA: New file \"F1\" is committed.\nB: New file \"F2\" is committed.\nB': New file \"F2\" is committed (identical in content to \"F2\" on B), and \"F1\" is \nrenamed to \"F3\".\n\nWhen the topic branch is rebased onto master with diff.renames=copies, git fails \nwhen attempting to build a fake ancestor for F1.  The key to reproducing the bug \nis to have an identical new file added on both B and B'.\n\nMy original patch in <http://marc.info/?l=git&m=122635667614099&w=2> addressed \nthis in builtin-apply.c, but Junio didn't like this approach as noted in \n<http://marc.info/?l=git&m=122636097120953&w=2>.\n\n> Patch does not apply to master or maint, due to conflict  with\n> v1.7.1-rc0~37^2~5 (rebase: support automatic notes  copying,\n> 2010-03-12).  One sneaky way to avoid this kind of thing would  be to\n> insert new tests at some logical point in the middle of a test  script.\n\n\nSorry about that--I forgot to rebase it to maint before sending it.\n\n> Test nitpicks:\n\n\nThanks!  I'll make the requested changes in the next patch.\n\n> This wants to notice that Y  was already added so the top patch can be\n> simplified to include only a  rename.\n\n\nActually, this is the key to reproducing the bug!\n\n> Can you explain why this test will fail without your  patch?\n\n\nHere is a stand-alone script that reproduces the bug:\n\n    git init test-repo &&\n    cd test-repo &&\n    echo hello > F1 &&\n    git add F1 &&\n    git commit -m \"A\" &&\n    git checkout -b topic &&\n    echo hi > F2 &&\n    git add F2 &&\n    git mv F1 F3 &&\n    git commit -m \"B'\" &&\n    git checkout master &&\n    echo hi > F2 &&\n    git add F2 &&\n    git commit -m \"B\" &&\n    git checkout topic &&\n    git config diff.renames copies &&\n    GIT_TRACE=1 git rebase master\n\nNote that the test case in my patch depended on \"F1\" (which was \"A\") being \ncommitted by an earlier test.\n\nDave\n"},{"id":"146087","messageId":"20100723170103.GA2507@burratino","threadId":"16256","inReplyTo":"681325.9577.qm@web30002.mail.mud.yahoo.com","subject":"[PATCH 0/5] Fix rebase with file move when diff.renames = copies","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:01:03Z","receivedAt":"2010-07-23T17:01:03Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"David D. Kilzer wrote:\n\n> My original patch in <http://marc.info/?l=git&m=122635667614099&w=2> addressed \n> this in builtin-apply.c, but Junio didn't like this approach as noted in \n> <http://marc.info/?l=git&m=122636097120953&w=2>.\n\nGot it.  This patch just treats the symptoms in my opinion, and if\nyou read Junio’s message carefully, I think he was also suggesting\nthat git apply should still be fixed.\n\nSomething like this series would fix both.  Please feel free to pick\nit up and take it in whatever direction you like.\n\nHope that helps.\n\nJonathan Nieder (3):\n  t4150 (am): style tweaks\n  t4150 (am): futureproof against failing tests\n  t3400 (rebase): whitespace cleanup\n\nJunio C Hamano (2):\n  Teach \"apply --index-info\" to handle rename patches\n  rebase: protect against diff.renames configuration\n\n builtin/apply.c   |    3 +-\n git-rebase.sh     |    2 +-\n t/t3400-rebase.sh |  204 ++++++++++++++++++--------------\n t/t4150-am.sh     |  334 +++++++++++++++++++++++++++++++++++-----------------\n t/test-lib.sh     |    4 +\n 5 files changed, 345 insertions(+), 202 deletions(-)\n\n-- \n1.7.2.rc3\n"},{"id":"146094","messageId":"20100723170307.GB2507@burratino","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"[PATCH 1/5] t4150 (am): style tweaks","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:03:07Z","receivedAt":"2010-07-23T17:03:07Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Place setup commands in test_expect_success blocks.  This makes the\nrare event of the setup commands breaking on some platform easier to\ndiagnose, and more importantly, it visually distinguishes where\neach test begins and ends.\n\nInstead of running test -z against the result of \"git diff\" command\nsubstitution, use \"git diff --exit-code\", to improve output when\nrunning with the \"-v\" option.\n\nUse test_cmp in place of \"test $(foo) = $(bar)\" for similar reasons.\n\nRemove whitespace after the > and < redirection operators for\nconsistency with other tests.\n\nThe order of arguments to test_cmp is \"test_cmp expected actual\".\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t4150-am.sh |  240 +++++++++++++++++++++++++++++++--------------------------\n t/test-lib.sh |    4 +\n 2 files changed, 136 insertions(+), 108 deletions(-)\n\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 810b04b..b50aad3 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -4,66 +4,71 @@ test_description='git am running'\n \n . ./test-lib.sh\n \n-cat >msg <<EOF\n-second\n-\n-Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy\n-eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam\n-voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita\n-kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem\n-ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod\n-tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At\n-vero eos et accusam et justo duo dolores et ea rebum.\n-\n-\tDuis autem vel eum iriure dolor in hendrerit in vulputate velit\n-\tesse molestie consequat, vel illum dolore eu feugiat nulla facilisis\n-\tat vero eros et accumsan et iusto odio dignissim qui blandit\n-\tpraesent luptatum zzril delenit augue duis dolore te feugait nulla\n-\tfacilisi.\n-\n-\n-Lorem ipsum dolor sit amet,\n-consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut\n-laoreet dolore magna aliquam erat volutpat.\n-\n-  git\n-  ---\n-  +++\n-\n-Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit\n-lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n-dolor in hendrerit in vulputate velit esse molestie consequat, vel illum\n-dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio\n-dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te\n-feugait nulla facilisi.\n-EOF\n-\n-cat >failmail <<EOF\n-From foo@example.com Fri May 23 10:43:49 2008\n-From:\tfoo@example.com\n-To:\tbar@example.com\n-Subject: Re: [RFC/PATCH] git-foo.sh\n-Date:\tFri, 23 May 2008 05:23:42 +0200\n-\n-Sometimes we have to find out that there's nothing left.\n-\n-EOF\n-\n-cat >pine <<EOF\n-From MAILER-DAEMON Fri May 23 10:43:49 2008\n-Date: 23 May 2008 05:23:42 +0200\n-From: Mail System Internal Data <MAILER-DAEMON@example.com>\n-Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA\n-Message-ID: <foo-0001@example.com>\n-\n-This text is part of the internal format of your mail folder, and is not\n-a real message.  It is created automatically by the mail system software.\n-If deleted, important folder data will be lost, and it will be re-created\n-with the data reset to initial values.\n-\n-EOF\n-\n-echo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\" >expected\n+test_expect_success 'setup: messages' '\n+\tcat >msg <<-\\EOF &&\n+\tsecond\n+\n+\tLorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy\n+\teirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam\n+\tvoluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita\n+\tkasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem\n+\tipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod\n+\ttempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At\n+\tvero eos et accusam et justo duo dolores et ea rebum.\n+\n+\tEOF\n+\tq_to_tab <<-\\EOF >>msg &&\n+\tQDuis autem vel eum iriure dolor in hendrerit in vulputate velit\n+\tQesse molestie consequat, vel illum dolore eu feugiat nulla facilisis\n+\tQat vero eros et accumsan et iusto odio dignissim qui blandit\n+\tQpraesent luptatum zzril delenit augue duis dolore te feugait nulla\n+\tQfacilisi.\n+\tEOF\n+\tcat >>msg <<-\\EOF &&\n+\n+\tLorem ipsum dolor sit amet,\n+\tconsectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut\n+\tlaoreet dolore magna aliquam erat volutpat.\n+\n+\t  git\n+\t  ---\n+\t  +++\n+\n+\tUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit\n+\tlobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n+\tdolor in hendrerit in vulputate velit esse molestie consequat, vel illum\n+\tdolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio\n+\tdignissim qui blandit praesent luptatum zzril delenit augue duis dolore te\n+\tfeugait nulla facilisi.\n+\tEOF\n+\n+\tcat >failmail <<-\\EOF &&\n+\tFrom foo@example.com Fri May 23 10:43:49 2008\n+\tFrom:\tfoo@example.com\n+\tTo:\tbar@example.com\n+\tSubject: Re: [RFC/PATCH] git-foo.sh\n+\tDate:\tFri, 23 May 2008 05:23:42 +0200\n+\n+\tSometimes we have to find out that there'\\''s nothing left.\n+\n+\tEOF\n+\n+\tcat >pine <<-\\EOF &&\n+\tFrom MAILER-DAEMON Fri May 23 10:43:49 2008\n+\tDate: 23 May 2008 05:23:42 +0200\n+\tFrom: Mail System Internal Data <MAILER-DAEMON@example.com>\n+\tSubject: DON'\\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA\n+\tMessage-ID: <foo-0001@example.com>\n+\n+\tThis text is part of the internal format of your mail folder, and is not\n+\ta real message.  It is created automatically by the mail system software.\n+\tIf deleted, important folder data will be lost, and it will be re-created\n+\twith the data reset to initial values.\n+\n+\tEOF\n+\n+\tsignoff=\"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\"\n+'\n \n test_expect_success setup '\n \techo hello >file &&\n@@ -71,11 +76,13 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -m first &&\n \tgit tag first &&\n+\n \techo world >>file &&\n \tgit add file &&\n \ttest_tick &&\n \tgit commit -s -F msg &&\n \tgit tag second &&\n+\n \tgit format-patch --stdout first >patch1 &&\n \t{\n \t\techo \"X-Fake-Field: Line One\" &&\n@@ -89,33 +96,37 @@ test_expect_success setup '\n \t\techo \"X-Fake-Field: Line Three\" &&\n \t\tgit format-patch --stdout first | sed -e \"1d\"\n \t} | append_cr >patch1-crlf.eml &&\n+\n \tsed -n -e \"3,\\$p\" msg >file &&\n \tgit add file &&\n \ttest_tick &&\n \tgit commit -m third &&\n+\n \tgit format-patch --stdout first >patch2\t&&\n+\n \tgit checkout -b lorem &&\n \tsed -n -e \"11,\\$p\" msg >file &&\n \thead -n 9 msg >>file &&\n \ttest_tick &&\n \tgit commit -a -m \"moved stuff\" &&\n+\n \techo goodbye >another &&\n \tgit add another &&\n \ttest_tick &&\n \tgit commit -m \"added another file\" &&\n-\tgit format-patch --stdout master >lorem-move.patch\n-'\n \n-# reset time\n-unset test_tick\n-test_tick\n+\tgit format-patch --stdout master >lorem-move.patch &&\n+\t# reset time\n+\tunset test_tick &&\n+\ttest_tick\n+'\n \n test_expect_success 'am applies patch correctly' '\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am <patch1 &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff second)\" &&\n+\tgit diff --exit-code second &&\n \ttest \"$(git rev-parse second)\" = \"$(git rev-parse HEAD)\" &&\n \ttest \"$(git rev-parse second^)\" = \"$(git rev-parse HEAD^)\"\n '\n@@ -124,7 +135,7 @@ test_expect_success 'am applies patch e-mail not in a mbox' '\n \tgit checkout first &&\n \tgit am patch1.eml &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff second)\" &&\n+\tgit diff --exit-code second &&\n \ttest \"$(git rev-parse second)\" = \"$(git rev-parse HEAD)\" &&\n \ttest \"$(git rev-parse second^)\" = \"$(git rev-parse HEAD^)\"\n '\n@@ -133,20 +144,23 @@ test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '\n \tgit checkout first &&\n \tgit am patch1-crlf.eml &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff second)\" &&\n+\tgit diff --exit-code second &&\n \ttest \"$(git rev-parse second)\" = \"$(git rev-parse HEAD)\" &&\n \ttest \"$(git rev-parse second^)\" = \"$(git rev-parse HEAD^)\"\n '\n \n-GIT_AUTHOR_NAME=\"Another Thor\"\n-GIT_AUTHOR_EMAIL=\"a.thor@example.com\"\n-GIT_COMMITTER_NAME=\"Co M Miter\"\n-GIT_COMMITTER_EMAIL=\"c.miter@example.com\"\n-export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL\n+test_expect_success 'setup: new author and committer' '\n+\tGIT_AUTHOR_NAME=\"Another Thor\" &&\n+\tGIT_AUTHOR_EMAIL=\"a.thor@example.com\" &&\n+\tGIT_COMMITTER_NAME=\"Co M Miter\" &&\n+\tGIT_COMMITTER_EMAIL=\"c.miter@example.com\" &&\n+\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL\n+'\n \n compare () {\n-\ttest \"$(git cat-file commit \"$2\" | grep \"^$1 \")\" = \\\n-\t     \"$(git cat-file commit \"$3\" | grep \"^$1 \")\"\n+\ta=$(git cat-file commit \"$2\" | grep \"^$1 \") &&\n+\tb=$(git cat-file commit \"$3\" | grep \"^$1 \") &&\n+\ttest \"$a\" = \"$b\"\n }\n \n test_expect_success 'am changes committer and keeps author' '\n@@ -155,8 +169,8 @@ test_expect_success 'am changes committer and keeps author' '\n \tgit am patch2 &&\n \t! test -d .git/rebase-apply &&\n \ttest \"$(git rev-parse master^^)\" = \"$(git rev-parse HEAD^^)\" &&\n-\ttest -z \"$(git diff master..HEAD)\" &&\n-\ttest -z \"$(git diff master^..HEAD^)\" &&\n+\tgit diff --exit-code master..HEAD &&\n+\tgit diff --exit-code master^..HEAD^ &&\n \tcompare author master HEAD &&\n \tcompare author master^ HEAD^ &&\n \ttest \"$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\" = \\\n@@ -166,16 +180,19 @@ test_expect_success 'am changes committer and keeps author' '\n test_expect_success 'am --signoff adds Signed-off-by: line' '\n \tgit checkout -b master2 first &&\n \tgit am --signoff <patch2 &&\n+\tprintf \"%s\\n\" \"$signoff\" >expected &&\n \techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\" >>expected &&\n \tgit cat-file commit HEAD^ | grep \"Signed-off-by:\" >actual &&\n-\ttest_cmp actual expected &&\n+\ttest_cmp expected actual &&\n \techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\" >expected &&\n \tgit cat-file commit HEAD | grep \"Signed-off-by:\" >actual &&\n-\ttest_cmp actual expected\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'am stays in branch' '\n-\ttest \"refs/heads/master2\" = \"$(git symbolic-ref HEAD)\"\n+\techo refs/heads/master2 >expected &&\n+\tgit symbolic-ref HEAD >actual &&\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '\n@@ -183,19 +200,22 @@ test_expect_success 'am --signoff does not add Signed-off-by: line if already th\n \tsed -e \"/^Subject/ s,\\[PATCH,Re: Re: Re: & 1/5 v2,\" patch3 >patch4\n \tgit checkout HEAD^ &&\n \tgit am --signoff patch4 &&\n-\ttest \"$(git cat-file commit HEAD | grep -c \"^Signed-off-by:\")\" -eq 1\n+\tgit cat-file commit HEAD >actual &&\n+\ttest $(grep -c \"^Signed-off-by:\" actual) -eq 1\n '\n \n test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '\n-\ttest \"$(git rev-parse HEAD)\" = \"$(git rev-parse master2)\"\n+\tgit rev-parse HEAD >expected &&\n+\tgit rev-parse master2 >actual &&\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'am --keep really keeps the subject' '\n \tgit checkout HEAD^ &&\n \tgit am --keep patch4 &&\n \t! test -d .git/rebase-apply &&\n-\tgit cat-file commit HEAD |\n-\t\tfgrep \"Re: Re: Re: [PATCH 1/5 v2] third\"\n+\tgit cat-file commit HEAD >actual &&\n+\tgrep \"Re: Re: Re: \\[PATCH 1/5 v2\\] third\" actual\n '\n \n test_expect_success 'am -3 falls back to 3-way merge' '\n@@ -207,7 +227,7 @@ test_expect_success 'am -3 falls back to 3-way merge' '\n \tgit commit -m \"copied stuff\" &&\n \tgit am -3 lorem-move.patch &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff lorem)\"\n+\tgit diff --exit-code lorem\n '\n \n test_expect_success 'am -3 -q is quiet' '\n@@ -217,7 +237,7 @@ test_expect_success 'am -3 -q is quiet' '\n \tgit add file &&\n \ttest_tick &&\n \tgit commit -m \"copied stuff\" &&\n-\tgit am -3 -q lorem-move.patch > output.out 2>&1 &&\n+\tgit am -3 -q lorem-move.patch >output.out 2>&1 &&\n \t! test -s output.out\n '\n \n@@ -228,13 +248,15 @@ test_expect_success 'am pauses on conflict' '\n '\n \n test_expect_success 'am --skip works' '\n+\techo goodbye >expected &&\n \tgit am --skip &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff lorem2^^ -- file)\" &&\n-\ttest goodbye = \"$(cat another)\"\n+\tgit diff --exit-code lorem2^^ -- file &&\n+\ttest_cmp expected another\n '\n \n test_expect_success 'am --resolved works' '\n+\techo goodbye >expected &&\n \tgit checkout lorem2^^ &&\n \ttest_must_fail git am lorem-move.patch &&\n \ttest -d .git/rebase-apply &&\n@@ -242,14 +264,14 @@ test_expect_success 'am --resolved works' '\n \tgit add file &&\n \tgit am --resolved &&\n \t! test -d .git/rebase-apply &&\n-\ttest goodbye = \"$(cat another)\"\n+\ttest_cmp expected another\n '\n \n test_expect_success 'am takes patches from a Pine mailbox' '\n \tgit checkout first &&\n \tcat pine patch1 | git am &&\n \t! test -d .git/rebase-apply &&\n-\ttest -z \"$(git diff master^..HEAD)\"\n+\tgit diff --exit-code master^..HEAD\n '\n \n test_expect_success 'am fails on mail without patch' '\n@@ -272,7 +294,7 @@ test_expect_success 'am works from stdin in subdirectory' '\n \t\tcd subdir &&\n \t\tgit am <../patch1\n \t) &&\n-\ttest -z \"$(git diff second)\"\n+\tgit diff --exit-code second\n '\n \n test_expect_success 'am works from file (relative path given) in subdirectory' '\n@@ -283,7 +305,7 @@ test_expect_success 'am works from file (relative path given) in subdirectory' '\n \t\tcd subdir &&\n \t\tgit am ../patch1\n \t) &&\n-\ttest -z \"$(git diff second)\"\n+\tgit diff --exit-code second\n '\n \n test_expect_success 'am works from file (absolute path given) in subdirectory' '\n@@ -295,7 +317,7 @@ test_expect_success 'am works from file (absolute path given) in subdirectory' '\n \t\tcd subdir &&\n \t\tgit am \"$P/patch1\"\n \t) &&\n-\ttest -z \"$(git diff second)\"\n+\tgit diff --exit-code second\n '\n \n test_expect_success 'am --committer-date-is-author-date' '\n@@ -303,9 +325,9 @@ test_expect_success 'am --committer-date-is-author-date' '\n \ttest_tick &&\n \tgit am --committer-date-is-author-date patch1 &&\n \tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head1 &&\n-\tat=$(sed -ne \"/^author /s/.*> //p\" head1) &&\n-\tct=$(sed -ne \"/^committer /s/.*> //p\" head1) &&\n-\ttest \"$at\" = \"$ct\"\n+\tsed -ne \"/^author /s/.*> //p\" head1 >at &&\n+\tsed -ne \"/^committer /s/.*> //p\" head1 >ct &&\n+\ttest_cmp at ct\n '\n \n test_expect_success 'am without --committer-date-is-author-date' '\n@@ -313,9 +335,9 @@ test_expect_success 'am without --committer-date-is-author-date' '\n \ttest_tick &&\n \tgit am patch1 &&\n \tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head1 &&\n-\tat=$(sed -ne \"/^author /s/.*> //p\" head1) &&\n-\tct=$(sed -ne \"/^committer /s/.*> //p\" head1) &&\n-\ttest \"$at\" != \"$ct\"\n+\tsed -ne \"/^author /s/.*> //p\" head1 >at &&\n+\tsed -ne \"/^committer /s/.*> //p\" head1 >ct &&\n+\t! test_cmp at ct\n '\n \n # This checks for +0000 because TZ is set to UTC and that should\n@@ -327,37 +349,39 @@ test_expect_success 'am --ignore-date' '\n \ttest_tick &&\n \tgit am --ignore-date patch1 &&\n \tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head1 &&\n-\tat=$(sed -ne \"/^author /s/.*> //p\" head1) &&\n-\techo \"$at\" | grep \"+0000\"\n+\tsed -ne \"/^author /s/.*> //p\" head1 >at &&\n+\tgrep \"+0000\" at\n '\n \n test_expect_success 'am into an unborn branch' '\n+\tgit rev-parse first^{tree} >expected &&\n \trm -fr subdir &&\n-\tmkdir -p subdir &&\n+\tmkdir subdir &&\n \tgit format-patch --numbered-files -o subdir -1 first &&\n \t(\n \t\tcd subdir &&\n \t\tgit init &&\n \t\tgit am 1\n \t) &&\n-\tresult=$(\n-\t\tcd subdir && git rev-parse HEAD^{tree}\n+\t(\n+\t\tcd subdir &&\n+\t\tgit rev-parse HEAD^{tree} >../actual\n \t) &&\n-\ttest \"z$result\" = \"z$(git rev-parse first^{tree})\"\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'am newline in subject' '\n \tgit checkout first &&\n \ttest_tick &&\n-\tsed -e \"s/second/second \\\\\\n foo/\" patch1 > patchnl &&\n-\tgit am < patchnl > output.out 2>&1 &&\n+\tsed -e \"s/second/second \\\\\\n foo/\" patch1 >patchnl &&\n+\tgit am <patchnl >output.out 2>&1 &&\n \tgrep \"^Applying: second \\\\\\n foo$\" output.out\n '\n \n test_expect_success 'am -q is quiet' '\n \tgit checkout first &&\n \ttest_tick &&\n-\tgit am -q < patch1 > output.out 2>&1 &&\n+\tgit am -q <patch1 >output.out 2>&1 &&\n \t! test -s output.out\n '\n \ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex e5523dd..cb15798 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -257,6 +257,10 @@ q_to_cr () {\n \ttr Q '\\015'\n }\n \n+q_to_tab () {\n+\ttr Q '\\011'\n+}\n+\n append_cr () {\n \tsed -e 's/$/Q/' | tr Q '\\015'\n }\n-- \n1.7.2.rc3\n"},{"id":"146088","messageId":"20100723170401.GC2507@burratino","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"[PATCH 2/5] t4150 (am): futureproof against failing tests","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:04:01Z","receivedAt":"2010-07-23T17:04:01Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Most tests in t4150 begin by navigating to a sane state and\napplying some patch:\n\n\tgit checkout first &&\n\tgit am patch1\n\nIf a previous test left behind unmerged files or a .git/rebase-apply\ndirectory, they are untouched and the test fails, causing later tests\nto fail, too.  This is not a problem in practice because none of the\ntests leave a mess behind.\n\nBut as a futureproofing measure, it is still best to avoid the problem\nand clean up at the start of each test.  In particular, this\nsimplifies the process of adding new tests that are known to fail.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t4150-am.sh |   48 +++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 47 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex b50aad3..70b57de 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -122,6 +122,8 @@ test_expect_success setup '\n '\n \n test_expect_success 'am applies patch correctly' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am <patch1 &&\n@@ -132,6 +134,8 @@ test_expect_success 'am applies patch correctly' '\n '\n \n test_expect_success 'am applies patch e-mail not in a mbox' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \tgit am patch1.eml &&\n \t! test -d .git/rebase-apply &&\n@@ -141,6 +145,8 @@ test_expect_success 'am applies patch e-mail not in a mbox' '\n '\n \n test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \tgit am patch1-crlf.eml &&\n \t! test -d .git/rebase-apply &&\n@@ -165,6 +171,8 @@ compare () {\n \n test_expect_success 'am changes committer and keeps author' '\n \ttest_tick &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \tgit am patch2 &&\n \t! test -d .git/rebase-apply &&\n@@ -178,6 +186,8 @@ test_expect_success 'am changes committer and keeps author' '\n '\n \n test_expect_success 'am --signoff adds Signed-off-by: line' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout -b master2 first &&\n \tgit am --signoff <patch2 &&\n \tprintf \"%s\\n\" \"$signoff\" >expected &&\n@@ -198,6 +208,8 @@ test_expect_success 'am stays in branch' '\n test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '\n \tgit format-patch --stdout HEAD^ >patch3 &&\n \tsed -e \"/^Subject/ s,\\[PATCH,Re: Re: Re: & 1/5 v2,\" patch3 >patch4\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout HEAD^ &&\n \tgit am --signoff patch4 &&\n \tgit cat-file commit HEAD >actual &&\n@@ -211,6 +223,8 @@ test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '\n '\n \n test_expect_success 'am --keep really keeps the subject' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout HEAD^ &&\n \tgit am --keep patch4 &&\n \t! test -d .git/rebase-apply &&\n@@ -219,6 +233,8 @@ test_expect_success 'am --keep really keeps the subject' '\n '\n \n test_expect_success 'am -3 falls back to 3-way merge' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout -b lorem2 master2 &&\n \tsed -n -e \"3,\\$p\" msg >file &&\n \thead -n 9 msg >>file &&\n@@ -231,6 +247,7 @@ test_expect_success 'am -3 falls back to 3-way merge' '\n '\n \n test_expect_success 'am -3 -q is quiet' '\n+\trm -fr .git/rebase-apply &&\n \tgit reset master2 --hard &&\n \tsed -n -e \"3,\\$p\" msg >file &&\n \thead -n 9 msg >>file &&\n@@ -242,6 +259,8 @@ test_expect_success 'am -3 -q is quiet' '\n '\n \n test_expect_success 'am pauses on conflict' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout lorem2^^ &&\n \ttest_must_fail git am lorem-move.patch &&\n \ttest -d .git/rebase-apply\n@@ -257,6 +276,8 @@ test_expect_success 'am --skip works' '\n \n test_expect_success 'am --resolved works' '\n \techo goodbye >expected &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout lorem2^^ &&\n \ttest_must_fail git am lorem-move.patch &&\n \ttest -d .git/rebase-apply &&\n@@ -268,6 +289,8 @@ test_expect_success 'am --resolved works' '\n '\n \n test_expect_success 'am takes patches from a Pine mailbox' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \tcat pine patch1 | git am &&\n \t! test -d .git/rebase-apply &&\n@@ -275,11 +298,16 @@ test_expect_success 'am takes patches from a Pine mailbox' '\n '\n \n test_expect_success 'am fails on mail without patch' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \ttest_must_fail git am <failmail &&\n-\trm -r .git/rebase-apply/\n+\tgit am --abort &&\n+\t! test -d .git/rebase-apply\n '\n \n test_expect_success 'am fails on empty patch' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \techo \"---\" >>failmail &&\n \ttest_must_fail git am <failmail &&\n \tgit am --skip &&\n@@ -288,6 +316,8 @@ test_expect_success 'am fails on empty patch' '\n \n test_expect_success 'am works from stdin in subdirectory' '\n \trm -fr subdir &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \t(\n \t\tmkdir -p subdir &&\n@@ -299,6 +329,8 @@ test_expect_success 'am works from stdin in subdirectory' '\n \n test_expect_success 'am works from file (relative path given) in subdirectory' '\n \trm -fr subdir &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \t(\n \t\tmkdir -p subdir &&\n@@ -310,6 +342,8 @@ test_expect_success 'am works from file (relative path given) in subdirectory' '\n \n test_expect_success 'am works from file (absolute path given) in subdirectory' '\n \trm -fr subdir &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \tP=$(pwd) &&\n \t(\n@@ -321,6 +355,8 @@ test_expect_success 'am works from file (absolute path given) in subdirectory' '\n '\n \n test_expect_success 'am --committer-date-is-author-date' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am --committer-date-is-author-date patch1 &&\n@@ -331,6 +367,8 @@ test_expect_success 'am --committer-date-is-author-date' '\n '\n \n test_expect_success 'am without --committer-date-is-author-date' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am patch1 &&\n@@ -345,6 +383,8 @@ test_expect_success 'am without --committer-date-is-author-date' '\n # by test_tick that uses -0700 timezone; if this feature does not\n # work, we will see that instead of +0000.\n test_expect_success 'am --ignore-date' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am --ignore-date patch1 &&\n@@ -355,6 +395,8 @@ test_expect_success 'am --ignore-date' '\n \n test_expect_success 'am into an unborn branch' '\n \tgit rev-parse first^{tree} >expected &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \trm -fr subdir &&\n \tmkdir subdir &&\n \tgit format-patch --numbered-files -o subdir -1 first &&\n@@ -371,6 +413,8 @@ test_expect_success 'am into an unborn branch' '\n '\n \n test_expect_success 'am newline in subject' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tsed -e \"s/second/second \\\\\\n foo/\" patch1 >patchnl &&\n@@ -379,6 +423,8 @@ test_expect_success 'am newline in subject' '\n '\n \n test_expect_success 'am -q is quiet' '\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n \tgit checkout first &&\n \ttest_tick &&\n \tgit am -q <patch1 >output.out 2>&1 &&\n-- \n1.7.2.rc3\n"},{"id":"146089","messageId":"20100723170444.GD2507@burratino","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"[PATCH 3/5] Teach \"apply --index-info\" to handle rename patches","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:04:44Z","receivedAt":"2010-07-23T17:04:44Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\nDate: Mon, 10 Nov 2008 15:49:03 -0800\n\nWith v1.5.3.2~14 (apply --index-info: fall back to current index for\nmode changes, 2007-09-17), git apply learned to stop worrying\nabout the lack of diff index line when a file already present in the\ncurrent index had no content change.\n\nBut it still worries too much: for rename patches, it is checking\nthat both the old and new filename are present in the current\nindex.  This makes no sense, since a file rename generally\ninvolves creating a file there was none before.\n\nSo just check the old filename.\n\nNoticed while trying to use “git rebase” with diff.renames = copies.\n\n[jn: add tests]\n\nReported-by: David D. Kilzer <ddkilzer@kilzer.net>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/apply.c |    3 +--\n t/t4150-am.sh   |   46 ++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 47 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 12ef9ea..f38c1f7 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2979,8 +2979,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \t\telse if (get_sha1(patch->old_sha1_prefix, sha1))\n \t\t\t/* git diff has no index line for mode/type changes */\n \t\t\tif (!patch->lines_added && !patch->lines_deleted) {\n-\t\t\t\tif (get_current_sha1(patch->new_name, sha1) ||\n-\t\t\t\t    get_current_sha1(patch->old_name, sha1))\n+\t\t\t\tif (get_current_sha1(patch->old_name, sha1))\n \t\t\t\t\tdie(\"mode change for %s, which is not \"\n \t\t\t\t\t\t\"in current HEAD\", name);\n \t\t\t\tsha1_ptr = sha1;\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 70b57de..1c3d8ed 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -116,6 +116,18 @@ test_expect_success setup '\n \tgit commit -m \"added another file\" &&\n \n \tgit format-patch --stdout master >lorem-move.patch &&\n+\n+\tgit checkout -b rename &&\n+\tgit mv file renamed &&\n+\tgit commit -m \"renamed a file\" &&\n+\n+\tgit format-patch -M --stdout lorem >rename.patch &&\n+\n+\tgit reset --soft lorem^ &&\n+\tgit commit -m \"renamed a file and added another\" &&\n+\n+\tgit format-patch -M --stdout lorem^ >rename-add.patch &&\n+\n \t# reset time\n \tunset test_tick &&\n \ttest_tick\n@@ -246,8 +258,42 @@ test_expect_success 'am -3 falls back to 3-way merge' '\n \tgit diff --exit-code lorem\n '\n \n+test_expect_success 'am can rename a file' '\n+\tgrep \"^rename from\" rename.patch &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n+\tgit checkout lorem^0 &&\n+\tgit am rename.patch &&\n+\t! test -d .git/rebase-apply &&\n+\tgit update-index --refresh &&\n+\tgit diff --exit-code rename\n+'\n+\n+test_expect_success 'am -3 can rename a file' '\n+\tgrep \"^rename from\" rename.patch &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n+\tgit checkout lorem^0 &&\n+\tgit am -3 rename.patch &&\n+\t! test -d .git/rebase-apply &&\n+\tgit update-index --refresh &&\n+\tgit diff --exit-code rename\n+'\n+\n+test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '\n+\tgrep \"^rename from\" rename-add.patch &&\n+\trm -fr .git/rebase-apply &&\n+\tgit reset --hard &&\n+\tgit checkout lorem^0 &&\n+\tgit am -3 rename-add.patch &&\n+\t! test -d .git/rebase-apply &&\n+\tgit update-index --refresh &&\n+\tgit diff --exit-code rename\n+'\n+\n test_expect_success 'am -3 -q is quiet' '\n \trm -fr .git/rebase-apply &&\n+\tgit checkout -f lorem2 &&\n \tgit reset master2 --hard &&\n \tsed -n -e \"3,\\$p\" msg >file &&\n \thead -n 9 msg >>file &&\n-- \n1.7.2.rc3\n"},{"id":"146090","messageId":"20100723170524.GE2507@burratino","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"[PATCH 4/5] t3400 (rebase): whitespace cleanup","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:05:24Z","receivedAt":"2010-07-23T17:05:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"This test used 5-space indents since it was added in 2005, but\nrecently the temptation to use tabs to indent has been too\nstrong, resulting in uneven whitespace.  Switch over completely\nto tabs.\n\nWhile at it, use a more modern style for consistency with other\ntests:\n\n - names of tests go on the same line as test_expect_success;\n - extra whitespace after > redirection operators is removed.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t3400-rebase.sh |  182 +++++++++++++++++++++++++++--------------------------\n 1 files changed, 92 insertions(+), 90 deletions(-)\n\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex d98c7b5..083d768 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -14,140 +14,142 @@ GIT_AUTHOR_NAME=author@name\n GIT_AUTHOR_EMAIL=bogus@email@address\n export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL\n \n-test_expect_success \\\n-    'prepare repository with topic branches' \\\n-    'git config core.logAllRefUpdates true &&\n-     echo First > A &&\n-     git update-index --add A &&\n-     git commit -m \"Add A.\" &&\n-     git checkout -b my-topic-branch &&\n-     echo Second > B &&\n-     git update-index --add B &&\n-     git commit -m \"Add B.\" &&\n-     git checkout -f master &&\n-     echo Third >> A &&\n-     git update-index A &&\n-     git commit -m \"Modify A.\" &&\n-     git checkout -b side my-topic-branch &&\n-     echo Side >> C &&\n-     git add C &&\n-     git commit -m \"Add C\" &&\n-     git checkout -b nonlinear my-topic-branch &&\n-     echo Edit >> B &&\n-     git add B &&\n-     git commit -m \"Modify B\" &&\n-     git merge side &&\n-     git checkout -b upstream-merged-nonlinear &&\n-     git merge master &&\n-     git checkout -f my-topic-branch &&\n-     git tag topic\n+test_expect_success 'prepare repository with topic branches' '\n+\tgit config core.logAllRefUpdates true &&\n+\techo First >A &&\n+\tgit update-index --add A &&\n+\tgit commit -m \"Add A.\" &&\n+\tgit checkout -b my-topic-branch &&\n+\techo Second >B &&\n+\tgit update-index --add B &&\n+\tgit commit -m \"Add B.\" &&\n+\tgit checkout -f master &&\n+\techo Third >>A &&\n+\tgit update-index A &&\n+\tgit commit -m \"Modify A.\" &&\n+\tgit checkout -b side my-topic-branch &&\n+\techo Side >>C &&\n+\tgit add C &&\n+\tgit commit -m \"Add C\" &&\n+\tgit checkout -b nonlinear my-topic-branch &&\n+\techo Edit >>B &&\n+\tgit add B &&\n+\tgit commit -m \"Modify B\" &&\n+\tgit merge side &&\n+\tgit checkout -b upstream-merged-nonlinear &&\n+\tgit merge master &&\n+\tgit checkout -f my-topic-branch &&\n+\tgit tag topic\n '\n \n test_expect_success 'rebase on dirty worktree' '\n-     echo dirty >> A &&\n-     test_must_fail git rebase master'\n+\techo dirty >>A &&\n+\ttest_must_fail git rebase master\n+'\n \n test_expect_success 'rebase on dirty cache' '\n-     git add A &&\n-     test_must_fail git rebase master'\n+\tgit add A &&\n+\ttest_must_fail git rebase master\n+'\n \n test_expect_success 'rebase against master' '\n-     git reset --hard HEAD &&\n-     git rebase master'\n+\tgit reset --hard HEAD &&\n+\tgit rebase master\n+'\n \n test_expect_success 'rebase against master twice' '\n-     git rebase master >out &&\n-     grep \"Current branch my-topic-branch is up to date\" out\n+\tgit rebase master >out &&\n+\tgrep \"Current branch my-topic-branch is up to date\" out\n '\n \n test_expect_success 'rebase against master twice with --force' '\n-     git rebase --force-rebase master >out &&\n-     grep \"Current branch my-topic-branch is up to date, rebase forced\" out\n+\tgit rebase --force-rebase master >out &&\n+\tgrep \"Current branch my-topic-branch is up to date, rebase forced\" out\n '\n \n test_expect_success 'rebase against master twice from another branch' '\n-     git checkout my-topic-branch^ &&\n-     git rebase master my-topic-branch >out &&\n-     grep \"Current branch my-topic-branch is up to date\" out\n+\tgit checkout my-topic-branch^ &&\n+\tgit rebase master my-topic-branch >out &&\n+\tgrep \"Current branch my-topic-branch is up to date\" out\n '\n \n test_expect_success 'rebase fast-forward to master' '\n-     git checkout my-topic-branch^ &&\n-     git rebase my-topic-branch >out &&\n-     grep \"Fast-forwarded HEAD to my-topic-branch\" out\n+\tgit checkout my-topic-branch^ &&\n+\tgit rebase my-topic-branch >out &&\n+\tgrep \"Fast-forwarded HEAD to my-topic-branch\" out\n '\n \n-test_expect_success \\\n-    'the rebase operation should not have destroyed author information' \\\n-    '! (git log | grep \"Author:\" | grep \"<>\")'\n+test_expect_success 'the rebase operation should not have destroyed author information' '\n+\t! (git log | grep \"Author:\" | grep \"<>\")\n+'\n \n-test_expect_success \\\n-    'the rebase operation should not have destroyed author information (2)' \\\n-    \"git log -1 | grep 'Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>'\"\n+test_expect_success 'the rebase operation should not have destroyed author information (2)' \"\n+\tgit log -1 |\n+\tgrep 'Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>'\n+\"\n \n test_expect_success 'HEAD was detached during rebase' '\n-     test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1})\n+\ttest $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1})\n '\n \n test_expect_success 'rebase after merge master' '\n-     git reset --hard topic &&\n-     git merge master &&\n-     git rebase master &&\n-     ! (git show | grep \"^Merge:\")\n+\tgit reset --hard topic &&\n+\tgit merge master &&\n+\tgit rebase master &&\n+\t! (git show | grep \"^Merge:\")\n '\n \n test_expect_success 'rebase of history with merges is linearized' '\n-     git checkout nonlinear &&\n-     test 4 = $(git rev-list master.. | wc -l) &&\n-     git rebase master &&\n-     test 3 = $(git rev-list master.. | wc -l)\n+\tgit checkout nonlinear &&\n+\ttest 4 = $(git rev-list master.. | wc -l) &&\n+\tgit rebase master &&\n+\ttest 3 = $(git rev-list master.. | wc -l)\n '\n \n-test_expect_success \\\n-    'rebase of history with merges after upstream merge is linearized' '\n-     git checkout upstream-merged-nonlinear &&\n-     test 5 = $(git rev-list master.. | wc -l) &&\n-     git rebase master &&\n-     test 3 = $(git rev-list master.. | wc -l)\n+test_expect_success 'rebase of history with merges after upstream merge is linearized' '\n+\tgit checkout upstream-merged-nonlinear &&\n+\ttest 5 = $(git rev-list master.. | wc -l) &&\n+\tgit rebase master &&\n+\ttest 3 = $(git rev-list master.. | wc -l)\n '\n \n test_expect_success 'rebase a single mode change' '\n-     git checkout master &&\n-     echo 1 > X &&\n-     git add X &&\n-     test_tick &&\n-     git commit -m prepare &&\n-     git checkout -b modechange HEAD^ &&\n-     echo 1 > X &&\n-     git add X &&\n-     test_chmod +x A &&\n-     test_tick &&\n-     git commit -m modechange &&\n-     GIT_TRACE=1 git rebase master\n+\tgit checkout master &&\n+\techo 1 >X &&\n+\tgit add X &&\n+\ttest_tick &&\n+\tgit commit -m prepare &&\n+\tgit checkout -b modechange HEAD^ &&\n+\techo 1 >X &&\n+\tgit add X &&\n+\ttest_chmod +x A &&\n+\ttest_tick &&\n+\tgit commit -m modechange &&\n+\tGIT_TRACE=1 git rebase master\n '\n \n test_expect_success 'Show verbose error when HEAD could not be detached' '\n-     : > B &&\n-     test_must_fail git rebase topic 2> output.err > output.out &&\n-     grep \"Untracked working tree file .B. would be overwritten\" output.err\n+\t>B &&\n+\ttest_must_fail git rebase topic 2>output.err >output.out &&\n+\tgrep \"Untracked working tree file .B. would be overwritten\" output.err\n '\n rm -f B\n \n test_expect_success 'dump usage when upstream arg is missing' '\n-     git checkout -b usage topic &&\n-     test_must_fail git rebase 2>error1 &&\n-     grep \"[Uu]sage\" error1 &&\n-     test_must_fail git rebase --abort 2>error2 &&\n-     grep \"No rebase in progress\" error2 &&\n-     test_must_fail git rebase --onto master 2>error3 &&\n-     grep \"[Uu]sage\" error3 &&\n-     ! grep \"can.t shift\" error3\n+\tgit checkout -b usage topic &&\n+\ttest_must_fail git rebase 2>error1 &&\n+\tgrep \"[Uu]sage\" error1 &&\n+\ttest_must_fail git rebase --abort 2>error2 &&\n+\tgrep \"No rebase in progress\" error2 &&\n+\ttest_must_fail git rebase --onto master 2>error3 &&\n+\tgrep \"[Uu]sage\" error3 &&\n+\t! grep \"can.t shift\" error3\n '\n \n test_expect_success 'rebase -q is quiet' '\n-     git checkout -b quiet topic &&\n-     git rebase -q master > output.out 2>&1 &&\n-     test ! -s output.out\n+\tgit checkout -b quiet topic &&\n+\tgit rebase -q master >output.out 2>&1 &&\n+\ttest ! -s output.out\n '\n \n test_expect_success 'Rebase a commit that sprinkles CRs in' '\n-- \n1.7.2.rc3\n"},{"id":"146091","messageId":"20100723170613.GF2507@burratino","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"[PATCH 5/5] rebase: protect against diff.renames configuration","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-23T17:06:13Z","receivedAt":"2010-07-23T17:06:13Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\nDate: Mon, 10 Nov 2008 16:15:49 -0800\n\nWe currently do not disable diff.renames configuration while rebase\ninternally runs \"format-patch\" to feed \"am -3\".\n\nThe end user configuration for \"diff\" should not affect the result\nproduced by the higher level command that is related to \"diff\" only\nbecause internally it is implemented in terms of it.\n\nFor that matter, I have a feeling that format-patch should not even look\nat diff.renames, but we seem to have been doing this for a long time so\nthere is no easy way to fix this thinko.\n\nIn any case, here is a much straightforward fix for \"rebase\".\n\n[jn: with test case from David]\n\nReported-by: David D. Kilzer <ddkilzer@kilzer.net>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n git-rebase.sh     |    2 +-\n t/t3400-rebase.sh |   24 +++++++++++++++++++++++-\n 2 files changed, 24 insertions(+), 2 deletions(-)\n\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex ab4afa7..386be43 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -543,7 +543,7 @@ fi\n if test -z \"$do_merge\"\n then\n \tgit format-patch -k --stdout --full-index --ignore-if-in-upstream \\\n-\t\t$root_flag \"$revisions\" |\n+\t\t--no-renames $root_flag \"$revisions\" |\n \tgit am $git_am_opt --rebasing --resolvemsg=\"$RESOLVEMSG\" &&\n \tmove_to_original_branch\n \tret=$?\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 083d768..a19aeb6 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -19,7 +19,16 @@ test_expect_success 'prepare repository with topic branches' '\n \techo First >A &&\n \tgit update-index --add A &&\n \tgit commit -m \"Add A.\" &&\n-\tgit checkout -b my-topic-branch &&\n+\tgit checkout -b force-3way &&\n+\techo Dummy >Y &&\n+\tgit update-index --add Y &&\n+\tgit commit -m \"Add Y.\" &&\n+\tgit checkout -b filemove &&\n+\tgit reset --soft master &&\n+\tmkdir D &&\n+\tgit mv A D/A &&\n+\tgit commit -m \"Move A.\" &&\n+\tgit checkout -b my-topic-branch master &&\n \techo Second >B &&\n \tgit update-index --add B &&\n \tgit commit -m \"Add B.\" &&\n@@ -128,6 +137,19 @@ test_expect_success 'rebase a single mode change' '\n \tGIT_TRACE=1 git rebase master\n '\n \n+test_expect_success 'rebase is not broken by diff.renames' '\n+\tgit config diff.renames copies &&\n+\ttest_when_finished \"git config --unset diff.renames\" &&\n+\tgit checkout filemove &&\n+\tGIT_TRACE=1 git rebase force-3way\n+'\n+\n+test_expect_success 'setup: recover' '\n+\ttest_might_fail git rebase --abort &&\n+\tgit reset --hard &&\n+\tgit checkout modechange\n+'\n+\n test_expect_success 'Show verbose error when HEAD could not be detached' '\n \t>B &&\n \ttest_must_fail git rebase topic 2>output.err >output.out &&\n-- \n1.7.2.rc3\n"},{"id":"146103","messageId":"624201.94995.qm@web30003.mail.mud.yahoo.com","threadId":"16256","inReplyTo":"20100723170103.GA2507@burratino","subject":"Re: [PATCH 0/5] Fix rebase with file move when diff.renames = copies","fromName":"David D. Kilzer","fromEmail":"ddkilzer@kilzer.net","sentAt":"2010-07-23T18:47:12Z","receivedAt":"2010-07-23T18:47:12Z","isPatch":true,"sender":{"key":"ddkilzer@kilzer.net","avatar":"https://avatars.githubusercontent.com/u/263571?v=4"},"body":"On Fri, July 23, 2010 at 10:01:03 AM, Jonathan Nieder wrote:\n\n\n> David D. Kilzer wrote:\n> \n> > My original patch in  <http://marc.info/?l=git&m=122635667614099&w=2> \n>addressed \n>\n> > this in  builtin-apply.c, but Junio didn't like this approach as noted in \n> >  <http://marc.info/?l=git&m=122636097120953&w=2>.\n> \n> Got it.  This  patch just treats the symptoms in my opinion, and if\n> you read Junio’s message  carefully, I think he was also suggesting\n> that git apply should still be  fixed.\n\n\nThanks!  At the time I needed to fix the issue and continue working.  I didn't \nhave time to investigate it further (which is why it sat for about 18 months).\n\n> Something like this series would fix both.  Please feel free to pick\n> it up and take it in whatever direction you like.\n\n\nIs this comment to me or Junio?  As a part-time contributor, I'm not sure what \nmy options are here.  :)\n\n> Hope that  helps.\n\nYes!  Thanks again!\n\nDave\n"},{"id":"146108","messageId":"AANLkTi=j8-YFwOYxcTWw3zqo=353fsB=vkmRttL4U+au@mail.gmail.com","threadId":"16256","inReplyTo":"20100723170613.GF2507@burratino","subject":"Re: [PATCH 5/5] rebase: protect against diff.renames configuration","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-07-23T19:51:29Z","receivedAt":"2010-07-23T19:51:29Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jul 23, 2010 at 12:06, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> The end user configuration for \"diff\" should not affect the result\n> produced by the higher level command that is related to \"diff\" only\n> because internally it is implemented in terms of it.\n\nAlmost completely unrelated and perhaps not relevant, I seem to recall\nthat if you set 'ui.color' to 'always' you will get unapplyable\npatches because 'git format-patch' will include the color in it's\noutput. Perhaps it should --no-color as well, while we're fixing it?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"146107","messageId":"AANLkTik3uZTmcjv4Jeg7VXbC8Lmai_xjRF80yHfUHxKf@mail.gmail.com","threadId":"16256","inReplyTo":"20100723170613.GF2507@burratino","subject":"Re: [PATCH 5/5] rebase: protect against diff.renames configuration","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-07-23T19:53:46Z","receivedAt":"2010-07-23T19:53:46Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jul 23, 2010 at 12:06, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> The end user configuration for \"diff\" should not affect the result\n> produced by the higher level command that is related to \"diff\" only\n> because internally it is implemented in terms of it.\n\nAlmost completely unrelated and perhaps not relevant, I seem to recall\nthat if you set 'ui.color' to 'always' you will get unapplyable\npatches because 'git format-patch' will include the color in it's\noutput. Perhaps it should --no-color as well, while we're fixing it?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"146112","messageId":"7vvd85ewqy.fsf@alter.siamese.dyndns.org","threadId":"16256","inReplyTo":"AANLkTi=j8-YFwOYxcTWw3zqo=353fsB=vkmRttL4U+au@mail.gmail.com","subject":"Re: [PATCH 5/5] rebase: protect against diff.renames configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-07-23T21:03:49Z","receivedAt":"2010-07-23T21:03:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> On Fri, Jul 23, 2010 at 12:06, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>> The end user configuration for \"diff\" should not affect the result\n>> produced by the higher level command that is related to \"diff\" only\n>> because internally it is implemented in terms of it.\n>\n> Almost completely unrelated and perhaps not relevant, I seem to recall\n> that if you set 'ui.color' to 'always' you will get unapplyable\n> patches because 'git format-patch' will include the color in it's\n> output. Perhaps it should --no-color as well, while we're fixing it?\n\nI think that it actually was a mistake for git_diff_basic_config() to call\ngit_color_default_config().  Parsing of diff.color.<slot> there is Ok and\nwas justified by 9a1805a (add a \"basic\" diff config callback, 2008-01-04),\nbut the change made to the function with 6b2f2d9 (Add color.ui variable\nwhich globally enables colorization if set, 2008-02-18) was probably a\nscrew-up.  The call should instead have gone to diff_ui_config().\n\nI also think format_config() should be changed not to call log_config()\n(we need to move parsing of the format.subjectprefix from the latter to\nthe former), and instead call diff_basic_config() directly.\n"},{"id":"146216","messageId":"20100724215910.GA5780@burratino","threadId":"16256","inReplyTo":"624201.94995.qm@web30003.mail.mud.yahoo.com","subject":"Re: [PATCH 0/5] Fix rebase with file move when diff.renames = copies","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-24T21:59:10Z","receivedAt":"2010-07-24T21:59:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"David D. Kilzer wrote:\n> On Fri, July 23, 2010 at 10:01:03 AM, Jonathan Nieder wrote:\n\n>> Something like this series would fix both.  Please feel free to pick\n>> it up and take it in whatever direction you like.\n>\n> Is this comment to me or Junio?  As a part-time contributor, I'm not sure what \n> my options are here.  :)\n\nIt is to the world at large, or more precisely, anyone who is interested.\n\nI only meant that I am not planning to keep track of what happens to\nthose patches in the future.  Ideally someone else (maybe you ;-))\nwill take care of pinging if a patch gets forgotten or improving the\npatches if some obvious change suggests itself.\n\nThanks for the initial ping, by the way.\n"}]}