status: show the branch name if possible in in-progress info

The typical use-case is starting a rebase, do something else, come back the day after, run "git status" or make a new commit and wonder what in the world's going on. Which branch is being rebased is probably the most useful tidbit to help, but the target may help too. Ideally, I would have loved to see "rebasing master on origin/master", but the target ref name is not stored during rebase, so this patch writes "rebasing master on a78c8c98b" as a half-measure to remind future users of that potential improvement. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Feb 3, 2013 at 12:53 UTC 0722c805d616eb644a868a995b891470f9e5e30d
3 files changed +142 -41
t/t7512-status-help.sh
+52 -35
@@ -73,10 +73,11 @@ test_expect_success 'prepare for rebase conflicts' '
73
74 test_expect_success 'status when rebase in progress before resolving conflicts' '
75 test_when_finished "git rebase --abort" &&
76 + ONTO=$(git rev-parse --short HEAD^^) &&
77 test_must_fail git rebase HEAD^ --onto HEAD^^ &&
77 - cat >expected <<-\EOF &&
78 + cat >expected <<-EOF &&
79 # Not currently on any branch.
79 - # You are currently rebasing.
80 + # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
81 # (fix conflicts and then run "git rebase --continue")
82 # (use "git rebase --skip" to skip this patch)
83 # (use "git rebase --abort" to check out the original branch)
@@ -97,12 +98,13 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
98 test_expect_success 'status when rebase in progress before rebase --continue' '
99 git reset --hard rebase_conflicts &&
100 test_when_finished "git rebase --abort" &&
101 + ONTO=$(git rev-parse --short HEAD^^) &&
102 test_must_fail git rebase HEAD^ --onto HEAD^^ &&
103 echo three >main.txt &&
104 git add main.txt &&
103 - cat >expected <<-\EOF &&
105 + cat >expected <<-EOF &&
106 # Not currently on any branch.
105 - # You are currently rebasing.
107 + # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
108 # (all conflicts fixed: run "git rebase --continue")
109 #
110 # Changes to be committed:
@@ -130,10 +132,11 @@ test_expect_success 'prepare for rebase_i_conflicts' '
132
133 test_expect_success 'status during rebase -i when conflicts unresolved' '
134 test_when_finished "git rebase --abort" &&
135 + ONTO=$(git rev-parse --short rebase_i_conflicts) &&
136 test_must_fail git rebase -i rebase_i_conflicts &&
134 - cat >expected <<-\EOF &&
137 + cat >expected <<-EOF &&
138 # Not currently on any branch.
136 - # You are currently rebasing.
139 + # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
140 # (fix conflicts and then run "git rebase --continue")
141 # (use "git rebase --skip" to skip this patch)
142 # (use "git rebase --abort" to check out the original branch)
@@ -154,11 +157,12 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '
157 test_expect_success 'status during rebase -i after resolving conflicts' '
158 git reset --hard rebase_i_conflicts_second &&
159 test_when_finished "git rebase --abort" &&
160 + ONTO=$(git rev-parse --short rebase_i_conflicts) &&
161 test_must_fail git rebase -i rebase_i_conflicts &&
162 git add main.txt &&
159 - cat >expected <<-\EOF &&
163 + cat >expected <<-EOF &&
164 # Not currently on any branch.
161 - # You are currently rebasing.
165 + # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
166 # (all conflicts fixed: run "git rebase --continue")
167 #
168 # Changes to be committed:
@@ -182,10 +186,11 @@ test_expect_success 'status when rebasing -i in edit mode' '
186 FAKE_LINES="1 edit 2" &&
187 export FAKE_LINES &&
188 test_when_finished "git rebase --abort" &&
189 + ONTO=$(git rev-parse --short HEAD~2) &&
190 git rebase -i HEAD~2 &&
186 - cat >expected <<-\EOF &&
191 + cat >expected <<-EOF &&
192 # Not currently on any branch.
188 - # You are currently editing a commit during a rebase.
193 + # You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''.
194 # (use "git commit --amend" to amend the current commit)
195 # (use "git rebase --continue" once you are satisfied with your changes)
196 #
@@ -206,11 +211,12 @@ test_expect_success 'status when splitting a commit' '
211 FAKE_LINES="1 edit 2 3" &&
212 export FAKE_LINES &&
213 test_when_finished "git rebase --abort" &&
214 + ONTO=$(git rev-parse --short HEAD~3) &&
215 git rebase -i HEAD~3 &&
216 git reset HEAD^ &&
211 - cat >expected <<-\EOF &&
217 + cat >expected <<-EOF &&
218 # Not currently on any branch.
213 - # You are currently splitting a commit during a rebase.
219 + # You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''.
220 # (Once your working directory is clean, run "git rebase --continue")
221 #
222 # Changes not staged for commit:
@@ -236,11 +242,12 @@ test_expect_success 'status after editing the last commit with --amend during a
242 FAKE_LINES="1 2 edit 3" &&
243 export FAKE_LINES &&
244 test_when_finished "git rebase --abort" &&
245 + ONTO=$(git rev-parse --short HEAD~3) &&
246 git rebase -i HEAD~3 &&
247 git commit --amend -m "foo" &&
241 - cat >expected <<-\EOF &&
248 + cat >expected <<-EOF &&
249 # Not currently on any branch.
243 - # You are currently editing a commit during a rebase.
250 + # You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''.
251 # (use "git commit --amend" to amend the current commit)
252 # (use "git rebase --continue" once you are satisfied with your changes)
253 #
@@ -265,11 +272,12 @@ test_expect_success 'status: (continue first edit) second edit' '
272 FAKE_LINES="edit 1 edit 2 3" &&
273 export FAKE_LINES &&
274 test_when_finished "git rebase --abort" &&
275 + ONTO=$(git rev-parse --short HEAD~3) &&
276 git rebase -i HEAD~3 &&
277 git rebase --continue &&
270 - cat >expected <<-\EOF &&
278 + cat >expected <<-EOF &&
279 # Not currently on any branch.
272 - # You are currently editing a commit during a rebase.
280 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
281 # (use "git commit --amend" to amend the current commit)
282 # (use "git rebase --continue" once you are satisfied with your changes)
283 #
@@ -285,12 +293,13 @@ test_expect_success 'status: (continue first edit) second edit and split' '
293 FAKE_LINES="edit 1 edit 2 3" &&
294 export FAKE_LINES &&
295 test_when_finished "git rebase --abort" &&
296 + ONTO=$(git rev-parse --short HEAD~3) &&
297 git rebase -i HEAD~3 &&
298 git rebase --continue &&
299 git reset HEAD^ &&
291 - cat >expected <<-\EOF &&
300 + cat >expected <<-EOF &&
301 # Not currently on any branch.
293 - # You are currently splitting a commit during a rebase.
302 + # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
303 # (Once your working directory is clean, run "git rebase --continue")
304 #
305 # Changes not staged for commit:
@@ -311,12 +320,13 @@ test_expect_success 'status: (continue first edit) second edit and amend' '
320 FAKE_LINES="edit 1 edit 2 3" &&
321 export FAKE_LINES &&
322 test_when_finished "git rebase --abort" &&
323 + ONTO=$(git rev-parse --short HEAD~3) &&
324 git rebase -i HEAD~3 &&
325 git rebase --continue &&
326 git commit --amend -m "foo" &&
317 - cat >expected <<-\EOF &&
327 + cat >expected <<-EOF &&
328 # Not currently on any branch.
319 - # You are currently editing a commit during a rebase.
329 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
330 # (use "git commit --amend" to amend the current commit)
331 # (use "git rebase --continue" once you are satisfied with your changes)
332 #
@@ -332,12 +342,13 @@ test_expect_success 'status: (amend first edit) second edit' '
342 FAKE_LINES="edit 1 edit 2 3" &&
343 export FAKE_LINES &&
344 test_when_finished "git rebase --abort" &&
345 + ONTO=$(git rev-parse --short HEAD~3) &&
346 git rebase -i HEAD~3 &&
347 git commit --amend -m "a" &&
348 git rebase --continue &&
338 - cat >expected <<-\EOF &&
349 + cat >expected <<-EOF &&
350 # Not currently on any branch.
340 - # You are currently editing a commit during a rebase.
351 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
352 # (use "git commit --amend" to amend the current commit)
353 # (use "git rebase --continue" once you are satisfied with your changes)
354 #
@@ -353,13 +364,14 @@ test_expect_success 'status: (amend first edit) second edit and split' '
364 FAKE_LINES="edit 1 edit 2 3" &&
365 export FAKE_LINES &&
366 test_when_finished "git rebase --abort" &&
367 + ONTO=$(git rev-parse --short HEAD~3) &&
368 git rebase -i HEAD~3 &&
369 git commit --amend -m "b" &&
370 git rebase --continue &&
371 git reset HEAD^ &&
360 - cat >expected <<-\EOF &&
372 + cat >expected <<-EOF &&
373 # Not currently on any branch.
362 - # You are currently splitting a commit during a rebase.
374 + # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
375 # (Once your working directory is clean, run "git rebase --continue")
376 #
377 # Changes not staged for commit:
@@ -380,13 +392,14 @@ test_expect_success 'status: (amend first edit) second edit and amend' '
392 FAKE_LINES="edit 1 edit 2 3" &&
393 export FAKE_LINES &&
394 test_when_finished "git rebase --abort" &&
395 + ONTO=$(git rev-parse --short HEAD~3) &&
396 git rebase -i HEAD~3 &&
397 git commit --amend -m "c" &&
398 git rebase --continue &&
399 git commit --amend -m "d" &&
387 - cat >expected <<-\EOF &&
400 + cat >expected <<-EOF &&
401 # Not currently on any branch.
389 - # You are currently editing a commit during a rebase.
402 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
403 # (use "git commit --amend" to amend the current commit)
404 # (use "git rebase --continue" once you are satisfied with your changes)
405 #
@@ -402,14 +415,15 @@ test_expect_success 'status: (split first edit) second edit' '
415 FAKE_LINES="edit 1 edit 2 3" &&
416 export FAKE_LINES &&
417 test_when_finished "git rebase --abort" &&
418 + ONTO=$(git rev-parse --short HEAD~3) &&
419 git rebase -i HEAD~3 &&
420 git reset HEAD^ &&
421 git add main.txt &&
422 git commit -m "e" &&
423 git rebase --continue &&
410 - cat >expected <<-\EOF &&
424 + cat >expected <<-EOF &&
425 # Not currently on any branch.
412 - # You are currently editing a commit during a rebase.
426 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
427 # (use "git commit --amend" to amend the current commit)
428 # (use "git rebase --continue" once you are satisfied with your changes)
429 #
@@ -425,15 +439,16 @@ test_expect_success 'status: (split first edit) second edit and split' '
439 FAKE_LINES="edit 1 edit 2 3" &&
440 export FAKE_LINES &&
441 test_when_finished "git rebase --abort" &&
442 + ONTO=$(git rev-parse --short HEAD~3) &&
443 git rebase -i HEAD~3 &&
444 git reset HEAD^ &&
445 git add main.txt &&
446 git commit --amend -m "f" &&
447 git rebase --continue &&
448 git reset HEAD^ &&
434 - cat >expected <<-\EOF &&
449 + cat >expected <<-EOF &&
450 # Not currently on any branch.
436 - # You are currently splitting a commit during a rebase.
451 + # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
452 # (Once your working directory is clean, run "git rebase --continue")
453 #
454 # Changes not staged for commit:
@@ -454,15 +469,16 @@ test_expect_success 'status: (split first edit) second edit and amend' '
469 FAKE_LINES="edit 1 edit 2 3" &&
470 export FAKE_LINES &&
471 test_when_finished "git rebase --abort" &&
472 + ONTO=$(git rev-parse --short HEAD~3) &&
473 git rebase -i HEAD~3 &&
474 git reset HEAD^ &&
475 git add main.txt &&
476 git commit --amend -m "g" &&
477 git rebase --continue &&
478 git commit --amend -m "h" &&
463 - cat >expected <<-\EOF &&
479 + cat >expected <<-EOF &&
480 # Not currently on any branch.
465 - # You are currently editing a commit during a rebase.
481 + # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
482 # (use "git commit --amend" to amend the current commit)
483 # (use "git rebase --continue" once you are satisfied with your changes)
484 #
@@ -558,7 +574,7 @@ test_expect_success 'status when bisecting' '
574 git bisect good one_bisect &&
575 cat >expected <<-\EOF &&
576 # Not currently on any branch.
561 - # You are currently bisecting.
577 + # You are currently bisecting branch '\''bisect'\''.
578 # (use "git bisect reset" to get back to the original branch)
579 #
580 nothing to commit (use -u to show untracked files)
@@ -577,10 +593,11 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
593 test_commit two_statushints main.txt two &&
594 test_commit three_statushints main.txt three &&
595 test_when_finished "git rebase --abort" &&
596 + ONTO=$(git rev-parse --short HEAD^^) &&
597 test_must_fail git rebase HEAD^ --onto HEAD^^ &&
581 - cat >expected <<-\EOF &&
598 + cat >expected <<-EOF &&
599 # Not currently on any branch.
583 - # You are currently rebasing.
600 + # You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
601 #
602 # Unmerged paths:
603 # both modified: main.txt
wt-status.c
+88 -6
@@ -872,7 +872,14 @@ static void show_rebase_in_progress(struct wt_status *s,
872 struct stat st;
873
874 if (has_unmerged(s)) {
875 - status_printf_ln(s, color, _("You are currently rebasing."));
875 + if (state->branch)
876 + status_printf_ln(s, color,
877 + _("You are currently rebasing branch '%s' on '%s'."),
878 + state->branch,
879 + state->onto);
880 + else
881 + status_printf_ln(s, color,
882 + _("You are currently rebasing."));
883 if (advice_status_hints) {
884 status_printf_ln(s, color,
885 _(" (fix conflicts and then run \"git rebase --continue\")"));
@@ -882,17 +889,38 @@ static void show_rebase_in_progress(struct wt_status *s,
889 _(" (use \"git rebase --abort\" to check out the original branch)"));
890 }
891 } else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
885 - status_printf_ln(s, color, _("You are currently rebasing."));
892 + if (state->branch)
893 + status_printf_ln(s, color,
894 + _("You are currently rebasing branch '%s' on '%s'."),
895 + state->branch,
896 + state->onto);
897 + else
898 + status_printf_ln(s, color,
899 + _("You are currently rebasing."));
900 if (advice_status_hints)
901 status_printf_ln(s, color,
902 _(" (all conflicts fixed: run \"git rebase --continue\")"));
903 } else if (split_commit_in_progress(s)) {
890 - status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
904 + if (state->branch)
905 + status_printf_ln(s, color,
906 + _("You are currently splitting a commit while rebasing branch '%s' on '%s'."),
907 + state->branch,
908 + state->onto);
909 + else
910 + status_printf_ln(s, color,
911 + _("You are currently splitting a commit during a rebase."));
912 if (advice_status_hints)
913 status_printf_ln(s, color,
914 _(" (Once your working directory is clean, run \"git rebase --continue\")"));
915 } else {
895 - status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
916 + if (state->branch)
917 + status_printf_ln(s, color,
918 + _("You are currently editing a commit while rebasing branch '%s' on '%s'."),
919 + state->branch,
920 + state->onto);
921 + else
922 + status_printf_ln(s, color,
923 + _("You are currently editing a commit during a rebase."));
924 if (advice_status_hints && !s->amend) {
925 status_printf_ln(s, color,
926 _(" (use \"git commit --amend\" to amend the current commit)"));
@@ -923,16 +951,57 @@ static void show_bisect_in_progress(struct wt_status *s,
951 struct wt_status_state *state,
952 const char *color)
953 {
926 - status_printf_ln(s, color, _("You are currently bisecting."));
954 + if (state->branch)
955 + status_printf_ln(s, color,
956 + _("You are currently bisecting branch '%s'."),
957 + state->branch);
958 + else
959 + status_printf_ln(s, color,
960 + _("You are currently bisecting."));
961 if (advice_status_hints)
962 status_printf_ln(s, color,
963 _(" (use \"git bisect reset\" to get back to the original branch)"));
964 wt_status_print_trailer(s);
965 }
966
967 +/*
968 + * Extract branch information from rebase/bisect
969 + */
970 +static void read_and_strip_branch(struct strbuf *sb,
971 + const char **branch,
972 + const char *path)
973 +{
974 + unsigned char sha1[20];
975 +
976 + strbuf_reset(sb);
977 + if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0)
978 + return;
979 +
980 + while (sb->len && sb->buf[sb->len - 1] == '\n')
981 + strbuf_setlen(sb, sb->len - 1);
982 + if (!sb->len)
983 + return;
984 + if (!prefixcmp(sb->buf, "refs/heads/"))
985 + *branch = sb->buf + strlen("refs/heads/");
986 + else if (!prefixcmp(sb->buf, "refs/"))
987 + *branch = sb->buf;
988 + else if (!get_sha1_hex(sb->buf, sha1)) {
989 + const char *abbrev;
990 + abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
991 + strbuf_reset(sb);
992 + strbuf_addstr(sb, abbrev);
993 + *branch = sb->buf;
994 + } else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */
995 + ;
996 + else /* bisect */
997 + *branch = sb->buf;
998 +}
999 +
1000 static void wt_status_print_state(struct wt_status *s)
1001 {
1002 const char *state_color = color(WT_STATUS_HEADER, s);
1003 + struct strbuf branch = STRBUF_INIT;
1004 + struct strbuf onto = STRBUF_INIT;
1005 struct wt_status_state state;
1006 struct stat st;
1007
@@ -947,17 +1016,28 @@ static void wt_status_print_state(struct wt_status *s)
1016 state.am_empty_patch = 1;
1017 } else {
1018 state.rebase_in_progress = 1;
1019 + read_and_strip_branch(&branch, &state.branch,
1020 + "rebase-apply/head-name");
1021 + read_and_strip_branch(&onto, &state.onto,
1022 + "rebase-apply/onto");
1023 }
1024 } else if (!stat(git_path("rebase-merge"), &st)) {
1025 if (!stat(git_path("rebase-merge/interactive"), &st))
1026 state.rebase_interactive_in_progress = 1;
1027 else
1028 state.rebase_in_progress = 1;
1029 + read_and_strip_branch(&branch, &state.branch,
1030 + "rebase-merge/head-name");
1031 + read_and_strip_branch(&onto, &state.onto,
1032 + "rebase-merge/onto");
1033 } else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
1034 state.cherry_pick_in_progress = 1;
1035 }
959 - if (!stat(git_path("BISECT_LOG"), &st))
1036 + if (!stat(git_path("BISECT_LOG"), &st)) {
1037 state.bisect_in_progress = 1;
1038 + read_and_strip_branch(&branch, &state.branch,
1039 + "BISECT_START");
1040 + }
1041
1042 if (state.merge_in_progress)
1043 show_merge_in_progress(s, &state, state_color);
@@ -969,6 +1049,8 @@ static void wt_status_print_state(struct wt_status *s)
1049 show_cherry_pick_in_progress(s, &state, state_color);
1050 if (state.bisect_in_progress)
1051 show_bisect_in_progress(s, &state, state_color);
1052 + strbuf_release(&branch);
1053 + strbuf_release(&onto);
1054 }
1055
1056 void wt_status_print(struct wt_status *s)
wt-status.h
+2
@@ -79,6 +79,8 @@ struct wt_status_state {
79 int rebase_interactive_in_progress;
80 int cherry_pick_in_progress;
81 int bisect_in_progress;
82 + const char *branch;
83 + const char *onto;
84 };
85
86 void wt_status_prepare(struct wt_status *s);