Git development
 help / color / mirror / Atom feed
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


  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