{"thread":{"id":"34205","subject":"[PATCH v2 0/7] Re-roll rr/rebase-checkout-reflog","startedAt":"2013-06-18T18:55:30Z","lastAt":"2013-06-19T18:29:23Z","messageCount":19,"participants":["Ramkumar Ramachandra","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":2,"patchTotal":7},"messages":[{"id":"221284","messageId":"1371581737-10013-1-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":null,"subject":"[PATCH v2 0/7] Re-roll rr/rebase-checkout-reflog","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:30Z","receivedAt":"2013-06-18T18:55:30Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"In this iteration, I've redone [6/7] and [7/7] to address the \"do not\nleak GIT_REFLOG_ACTION\" problem that Junio talked about.  Predictably,\nI couldn't convince myself to take Junio's subshell approach.\nInstead, I've reworked the entire logic to have two variables:\nGIT_REFLOG_ACTION and base_reflog_action.  It is now elegant and\ncorrect.\n\nI'm elated that I got the chance to do this right.\n\nThanks.\n\nJunio C Hamano (1):\n  t/t7512-status-help: test \"HEAD detached from\"\n\nRamkumar Ramachandra (6):\n  wt-status: remove unused field in grab_1st_switch_cbdata\n  t/t2012-checkout-last: test \"checkout -\" after a rebase\n  status: do not depend on rebase reflog messages\n  checkout: respect GIT_REFLOG_ACTION\n  rebase: write better reflog messages\n  rebase -i: write better reflog messages\n\n builtin/checkout.c            | 11 +++++++---\n git-am.sh                     |  4 +++-\n git-rebase--am.sh             |  5 +++++\n git-rebase--interactive.sh    | 14 +++++++++----\n git-rebase.sh                 | 13 ++++++++++--\n t/t2012-checkout-last.sh      | 34 +++++++++++++++++++++++++++++++\n t/t3404-rebase-interactive.sh | 15 ++++++++++++++\n t/t7512-status-help.sh        | 47 ++++++++++++++++++++++++-------------------\n wt-status.c                   |  7 ++++---\n 9 files changed, 116 insertions(+), 34 deletions(-)\n\n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221285","messageId":"1371581737-10013-2-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 1/7] t/t7512-status-help: test \"HEAD detached from\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:31Z","receivedAt":"2013-06-18T18:55:31Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\n\nb397ea (status: show more info than \"currently not on any branch\",\n2013-03-13) wanted to make sure that after a checkout to detach HEAD,\nthe user can see where the HEAD was originally detached from.  The last\ntest added by that commit to t/status-help shows one example,\nimmediately after HEAD is detached via a checkout.  Enhance that test to\ntest the \"HEAD detached from\" message is displayed when the user further\nresets to another commit.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n t/t7512-status-help.sh | 10 +++++++++-\n 1 file changed, 9 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex bf08d4e..bafa5e7 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -667,7 +667,7 @@ test_expect_success 'status when cherry-picking after resolving conflicts' '\n \ttest_i18ncmp expected actual\n '\n \n-test_expect_success 'status showing detached from a tag' '\n+test_expect_success 'status showing detached at and from a tag' '\n \ttest_commit atag tagging &&\n \tgit checkout atag &&\n \tcat >expected <<-\\EOF\n@@ -675,6 +675,14 @@ test_expect_success 'status showing detached from a tag' '\n \tnothing to commit (use -u to show untracked files)\n \tEOF\n \tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual &&\n+\n+\tgit reset --hard HEAD^ &&\n+\tcat >expected <<-\\EOF\n+\t# HEAD detached from atag\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n \ttest_i18ncmp expected actual\n '\n \n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221286","messageId":"1371581737-10013-3-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 2/7] wt-status: remove unused field in grab_1st_switch_cbdata","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:32Z","receivedAt":"2013-06-18T18:55:32Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"The struct grab_1st_switch_cbdata has the field \"found\", which is\nset in grab_1st_switch() when a match is found.  This information is\nredundant and unused by any code.  The return value of the function\nserves to communicate this information anyway.\n\nRemove the field.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n wt-status.c | 2 --\n 1 file changed, 2 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex bf84a86..2511270 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1035,7 +1035,6 @@ got_nothing:\n }\n \n struct grab_1st_switch_cbdata {\n-\tint found;\n \tstruct strbuf buf;\n \tunsigned char nsha1[20];\n };\n@@ -1059,7 +1058,6 @@ static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1,\n \tfor (end = target; *end && *end != '\\n'; end++)\n \t\t;\n \tstrbuf_add(&cb->buf, target, end - target);\n-\tcb->found = 1;\n \treturn 1;\n }\n \n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221287","messageId":"1371581737-10013-4-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 3/7] t/t2012-checkout-last: test \"checkout -\" after a rebase","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:33Z","receivedAt":"2013-06-18T18:55:33Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"  $ git checkout -\n\ndoes not work as expected after a rebase.  This is because the\nreflog records \"checkout\" made by \"rebase\" as its implementation\ndetail the same way as end-user initiated \"checkout\", and makes it\ncount as the branch that was previously checked out.\n\nAdd four failing tests documenting this bug: two for a normal rebase,\nand another two for an interactive rebase.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t2012-checkout-last.sh | 34 ++++++++++++++++++++++++++++++++++\n 1 file changed, 34 insertions(+)\n\ndiff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh\nindex b44de9d..6ad6edf 100755\n--- a/t/t2012-checkout-last.sh\n+++ b/t/t2012-checkout-last.sh\n@@ -116,4 +116,38 @@ test_expect_success 'master...' '\n \ttest \"z$(git rev-parse --verify HEAD)\" = \"z$(git rev-parse --verify master^)\"\n '\n \n+test_expect_failure '\"checkout -\" works after a rebase A' '\n+\tgit checkout master &&\n+\tgit checkout other &&\n+\tgit rebase master &&\n+\tgit checkout - &&\n+\ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n+'\n+\n+test_expect_failure '\"checkout -\" works after a rebase A B' '\n+\tgit branch moodle master~1 &&\n+\tgit checkout master &&\n+\tgit checkout other &&\n+\tgit rebase master moodle &&\n+\tgit checkout - &&\n+\ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n+'\n+\n+test_expect_failure '\"checkout -\" works after a rebase -i A' '\n+\tgit checkout master &&\n+\tgit checkout other &&\n+\tgit rebase -i master &&\n+\tgit checkout - &&\n+\ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n+'\n+\n+test_expect_failure '\"checkout -\" works after a rebase -i A B' '\n+\tgit branch foodle master~1 &&\n+\tgit checkout master &&\n+\tgit checkout other &&\n+\tgit rebase master foodle &&\n+\tgit checkout - &&\n+\ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n+'\n+\n test_done\n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221289","messageId":"1371581737-10013-5-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 4/7] status: do not depend on rebase reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:34Z","receivedAt":"2013-06-18T18:55:34Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"b397ea4 (status: show more info than \"currently not on any branch\",\n2013-03-13) attempted to make the output of 'git status' richer in\nthe case of a detached HEAD.  Before this patch, with a detached\nHEAD, we saw:\n\n  $ git status\n  # Not currently on any branch.\n\nBut after the patch, we see:\n\n  $ git checkout v1.8.2\n  $ git status\n  # HEAD detached at v1.8.2\n\nIt works by digging the reflog for the most recent message of the\nform \"checkout: moving from xxxx to yyyy\".  It then asserts that\nHEAD and \"yyyy\" are the same, and displays this message.  When they\naren't equal, it displays:\n\n  $ git status\n  # HEAD detached from fe11db\n\nso that the user can see where the HEAD was first detached.\n\nIn case of a rebase [-i] operation in progress, this message depends on\nthe implementation of rebase writing \"checkout: \" messages to the\nreflog, but that is an implementation detail of \"rebase\".  To remove\nthis dependency so that rebase can be updated to write better reflog\nmessages, replace this \"HEAD detached from\" message with:\n\n  # rebase in progress; onto $ONTO\n\nChanges to the commit object name in the expected output for some of the\ntests shows that what the test expected \"status\" to show during \"rebase\n-i\" was not consistent with the output during a vanilla \"rebase\", which\nshowed on top of what commit the series is being replayed.  Now we\nconsistently show something meaningful to the end user.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t7512-status-help.sh | 37 +++++++++++++++++--------------------\n wt-status.c            |  5 ++++-\n 2 files changed, 21 insertions(+), 21 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex bafa5e7..d6c66d7 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -77,7 +77,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \tONTO=$(git rev-parse --short HEAD^^) &&\n \ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently rebasing branch '\\''rebase_conflicts'\\'' on '\\''$ONTO'\\''.\n \t#   (fix conflicts and then run \"git rebase --continue\")\n \t#   (use \"git rebase --skip\" to skip this patch)\n@@ -104,7 +104,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '\n \techo three >main.txt &&\n \tgit add main.txt &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently rebasing branch '\\''rebase_conflicts'\\'' on '\\''$ONTO'\\''.\n \t#   (all conflicts fixed: run \"git rebase --continue\")\n \t#\n@@ -136,7 +136,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '\n \tONTO=$(git rev-parse --short rebase_i_conflicts) &&\n \ttest_must_fail git rebase -i rebase_i_conflicts &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently rebasing branch '\\''rebase_i_conflicts_second'\\'' on '\\''$ONTO'\\''.\n \t#   (fix conflicts and then run \"git rebase --continue\")\n \t#   (use \"git rebase --skip\" to skip this patch)\n@@ -162,7 +162,7 @@ test_expect_success 'status during rebase -i after resolving conflicts' '\n \ttest_must_fail git rebase -i rebase_i_conflicts &&\n \tgit add main.txt &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently rebasing branch '\\''rebase_i_conflicts_second'\\'' on '\\''$ONTO'\\''.\n \t#   (all conflicts fixed: run \"git rebase --continue\")\n \t#\n@@ -188,10 +188,9 @@ test_expect_success 'status when rebasing -i in edit mode' '\n \texport FAKE_LINES &&\n \ttest_when_finished \"git rebase --abort\" &&\n \tONTO=$(git rev-parse --short HEAD~2) &&\n-\tTGT=$(git rev-parse --short two_rebase_i) &&\n \tgit rebase -i HEAD~2 &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $TGT\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''rebase_i_edit'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -216,9 +215,8 @@ test_expect_success 'status when splitting a commit' '\n \tONTO=$(git rev-parse --short HEAD~3) &&\n \tgit rebase -i HEAD~3 &&\n \tgit reset HEAD^ &&\n-\tTGT=$(git rev-parse --short HEAD) &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $TGT\n+\t# rebase in progress; onto $ONTO\n \t# You are currently splitting a commit while rebasing branch '\\''split_commit'\\'' on '\\''$ONTO'\\''.\n \t#   (Once your working directory is clean, run \"git rebase --continue\")\n \t#\n@@ -246,11 +244,10 @@ test_expect_success 'status after editing the last commit with --amend during a\n \texport FAKE_LINES &&\n \ttest_when_finished \"git rebase --abort\" &&\n \tONTO=$(git rev-parse --short HEAD~3) &&\n-\tTGT=$(git rev-parse --short three_amend) &&\n \tgit rebase -i HEAD~3 &&\n \tgit commit --amend -m \"foo\" &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $TGT\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''amend_last'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -280,7 +277,7 @@ test_expect_success 'status: (continue first edit) second edit' '\n \tgit rebase -i HEAD~3 &&\n \tgit rebase --continue &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -302,7 +299,7 @@ test_expect_success 'status: (continue first edit) second edit and split' '\n \tgit rebase --continue &&\n \tgit reset HEAD^ &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently splitting a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (Once your working directory is clean, run \"git rebase --continue\")\n \t#\n@@ -329,7 +326,7 @@ test_expect_success 'status: (continue first edit) second edit and amend' '\n \tgit rebase --continue &&\n \tgit commit --amend -m \"foo\" &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -351,7 +348,7 @@ test_expect_success 'status: (amend first edit) second edit' '\n \tgit commit --amend -m \"a\" &&\n \tgit rebase --continue &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -374,7 +371,7 @@ test_expect_success 'status: (amend first edit) second edit and split' '\n \tgit rebase --continue &&\n \tgit reset HEAD^ &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently splitting a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (Once your working directory is clean, run \"git rebase --continue\")\n \t#\n@@ -402,7 +399,7 @@ test_expect_success 'status: (amend first edit) second edit and amend' '\n \tgit rebase --continue &&\n \tgit commit --amend -m \"d\" &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -426,7 +423,7 @@ test_expect_success 'status: (split first edit) second edit' '\n \tgit commit -m \"e\" &&\n \tgit rebase --continue &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -451,7 +448,7 @@ test_expect_success 'status: (split first edit) second edit and split' '\n \tgit rebase --continue &&\n \tgit reset HEAD^ &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently splitting a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (Once your working directory is clean, run \"git rebase --continue\")\n \t#\n@@ -481,7 +478,7 @@ test_expect_success 'status: (split first edit) second edit and amend' '\n \tgit rebase --continue &&\n \tgit commit --amend -m \"h\" &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached from $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently editing a commit while rebasing branch '\\''several_edits'\\'' on '\\''$ONTO'\\''.\n \t#   (use \"git commit --amend\" to amend the current commit)\n \t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n@@ -601,7 +598,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '\n \tONTO=$(git rev-parse --short HEAD^^) &&\n \ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n \tcat >expected <<-EOF &&\n-\t# HEAD detached at $ONTO\n+\t# rebase in progress; onto $ONTO\n \t# You are currently rebasing branch '\\''statushints_disabled'\\'' on '\\''$ONTO'\\''.\n \t#\n \t# Unmerged paths:\ndiff --git a/wt-status.c b/wt-status.c\nindex 2511270..85a00f1 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1174,7 +1174,10 @@ void wt_status_print(struct wt_status *s)\n \t\t\tbranch_name += 11;\n \t\telse if (!strcmp(branch_name, \"HEAD\")) {\n \t\t\tbranch_status_color = color(WT_STATUS_NOBRANCH, s);\n-\t\t\tif (state.detached_from) {\n+\t\t\tif (state.rebase_in_progress || state.rebase_interactive_in_progress) {\n+\t\t\t\ton_what = _(\"rebase in progress; onto \");\n+\t\t\t\tbranch_name = state.onto;\n+\t\t\t} else if (state.detached_from) {\n \t\t\t\tunsigned char sha1[20];\n \t\t\t\tbranch_name = state.detached_from;\n \t\t\t\tif (!get_sha1(\"HEAD\", sha1) &&\n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221288","messageId":"1371581737-10013-6-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 5/7] checkout: respect GIT_REFLOG_ACTION","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:35Z","receivedAt":"2013-06-18T18:55:35Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"GIT_REFLOG_ACTION is an environment variable specifying the reflog\nmessage to write after an action is completed.  Several other commands\nincluding merge, reset, and commit respect it.\n\nFix the failing tests in t/checkout-last by making checkout respect it\ntoo.  You can now expect\n\n  $ git checkout -\n\nto work as expected after any a rebase [-i].  It will also work with any\nother scripts provided they set an appropriate GIT_REFLOG_ACTION if they\ninternally use \"git checkout\".\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/checkout.c       | 11 ++++++++---\n t/t2012-checkout-last.sh |  8 ++++----\n 2 files changed, 12 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex f5b50e5..1e2af85 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -587,7 +587,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,\n \t\t\t\t   struct branch_info *new)\n {\n \tstruct strbuf msg = STRBUF_INIT;\n-\tconst char *old_desc;\n+\tconst char *old_desc, *reflog_msg;\n \tif (opts->new_branch) {\n \t\tif (opts->new_orphan_branch) {\n \t\t\tif (opts->new_branch_log && !log_all_ref_updates) {\n@@ -620,8 +620,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts,\n \told_desc = old->name;\n \tif (!old_desc && old->commit)\n \t\told_desc = sha1_to_hex(old->commit->object.sha1);\n-\tstrbuf_addf(&msg, \"checkout: moving from %s to %s\",\n-\t\t    old_desc ? old_desc : \"(invalid)\", new->name);\n+\n+\treflog_msg = getenv(\"GIT_REFLOG_ACTION\");\n+\tif (!reflog_msg)\n+\t\tstrbuf_addf(&msg, \"checkout: moving from %s to %s\",\n+\t\t\told_desc ? old_desc : \"(invalid)\", new->name);\n+\telse\n+\t\tstrbuf_insert(&msg, 0, reflog_msg, strlen(reflog_msg));\n \n \tif (!strcmp(new->name, \"HEAD\") && !new->path && !opts->force_detach) {\n \t\t/* Nothing to do. */\ndiff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh\nindex 6ad6edf..e7ba8c5 100755\n--- a/t/t2012-checkout-last.sh\n+++ b/t/t2012-checkout-last.sh\n@@ -116,7 +116,7 @@ test_expect_success 'master...' '\n \ttest \"z$(git rev-parse --verify HEAD)\" = \"z$(git rev-parse --verify master^)\"\n '\n \n-test_expect_failure '\"checkout -\" works after a rebase A' '\n+test_expect_success '\"checkout -\" works after a rebase A' '\n \tgit checkout master &&\n \tgit checkout other &&\n \tgit rebase master &&\n@@ -124,7 +124,7 @@ test_expect_failure '\"checkout -\" works after a rebase A' '\n \ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n '\n \n-test_expect_failure '\"checkout -\" works after a rebase A B' '\n+test_expect_success '\"checkout -\" works after a rebase A B' '\n \tgit branch moodle master~1 &&\n \tgit checkout master &&\n \tgit checkout other &&\n@@ -133,7 +133,7 @@ test_expect_failure '\"checkout -\" works after a rebase A B' '\n \ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n '\n \n-test_expect_failure '\"checkout -\" works after a rebase -i A' '\n+test_expect_success '\"checkout -\" works after a rebase -i A' '\n \tgit checkout master &&\n \tgit checkout other &&\n \tgit rebase -i master &&\n@@ -141,7 +141,7 @@ test_expect_failure '\"checkout -\" works after a rebase -i A' '\n \ttest \"z$(git symbolic-ref HEAD)\" = \"zrefs/heads/master\"\n '\n \n-test_expect_failure '\"checkout -\" works after a rebase -i A B' '\n+test_expect_success '\"checkout -\" works after a rebase -i A B' '\n \tgit branch foodle master~1 &&\n \tgit checkout master &&\n \tgit checkout other &&\n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221290","messageId":"1371581737-10013-7-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 6/7] rebase: write better reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:36Z","receivedAt":"2013-06-18T18:55:36Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Now that the \"checkout\" invoked internally from \"rebase\" knows to honor\nGIT_REFLOG_ACTION, we can start to use it to write a better reflog\nmessage when \"rebase anotherbranch\", \"rebase --onto branch\",\netc. internally checks out the new fork point.  We will write:\n\n  rebase: checkout master\n\ninstead of the old\n\n  rebase\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-am.sh         |  4 +++-\n git-rebase--am.sh |  5 +++++\n git-rebase.sh     | 13 +++++++++++--\n 3 files changed, 19 insertions(+), 3 deletions(-)\n\ndiff --git a/git-am.sh b/git-am.sh\nindex 1cf3d1d..74ef9ca 100755\n--- a/git-am.sh\n+++ b/git-am.sh\n@@ -46,6 +46,8 @@ set_reflog_action am\n require_work_tree\n cd_to_toplevel\n \n+base_reflog_action=\"$GIT_REFLOG_ACTION\"\n+\n git var GIT_COMMITTER_IDENT >/dev/null ||\n \tdie \"$(gettext \"You need to set your committer info first\")\"\n \n@@ -884,7 +886,7 @@ did you forget to use 'git add'?\"\n \t\tfi &&\n \t\tgit commit-tree $tree ${parent:+-p} $parent <\"$dotest/final-commit\"\n \t) &&\n-\tgit update-ref -m \"$GIT_REFLOG_ACTION: $FIRSTLINE\" HEAD $commit $parent ||\n+\tgit update-ref -m \"$base_reflog_action: $FIRSTLINE\" HEAD $commit $parent ||\n \tstop_here $this\n \n \tif test -f \"$dotest/original-commit\"; then\ndiff --git a/git-rebase--am.sh b/git-rebase--am.sh\nindex 34e3102..69fae7a 100644\n--- a/git-rebase--am.sh\n+++ b/git-rebase--am.sh\n@@ -5,11 +5,13 @@\n \n case \"$action\" in\n continue)\n+\tGIT_REFLOG_ACTION=\"$base_reflog_action\"\n \tgit am --resolved --resolvemsg=\"$resolvemsg\" &&\n \tmove_to_original_branch\n \treturn\n \t;;\n skip)\n+\tGIT_REFLOG_ACTION=\"$base_reflog_action\"\n \tgit am --skip --resolvemsg=\"$resolvemsg\" &&\n \tmove_to_original_branch\n \treturn\n@@ -40,9 +42,11 @@ else\n \t\trm -f \"$GIT_DIR/rebased-patches\"\n \t\tcase \"$head_name\" in\n \t\trefs/heads/*)\n+\t\t\tGIT_REFLOG_ACTION=\"$base_reflog_action: checkout $head_name\"\n \t\t\tgit checkout -q \"$head_name\"\n \t\t\t;;\n \t\t*)\n+\t\t\tGIT_REFLOG_ACTION=\"$base_reflog_action: checkout $orig_head\"\n \t\t\tgit checkout -q \"$orig_head\"\n \t\t\t;;\n \t\tesac\n@@ -59,6 +63,7 @@ else\n \t\treturn $?\n \tfi\n \n+\tGIT_REFLOG_ACTION=\"$base_reflog_action\"\n \tgit am $git_am_opt --rebasing --resolvemsg=\"$resolvemsg\" <\"$GIT_DIR/rebased-patches\"\n \tret=$?\n \ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex d0c11a9..1c72120 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -47,6 +47,8 @@ set_reflog_action rebase\n require_work_tree_exists\n cd_to_toplevel\n \n+base_reflog_action=\"$GIT_REFLOG_ACTION\"\n+\n LF='\n '\n ok_to_skip_pre_rebase=\n@@ -336,7 +338,8 @@ then\n \t# Only interactive rebase uses detailed reflog messages\n \tif test \"$type\" = interactive && test \"$GIT_REFLOG_ACTION\" = rebase\n \tthen\n-\t\tGIT_REFLOG_ACTION=\"rebase -i ($action)\"\n+\t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n+\t\tbase_reflog_action=\"$GIT_REFLOG_ACTION\"\n \t\texport GIT_REFLOG_ACTION\n \tfi\n fi\n@@ -543,7 +546,11 @@ then\n \tif test -z \"$force_rebase\"\n \tthen\n \t\t# Lazily switch to the target branch if needed...\n-\t\ttest -z \"$switch_to\" || git checkout \"$switch_to\" --\n+\t\tif test -n \"$switch_to\"\n+\t\tthen\n+\t\t\tGIT_REFLOG_ACTION=\"$base_reflog_action: checkout $switch_to\"\n+\t\t\tgit checkout \"$switch_to\" --\n+\t\tfi\n \t\tsay \"$(eval_gettext \"Current branch \\$branch_name is up to date.\")\"\n \t\texit 0\n \telse\n@@ -568,6 +575,8 @@ test \"$type\" = interactive && run_specific_rebase\n \n # Detach HEAD and reset the tree\n say \"$(gettext \"First, rewinding head to replay your work on top of it...\")\"\n+\n+GIT_REFLOG_ACTION=\"$base_reflog_action: checkout $onto_name\"\n git checkout -q \"$onto^0\" || die \"could not detach HEAD\"\n git update-ref ORIG_HEAD $orig_head\n \n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221291","messageId":"1371581737-10013-8-git-send-email-artagnon@gmail.com","threadId":"34205","inReplyTo":"1371581737-10013-1-git-send-email-artagnon@gmail.com","subject":"[PATCH v2 7/7] rebase -i: write better reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T18:55:37Z","receivedAt":"2013-06-18T18:55:37Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Now that the \"checkout\" invoked internally from \"rebase -i\" knows to\nhonor GIT_REFLOG_ACTION, we can start to use it to write a better reflog\nmessage when \"rebase -i anotherbranch\", \"rebase -i --onto branch\",\netc. internally checks out the new fork point.  We will write:\n\n  rebase -i (start): checkout master\n\ninstead of the old\n\n  rebase -i (start)\n\n[jc: add rebase-reflog test]\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-rebase--interactive.sh    | 14 ++++++++++----\n t/t3404-rebase-interactive.sh | 15 +++++++++++++++\n 2 files changed, 25 insertions(+), 4 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex f953d8d..8429c87 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -95,12 +95,15 @@ commit_message () {\n \tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n }\n \n-orig_reflog_action=\"$GIT_REFLOG_ACTION\"\n+base_reflog_action=\"$GIT_REFLOG_ACTION\"\n \n comment_for_reflog () {\n-\tcase \"$orig_reflog_action\" in\n+\tcase \"$base_reflog_action\" in\n+\t# if GIT_REFLOG_ACTION was set by caller git-rebase, overwrite\n+\t# it with rebase -i.\n \t''|rebase*)\n \t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n+\t\tbase_reflog_action=\"$GIT_REFLOG_ACTION\"\n \t\texport GIT_REFLOG_ACTION\n \t\t;;\n \tesac\n@@ -326,6 +329,7 @@ pick_one_preserving_merges () {\n \t\tif [ \"$1\" != \"-n\" ]\n \t\tthen\n \t\t\t# detach HEAD to current parent\n+\t\t\tGIT_REFLOG_ACTION=\"$base_reflog_action: checkout $first_parent\"\n \t\t\toutput git checkout $first_parent 2> /dev/null ||\n \t\t\t\tdie \"Cannot move HEAD to $first_parent\"\n \t\tfi\n@@ -608,10 +612,10 @@ do_next () {\n \tnewhead=$(git rev-parse HEAD) &&\n \tcase $head_name in\n \trefs/*)\n-\t\tmessage=\"$GIT_REFLOG_ACTION: $head_name onto $onto\" &&\n+\t\tmessage=\"$base_reflog_action: $head_name onto $onto\" &&\n \t\tgit update-ref -m \"$message\" $head_name $newhead $orig_head &&\n \t\tgit symbolic-ref \\\n-\t\t  -m \"$GIT_REFLOG_ACTION: returning to $head_name\" \\\n+\t\t  -m \"$base_reflog_action: returning to $head_name\" \\\n \t\t  HEAD $head_name\n \t\t;;\n \tesac && {\n@@ -838,6 +842,7 @@ comment_for_reflog start\n \n if test ! -z \"$switch_to\"\n then\n+\tGIT_REFLOG_ACTION=\"$base_reflog_action: checkout $switch_to\"\n \toutput git checkout \"$switch_to\" -- ||\n \t\tdie \"Could not checkout $switch_to\"\n fi\n@@ -981,6 +986,7 @@ has_action \"$todo\" ||\n \n test -d \"$rewritten\" || test -n \"$force_rebase\" || skip_unnecessary_picks\n \n+GIT_REFLOG_ACTION=\"$base_reflog_action: checkout $onto_name\"\n output git checkout $onto || die_abort \"could not detach HEAD\"\n git update-ref ORIG_HEAD $orig_head\n do_rest\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 79e8d3c..f7d0147 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -934,6 +934,21 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '\n \ttest L = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n \n+test_expect_success 'rebase -i produces readable reflog' '\n+\tgit reset --hard &&\n+\tgit branch -f branch1 H &&\n+\tgit rebase -i --onto I F branch1 &&\n+\tcat >expect <<-\\EOF &&\n+\trebase -i (start): checkout I\n+\trebase -i (pick): G\n+\trebase -i (pick): H\n+\trebase -i (finish): returning to refs/heads/branch1\n+\tEOF\n+\ttail -n 4 .git/logs/HEAD |\n+\tsed -e \"s/.*\t//\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'rebase -i respects core.commentchar' '\n \tgit reset --hard &&\n \tgit checkout E^0 &&\n-- \n1.8.3.1.455.g5932b31\n"},{"id":"221300","messageId":"7va9mn40nw.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"1371581737-10013-7-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-18T20:35:47Z","receivedAt":"2013-06-18T20:35:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Now that the \"checkout\" invoked internally from \"rebase\" knows to honor\n> GIT_REFLOG_ACTION, we can start to use it to write a better reflog\n> message when \"rebase anotherbranch\", \"rebase --onto branch\",\n> etc. internally checks out the new fork point.  We will write:\n>\n>   rebase: checkout master\n>\n> instead of the old\n>\n>   rebase\n>\n> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n\nSo the approach taken by this round is to change everybody's\nassumption so far that they can start from a clean and usable\nGIT_REFLOG_ACTION when creating their own message, and stop\ndepending on what is left in GIT_REFLOG_ACTION.\n\nThat would certainly allow this patch to leave whatever cruft in\nGIT_REFLOG_ACTION, because everybody else will now create the value\nto be assigned to that variable from scratch based on a new and\ndifferent variable.  All existing \"everybody else\" is converted to\nadjust to the new reality.\n\nA one-shot assignment \"VAR=VAL git checkout\" is sometimes cumbersome\nto arrange, especially when what calls the \"git checkout\" is wrapped\nin a shell function like \"output\", I think this is an OK approach.\n\nIf we are adopting that convention, however, the new variable that\nholds the name of the overall program, base_reflog_action, needs to\nbe a bit more prominently documented in the code, to let the other\npeople know that is the new convention to follow.\n\nSomething like...\n\n\t# Use this as the prefix when setting and exporting\n        # GIT_REFLOG_ACTION variable.\n\tbase_reflog_action=am\n\nAnd the fact that we are declaring the new convention and expecting\neverybody to stick to it should be in the log message.\n\nThanks.\n"},{"id":"221301","messageId":"7v38sf40my.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"1371581737-10013-8-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH v2 7/7] rebase -i: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-18T20:36:21Z","receivedAt":"2013-06-18T20:36:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n> index 79e8d3c..f7d0147 100755\n> --- a/t/t3404-rebase-interactive.sh\n> +++ b/t/t3404-rebase-interactive.sh\n> @@ -934,6 +934,21 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '\n>  \ttest L = $(git cat-file commit HEAD | sed -ne \\$p)\n>  '\n>  \n> +test_expect_success 'rebase -i produces readable reflog' '\n> +\tgit reset --hard &&\n> +\tgit branch -f branch1 H &&\n\nWhy did this have to change back from branch-reflog-test to branch1\n(which I used by mistake in \"how about this\" patch, but fixed in the\nversion queued on 'pu')?\n\nThe reason I did not use 'branch1' in the version I queued on 'pu'\nis because rr/rebase-sha1-by-string-query, when merged on top of\nthis, makes an assumption on where branch1 is in the test and\nfliping its tip here will break it.\n\nHave you tested this with combination of that topic before sending\nit out?\n"},{"id":"221302","messageId":"CALkWK0==+Zs-Ej92VsHnF60_=RTigkKo+3xLew3JdavC3fbzoA@mail.gmail.com","threadId":"34205","inReplyTo":"7v38sf40my.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 7/7] rebase -i: write better reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-18T20:38:16Z","receivedAt":"2013-06-18T20:38:16Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Why did this have to change back from branch-reflog-test to branch1\n> (which I used by mistake in \"how about this\" patch, but fixed in the\n> version queued on 'pu')?\n>\n> The reason I did not use 'branch1' in the version I queued on 'pu'\n> is because rr/rebase-sha1-by-string-query, when merged on top of\n> this, makes an assumption on where branch1 is in the test and\n> fliping its tip here will break it.\n\nOh, okay.  Then just tweak before applying, if you don't mind?\n"},{"id":"221304","messageId":"7vsj0f2l6z.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"CALkWK0==+Zs-Ej92VsHnF60_=RTigkKo+3xLew3JdavC3fbzoA@mail.gmail.com","subject":"Re: [PATCH v2 7/7] rebase -i: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-18T20:55:16Z","receivedAt":"2013-06-18T20:55:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>> Why did this have to change back from branch-reflog-test to branch1\n>> (which I used by mistake in \"how about this\" patch, but fixed in the\n>> version queued on 'pu')?\n>>\n>> The reason I did not use 'branch1' in the version I queued on 'pu'\n>> is because rr/rebase-sha1-by-string-query, when merged on top of\n>> this, makes an assumption on where branch1 is in the test and\n>> fliping its tip here will break it.\n>\n> Oh, okay.  Then just tweak before applying, if you don't mind?\n\nSorry, you've already used my time allotment for this week.\n"},{"id":"221322","messageId":"CALkWK0nfMax6SmybNunob=3+MtJhXQ3_X=34dq+cMV+hA8cKQw@mail.gmail.com","threadId":"34205","inReplyTo":"7vsj0f2l6z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 7/7] rebase -i: write better reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-19T04:07:52Z","receivedAt":"2013-06-19T04:07:52Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n>> Oh, okay.  Then just tweak before applying, if you don't mind?\n>\n> Sorry, you've already used my time allotment for this week.\n\nNo worries, I'll re-roll.\n"},{"id":"221328","messageId":"51C1442A.2010904@viscovery.net","threadId":"34205","inReplyTo":"1371581737-10013-7-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2013-06-19T05:39:54Z","receivedAt":"2013-06-19T05:39:54Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 6/18/2013 20:55, schrieb Ramkumar Ramachandra:\n> Now that the \"checkout\" invoked internally from \"rebase\" knows to honor\n> GIT_REFLOG_ACTION, we can start to use it to write a better reflog\n> message when \"rebase anotherbranch\", \"rebase --onto branch\",\n> etc. internally checks out the new fork point.  We will write:\n> \n>   rebase: checkout master\n> \n> instead of the old\n> \n>   rebase\n\n> diff --git a/git-rebase--am.sh b/git-rebase--am.sh\n> index 34e3102..69fae7a 100644\n> --- a/git-rebase--am.sh\n> +++ b/git-rebase--am.sh\n> @@ -5,11 +5,13 @@\n>  \n>  case \"$action\" in\n>  continue)\n> +\tGIT_REFLOG_ACTION=\"$base_reflog_action\"\n\nI haven't followed the topic closely, but I wonder why there are so many\nexplicit assignments to GIT_REFLOG_ACTION. Is calling set_reflog_action\n(defined in git-sh-setup) the wrong thing to do?\n\n-- Hannes\n"},{"id":"221335","messageId":"CALkWK0mMLPHp=OcWAPW5g3Eb7CBt42dtqkDwpQp69tKwLNYe0Q@mail.gmail.com","threadId":"34205","inReplyTo":"51C1442A.2010904@viscovery.net","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-06-19T06:09:00Z","receivedAt":"2013-06-19T06:09:00Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Johannes Sixt wrote:\n> I haven't followed the topic closely, but I wonder why there are so many\n> explicit assignments to GIT_REFLOG_ACTION. Is calling set_reflog_action\n> (defined in git-sh-setup) the wrong thing to do?\n\nDoes this answer your question?\n\nset_reflog_action() {\n\tif [ -z \"${GIT_REFLOG_ACTION:+set}\" ]\n\tthen\n\t\tGIT_REFLOG_ACTION=\"$*\"\n\t\texport GIT_REFLOG_ACTION\n\tfi\n}\n"},{"id":"221337","messageId":"51C14E93.5000707@viscovery.net","threadId":"34205","inReplyTo":"CALkWK0mMLPHp=OcWAPW5g3Eb7CBt42dtqkDwpQp69tKwLNYe0Q@mail.gmail.com","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2013-06-19T06:24:19Z","receivedAt":"2013-06-19T06:24:19Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 6/19/2013 8:09, schrieb Ramkumar Ramachandra:\n> Johannes Sixt wrote:\n>> I haven't followed the topic closely, but I wonder why there are so many\n>> explicit assignments to GIT_REFLOG_ACTION. Is calling set_reflog_action\n>> (defined in git-sh-setup) the wrong thing to do?\n> \n> Does this answer your question?\n> \n> set_reflog_action() {\n> \tif [ -z \"${GIT_REFLOG_ACTION:+set}\" ]\n> \tthen\n> \t\tGIT_REFLOG_ACTION=\"$*\"\n> \t\texport GIT_REFLOG_ACTION\n> \tfi\n> }\n\nPlease don't state the obvious, that does not help. Of course, this does\nnot answer my question. I was rather hinting that it may be wrong to set\nGIT_REFLOG_ACTION explicitly.\n\nI thought that the convention is not to modify GIT_REFLOG_ACTION if it is\nalready set. set_reflog_action does just that.\n\n-- Hannes\n"},{"id":"221384","messageId":"7vy5a611hb.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"51C1442A.2010904@viscovery.net","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-19T16:58:40Z","receivedAt":"2013-06-19T16:58:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Am 6/18/2013 20:55, schrieb Ramkumar Ramachandra:\n>> Now that the \"checkout\" invoked internally from \"rebase\" knows to honor\n>> GIT_REFLOG_ACTION, we can start to use it to write a better reflog\n>> message when \"rebase anotherbranch\", \"rebase --onto branch\",\n>> etc. internally checks out the new fork point.  We will write:\n>> \n>>   rebase: checkout master\n>> \n>> instead of the old\n>> \n>>   rebase\n>\n>> diff --git a/git-rebase--am.sh b/git-rebase--am.sh\n>> index 34e3102..69fae7a 100644\n>> --- a/git-rebase--am.sh\n>> +++ b/git-rebase--am.sh\n>> @@ -5,11 +5,13 @@\n>>  \n>>  case \"$action\" in\n>>  continue)\n>> +\tGIT_REFLOG_ACTION=\"$base_reflog_action\"\n>\n> I haven't followed the topic closely, but I wonder why there are so many\n> explicit assignments to GIT_REFLOG_ACTION. Is calling set_reflog_action\n> (defined in git-sh-setup) the wrong thing to do?\n\nExcellent question, and I think this illustrates why the recent\nreroll that uses an approach to use base_reflog_action is not\ncomplete and needs further work (to put it mildly).\n\nset_reflog_action is designed to be used once at the very top of a\nprogram, like this in \"git am\", for example:\n\n\tset_reflog_action am\n\nThe helper function sets the given string to GIT_REFLOG_ACTION only\nwhen GIT_REFLOG_ACTION is not yet set.  Thanks to this, \"git am\",\nwhen run as the top-level program, will use \"am\" in GIT_REFLOG_ACTION\nand the reflog entries made by whatever it does will say \"am did this\".\n\nBecause of the conditional assignment, when \"git am\" is run as a\nsubprogram (i.e. an implementation detail) of \"git rebase\", the call\nto the helper function at the beginning will *not* have any effect.\nSo \"git rebase\" can do this:\n\n\tset_reflog_action rebase\n\t... do its own preparation, like checking out \"onto\" commit\n        ... decide to do \"format-patch\" to \"am\" pipeline\n        \tgit format-patch --stdout >mbox\n\t\tgit am mbox\n\nand the reflog entries made inside \"git am\" invocation will say\n\"rebase\", not \"am\".\n\nThe approach to introduce base_reflog_action may be valid, but if we\nwere to go that route, set_reflog_action needs to learn the new\nconvention.  Perhaps by doing something like this:\n\n 1. set_reflog_action to set GIT_REFLOG_NAME and GIT_REFLOG_ACTION;\n    Program names like \"am\", \"rebase\" will be set to this value.\n\n 2. If the program does not want to say anything more than its\n    program name in the reflog, it does not have to do anything.\n    GIT_REFLOG_ACTION that is set upfront (or inherited from the\n    calling program) will be written in the reflog.\n\n 3. If the program wants to say more than just its name, it needs to\n    arrange GIT_REFLOG_ACTION not to be clobbered.  It can do so in\n    various ways:\n\n   a) A one-shot invocation of any program that writes to reflog can\n      do:\n\n\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_NAME: custom message\" \\\n        \tgit cmd\n\n      An important thing is that GIT_REFLOG_ACTION is left as the\n      original, i.e. \"am\" or \"rebase\", so that calls to programs that\n      write reflog using the default (i.e. program name only) will\n      not be affected.\n\n   b) Or it can temporarily change it and revert it back (necessary\n      to use shell function like \"output\" that cannot use the above\n      \"single shot export\" technique):\n\n\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_NAME: custom message\"\n        output git cmd\n \tGIT_REFLOG_ACTION=$GIT_REFLOG_NAME\n\nBut after writing it down this way, I realize that introduction of\nbase_reflog_action (or GIT_REFLOG_NAME which is a moral equivalent)\nis not helping us at all.  As long as calls to \"git\" command in the\nsecond category exists in these scripts, GIT_REFLOG_ACTION *must* be\nkept pristine after set_reflog_action sets it, so we can get rid of\nthis new variable, and rewrite 3.a and 3.b like so:\n\n    3-a)\n\n\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: custom message\" \\\n        \tgit cmd\n\n    3-b)\n\n\tSAVED=$GIT_REFLOG_ACTION\n\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: custom message\"\n        output git cmd\n \tGIT_REFLOG_ACTION=$SAVED\n\n\t    or\n\n\t(\n                GIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: custom message\"\n                output git cmd\n\t)\n\nThat essentially boils down to the very original suggestion I made\nbefore Ram introduced the base_reflog_action.\n"},{"id":"221390","messageId":"7v8v260yy5.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"7vy5a611hb.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-19T17:53:22Z","receivedAt":"2013-06-19T17:53:22Z","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> Excellent question, and I think this illustrates why the recent\n> reroll that uses an approach to use base_reflog_action is not\n> complete and needs further work (to put it mildly).\n> ...\n> That essentially boils down to the very original suggestion I made\n> before Ram introduced the base_reflog_action.\n\nSo how about doing something like this?\n\nIncidentally, I noticed that GIT_LITERAL_PATHSPECS:: heading in the\nenumeration of environment variables is marked-up differently from\nothers, which is a low-hanging fruit somebody may want to fix.\n\n Documentation/git-sh-setup.txt |  8 +++++---\n Documentation/git.txt          | 10 ++++++++++\n git-sh-setup.sh                | 34 ++++++++++++++++++++++++++++++++++\n 3 files changed, 49 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt\nindex 5d709d0..4f67c4c 100644\n--- a/Documentation/git-sh-setup.txt\n+++ b/Documentation/git-sh-setup.txt\n@@ -41,9 +41,11 @@ usage::\n \tdie with the usage message.\n \n set_reflog_action::\n-\tset the message that will be recorded to describe the\n-\tend-user action in the reflog, when the script updates a\n-\tref.\n+\tSet GIT_REFLOG_ACTION environment to a given string (typically\n+\tthe name of the program) unless it is already set.  Whenever\n+\tthe script runs a `git` command that updates refs, a reflog\n+\tentry is created using the value of this string to leave the\n+\trecord of what command updated the ref.\n \n git_editor::\n \truns an editor of user's choice (GIT_EDITOR, core.editor, VISUAL or\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex 2e23cbb..e2bdcc9 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -846,6 +846,16 @@ GIT_LITERAL_PATHSPECS::\n \tliteral paths to Git (e.g., paths previously given to you by\n \t`git ls-tree`, `--raw` diff output, etc).\n \n+'GIT_REFLOG_ACTION'::\n+\tWhen a ref is updated, reflog entries are created to keep\n+\ttrack of the reason why the ref was updated (which is\n+\ttypically the name of the high-level command that updated\n+\tthe ref), in addition to the old and new values of the ref.\n+\tA scripted Porcelain command can use set_reflog_action\n+\thelper function in `git-sh-setup` to set its name to this\n+\tvariable when it is invoked as the top level command by the\n+\tend user, to be recorded in the body of the reflog.\n+\n \n Discussion[[Discussion]]\n ------------------------\ndiff --git a/git-sh-setup.sh b/git-sh-setup.sh\nindex 2f78359..e5379bc 100644\n--- a/git-sh-setup.sh\n+++ b/git-sh-setup.sh\n@@ -103,6 +103,40 @@ $LONG_USAGE\"\n \tesac\n fi\n \n+# Set the name of the end-user facing command in the reflog when the\n+# script may update refs.  When GIT_REFLOG_ACTION is already set, this\n+# will not overwrite it, so that a scripted Porcelain (e.g. \"git\n+# rebase\") can set it to its own name (e.g. \"rebase\") and then call\n+# another scripted Porcelain (e.g. \"git am\") and a call to this\n+# function in the latter will keep the name of the end-user facing\n+# program (e.g. \"rebase\") in GIT_REFLOG_ACTION, ensuring whatever it\n+# does will be record as actions done as part of the end-user facing\n+# operation (e.g. \"rebase\").\n+#\n+# NOTE NOTE NOTE: consequently, after assigning a specific message to\n+# GIT_REFLOG_ACTION when calling a \"git\" command to record a custom\n+# reflog message, do not leave that custom value in GIT_REFLOG_ACTION,\n+# after you are done.  Other callers of \"git\" commands that rely on\n+# writing the default \"program name\" in reflog expect the variable to\n+# contain the value set by this function.\n+#\n+# To use a custom reflog message, do either one of these three:\n+#\n+# (a) use a single-shot export form:\n+#     GIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: preparing frotz\" \\\n+#         git command-that-updates-a-ref\n+#\n+# (b) save the original away and restore:\n+#     SAVED_ACTION=$GIT_REFLOG_ACTION\n+#     GIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: preparing frotz\"\n+#     git command-that-updates-a-ref\n+#     GIT_REFLOG_ACITON=$SAVED_ACTION\n+#\n+# (c) assign the variable in a subshell:\n+#     (\n+#         GIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: preparing frotz\"\n+#         git command-that-updates-a-ref\n+#     )\n set_reflog_action() {\n \tif [ -z \"${GIT_REFLOG_ACTION:+set}\" ]\n \tthen\n"},{"id":"221391","messageId":"7v4ncu0xa4.fsf@alter.siamese.dyndns.org","threadId":"34205","inReplyTo":"7v8v260yy5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 6/7] rebase: write better reflog messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-19T18:29:23Z","receivedAt":"2013-06-19T18:29:23Z","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> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Excellent question, and I think this illustrates why the recent\n>> reroll that uses an approach to use base_reflog_action is not\n>> complete and needs further work (to put it mildly).\n>> ...\n>> That essentially boils down to the very original suggestion I made\n>> before Ram introduced the base_reflog_action.\n>\n> So how about doing something like this?\n\nHaving said all that, although I think the \"something like this\"\npatch is an improvement in that it spells out the rules regarding\nthe use of GIT_REFLOG_ACTION environment variable, which was not\ndocumented so far, I think the environment variable is showing its\nflaws.\n\nIt was a good mechanism in simpler times, back when \"git commit\",\n\"git fetch\" and \"git merge\" were its primary users.  They didn't do\nmany ref updates, and having a way to record that \"this update was\ndone by a 'merge' command initiated by the end user\" was perfectly\nadequate.\n\nFor a command like \"rebase\" that can do many ref updates, having to\nset a custom message and export the variable in each and every step\nis cumbersome, and keeping the same prefix across becomes even more\nso.\n\nThe $orig_reflog_action used inside git-rebase--interactive is a\nreasonable local solution for the \"keeping the same prefix\" problem,\nbut it is a _local_ solution that does not scale.  In the end, it\nupdates the GIT_REFLOG_ACTION variable, so the script has to be very\ncareful to make sure the variable has a sensible value before\ncalling any ref-updating \"git\" command.  It will have to set it back\nto $orig_reflog_action if it ever wants to call another scripted\nPorcelain.\n\nAmong the C infrastructure, commit, fetch, merge and reset are the\nonly ones that pay attention to GIT_REFLOG_ACTION, and we will be\nadding checkout to the mix.  If we originally did not make the\nmistake of using GIT_REFLOG_ACTION as a whole message, and instead\nused it to convey _only_ the prefix (i.e. \"rebase\", \"am\", etc.) to\nsubprocesses in order to remember what the end-user initiated\ncommand was, and used a command line argument to give the actual\nmessages, we would have been in much better shape.  E.g. a\n\"checkout\" call inside \"git rebase\" may become\n\n\tgit checkout \\\n            --reflog-message=\"$GIT_REFLOG_ACTION: detaching\" \\\n\t    $onto^0\n\nand nobody other than set_reflog_action shell function would be\nsetting GIT_REFLOG_ACTION variable.\n\nOh well.\n"}]}