Skip to content

Commit 0afb943

Browse files
committed
Merge branch 'pb/status-rebase-fixes' into jch
A few fixes around "git status" while "git rebase" is running, plus a corner case bug fix for "git rebase -r". * pb/status-rebase-fixes: wt-status: suggest 'git rebase --continue' to conclude 'merge' instruction wt-status: also abbreviate 'merge' and 'fixup -C' lines during rebase SQUASH??? - <CAPig+cS92W_gYuNsaTvQxiP3xBK7Wpg0__uVkgAU1x0OFJUZgQ@mail.gmail.com> rebase -r: do create merge commit after empty resolution
2 parents 0e115e4 + d12e6b2 commit 0afb943

File tree

5 files changed

+138
-14
lines changed

5 files changed

+138
-14
lines changed

sequencer.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -4333,6 +4333,7 @@ static int do_merge(struct repository *r,
43334333
error(_("could not even attempt to merge '%.*s'"),
43344334
merge_arg_len, arg);
43354335
unlink(git_path_merge_msg(r));
4336+
unlink(git_path_merge_head(r));
43364337
goto leave_merge;
43374338
}
43384339
/*
@@ -5348,7 +5349,7 @@ static int commit_staged_changes(struct repository *r,
53485349
flags |= AMEND_MSG;
53495350
}
53505351

5351-
if (is_clean) {
5352+
if (is_clean && !file_exists(git_path_merge_head(r))) {
53525353
if (refs_ref_exists(get_main_ref_store(r),
53535354
"CHERRY_PICK_HEAD") &&
53545355
refs_delete_ref(get_main_ref_store(r), "",

t/t3418-rebase-continue.sh

+24
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,30 @@ test_expect_success 'rebase -r passes merge strategy options correctly' '
111111
git rebase --continue
112112
'
113113

114+
test_expect_success '--continue creates merge commit after empty resolution' '
115+
git reset --hard main &&
116+
git checkout -b rebase_i_merge &&
117+
test_commit unrelated &&
118+
git checkout -b rebase_i_merge_side &&
119+
test_commit side2 main.txt &&
120+
git checkout rebase_i_merge &&
121+
test_commit side1 main.txt &&
122+
PICK=$(git rev-parse --short rebase_i_merge) &&
123+
test_must_fail git merge rebase_i_merge_side &&
124+
echo side1 >main.txt &&
125+
git add main.txt &&
126+
test_tick &&
127+
git commit --no-edit &&
128+
129+
test_must_fail env FAKE_LINES="1 2 3 5 6 7 8 9 10 11" \
130+
git rebase -ir main &&
131+
echo side1 >main.txt &&
132+
git add main.txt &&
133+
git rebase --continue &&
134+
git log --merges >out &&
135+
test_grep "Merge branch .rebase_i_merge_side." out
136+
'
137+
114138
test_expect_success '--skip after failed fixup cleans commit message' '
115139
test_when_finished "test_might_fail git rebase --abort" &&
116140
git checkout -b with-conflicting-fixup &&

t/t7512-status-help.sh

+75
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

+36-13
Original file line numberDiff line numberDiff line change
@@ -1342,9 +1342,11 @@ static int split_commit_in_progress(struct wt_status *s)
13421342

13431343
/*
13441344
* Turn
1345-
* "pick d6a2f0303e897ec257dd0e0a39a5ccb709bc2047 some message"
1345+
* "pick d6a2f0303e897ec257dd0e0a39a5ccb709bc2047 some message" and
1346+
* "merge -C d6a2f0303e897ec257dd0e0a39a5ccb709bc2047 some-branch"
13461347
* into
1347-
* "pick d6a2f03 some message"
1348+
* "pick d6a2f03 some message" and
1349+
* "merge -C d6a2f03 some-branch"
13481350
*
13491351
* The function assumes that the line does not contain useless spaces
13501352
* before or after the command.
@@ -1360,20 +1362,31 @@ static void abbrev_oid_in_line(struct strbuf *line)
13601362
starts_with(line->buf, "l "))
13611363
return;
13621364

1363-
split = strbuf_split_max(line, ' ', 3);
1365+
split = strbuf_split_max(line, ' ', 4);
13641366
if (split[0] && split[1]) {
13651367
struct object_id oid;
1366-
1368+
struct strbuf *hash;
1369+
1370+
if ((!strcmp(split[0]->buf, "merge ") ||
1371+
!strcmp(split[0]->buf, "m " ) ||
1372+
!strcmp(split[0]->buf, "fixup ") ||
1373+
!strcmp(split[0]->buf, "f " )) &&
1374+
(!strcmp(split[1]->buf, "-C ") ||
1375+
!strcmp(split[1]->buf, "-c "))) {
1376+
hash = split[2];
1377+
} else {
1378+
hash = split[1];
1379+
}
13671380
/*
13681381
* strbuf_split_max left a space. Trim it and re-add
13691382
* it after abbreviation.
13701383
*/
1371-
strbuf_trim(split[1]);
1372-
if (!repo_get_oid(the_repository, split[1]->buf, &oid)) {
1373-
strbuf_reset(split[1]);
1374-
strbuf_add_unique_abbrev(split[1], &oid,
1384+
strbuf_trim(hash);
1385+
if (!repo_get_oid(the_repository, hash->buf, &oid)) {
1386+
strbuf_reset(hash);
1387+
strbuf_add_unique_abbrev(hash, &oid,
13751388
DEFAULT_ABBREV);
1376-
strbuf_addch(split[1], ' ');
1389+
strbuf_addch(hash, ' ');
13771390
strbuf_reset(line);
13781391
for (i = 0; split[i]; i++)
13791392
strbuf_addbuf(line, split[i]);
@@ -1731,6 +1744,7 @@ int wt_status_check_rebase(const struct worktree *wt,
17311744
struct wt_status_state *state)
17321745
{
17331746
struct stat st;
1747+
struct string_list have_done = STRING_LIST_INIT_DUP;
17341748

17351749
if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
17361750
if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
@@ -1747,8 +1761,12 @@ int wt_status_check_rebase(const struct worktree *wt,
17471761
state->rebase_interactive_in_progress = 1;
17481762
else
17491763
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;
17501767
state->branch = get_branch(wt, "rebase-merge/head-name");
17511768
state->onto = get_branch(wt, "rebase-merge/onto");
1769+
string_list_clear(&have_done, 0);
17521770
} else
17531771
return 0;
17541772
return 1;
@@ -1842,10 +1860,15 @@ static void wt_longstatus_print_state(struct wt_status *s)
18421860

18431861
if (state->merge_in_progress) {
18441862
if (state->rebase_interactive_in_progress) {
1845-
show_rebase_information(s, state_color);
1846-
fputs("\n", s->fp);
1847-
}
1848-
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);
18491872
} else if (state->am_in_progress)
18501873
show_am_in_progress(s, state_color);
18511874
else if (state->rebase_in_progress || state->rebase_interactive_in_progress)

wt-status.h

+1
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)