Skip to content

Commit c45f0f5

Browse files
pcloudsgitster
authored andcommitted
switch: reject if some operation is in progress
Unless you know what you're doing, switching to another branch to do something then switching back could be confusing. Worse, you may even forget that you're in the middle of something. By the time you realize, you may have done a ton of work and it gets harder to go back. A new option --ignore-in-progress was considered but dropped because it was not exactly clear what should happen. Sometimes you can switch away and get back safely and resume the operation. Sometimes not. And the git-checkout behavior is automatically clear merge/revert/cherry-pick, which makes it a bit even more confusing [1]. We may revisit and add this option in the future. But for now play it safe and not allow it (you can't even skip this check with --force). The user is suggested to cancel the operation by themselves (and hopefully they do consider the consequences, not blindly type the command), or to create a separate worktree instead of switching. The third option is the good old "git checkout", but it's not mentioned. [1] CACsJy8Axa5WsLSjiscjnxVK6jQHkfs-gH959=YtUvQkWriAk5w@mail.gmail.com Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 65f099b commit c45f0f5

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

builtin/checkout.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "tree.h"
2525
#include "tree-walk.h"
2626
#include "unpack-trees.h"
27+
#include "wt-status.h"
2728
#include "xdiff-interface.h"
2829

2930
static const char * const checkout_usage[] = {
@@ -56,6 +57,7 @@ struct checkout_opts {
5657
int accept_pathspec;
5758
int switch_branch_doing_nothing_is_ok;
5859
int only_merge_on_switching_branches;
60+
int can_switch_when_in_progress;
5961

6062
const char *new_branch;
6163
const char *new_branch_force;
@@ -1202,6 +1204,39 @@ static void die_expecting_a_branch(const struct branch_info *branch_info)
12021204
die(_("a branch is expected, got '%s'"), branch_info->name);
12031205
}
12041206

1207+
static void die_if_some_operation_in_progress(void)
1208+
{
1209+
struct wt_status_state state;
1210+
1211+
memset(&state, 0, sizeof(state));
1212+
wt_status_get_state(the_repository, &state, 0);
1213+
1214+
if (state.merge_in_progress)
1215+
die(_("cannot switch branch while merging\n"
1216+
"Consider \"git merge --quit\" "
1217+
"or \"git worktree add\"."));
1218+
if (state.am_in_progress)
1219+
die(_("cannot switch branch in the middle of an am session\n"
1220+
"Consider \"git am --quit\" "
1221+
"or \"git worktree add\"."));
1222+
if (state.rebase_interactive_in_progress || state.rebase_in_progress)
1223+
die(_("cannot switch branch while rebasing\n"
1224+
"Consider \"git rebase --quit\" "
1225+
"or \"git worktree add\"."));
1226+
if (state.cherry_pick_in_progress)
1227+
die(_("cannot switch branch while cherry-picking\n"
1228+
"Consider \"git cherry-pick --quit\" "
1229+
"or \"git worktree add\"."));
1230+
if (state.revert_in_progress)
1231+
die(_("cannot switch branch while reverting\n"
1232+
"Consider \"git revert --quit\" "
1233+
"or \"git worktree add\"."));
1234+
if (state.bisect_in_progress)
1235+
die(_("cannot switch branch while bisecting\n"
1236+
"Consider \"git bisect reset HEAD\" "
1237+
"or \"git worktree add\"."));
1238+
}
1239+
12051240
static int checkout_branch(struct checkout_opts *opts,
12061241
struct branch_info *new_branch_info)
12071242
{
@@ -1257,6 +1292,9 @@ static int checkout_branch(struct checkout_opts *opts,
12571292
!new_branch_info->path)
12581293
die_expecting_a_branch(new_branch_info);
12591294

1295+
if (!opts->can_switch_when_in_progress)
1296+
die_if_some_operation_in_progress();
1297+
12601298
if (new_branch_info->path && !opts->force_detach && !opts->new_branch &&
12611299
!opts->ignore_other_worktrees) {
12621300
int flag;
@@ -1514,6 +1552,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
15141552
opts.only_merge_on_switching_branches = 0;
15151553
opts.accept_pathspec = 1;
15161554
opts.implicit_detach = 1;
1555+
opts.can_switch_when_in_progress = 1;
15171556

15181557
options = parse_options_dup(checkout_options);
15191558
options = add_common_options(&opts, options);
@@ -1549,6 +1588,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
15491588
opts.switch_branch_doing_nothing_is_ok = 0;
15501589
opts.only_merge_on_switching_branches = 1;
15511590
opts.implicit_detach = 0;
1591+
opts.can_switch_when_in_progress = 0;
15521592

15531593
options = parse_options_dup(switch_options);
15541594
options = add_common_options(&opts, options);

0 commit comments

Comments
 (0)