path: root/builtin
diff options
authorJonathan Nieder <>2011-12-10 12:49:25 (GMT)
committerJunio C Hamano <>2011-12-12 21:31:32 (GMT)
commit093a309136c38eca0ea2dd5da3c68b483443d113 (patch)
tree30b2b0d8aff3c55b0d4aa2860d3e9a0b0ca5c6d3 /builtin
parent1df9bf46d656970d0db254cb7faab0d0505802e0 (diff)
revert: allow cherry-pick --continue to commit before resuming
When "git cherry-pick" encounters conflicts, permit the operator to use cherry-pick --continue after resolving them as a shortcut for "git commit && git cherry-pick --continue" to record the resolution and carry on with the rest of the sequence. This improves the analogy with "git rebase" (in olden days --continue was the way to preserve authorship when a rebase encountered conflicts) and fits well with a general UI goal of making "git cmd --continue" save humans the trouble of deciding what to do next. Example: after encountering a conflict from running "git cherry-pick foo bar baz": CONFLICT (content): Merge conflict in main.c error: could not apply f78a8d98c... bar! hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: and commit the result with 'git commit' We edit main.c to resolve the conflict, mark it acceptable with "git add main.c", and can run "cherry-pick --continue" to resume the sequence. $ git cherry-pick --continue [editor opens to confirm commit message] [master 78c8a8c98] bar! 1 files changed, 1 insertions(+), 1 deletions(-) [master 87ca8798c] baz! 1 files changed, 1 insertions(+), 1 deletions(-) This is done for both codepaths to pick multiple commits and a single commit. Signed-off-by: Jonathan Nieder <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'builtin')
1 files changed, 20 insertions, 3 deletions
diff --git a/builtin/revert.c b/builtin/revert.c
index 9f6c85c..a43b4d8 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -1038,18 +1038,35 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
return 0;
+static int continue_single_pick(void)
+ const char *argv[] = { "commit", NULL };
+ if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
+ !file_exists(git_path("REVERT_HEAD")))
+ return error(_("no cherry-pick or revert in progress"));
+ return run_command_v_opt(argv, RUN_GIT_CMD);
static int sequencer_continue(struct replay_opts *opts)
struct commit_list *todo_list = NULL;
if (!file_exists(git_path(SEQ_TODO_FILE)))
- return error(_("No %s in progress"), action_name(opts));
+ return continue_single_pick();
read_populate_todo(&todo_list, opts);
/* Verify that the conflict has been resolved */
- if (!index_differs_from("HEAD", 0))
- todo_list = todo_list->next;
+ if (file_exists(git_path("CHERRY_PICK_HEAD")) ||
+ file_exists(git_path("REVERT_HEAD"))) {
+ int ret = continue_single_pick();
+ if (ret)
+ return ret;
+ }
+ if (index_differs_from("HEAD", 0))
+ return error_dirty_index(opts);
+ todo_list = todo_list->next;
return pick_commits(todo_list, opts);