[PATCH 1/1] revert/cherry-pick: add --show-current-patch option
From: Michael Lohmann <hidden>
Date: 2023-12-18 12:10:58
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
This aligns the interface to the rebase one and allows for an easier way of figuring out how to resolve conflicts if commits fail to apply (especially when reverting/cherry-picking multiple commits at the same time) Signed-off-by: Michael Lohmann <redacted> --- Documentation/git-cherry-pick.txt | 2 +- Documentation/git-revert.txt | 2 +- Documentation/sequencer.txt | 5 +++++ builtin/rebase.c | 7 ++---- builtin/revert.c | 9 ++++++-- contrib/completion/git-completion.bash | 2 +- sequencer.c | 24 +++++++++++++++++++++ sequencer.h | 2 ++ t/t3507-cherry-pick-conflict.sh | 30 ++++++++++++++++++++++++++ 9 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index fdcad3d200..af41903fe7 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt@@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git cherry-pick' [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] [-S[<keyid>]] <commit>... -'git cherry-pick' (--continue | --skip | --abort | --quit) +'git cherry-pick' (--continue | --skip | --abort | --quit | --show-current-patch) DESCRIPTION -----------
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index cbe0208834..5bd2ecf35a 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt@@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git revert' [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] <commit>... -'git revert' (--continue | --skip | --abort | --quit) +'git revert' (--continue | --skip | --abort | --quit | --show-current-patch) DESCRIPTION -----------
diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt
index 3bceb56474..e9394761bc 100644
--- a/Documentation/sequencer.txt
+++ b/Documentation/sequencer.txt@@ -12,5 +12,10 @@ to clear the sequencer state after a failed cherry-pick or revert. +--show-current-patch:: + Show the current patch when a revert or cherry-pick is + stopped because of conflicts. This is the equivalent of + `git show REVERT_HEAD` or `git show CHERRY_PICK_HEAD`. + --abort:: Cancel the operation and return to the pre-sequence state.
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 9f8192e0a5..8ad3cf3e90 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c@@ -360,12 +360,9 @@ static int run_sequencer_rebase(struct rebase_options *opts) ret = edit_todo_file(flags); break; case ACTION_SHOW_CURRENT_PATCH: { - struct child_process cmd = CHILD_PROCESS_INIT; - - cmd.git_cmd = 1; - strvec_pushl(&cmd.args, "show", "REBASE_HEAD", "--", NULL); - ret = run_command(&cmd); + struct replay_opts replay_opts = get_replay_opts(opts); + ret = sequencer_show_current_patch(the_repository, &replay_opts); break; } default:
diff --git a/builtin/revert.c b/builtin/revert.c
index e6f9a1ad26..cbcd9fdc23 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c@@ -24,14 +24,14 @@ static const char * const revert_usage[] = { N_("git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] <commit>..."), - N_("git revert (--continue | --skip | --abort | --quit)"), + N_("git revert (--continue | --skip | --abort | --quit | --show-current-patch)"), NULL }; static const char * const cherry_pick_usage[] = { N_("git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n" " [-S[<keyid>]] <commit>..."), - N_("git cherry-pick (--continue | --skip | --abort | --quit)"), + N_("git cherry-pick (--continue | --skip | --abort | --quit | --show-current-patch)"), NULL };
@@ -93,6 +93,7 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'), OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'), OPT_CMDMODE(0, "skip", &cmd, N_("skip current commit and continue"), 's'), + OPT_CMDMODE(0, "show-current-patch", &cmd, N_("show the patch file being reverted or cherry-picked"), 'p'), OPT_CLEANUP(&cleanup_arg), OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")),
@@ -154,6 +155,8 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, this_operation = "--continue"; else if (cmd == 's') this_operation = "--skip"; + else if (cmd == 'p') + this_operation = "--show-current-patch"; else { assert(cmd == 'a'); this_operation = "--abort";
@@ -224,6 +227,8 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, return sequencer_rollback(the_repository, opts); if (cmd == 's') return sequencer_skip(the_repository, opts); + if (cmd == 'p') + return sequencer_show_current_patch(the_repository, opts); return sequencer_pick_revisions(the_repository, opts); }
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 13a39ebd2e..b740b7d48c 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash@@ -1618,7 +1618,7 @@ _git_checkout () esac } -__git_sequencer_inprogress_options="--continue --quit --abort --skip" +__git_sequencer_inprogress_options="--continue --quit --abort --skip --show-current-patch" __git_cherry_pick_inprogress_options=$__git_sequencer_inprogress_options
diff --git a/sequencer.c b/sequencer.c
index d584cac8ed..3f6f9ad75c 100644
--- a/sequencer.c
+++ b/sequencer.c@@ -3417,6 +3417,30 @@ int sequencer_skip(struct repository *r, struct replay_opts *opts) return -1; } +int sequencer_show_current_patch(struct repository *r, struct replay_opts *opts) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + cmd.git_cmd = 1; + switch (opts->action) { + case REPLAY_REVERT: + if (!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) + die(_("No revert in progress?")); + strvec_pushl(&cmd.args, "show", "REVERT_HEAD", "--", NULL); + break; + case REPLAY_PICK: + if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD")) + die(_("No cherry-pick in progress?")); + strvec_pushl(&cmd.args, "show", "CHERRY_PICK_HEAD", "--", NULL); + break; + case REPLAY_INTERACTIVE_REBASE: + if (!refs_ref_exists(get_main_ref_store(r), "REBASE_HEAD")) + die(_("No rebase in progress?")); + strvec_pushl(&cmd.args, "show", "REBASE_HEAD", "--", NULL); + break; + } + return run_command(&cmd); +} + static int save_todo(struct todo_list *todo_list, struct replay_opts *opts, int reschedule) {
diff --git a/sequencer.h b/sequencer.h
index 913a0f652d..e20cb8bc56 100644
--- a/sequencer.h
+++ b/sequencer.h@@ -162,6 +162,8 @@ int sequencer_pick_revisions(struct repository *repo, struct replay_opts *opts); int sequencer_continue(struct repository *repo, struct replay_opts *opts); int sequencer_rollback(struct repository *repo, struct replay_opts *opts); +int sequencer_show_current_patch(struct repository *repo, + struct replay_opts *opts); int sequencer_skip(struct repository *repo, struct replay_opts *opts); void replay_opts_release(struct replay_opts *opts); int sequencer_remove_state(struct replay_opts *opts);
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index c88d597b12..4f50d287a6 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh@@ -566,6 +566,36 @@ test_expect_success 'cherry-pick preserves sparse-checkout' ' test_grep ! "Changes not staged for commit:" actual ' +test_expect_success 'cherry-pick --show-current-patch fails if no cherry-pick in progress' ' + pristine_detach initial && + test_must_fail git cherry-pick --show-current-patch +' + +test_expect_success 'cherry-pick --show-current-patch describes patch that failed to apply' ' + test_when_finished "git cherry-pick --abort || :" && + pristine_detach initial && + git show picked >expected && + + test_must_fail git cherry-pick picked && + + git cherry-pick --show-current-patch >actual && + test_cmp expected actual +' + +test_expect_success 'revert --show-current-patch fails if no revert in progress' ' + pristine_detach initial && + test_must_fail git revert --show-current-patch +' + +test_expect_success 'revert --show-current-patch describes patch that failed to apply' ' + test_when_finished "git revert --abort || :" && + pristine_detach initial && + git show picked >expected && + test_must_fail git revert picked && + git revert --show-current-patch >actual && + test_cmp expected actual +' + test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' ' test_when_finished "git cherry-pick --abort || :" && pristine_detach initial &&
--
2.43.0.77.gff6ea8bb74