diff options
| author | Junio C Hamano <gitster@pobox.com> | 2026-04-03 13:01:09 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-04-03 13:01:09 -0700 |
| commit | e0613d24f9902a581b6a1cf0aa39b517db1e3f2f (patch) | |
| tree | 16ed0d60d123a86a07682df15c05037d894639f6 /builtin | |
| parent | 05ddb9ee8a4c619fbb0e7309fe291bff5cd7c987 (diff) | |
| parent | 2760ee49834953c0860fa5d7983a6af4d27cb6a9 (diff) | |
| download | git-e0613d24f9902a581b6a1cf0aa39b517db1e3f2f.tar.xz | |
Merge branch 'sa/replay-revert'
"git replay" (experimental) learns, in addition to "pick" and
"replay", a new operating mode "revert".
* sa/replay-revert:
replay: add --revert mode to reverse commit changes
sequencer: extract revert message formatting into shared function
Diffstat (limited to 'builtin')
| -rw-r--r-- | builtin/replay.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/builtin/replay.c b/builtin/replay.c index 2cdde830a8..a0879b020f 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -79,11 +79,12 @@ int cmd_replay(int argc, struct ref_transaction *transaction = NULL; struct strbuf transaction_err = STRBUF_INIT; struct strbuf reflog_msg = STRBUF_INIT; + int desired_reverse; int ret = 0; const char *const replay_usage[] = { N_("(EXPERIMENTAL!) git replay " - "([--contained] --onto <newbase> | --advance <branch>) " + "([--contained] --onto <newbase> | --advance <branch> | --revert <branch>) " "[--ref-action[=<mode>]] <revision-range>"), NULL }; @@ -96,6 +97,9 @@ int cmd_replay(int argc, N_("replay onto given commit")), OPT_BOOL(0, "contained", &opts.contained, N_("update all branches that point at commits in <revision-range>")), + OPT_STRING(0, "revert", &opts.revert, + N_("branch"), + N_("revert commits onto given branch")), OPT_STRING(0, "ref-action", &ref_action, N_("mode"), N_("control ref update behavior (update|print)")), @@ -105,19 +109,31 @@ int cmd_replay(int argc, argc = parse_options(argc, argv, prefix, replay_options, replay_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); - if (!opts.onto && !opts.advance) { - error(_("option --onto or --advance is mandatory")); + /* Exactly one mode must be specified */ + if (!opts.onto && !opts.advance && !opts.revert) { + error(_("exactly one of --onto, --advance, or --revert is required")); usage_with_options(replay_usage, replay_options); } + die_for_incompatible_opt3(!!opts.onto, "--onto", + !!opts.advance, "--advance", + !!opts.revert, "--revert"); die_for_incompatible_opt2(!!opts.advance, "--advance", opts.contained, "--contained"); - die_for_incompatible_opt2(!!opts.advance, "--advance", - !!opts.onto, "--onto"); + die_for_incompatible_opt2(!!opts.revert, "--revert", + opts.contained, "--contained"); /* Parse ref action mode from command line or config */ ref_mode = get_ref_action_mode(repo, ref_action); + /* + * Cherry-pick/rebase need oldest-first ordering so that each + * replayed commit can build on its already-replayed parent. + * Revert needs newest-first ordering (like git revert) to + * reduce conflicts by peeling off changes from the top. + */ + desired_reverse = !opts.revert; + repo_init_revisions(repo, &revs, prefix); /* @@ -129,7 +145,7 @@ int cmd_replay(int argc, * some options changing these values if we think they could * be useful. */ - revs.reverse = 1; + revs.reverse = desired_reverse; revs.sort_order = REV_SORT_IN_GRAPH_ORDER; revs.topo_order = 1; revs.simplify_history = 0; @@ -144,11 +160,11 @@ int cmd_replay(int argc, * Detect and warn if we override some user specified rev * walking options. */ - if (revs.reverse != 1) { + if (revs.reverse != desired_reverse) { warning(_("some rev walking options will be overridden as " "'%s' bit in 'struct rev_info' will be forced"), "reverse"); - revs.reverse = 1; + revs.reverse = desired_reverse; } if (revs.sort_order != REV_SORT_IN_GRAPH_ORDER) { warning(_("some rev walking options will be overridden as " @@ -174,7 +190,9 @@ int cmd_replay(int argc, goto cleanup; /* Build reflog message */ - if (opts.advance) { + if (opts.revert) { + strbuf_addf(&reflog_msg, "replay --revert %s", opts.revert); + } else if (opts.advance) { strbuf_addf(&reflog_msg, "replay --advance %s", opts.advance); } else { struct object_id oid; |
