Skip to content

Commit d12e6b2

Browse files
phil-blaingitster
authored andcommitted
wt-status: suggest 'git rebase --continue' to conclude 'merge' instruction
Since 982288e (status: rebase and merge can be in progress at the same time, 2018-11-12), when a merge is in progress as part of a 'git rebase -r' operation, 'wt_longstatus_print_state' shows information about the in-progress rebase (via show_rebase_information), and then calls 'show_merge_in_progress' to help the user conclude the merge. This function suggests using 'git commit' to do so, but this throws away the authorship information from the original merge, which is not ideal. Using 'git rebase --continue' instead preserves the authorship information, since we enter 'sequencer.c:run_git_commit' which calls read_env_script to read the author-script file. Note however that this only works when a merge was scheduled using a 'merge' instruction in the rebase todo list. Indeed, when using 'exec git merge', the state files necessary for 'git rebase --continue' are not present, and one must use 'git commit' (or 'git merge --continue') in that case. Be more helpful to the user by suggesting either 'git rebase --continue', when the merge was scheduled using a 'merge' instruction, and 'git commit' otherwise. As such, add a 'merge_during_rebase_in_progress' field to 'struct wt_status_state', and detect this situation in wt_status_check_rebase by looking at the last command done. Adjust wt_longstatus_print_state to check this field and suggest 'git rebase --continue' if a merge came from a 'merge' instruction, by calling show_rebase_in_progress directly. Add two tests for the new behaviour, using 'merge' and 'exec git merge' instructions. Signed-off-by: Philippe Blain <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4df4aed commit d12e6b2

File tree

3 files changed

+90
-4
lines changed

3 files changed

+90
-4
lines changed

t/t7512-status-help.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,81 @@ EOF
183183
test_cmp expected actual
184184
'
185185

186+
test_expect_success 'status during rebase -ir after conflicted merge (exec git merge)' '
187+
git reset --hard main &&
188+
git checkout -b rebase_i_merge &&
189+
test_commit unrelated &&
190+
git checkout -b rebase_i_merge_side &&
191+
test_commit side2 main.txt &&
192+
git checkout rebase_i_merge &&
193+
test_commit side1 main.txt &&
194+
PICK=$(git rev-parse --short rebase_i_merge) &&
195+
test_must_fail git merge rebase_i_merge_side &&
196+
echo side1 >main.txt &&
197+
git add main.txt &&
198+
test_tick &&
199+
git commit --no-edit &&
200+
MERGE=$(git rev-parse --short rebase_i_merge) &&
201+
ONTO=$(git rev-parse --short main) &&
202+
test_when_finished "git rebase --abort" &&
203+
FAKE_LINES="1 2 3 5 6 7 8 9 10 exec_git_merge_refs/rewritten/rebase-i-merge-side" &&
204+
export FAKE_LINES &&
205+
test_must_fail git rebase -ir main &&
206+
cat >expect <<EOF &&
207+
interactive rebase in progress; onto $ONTO
208+
Last commands done (8 commands done):
209+
pick $PICK side1
210+
exec git merge refs/rewritten/rebase-i-merge-side
211+
(see more in file .git/rebase-merge/done)
212+
No commands remaining.
213+
214+
You have unmerged paths.
215+
(fix conflicts and run "git commit")
216+
(use "git merge --abort" to abort the merge)
217+
218+
Unmerged paths:
219+
(use "git add <file>..." to mark resolution)
220+
both modified: main.txt
221+
222+
no changes added to commit (use "git add" and/or "git commit -a")
223+
EOF
224+
git status --untracked-files=no >actual &&
225+
test_cmp expect actual
226+
'
227+
228+
test_expect_success 'status during rebase -ir after replaying conflicted merge (merge)' '
229+
PICK=$(git rev-parse --short :/side1) &&
230+
UNRELATED=$(git rev-parse --short :/unrelated) &&
231+
MERGE=$(git rev-parse --short rebase_i_merge) &&
232+
ONTO=$(git rev-parse --short main) &&
233+
test_when_finished "git rebase --abort" &&
234+
FAKE_LINES="1 2 3 5 6 7 8 9 10 11 4" &&
235+
export FAKE_LINES &&
236+
test_must_fail git rebase -ir main &&
237+
cat >expect <<EOF &&
238+
interactive rebase in progress; onto $ONTO
239+
Last commands done (8 commands done):
240+
pick $PICK side1
241+
merge -C $MERGE rebase-i-merge-side # Merge branch '\''rebase_i_merge_side'\'' into rebase_i_merge
242+
(see more in file .git/rebase-merge/done)
243+
Next command to do (1 remaining command):
244+
pick $UNRELATED unrelated
245+
(use "git rebase --edit-todo" to view and edit)
246+
You are currently rebasing branch '\''rebase_i_merge'\'' on '\''$ONTO'\''.
247+
(fix conflicts and then run "git rebase --continue")
248+
(use "git rebase --skip" to skip this patch)
249+
(use "git rebase --abort" to check out the original branch)
250+
251+
Unmerged paths:
252+
(use "git add <file>..." to mark resolution)
253+
both modified: main.txt
254+
255+
no changes added to commit (use "git add" and/or "git commit -a")
256+
EOF
257+
git status --untracked-files=no >actual &&
258+
test_cmp expect actual
259+
'
260+
186261

187262
test_expect_success 'status when rebasing -i in edit mode' '
188263
git reset --hard main &&

wt-status.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,7 @@ int wt_status_check_rebase(const struct worktree *wt,
17441744
struct wt_status_state *state)
17451745
{
17461746
struct stat st;
1747+
struct string_list have_done = STRING_LIST_INIT_DUP;
17471748

17481749
if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
17491750
if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
@@ -1760,8 +1761,12 @@ int wt_status_check_rebase(const struct worktree *wt,
17601761
state->rebase_interactive_in_progress = 1;
17611762
else
17621763
state->rebase_in_progress = 1;
1764+
read_rebase_todolist("rebase-merge/done", &have_done);
1765+
if (have_done.nr > 0 && starts_with(have_done.items[have_done.nr - 1].string, "merge"))
1766+
state->merge_during_rebase_in_progress = 1;
17631767
state->branch = get_branch(wt, "rebase-merge/head-name");
17641768
state->onto = get_branch(wt, "rebase-merge/onto");
1769+
string_list_clear(&have_done, 0);
17651770
} else
17661771
return 0;
17671772
return 1;
@@ -1855,10 +1860,15 @@ static void wt_longstatus_print_state(struct wt_status *s)
18551860

18561861
if (state->merge_in_progress) {
18571862
if (state->rebase_interactive_in_progress) {
1858-
show_rebase_information(s, state_color);
1859-
fputs("\n", s->fp);
1860-
}
1861-
show_merge_in_progress(s, state_color);
1863+
if (state->merge_during_rebase_in_progress)
1864+
show_rebase_in_progress(s, state_color);
1865+
else {
1866+
show_rebase_information(s, state_color);
1867+
fputs("\n", s->fp);
1868+
show_merge_in_progress(s, state_color);
1869+
}
1870+
} else
1871+
show_merge_in_progress(s, state_color);
18621872
} else if (state->am_in_progress)
18631873
show_am_in_progress(s, state_color);
18641874
else if (state->rebase_in_progress || state->rebase_interactive_in_progress)

wt-status.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct wt_status_state {
8787
int am_empty_patch;
8888
int rebase_in_progress;
8989
int rebase_interactive_in_progress;
90+
int merge_during_rebase_in_progress;
9091
int cherry_pick_in_progress;
9192
int bisect_in_progress;
9293
int revert_in_progress;

0 commit comments

Comments
 (0)