From: Toon Claes <toon@iotcl.com>
To: git@vger.kernel.org
Cc: Justin Tobler <jltobler@gmail.com>,
Siddharth Asthana <siddharthasthana31@gmail.com>,
Yee Cheng Chin <yeecheng.chin@gmail.com>,
Toon Claes <toon@iotcl.com>
Subject: [PATCH v3 0/3] Add option --ref to git-replay(1)
Date: Wed, 01 Apr 2026 22:55:09 +0200 [thread overview]
Message-ID: <20260401-toon-replay-arbitrary-ref-v3-0-a0b4fabb34b3@iotcl.com> (raw)
In-Reply-To: <20260325-toon-replay-arbitrary-ref-v2-0-553038702c9c@iotcl.com>
In a previous RFC[1] I suggested to implement subcommands into
git-replay(1). While it would be arguable nice to have subcommands for
the different modes, because git-replay(1) is a plumbing commands, it's
fine to keep a status quo.
This series takes one thing for that RFC though: adding option --ref.
This new option is useful if you want to have full control over which
ref is being updated, and not want to rely on the refs that are using
in the <revision-range> or as the value for --advance and --revert.
These changes answer the needs expressed in[2].
This series is based on Siddharth's series[3] to add '--revert' to
git-replay(1) (sa/replay-revert @ ba5c0d03d3).
[1]: https://lore.kernel.org/git/20260309-toon-replay-subcommands-v1-1-864ec82ef68a@iotcl.com/
[2]: https://lore.kernel.org/git/CAHTeOx-SMLh_idKhGczPKzZNOKy04uYXmUhL8Z79yRuNpmE4eA@mail.gmail.com/
[3]: https://lore.kernel.org/git/20260313054035.26605-1-siddharthasthana31@gmail.com/
---
Changes in v3:
- In the docs, clarify --ref requires a fully qualified ref, not just a
branch name.
- Fix crash by initializing merge_opt to `{ 0 }`.
- Link to v2: https://patch.msgid.link/20260325-toon-replay-arbitrary-ref-v2-0-553038702c9c@iotcl.com
Changes in v2:
- Dropped the test-only consistency patch.
- Separated commit to mark options as not negatable.
- Modified git-replay(1) docs to everywhere use stuck form.
- Added code and test ensure the revision range has a single tip when
both --onto and --ref are given.
- Rephrased some comments and docs.
- Link to v1: https://patch.msgid.link/20260323-toon-replay-arbitrary-ref-v1-0-5c7172f675ec@iotcl.com
---
Toon Claes (3):
builtin/replay: mark options as not negatable
replay: use stuck form in documentation and help message
replay: allow to specify a ref with option --ref
Documentation/git-replay.adoc | 45 +++++++++++++++++++++--------
builtin/replay.c | 38 ++++++++++++++++---------
replay.c | 35 +++++++++++++++++------
replay.h | 7 +++++
t/t3650-replay-basics.sh | 66 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 157 insertions(+), 34 deletions(-)
Range-diff versus v2:
1: 260dff6c82 = 1: dd46a0efd5 builtin/replay: mark options as not negatable
2: eca4dffa18 ! 2: b290493bd0 replay: use stuck form in documentation and help message
@@ Documentation/git-replay.adoc: git-replay - EXPERIMENTAL: Replay commits on a ne
SYNOPSIS
--------
[verse]
--(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch> | --revert <branch>) [--ref-action[=<mode>]] <revision-range>...
+-(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch> | --revert <branch>) [--ref-action[=<mode>]] <revision-range>
+(EXPERIMENTAL!) 'git replay' ([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>)
+ [--ref-action=<mode>] <revision-range>
@@ Documentation/git-replay.adoc: The default mode can be configured via the `repla
<revision-range>::
Range of commits to replay; see "Specifying Ranges" in
-- linkgit:git-rev-parse[1]. In `--advance <branch>` mode, the
-+ linkgit:git-rev-parse[1]. In `--advance=<branch>` mode, the
- range should have a single tip, so that it's clear to which tip the
- advanced <branch> should point. Any commits in the range whose
- changes are already present in the branch the commits are being
+- linkgit:git-rev-parse[1]. In `--advance <branch>` or
+- `--revert <branch>` mode, the range should have a single tip,
++ linkgit:git-rev-parse[1]. In `--advance=<branch>` or
++ `--revert=<branch>` mode, the range should have a single tip,
+ so that it's clear to which tip the advanced or reverted
+ <branch> should point. Any commits in the range whose changes
+ are already present in the branch the commits are being
@@ Documentation/git-replay.adoc: EXAMPLES
To simply rebase `mybranch` onto `target`:
@@ builtin/replay.c: int cmd_replay(int argc,
const char *const replay_usage[] = {
N_("(EXPERIMENTAL!) git replay "
- "([--contained] --onto <newbase> | --advance <branch> | --revert <branch>) "
-- "[--ref-action[=<mode>]] <revision-range>..."),
+- "[--ref-action[=<mode>]] <revision-range>"),
+ "([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>)\n"
+ "[--ref-action=<mode>] <revision-range>"),
NULL
3: 2676c2ae78 ! 3: 44e825d9e6 replay: allow to specify a ref with option --ref
@@ Commit message
using option '--ref', the refs described above are left untouched and
instead the argument of this option is updated instead.
+ Because this introduces code paths in replay.c that jump to `out` before
+ init_basic_merge_options() is called on `merge_opt`, zero-initialize the
+ struct.
+
Signed-off-by: Toon Claes <toon@iotcl.com>
## Documentation/git-replay.adoc ##
@@ Documentation/git-replay.adoc: SYNOPSIS
[verse]
(EXPERIMENTAL!) 'git replay' ([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>)
- [--ref-action=<mode>] <revision-range>
-+ [--ref=<branch>] [--ref-action=<mode>] <revision-range>
++ [--ref=<ref>] [--ref-action=<mode>] <revision-range>
DESCRIPTION
-----------
@@ Documentation/git-replay.adoc: incompatible with `--contained` (which is a modif
Update all branches that point at commits in
<revision-range>. Requires `--onto`.
-+--ref=<branch>::
++--ref=<ref>::
+ Override which reference is updated with the result of the replay.
++ The ref must be fully qualified.
+ When used with `--onto`, the `<revision-range>` should have a
+ single tip and only the specified reference is updated instead of
+ inferring refs from the revision range.
+ When used with `--advance` or `--revert`, the specified reference is
-+ updated instead of the branch given to those options. This option is
-+ incompatible with `--contained`.
++ updated instead of the branch given to those options.
++ This option is incompatible with `--contained`.
+
--ref-action[=<mode>]::
Control how references are updated. The mode can be:
@@ builtin/replay.c: int cmd_replay(int argc,
N_("(EXPERIMENTAL!) git replay "
"([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>)\n"
- "[--ref-action=<mode>] <revision-range>"),
-+ "[--ref=<branch>] [--ref-action=<mode>] <revision-range>"),
++ "[--ref=<ref>] [--ref-action=<mode>] <revision-range>"),
NULL
};
struct option replay_options[] = {
@@ builtin/replay.c: int cmd_replay(int argc,
N_("mode"),
N_("control ref update behavior (update|print)"),
@@ builtin/replay.c: int cmd_replay(int argc,
- die_for_incompatible_opt3(!!opts.onto, "--onto",
- !!opts.advance, "--advance",
- !!opts.revert, "--revert");
+ opts.contained, "--contained");
+ die_for_incompatible_opt2(!!opts.revert, "--revert",
+ opts.contained, "--contained");
+ die_for_incompatible_opt2(!!opts.ref, "--ref",
+ !!opts.contained, "--contained");
- if (opts.contained && !opts.onto)
- die(_("--contained requires --onto"));
+ /* Parse ref action mode from command line or config */
+ ref_mode = get_ref_action_mode(repo, ref_action);
## replay.c ##
@@ replay.c: int replay_revisions(struct rev_info *revs,
+ struct commit *last_commit = NULL;
+ struct commit *commit;
+ struct commit *onto = NULL;
+- struct merge_options merge_opt;
++ struct merge_options merge_opt = { 0 };
+ struct merge_result result = {
+ .clean = 1,
+ };
bool detached_head;
char *advance;
char *revert;
---
base-commit: 2760ee49834953c0860fa5d7983a6af4d27cb6a9
change-id: 20260323-toon-replay-arbitrary-ref-5a81f5f976c7
next prev parent reply other threads:[~2026-04-01 20:55 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 16:09 [PATCH 0/3] Add option --ref to git-replay(1) Toon Claes
2026-03-23 16:09 ` [PATCH 1/3] t3650: use option with value consistenly with equal sign Toon Claes
2026-03-23 19:17 ` Kristoffer Haugsbakk
2026-03-23 20:06 ` Junio C Hamano
2026-03-25 12:43 ` Toon Claes
2026-03-23 16:09 ` [PATCH 2/3] builtin/replay: improve documentation on options Toon Claes
2026-03-23 16:09 ` [PATCH 3/3] replay: allow to specify a ref with option --ref Toon Claes
2026-03-23 18:01 ` Tian Yuchen
2026-03-25 12:50 ` Toon Claes
2026-03-23 19:07 ` Kristoffer Haugsbakk
2026-03-25 12:49 ` Toon Claes
2026-03-25 15:59 ` [PATCH v2 0/3] Add option --ref to git-replay(1) Toon Claes
2026-03-25 15:59 ` [PATCH v2 1/3] builtin/replay: mark options as not negatable Toon Claes
2026-03-25 15:59 ` [PATCH v2 2/3] replay: use stuck form in documentation and help message Toon Claes
2026-03-25 15:59 ` [PATCH v2 3/3] replay: allow to specify a ref with option --ref Toon Claes
2026-03-25 18:44 ` Junio C Hamano
2026-03-31 7:56 ` Toon Claes
2026-03-25 18:34 ` [PATCH v2 0/3] Add option --ref to git-replay(1) Junio C Hamano
2026-03-26 21:20 ` Junio C Hamano
2026-03-31 7:55 ` Toon Claes
2026-03-31 21:42 ` Junio C Hamano
2026-04-01 20:55 ` Toon Claes [this message]
2026-04-01 20:55 ` [PATCH v3 1/3] builtin/replay: mark options as not negatable Toon Claes
2026-04-01 20:55 ` [PATCH v3 2/3] replay: use stuck form in documentation and help message Toon Claes
2026-04-01 20:55 ` [PATCH v3 3/3] replay: allow to specify a ref with option --ref Toon Claes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260401-toon-replay-arbitrary-ref-v3-0-a0b4fabb34b3@iotcl.com \
--to=toon@iotcl.com \
--cc=git@vger.kernel.org \
--cc=jltobler@gmail.com \
--cc=siddharthasthana31@gmail.com \
--cc=yeecheng.chin@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox