{"thread":{"id":"30422","subject":"[PATCH 1/2] t2020-checkout-detach: check for the number of orphaned commits","startedAt":"2012-05-04T18:13:14Z","lastAt":"2012-05-05T09:01:09Z","messageCount":4,"participants":["Johannes Sixt","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"190774","messageId":"4FA41C3A.9080002@kdbg.org","threadId":"30422","inReplyTo":null,"subject":"[PATCH 1/2] t2020-checkout-detach: check for the number of orphaned commits","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2012-05-04T18:13:14Z","receivedAt":"2012-05-04T18:13:14Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Change the test that orphans commits to leave 2 commits behind. Add a test\nthat leaves only one of these behind.\n\nThe next patch will truncate the list of orphaned commits earlier. With\nthis preliminary update, its effect will become more obvious.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n I noticed that when you have a detached history, and walk back only part\n of it, the warning lists all of the detached history even if the part\n that ends at the new HEAD is not orphaned. This patch prepares the tests,\n and the next patch changes git-checkout.\n\n t/t2020-checkout-detach.sh | 21 ++++++++++++++++-----\n 1 file changed, 16 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh\nindex b37ce25..1839b32 100755\n--- a/t/t2020-checkout-detach.sh\n+++ b/t/t2020-checkout-detach.sh\n@@ -11,14 +11,13 @@ check_not_detached () {\n \tgit symbolic-ref -q HEAD >/dev/null\n }\n \n-ORPHAN_WARNING='you are leaving .* commit.*behind'\n PREV_HEAD_DESC='Previous HEAD position was'\n check_orphan_warning() {\n-\ttest_i18ngrep \"$ORPHAN_WARNING\" \"$1\" &&\n+\ttest_i18ngrep \"you are leaving $2 behind\" \"$1\" &&\n \ttest_i18ngrep ! \"$PREV_HEAD_DESC\" \"$1\"\n }\n check_no_orphan_warning() {\n-\ttest_i18ngrep ! \"$ORPHAN_WARNING\" \"$1\" &&\n+\ttest_i18ngrep ! \"you are leaving .* commit.*behind\" \"$1\" &&\n \ttest_i18ngrep \"$PREV_HEAD_DESC\" \"$1\"\n }\n \n@@ -110,12 +109,24 @@ test_expect_success 'checkout warns on orphan commits' '\n \tgit checkout --detach two &&\n \techo content >orphan &&\n \tgit add orphan &&\n-\tgit commit -a -m orphan &&\n+\tgit commit -a -m orphan1 &&\n+\techo new content >orphan &&\n+\tgit commit -a -m orphan2 &&\n+\torphan2=$(git rev-parse HEAD) &&\n \tgit checkout master 2>stderr\n '\n \n test_expect_success 'checkout warns on orphan commits: output' '\n-\tcheck_orphan_warning stderr\n+\tcheck_orphan_warning stderr \"2 commits\"\n+'\n+\n+test_expect_success 'checkout warns orphaning 1 of 2 commits' '\n+\tgit checkout \"$orphan2\" &&\n+\tgit checkout HEAD^ 2>stderr\n+'\n+\n+test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '\n+\tcheck_orphan_warning stderr \"2 commits\"\n '\n \n test_expect_success 'checkout does not warn leaving ref tip' '\n-- \n1.7.10.1.462.g199f411\n"},{"id":"190775","messageId":"4FA41C98.2010105@kdbg.org","threadId":"30422","inReplyTo":"4FA41C3A.9080002@kdbg.org","subject":"[PATCH 2/2] checkout (detached): truncate list of orphaned commits at the new HEAD","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2012-05-04T18:14:48Z","receivedAt":"2012-05-04T18:14:48Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"When git checkout switches from a detached HEAD to any other commit, then\nall orphaned commits were listed in a warning:\n\n  Warning: you are leaving 2 commits behind...:\n\n    a5e5396 another fixup\n    6aa1af6 fixup foo\n\nBut if the new commit is actually one from this list (6aa1af6 in this\nexample), then the list in the warning can be truncated at the new HEAD,\nbecause history beginning at HEAD is not \"left behind\". This makes it so.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n builtin/checkout.c         | 13 +++++++------\n t/t2020-checkout-detach.sh |  2 +-\n 2 files changed, 8 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 23fc56d..c93efe4 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -672,10 +672,10 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)\n  * HEAD.  If it is not reachable from any ref, this is the last chance\n  * for the user to do so without resorting to reflog.\n  */\n-static void orphaned_commit_warning(struct commit *commit)\n+static void orphaned_commit_warning(struct commit *old, struct commit *new)\n {\n \tstruct rev_info revs;\n-\tstruct object *object = &commit->object;\n+\tstruct object *object = &old->object;\n \tstruct object_array refs;\n \n \tinit_revisions(&revs, NULL);\n@@ -685,16 +685,17 @@ static void orphaned_commit_warning(struct commit *commit)\n \tadd_pending_object(&revs, object, sha1_to_hex(object->sha1));\n \n \tfor_each_ref(add_pending_uninteresting_ref, &revs);\n+\tadd_pending_sha1(&revs, \"HEAD\", new->object.sha1, UNINTERESTING);\n \n \trefs = revs.pending;\n \trevs.leak_pending = 1;\n \n \tif (prepare_revision_walk(&revs))\n \t\tdie(_(\"internal error in revision walk\"));\n-\tif (!(commit->object.flags & UNINTERESTING))\n-\t\tsuggest_reattach(commit, &revs);\n+\tif (!(old->object.flags & UNINTERESTING))\n+\t\tsuggest_reattach(old, &revs);\n \telse\n-\t\tdescribe_detached_head(_(\"Previous HEAD position was\"), commit);\n+\t\tdescribe_detached_head(_(\"Previous HEAD position was\"), old);\n \n \tclear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);\n \tfree(refs.objects);\n@@ -731,7 +732,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)\n \t}\n \n \tif (!opts->quiet && !old.path && old.commit && new->commit != old.commit)\n-\t\torphaned_commit_warning(old.commit);\n+\t\torphaned_commit_warning(old.commit, new->commit);\n \n \tupdate_refs_for_switch(opts, &old, new);\n \ndiff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh\nindex 1839b32..8100537 100755\n--- a/t/t2020-checkout-detach.sh\n+++ b/t/t2020-checkout-detach.sh\n@@ -126,7 +126,7 @@ test_expect_success 'checkout warns orphaning 1 of 2 commits' '\n '\n \n test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '\n-\tcheck_orphan_warning stderr \"2 commits\"\n+\tcheck_orphan_warning stderr \"1 commit\"\n '\n \n test_expect_success 'checkout does not warn leaving ref tip' '\n-- \n1.7.10.1.462.g199f411\n"},{"id":"190798","messageId":"7vaa1nafnj.fsf@alter.siamese.dyndns.org","threadId":"30422","inReplyTo":"4FA41C98.2010105@kdbg.org","subject":"Re: [PATCH 2/2] checkout (detached): truncate list of orphaned commits at the new HEAD","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-04T19:51:28Z","receivedAt":"2012-05-04T19:51:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> When git checkout switches from a detached HEAD to any other commit, then\n> all orphaned commits were listed in a warning:\n>\n>   Warning: you are leaving 2 commits behind...:\n>\n>     a5e5396 another fixup\n>     6aa1af6 fixup foo\n>\n> But if the new commit is actually one from this list (6aa1af6 in this\n> example), then the list in the warning can be truncated at the new HEAD,\n> because history beginning at HEAD is not \"left behind\". This makes it so.\n\nIf you did:\n\n\tgit checkout master^0\n        git commit --allow-empty -m emp0\n        git commit --allow-empty -m emp1\n        tip=$(git rev-parse HEAD)\n        git reset --hard HEAD^\n\nand then\n\n\tgit checkout $tip\n\nit used to warn about \"emp0\" but because you are checking out \"emp1\",\nwhich is a descendant of \"emp0\", nothing is lost and no lossage is\nreported with the updated code.\n\nMakes sense; thanks.\n"},{"id":"190829","messageId":"20120505090108.GA8172@sigill.intra.peff.net","threadId":"30422","inReplyTo":"4FA41C98.2010105@kdbg.org","subject":"Re: [PATCH 2/2] checkout (detached): truncate list of orphaned commits at the new HEAD","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-05T09:01:09Z","receivedAt":"2012-05-05T09:01:09Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 04, 2012 at 08:14:48PM +0200, Johannes Sixt wrote:\n\n> When git checkout switches from a detached HEAD to any other commit, then\n> all orphaned commits were listed in a warning:\n> \n>   Warning: you are leaving 2 commits behind...:\n> \n>     a5e5396 another fixup\n>     6aa1af6 fixup foo\n> \n> But if the new commit is actually one from this list (6aa1af6 in this\n> example), then the list in the warning can be truncated at the new HEAD,\n> because history beginning at HEAD is not \"left behind\". This makes it so.\n\nThanks, this has bugged me a few times in the past, but I've never\ngotten around to investigating and fixing it.\n\n>  builtin/checkout.c         | 13 +++++++------\n>  t/t2020-checkout-detach.sh |  2 +-\n>  2 files changed, 8 insertions(+), 7 deletions(-)\n\nThe patch looks right to me.\n\n-Peff\n"}]}