Skip to content

Commit b9475f5

Browse files
committed
cherry-pick: refuse cherry-pick sequence if index is dirty
Cherry-pick, like merge or rebase, refuses to run when there are changes in the index. However, if a cherry-pick sequence is requested, this refusal happens "too late": when the cherry-pick sequence has already started, and an "--abort" or "--quit" is needed to resume normal operation. Normally, when an operation is "in-progress" and you want to go back to where you were before, "--abort" is the right thing to run. If you run "git cherry-pick --abort" in this specific situation, however, your staged changes are destroyed as part of the abort! Generally speaking, the abort process assumes any changes in the index are part of the operation to be aborted. Add an earlier check in the cherry-pick sequence process to ensure that the index is clean, reusing the already-generalized method used for rebase. Also add a test. Signed-off-by: Tao Klerks <[email protected]>
1 parent 4a714b3 commit b9475f5

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed

builtin/revert.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
224224
return sequencer_rollback(the_repository, opts);
225225
if (cmd == 's')
226226
return sequencer_skip(the_repository, opts);
227-
return sequencer_pick_revisions(the_repository, opts);
227+
return sequencer_pick_revisions(the_repository, opts, me);
228228
}
229229

230230
int cmd_revert(int argc, const char **argv, const char *prefix)

sequencer.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5169,7 +5169,8 @@ static int single_pick(struct repository *r,
51695169
}
51705170

51715171
int sequencer_pick_revisions(struct repository *r,
5172-
struct replay_opts *opts)
5172+
struct replay_opts *opts,
5173+
char *me)
51735174
{
51745175
struct todo_list todo_list = TODO_LIST_INIT;
51755176
struct object_id oid;
@@ -5223,10 +5224,13 @@ int sequencer_pick_revisions(struct repository *r,
52235224

52245225
/*
52255226
* Start a new cherry-pick/ revert sequence; but
5226-
* first, make sure that an existing one isn't in
5227-
* progress
5227+
* first, make sure that the index is clean and that
5228+
* an existing one isn't in progress.
52285229
*/
52295230

5231+
if (require_clean_work_tree(the_repository, me,
5232+
_("Please commit or stash them."), 1, 1))
5233+
return -1;
52305234
if (walk_revs_populate_todo(&todo_list, opts) ||
52315235
create_seq_dir(r) < 0)
52325236
return -1;

sequencer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ void todo_list_filter_update_refs(struct repository *r,
159159
/* Call this to setup defaults before parsing command line options */
160160
void sequencer_init_config(struct replay_opts *opts);
161161
int sequencer_pick_revisions(struct repository *repo,
162-
struct replay_opts *opts);
162+
struct replay_opts *opts,
163+
char *me);
163164
int sequencer_continue(struct repository *repo, struct replay_opts *opts);
164165
int sequencer_rollback(struct repository *repo, struct replay_opts *opts);
165166
int sequencer_skip(struct repository *repo, struct replay_opts *opts);

t/t3510-cherry-pick-sequence.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ test_expect_success 'cherry-pick persists data on failure' '
4747
test_path_is_file .git/sequencer/opts
4848
'
4949

50+
test_expect_success 'cherry-pick sequence refuses to run on dirty index' '
51+
pristine_detach initial &&
52+
touch localindexchange &&
53+
git add localindexchange &&
54+
echo picking &&
55+
test_must_fail git cherry-pick initial..picked &&
56+
test_path_is_missing .git/sequencer &&
57+
test_must_fail git cherry-pick --abort
58+
'
59+
5060
test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
5161
pristine_detach initial &&
5262
test_must_fail git cherry-pick base..anotherpick &&

0 commit comments

Comments
 (0)