Skip to content

Commit 4a72486

Browse files
phillipwoodgitster
authored andcommitted
fix cherry-pick/revert status after commit
If the user commits a conflict resolution using `git commit` in the middle of a sequence of cherry-picks/reverts then `git status` missed the fact that a cherry-pick/revert is still in progress. Signed-off-by: Phillip Wood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b07d9bf commit 4a72486

File tree

4 files changed

+107
-5
lines changed

4 files changed

+107
-5
lines changed

sequencer.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,41 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
21422142
return !item->commit;
21432143
}
21442144

2145+
int sequencer_get_last_command(struct repository *r, enum replay_action *action)
2146+
{
2147+
struct todo_item item;
2148+
char *eol;
2149+
const char *todo_file;
2150+
struct strbuf buf = STRBUF_INIT;
2151+
int ret = -1;
2152+
2153+
todo_file = git_path_todo_file();
2154+
if (strbuf_read_file(&buf, todo_file, 0) < 0) {
2155+
if (errno == ENOENT)
2156+
return -1;
2157+
else
2158+
return error_errno("unable to open '%s'", todo_file);
2159+
}
2160+
eol = strchrnul(buf.buf, '\n');
2161+
if (buf.buf != eol && eol[-1] == '\r')
2162+
eol--; /* strip Carriage Return */
2163+
if (parse_insn_line(r, &item, buf.buf, eol))
2164+
goto fail;
2165+
if (item.command == TODO_PICK)
2166+
*action = REPLAY_PICK;
2167+
else if (item.command == TODO_REVERT)
2168+
*action = REPLAY_REVERT;
2169+
else
2170+
goto fail;
2171+
2172+
ret = 0;
2173+
2174+
fail:
2175+
strbuf_release(&buf);
2176+
2177+
return ret;
2178+
}
2179+
21452180
static int parse_insn_buffer(struct repository *r, char *buf,
21462181
struct todo_list *todo_list)
21472182
{

sequencer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,5 @@ void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
145145
int write_basic_state(struct replay_opts *opts, const char *head_name,
146146
const char *onto, const char *orig_head);
147147
void sequencer_post_commit_cleanup(struct repository *r);
148+
int sequencer_get_last_command(struct repository* r,
149+
enum replay_action *action);

t/t7512-status-help.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,24 @@ EOF
780780
test_i18ncmp expected actual
781781
'
782782

783+
test_expect_success 'status when cherry-picking after committing conflict resolution' '
784+
git reset --hard cherry_branch &&
785+
test_when_finished "git cherry-pick --abort" &&
786+
test_must_fail git cherry-pick cherry_branch_second one_cherry &&
787+
echo end >main.txt &&
788+
git commit -a &&
789+
cat >expected <<EOF &&
790+
On branch cherry_branch
791+
Cherry-pick currently in progress.
792+
(run "git cherry-pick --continue" to continue)
793+
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
794+
795+
nothing to commit (use -u to show untracked files)
796+
EOF
797+
git status --untracked-files=no >actual &&
798+
test_i18ncmp expected actual
799+
'
800+
783801
test_expect_success 'status showing detached at and from a tag' '
784802
test_commit atag tagging &&
785803
git checkout atag &&
@@ -857,6 +875,24 @@ EOF
857875
test_i18ncmp expected actual
858876
'
859877

878+
test_expect_success 'status while reverting after committing conflict resolution' '
879+
test_when_finished "git revert --abort" &&
880+
git reset --hard new &&
881+
test_must_fail git revert old new &&
882+
echo reverted >to-revert.txt &&
883+
git commit -a &&
884+
cat >expected <<EOF &&
885+
On branch master
886+
Revert currently in progress.
887+
(run "git revert --continue" to continue)
888+
(use "git revert --abort" to cancel the revert operation)
889+
890+
nothing to commit (use -u to show untracked files)
891+
EOF
892+
git status --untracked-files=no >actual &&
893+
test_i18ncmp expected actual
894+
'
895+
860896
test_expect_success 'prepare for different number of commits rebased' '
861897
git reset --hard master &&
862898
git checkout -b several_commits &&

wt-status.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "utf8.h"
1818
#include "worktree.h"
1919
#include "lockfile.h"
20+
#include "sequencer.h"
2021

2122
static const char cut_line[] =
2223
"------------------------ >8 ------------------------\n";
@@ -1369,12 +1370,22 @@ static void show_rebase_in_progress(struct wt_status *s,
13691370
static void show_cherry_pick_in_progress(struct wt_status *s,
13701371
const char *color)
13711372
{
1372-
status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
1373-
find_unique_abbrev(&s->state.cherry_pick_head_oid, DEFAULT_ABBREV));
1373+
if (is_null_oid(&s->state.cherry_pick_head_oid))
1374+
status_printf_ln(s, color,
1375+
_("Cherry-pick currently in progress."));
1376+
else
1377+
status_printf_ln(s, color,
1378+
_("You are currently cherry-picking commit %s."),
1379+
find_unique_abbrev(&s->state.cherry_pick_head_oid,
1380+
DEFAULT_ABBREV));
1381+
13741382
if (s->hints) {
13751383
if (has_unmerged(s))
13761384
status_printf_ln(s, color,
13771385
_(" (fix conflicts and run \"git cherry-pick --continue\")"));
1386+
else if (is_null_oid(&s->state.cherry_pick_head_oid))
1387+
status_printf_ln(s, color,
1388+
_(" (run \"git cherry-pick --continue\" to continue)"));
13781389
else
13791390
status_printf_ln(s, color,
13801391
_(" (all conflicts fixed: run \"git cherry-pick --continue\")"));
@@ -1387,12 +1398,21 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
13871398
static void show_revert_in_progress(struct wt_status *s,
13881399
const char *color)
13891400
{
1390-
status_printf_ln(s, color, _("You are currently reverting commit %s."),
1391-
find_unique_abbrev(&s->state.revert_head_oid, DEFAULT_ABBREV));
1401+
if (is_null_oid(&s->state.revert_head_oid))
1402+
status_printf_ln(s, color,
1403+
_("Revert currently in progress."));
1404+
else
1405+
status_printf_ln(s, color,
1406+
_("You are currently reverting commit %s."),
1407+
find_unique_abbrev(&s->state.revert_head_oid,
1408+
DEFAULT_ABBREV));
13921409
if (s->hints) {
13931410
if (has_unmerged(s))
13941411
status_printf_ln(s, color,
13951412
_(" (fix conflicts and run \"git revert --continue\")"));
1413+
else if (is_null_oid(&s->state.revert_head_oid))
1414+
status_printf_ln(s, color,
1415+
_(" (run \"git revert --continue\" to continue)"));
13961416
else
13971417
status_printf_ln(s, color,
13981418
_(" (all conflicts fixed: run \"git revert --continue\")"));
@@ -1563,6 +1583,7 @@ void wt_status_get_state(struct repository *r,
15631583
{
15641584
struct stat st;
15651585
struct object_id oid;
1586+
enum replay_action action;
15661587

15671588
if (!stat(git_path_merge_head(r), &st)) {
15681589
wt_status_check_rebase(NULL, state);
@@ -1580,7 +1601,15 @@ void wt_status_get_state(struct repository *r,
15801601
state->revert_in_progress = 1;
15811602
oidcpy(&state->revert_head_oid, &oid);
15821603
}
1583-
1604+
if (!sequencer_get_last_command(r, &action)) {
1605+
if (action == REPLAY_PICK) {
1606+
state->cherry_pick_in_progress = 1;
1607+
oidcpy(&state->cherry_pick_head_oid, &null_oid);
1608+
} else {
1609+
state->revert_in_progress = 1;
1610+
oidcpy(&state->revert_head_oid, &null_oid);
1611+
}
1612+
}
15841613
if (get_detached_from)
15851614
wt_status_get_detached_from(r, state);
15861615
}

0 commit comments

Comments
 (0)