<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/replay.c, branch jch</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=jch</id>
<link rel='self' href='https://git.shady.money/git/atom?h=jch'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2026-04-08T17:19:18Z</updated>
<entry>
<title>Merge branch 'tc/replay-ref'</title>
<updated>2026-04-08T17:19:18Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-04-08T17:19:18Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=37a4780f2c30de9fe0bef533a266c6bca767a50f'/>
<id>urn:sha1:37a4780f2c30de9fe0bef533a266c6bca767a50f</id>
<content type='text'>
The experimental `git replay` command learned the `--ref=&lt;ref&gt;` option
to allow specifying which ref to update, overriding the default behavior.

* tc/replay-ref:
  replay: allow to specify a ref with option --ref
  replay: use stuck form in documentation and help message
  builtin/replay: mark options as not negatable
</content>
</entry>
<entry>
<title>Merge branch 'tc/replay-down-to-root'</title>
<updated>2026-04-06T22:42:49Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-04-06T22:42:49Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=da54784d1cc3f4fdd90622fb9e3ae34a9e771702'/>
<id>urn:sha1:da54784d1cc3f4fdd90622fb9e3ae34a9e771702</id>
<content type='text'>
git replay now supports replaying down to the root commit.

* tc/replay-down-to-root:
  replay: support replaying down from root commit
</content>
</entry>
<entry>
<title>Merge branch 'sa/replay-revert'</title>
<updated>2026-04-03T20:01:09Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-04-03T20:01:09Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e0613d24f9902a581b6a1cf0aa39b517db1e3f2f'/>
<id>urn:sha1:e0613d24f9902a581b6a1cf0aa39b517db1e3f2f</id>
<content type='text'>
"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
</content>
</entry>
<entry>
<title>replay: allow to specify a ref with option --ref</title>
<updated>2026-04-02T04:34:25Z</updated>
<author>
<name>Toon Claes</name>
<email>toon@iotcl.com</email>
</author>
<published>2026-04-01T20:55:12Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=23d83f8ddbef9adcb87671358b473e55cf90c90b'/>
<id>urn:sha1:23d83f8ddbef9adcb87671358b473e55cf90c90b</id>
<content type='text'>
When option '--onto' is passed to git-replay(1), the command will update
refs from the &lt;revision-range&gt; passed to the command. When using option
'--advance' or '--revert', the argument of that option is a ref that
will be updated.

To enable users to specify which ref to update, add option '--ref'. When
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 &lt;toon@iotcl.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'sa/replay-revert' into tc/replay-ref</title>
<updated>2026-03-25T21:22:38Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-03-25T21:22:38Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=ff071a3af442c691b5a46e200a4c023fc25ae4e3'/>
<id>urn:sha1:ff071a3af442c691b5a46e200a4c023fc25ae4e3</id>
<content type='text'>
* sa/replay-revert:
  replay: add --revert mode to reverse commit changes
  sequencer: extract revert message formatting into shared function
</content>
</entry>
<entry>
<title>replay: add --revert mode to reverse commit changes</title>
<updated>2026-03-25T21:21:20Z</updated>
<author>
<name>Siddharth Asthana</name>
<email>siddharthasthana31@gmail.com</email>
</author>
<published>2026-03-25T20:23:52Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=2760ee49834953c0860fa5d7983a6af4d27cb6a9'/>
<id>urn:sha1:2760ee49834953c0860fa5d7983a6af4d27cb6a9</id>
<content type='text'>
Add a `--revert &lt;branch&gt;` mode to git replay that undoes the changes
introduced by the specified commits. Like --onto and --advance, --revert
is a standalone mode: it takes a branch argument and updates that branch
with the newly created revert commits.

At GitLab, we need this in Gitaly for reverting commits directly on bare
repositories without requiring a working tree checkout.

The approach is the same as sequencer.c's do_pick_commit() -- cherry-pick
and revert are just the same three-way merge with swapped arguments:

  - Cherry-pick: merge(ancestor=parent, ours=current, theirs=commit)
  - Revert: merge(ancestor=commit, ours=current, theirs=parent)

We swap the base and pickme trees passed to merge_incore_nonrecursive()
to reverse the diff direction.

Reverts are processed newest-first (matching git revert behavior) to
reduce conflicts by peeling off changes from the top. Each revert
builds on the result of the previous one via the last_commit fallback
in the main replay loop, rather than relying on the parent-mapping
used for cherry-pick.

Revert commit messages follow the usual git revert conventions: prefixed
with "Revert" (or "Reapply" when reverting a revert), and including
"This reverts commit &lt;hash&gt;.". The author is set to the current user
rather than preserving the original author, matching git revert behavior.

Helped-by: Christian Couder &lt;christian.couder@gmail.com&gt;
Helped-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Helped-by: Elijah Newren &lt;newren@gmail.com&gt;
Helped-by: Phillip Wood &lt;phillip.wood123@gmail.com&gt;
Helped-by: Johannes Schindelin &lt;Johannes.Schindelin@gmx.de&gt;
Helped-by: Junio C Hamano &lt;gitster@pobox.com&gt;
Helped-by: Toon Claes &lt;toon@iotcl.com&gt;
Signed-off-by: Siddharth Asthana &lt;siddharthasthana31@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>replay: support replaying down from root commit</title>
<updated>2026-03-24T19:41:13Z</updated>
<author>
<name>Toon Claes</name>
<email>toon@iotcl.com</email>
</author>
<published>2026-03-24T19:35:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e8b79a96ebaa2113391d14bfcdabe239f6ff8611'/>
<id>urn:sha1:e8b79a96ebaa2113391d14bfcdabe239f6ff8611</id>
<content type='text'>
git-replay(1) doesn't allow replaying commits all the way down to the
root commit. Fix that.

Signed-off-by: Toon Claes &lt;toon@iotcl.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>replay: prevent the_repository from coming back</title>
<updated>2026-02-22T02:37:25Z</updated>
<author>
<name>Elijah Newren</name>
<email>newren@gmail.com</email>
</author>
<published>2026-02-20T01:59:48Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=3249d07962f081bd84bace9ca7f808575e2cae56'/>
<id>urn:sha1:3249d07962f081bd84bace9ca7f808575e2cae56</id>
<content type='text'>
Due to the use of DEFAULT_ABBREV, we cannot get rid of our usage of
USE_THE_REPOSITORY_VARIABLE.  We have removed all other uses of
the_repository before, but without removing that definition, they keep
coming back.

Define the_repository to make it a compilation error so that they don't
come back any more; the repo parameter plumbed through the various
functions can be used instead.

Signed-off-by: Elijah Newren &lt;newren@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>replay: drop commits that become empty</title>
<updated>2026-01-13T14:13:37Z</updated>
<author>
<name>Phillip Wood</name>
<email>phillip.wood@dunelm.org.uk</email>
</author>
<published>2025-12-18T16:50:26Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=0ee71f4bd035db61342c2c5a25984e4545347c11'/>
<id>urn:sha1:0ee71f4bd035db61342c2c5a25984e4545347c11</id>
<content type='text'>
If the changes in a commit being replayed are already in the branch
that the commits are being replayed onto, then "git replay" creates an
empty commit. This is confusing because the commit message no longer
matches the contents of the commit. Drop the commit instead. Commits
that start off empty are not dropped. This matches the behavior of
"git rebase --reapply-cherry-pick --empty=drop" and "git cherry-pick
--empty-drop".

If a branch points to a commit that is dropped it will be updated
to point to the last commit that was not dropped. This can be seen
in the new test where "topic1" is updated to point to the rebased
"C" as "F" is dropped because it is already upstream. While this is
a breaking change, "git replay" is marked as experimental to allow
improvements like this that change the behavior.

Helped-by: Elijah Newren &lt;newren@gmail.com&gt;
Signed-off-by: Phillip Wood &lt;phillip.wood@dunelm.org.uk&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>replay: support updating detached HEAD</title>
<updated>2026-01-13T13:41:16Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2026-01-13T09:54:36Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=48a72f61f04cb2357544f373677acd5b4149237e'/>
<id>urn:sha1:48a72f61f04cb2357544f373677acd5b4149237e</id>
<content type='text'>
In a subsequent commit we're about to introduce a new git-history(1)
command, which will by default work on all local branches and HEAD. This
is already well-supported by the replay machinery for most of the part:
updating branches is one of its prime use cases, and the HEAD ref is
also updated in case it points to any of the branches.

However, what's not supported yet is to update HEAD in case it is not a
symbolic ref. We determine the refs that need to be updated by iterating
through the decorations of the original commit, but we only update those
refs that are `DECORATION_REF_LOCAL`, which covers local branches.

Address this gap by also handling `DECORATION_REF_HEAD`. Note though
that this needs to only happen in case we're working on a detached HEAD.
If HEAD is pointing to a branch, then we'd already update that branch
via `DECORATION_REF_LOCAL`.

Refactor the loop that iterates through the decorations a bit to make
the individual conditions easier to understand.

Based-on-patch-by: Elijah Newren &lt;newren@gmail.com&gt;
Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
