From: Siddharth Asthana <siddharthasthana31@gmail•com>
To: git@vger•kernel.org
Cc: christian.couder@gmail•com, ps@pks•im, newren@gmail•com,
gitster@pobox•com, phillip.wood123@gmail•com,
phillip.wood@dunelm•org.uk, karthik.188@gmail•com,
code@khaugsbakk•name, rybak.a.v@gmail•com, jltobler@gmail•com,
toon@iotcl•com, johncai86@gmail•com, johannes.schindelin@gmx•de,
Siddharth Asthana <siddharthasthana31@gmail•com>
Subject: [PATCH 1/1] replay: add --revert option to reverse commit changes
Date: Tue, 25 Nov 2025 22:30:56 +0530 [thread overview]
Message-ID: <20251125170056.34489-2-siddharthasthana31@gmail.com> (raw)
In-Reply-To: <20251125170056.34489-1-siddharthasthana31@gmail.com>
The `git replay` command performs server-side history rewriting without
requiring a working tree. While it currently supports cherry-picking
commits, it lacks the ability to revert them.
At GitLab, we use replay in Gitaly for efficient server-side operations
on bare repositories. Adding revert functionality enables us to reverse
problematic commits directly on the server, eliminating client-side
roundtrips and reducing network overhead.
Add a `--revert` option that reverses the changes introduced by the
specified commits. The implementation follows the same approach as
`sequencer.c` (around lines 2358-2390), where cherry-pick and revert
are essentially the same merge operation but 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 when calling
`merge_incore_nonrecursive()`, effectively reversing the diff direction.
The existing conflict handling, ref updates, and atomic transaction
support work unchanged.
The revert message generation logic (handling "Revert" and "Reapply"
cases) is extracted into a new `sequencer_format_revert_header()`
function in `sequencer.c`, which can be shared between `sequencer.c`
and `builtin/replay.c`. The `builtin/replay.c` code calls this shared
function and then appends the commit OID using `oid_to_hex()` directly,
since git replay is designed for simpler server-side operations without
the interactive features and `replay_opts` framework used by
`sequencer.c`.
The commit messages follow `git revert` conventions: prefixed with
"Revert" and including the original commit SHA. When reverting a commit
that itself starts with "Revert", the message uses "Reapply" instead.
Unlike cherry-pick which preserves the original author, revert commits
use the current user as the author, matching the behavior of `git
revert`.
Mark the option as incompatible with `--contained` since reverting
changes across multiple branches simultaneously could lead to
inconsistent repository states.
Helped-by: Christian Couder <christian.couder@gmail•com>
Helped-by: Patrick Steinhardt <ps@pks•im>
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail•com>
---
Documentation/git-replay.adoc | 35 +++++++-
builtin/replay.c | 86 ++++++++++++++----
sequencer.c | 23 +++++
sequencer.h | 8 ++
t/t3650-replay-basics.sh | 160 ++++++++++++++++++++++++++++++++++
5 files changed, 295 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-replay.adoc b/Documentation/git-replay.adoc
index dcb26e8a8e..ad7dc08622 100644
--- a/Documentation/git-replay.adoc
+++ b/Documentation/git-replay.adoc
@@ -9,7 +9,7 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t
SYNOPSIS
--------
[verse]
-(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch>) [--ref-action[=<mode>]] <revision-range>...
+(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch>) [--ref-action[=<mode>]] [--revert] <revision-range>...
DESCRIPTION
-----------
@@ -54,6 +54,18 @@ which uses the target only as a starting point without updating it.
+
The default mode can be configured via the `replay.refAction` configuration variable.
+--revert::
+ Revert the changes introduced by the commits in the revision range
+ instead of applying them. This reverses the diff direction and creates
+ new commits that undo the changes, similar to `git revert`.
++
+The commit messages are prefixed with "Revert" and include the original
+commit SHA. If reverting a commit whose message starts with "Revert", the new
+message will start with "Reapply" instead. The author of the new commits
+will be the current user, not the original commit author.
++
+This option is incompatible with `--contained`.
+
<revision-range>::
Range of commits to replay. More than one <revision-range> can
be passed, but in `--advance <branch>` mode, they should have
@@ -141,6 +153,27 @@ all commits they have since `base`, playing them on top of
`origin/main`. These three branches may have commits on top of `base`
that they have in common, but that does not need to be the case.
+To revert a range of commits:
+
+------------
+$ git replay --revert --onto main feature~3..feature
+------------
+
+This creates new commits on top of 'main' that reverse the changes introduced
+by the last three commits on 'feature'. The 'feature' branch is updated to
+point at the last of these revert commits. The 'main' branch is not updated
+in this case.
+
+To revert commits and advance a branch:
+
+------------
+$ git replay --revert --advance main feature~2..feature
+------------
+
+This reverts the last two commits from 'feature', applies those reverts
+on top of 'main', and updates 'main' to point at the result. The 'feature'
+branch is not updated in this case.
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/builtin/replay.c b/builtin/replay.c
index 6606a2c94b..7258d0bbc5 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -17,6 +17,7 @@
#include "parse-options.h"
#include "refs.h"
#include "revision.h"
+#include "sequencer.h"
#include "strmap.h"
#include <oidset.h>
#include <tree.h>
@@ -57,10 +58,25 @@ static char *get_author(const char *message)
return NULL;
}
+/*
+ * Generates a revert commit message using the shared sequencer function.
+ * We use oid_to_hex() directly instead of refer_to_commit() since git replay
+ * is designed for simpler server-side operations without interactive features.
+ */
+static void generate_revert_message(struct strbuf *msg,
+ const char *orig_message,
+ const struct object_id *oid)
+{
+ sequencer_format_revert_header(msg, orig_message);
+ strbuf_addstr(msg, oid_to_hex(oid));
+ strbuf_addstr(msg, ".\n");
+}
+
static struct commit *create_commit(struct repository *repo,
struct tree *tree,
struct commit *based_on,
- struct commit *parent)
+ struct commit *parent,
+ int is_revert)
{
struct object_id ret;
struct object *obj = NULL;
@@ -78,8 +94,17 @@ static struct commit *create_commit(struct repository *repo,
commit_list_insert(parent, &parents);
extra = read_commit_extra_headers(based_on, exclude_gpgsig);
find_commit_subject(message, &orig_message);
- strbuf_addstr(&msg, orig_message);
- author = get_author(message);
+
+ if (is_revert) {
+ generate_revert_message(&msg, orig_message, &based_on->object.oid);
+ /* For revert, use current user as author */
+ author = NULL;
+ } else {
+ /* Cherry-pick mode: use original commit message and author */
+ strbuf_addstr(&msg, orig_message);
+ author = get_author(message);
+ }
+
reset_ident_date();
if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents,
&ret, author, NULL, sign_commit, extra)) {
@@ -261,7 +286,8 @@ static struct commit *pick_regular_commit(struct repository *repo,
kh_oid_map_t *replayed_commits,
struct commit *onto,
struct merge_options *merge_opt,
- struct merge_result *result)
+ struct merge_result *result,
+ int is_revert)
{
struct commit *base, *replayed_base;
struct tree *pickme_tree, *base_tree;
@@ -273,21 +299,41 @@ static struct commit *pick_regular_commit(struct repository *repo,
pickme_tree = repo_get_commit_tree(repo, pickme);
base_tree = repo_get_commit_tree(repo, base);
- merge_opt->branch1 = short_commit_name(repo, replayed_base);
- merge_opt->branch2 = short_commit_name(repo, pickme);
- merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
+ if (is_revert) {
+ /* For revert: swap base and pickme to reverse the diff */
+ merge_opt->branch1 = short_commit_name(repo, replayed_base);
+ merge_opt->branch2 = xstrfmt("parent of %s", short_commit_name(repo, pickme));
+ merge_opt->ancestor = short_commit_name(repo, pickme);
- merge_incore_nonrecursive(merge_opt,
- base_tree,
- result->tree,
- pickme_tree,
- result);
+ merge_incore_nonrecursive(merge_opt,
+ pickme_tree,
+ result->tree,
+ base_tree,
+ result);
+
+ /* branch2 was allocated with xstrfmt, needs freeing */
+ free((char *)merge_opt->branch2);
+ } else {
+ /* For cherry-pick: normal order */
+ merge_opt->branch1 = short_commit_name(repo, replayed_base);
+ merge_opt->branch2 = short_commit_name(repo, pickme);
+ merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
+
+ merge_incore_nonrecursive(merge_opt,
+ base_tree,
+ result->tree,
+ pickme_tree,
+ result);
+
+ /* ancestor was allocated with xstrfmt, needs freeing */
+ free((char *)merge_opt->ancestor);
+ }
- free((char*)merge_opt->ancestor);
merge_opt->ancestor = NULL;
+ merge_opt->branch2 = NULL;
if (!result->clean)
return NULL;
- return create_commit(repo, result->tree, pickme, replayed_base);
+ return create_commit(repo, result->tree, pickme, replayed_base, is_revert);
}
static enum ref_action_mode parse_ref_action_mode(const char *ref_action, const char *source)
@@ -350,6 +396,7 @@ int cmd_replay(int argc,
int contained = 0;
const char *ref_action = NULL;
enum ref_action_mode ref_mode;
+ int is_revert = 0;
struct rev_info revs;
struct commit *last_commit = NULL;
@@ -366,7 +413,7 @@ int cmd_replay(int argc,
const char *const replay_usage[] = {
N_("(EXPERIMENTAL!) git replay "
"([--contained] --onto <newbase> | --advance <branch>) "
- "[--ref-action[=<mode>]] <revision-range>..."),
+ "[--ref-action[=<mode>]] [--revert] <revision-range>..."),
NULL
};
struct option replay_options[] = {
@@ -381,6 +428,8 @@ int cmd_replay(int argc,
OPT_STRING(0, "ref-action", &ref_action,
N_("mode"),
N_("control ref update behavior (update|print)")),
+ OPT_BOOL(0, "revert", &is_revert,
+ N_("revert commits instead of cherry-picking them")),
OPT_END()
};
@@ -395,6 +444,10 @@ int cmd_replay(int argc,
die_for_incompatible_opt2(!!advance_name_opt, "--advance",
contained, "--contained");
+ /* --revert is incompatible with --contained */
+ die_for_incompatible_opt2(is_revert, "--revert",
+ contained, "--contained");
+
/* Parse ref action mode from command line or config */
ref_mode = get_ref_action_mode(repo, ref_action);
@@ -496,7 +549,8 @@ int cmd_replay(int argc,
die(_("replaying merge commits is not supported yet!"));
last_commit = pick_regular_commit(repo, commit, replayed_commits,
- onto, &merge_opt, &result);
+ onto, &merge_opt, &result,
+ is_revert);
if (!last_commit)
break;
diff --git a/sequencer.c b/sequencer.c
index 5476d39ba9..e6d82c8368 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -5572,6 +5572,29 @@ int sequencer_pick_revisions(struct repository *r,
return res;
}
+void sequencer_format_revert_header(struct strbuf *out, const char *orig_subject)
+{
+ const char *revert_subject;
+
+ if (skip_prefix(orig_subject, "Revert \"", &revert_subject) &&
+ /*
+ * We don't touch pre-existing repeated reverts, because
+ * theoretically these can be nested arbitrarily deeply,
+ * thus requiring excessive complexity to deal with.
+ */
+ !starts_with(revert_subject, "Revert \"")) {
+ strbuf_addstr(out, "Reapply \"");
+ strbuf_addstr(out, revert_subject);
+ strbuf_addch(out, '\n');
+ } else {
+ strbuf_addstr(out, "Revert \"");
+ strbuf_addstr(out, orig_subject);
+ strbuf_addstr(out, "\"\n");
+ }
+
+ strbuf_addstr(out, "\nThis reverts commit ");
+}
+
void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
{
unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
diff --git a/sequencer.h b/sequencer.h
index 719684c8a9..2d4a2d3fac 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -205,6 +205,14 @@ int todo_list_rearrange_squash(struct todo_list *todo_list);
*/
void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag);
+/*
+ * Formats a revert commit message header following standard Git conventions.
+ * Handles both regular reverts ("Revert \"<subject>\"") and revert of revert
+ * cases ("Reapply \"<subject>\""). Adds "This reverts commit " at the end.
+ * The caller should append the commit OID after calling this function.
+ */
+void sequencer_format_revert_header(struct strbuf *out, const char *orig_subject);
+
void append_conflicts_hint(struct index_state *istate,
struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode);
enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg,
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index cf3aacf355..5fcd730b54 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -314,4 +314,164 @@ test_expect_success 'invalid replay.refAction value' '
test_grep "invalid.*replay.refAction.*value" error
'
+test_expect_success 'using replay with --revert to revert a commit' '
+ # Revert commits D and E from topic2
+ git replay --revert --onto topic1 topic1..topic2 >result &&
+
+ test_line_count = 1 result &&
+ NEW_TOPIC2=$(cut -f 3 -d " " result) &&
+
+ # Verify the result updates the topic2 branch
+ printf "update refs/heads/topic2 " >expect &&
+ printf "%s " $NEW_TOPIC2 >>expect &&
+ git rev-parse topic2 >>expect &&
+
+ test_cmp expect result &&
+
+ # Verify the commit messages contain "Revert"
+ # topic1..topic2 contains D and E, so we get 2 reverts on top of topic1 (which has F, C, B, A)
+ git log --format=%s $NEW_TOPIC2 >actual &&
+ test_line_count = 6 actual &&
+ head -n 1 actual >first-line &&
+ test_grep "^Revert" first-line
+'
+
+test_expect_success 'using replay with --revert on bare repo' '
+ git -C bare replay --revert --onto topic1 topic1..topic2 >result-bare &&
+
+ test_line_count = 1 result-bare &&
+ NEW_COMMIT=$(cut -f 3 -d " " result-bare) &&
+
+ # Verify the commit message contains "Revert"
+ git -C bare log --format=%s $NEW_COMMIT >actual-bare &&
+ test_line_count = 6 actual-bare &&
+ head -n 1 actual-bare >first-line-bare &&
+ test_grep "^Revert" first-line-bare
+'
+
+test_expect_success 'using replay with --revert and --advance' '
+ # Revert commits from topic2 and advance main
+ git replay --revert --advance main topic1..topic2 >result &&
+
+ test_line_count = 1 result &&
+ NEW_MAIN=$(cut -f 3 -d " " result) &&
+
+ # Verify the result updates the main branch
+ printf "update refs/heads/main " >expect &&
+ printf "%s " $NEW_MAIN >>expect &&
+ git rev-parse main >>expect &&
+
+ test_cmp expect result &&
+
+ # Verify the commit message contains "Revert"
+ git log --format=%s $NEW_MAIN >actual &&
+ head -n 1 actual >first-line &&
+ test_grep "^Revert" first-line
+'
+
+test_expect_success 'replay with --revert fails with --contained' '
+ test_must_fail git replay --revert --contained --onto main main..topic3 2>error &&
+ test_grep "revert.*contained.*cannot be used together" error
+'
+
+test_expect_success 'verify revert actually reverses changes' '
+ # Create a branch with a simple change
+ git switch -c revert-test main &&
+ echo "new content" >test-file.txt &&
+ git add test-file.txt &&
+ git commit -m "Add test file" &&
+
+ # Revert the commit
+ git replay --revert --advance revert-test HEAD^..HEAD >result &&
+ REVERTED=$(cut -f 3 -d " " result) &&
+
+ # The file should no longer exist (reverted)
+ test_must_fail git show $REVERTED:test-file.txt
+'
+
+test_expect_success 'revert of a revert creates reapply message' '
+ # Create a commit
+ git switch -c revert-revert main &&
+ echo "content" >revert-test-2.txt &&
+ git add revert-test-2.txt &&
+ git commit -m "Add revert test file" &&
+
+ ORIGINAL=$(git rev-parse HEAD) &&
+
+ # First revert
+ git replay --revert --advance revert-revert HEAD^..HEAD >result1 &&
+ FIRST_REVERT=$(cut -f 3 -d " " result1) &&
+
+ # Check first revert message starts with "Revert"
+ git log --format=%s -1 $FIRST_REVERT >msg1 &&
+ test_grep "^Revert" msg1 &&
+
+ # Now revert the revert
+ git replay --revert --advance revert-revert $ORIGINAL..$FIRST_REVERT >result2 &&
+ REAPPLY=$(cut -f 3 -d " " result2) &&
+
+ # Check second revert message starts with "Reapply"
+ git log --format=%s -1 $REAPPLY >msg2 &&
+ test_grep "^Reapply" msg2 &&
+
+ # The file should exist again (reapplied)
+ git show $REAPPLY:revert-test-2.txt >actual &&
+ echo "content" >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'replay --revert includes commit SHA in message' '
+ git switch -c revert-sha-test main &&
+ echo "test" >sha-test.txt &&
+ git add sha-test.txt &&
+ git commit -m "Test commit for SHA" &&
+
+ COMMIT_SHA=$(git rev-parse HEAD) &&
+ git replay --revert --advance revert-sha-test HEAD^..HEAD >result &&
+ REVERT_COMMIT=$(cut -f 3 -d " " result) &&
+
+ # Check that the commit message includes the original SHA
+ git log --format=%B -1 $REVERT_COMMIT >msg &&
+ test_grep "$COMMIT_SHA" msg
+'
+
+test_expect_success 'replay --revert with conflict' '
+ # Create a conflicting situation
+ git switch -c revert-conflict main &&
+ echo "line1" >conflict-file.txt &&
+ git add conflict-file.txt &&
+ git commit -m "Add conflict file" &&
+
+ git switch -c revert-conflict-branch HEAD^ &&
+ echo "different" >conflict-file.txt &&
+ git add conflict-file.txt &&
+ git commit -m "Different content" &&
+
+ # Try to revert the first commit onto the conflicting branch
+ test_expect_code 1 git replay --revert --onto revert-conflict-branch revert-conflict^..revert-conflict
+'
+
+test_expect_success 'replay --revert handles multiple commits' '
+ # Verify that reverting multiple commits works correctly
+ # The output should show both revert commits in the history
+ git log --format=%s topic2 >topic2-log &&
+ test_write_lines E D C B A >expected-topic2 &&
+ test_cmp expected-topic2 topic2-log &&
+
+ # Revert D and E from topic2, applying the reverts onto topic1
+ git replay --revert --onto topic1 topic1..topic2 >result &&
+
+ test_line_count = 1 result &&
+ FINAL=$(cut -f 3 -d " " result) &&
+
+ # Verify both revert commits appear in the log
+ git log --format=%s $FINAL >log &&
+ head -n 2 log >first-two &&
+ test_grep "^Revert" first-two &&
+
+ # Verify we have both "Revert D" and "Revert E"
+ test_grep "Revert.*E" log &&
+ test_grep "Revert.*D" log
+'
+
test_done
--
2.51.0
next prev parent reply other threads:[~2025-11-25 17:01 UTC|newest]
Thread overview: 96+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-25 17:00 [PATCH 0/1] replay: add --revert option to reverse commit changes Siddharth Asthana
2025-11-25 17:00 ` Siddharth Asthana [this message]
2025-11-25 19:22 ` [PATCH 1/1] " Junio C Hamano
2025-11-25 19:30 ` Junio C Hamano
2025-11-25 19:39 ` Junio C Hamano
2025-11-25 20:06 ` Junio C Hamano
2025-11-26 19:31 ` Siddharth Asthana
2025-11-26 19:28 ` Siddharth Asthana
2025-11-26 19:26 ` Siddharth Asthana
2025-11-26 21:13 ` Junio C Hamano
2025-11-27 19:23 ` Siddharth Asthana
2025-11-26 11:10 ` Phillip Wood
2025-11-26 17:35 ` Elijah Newren
2025-11-26 18:41 ` Junio C Hamano
2025-11-26 21:17 ` Junio C Hamano
2025-11-26 23:06 ` Elijah Newren
2025-11-26 23:14 ` Junio C Hamano
2025-11-26 23:57 ` Elijah Newren
2025-11-26 19:50 ` Siddharth Asthana
2025-11-26 19:39 ` Siddharth Asthana
2025-11-27 16:21 ` Phillip Wood
2025-11-27 19:24 ` Siddharth Asthana
2025-11-25 17:25 ` [PATCH 0/1] " Johannes Schindelin
2025-11-25 18:02 ` Junio C Hamano
2025-11-26 19:18 ` Siddharth Asthana
2025-11-26 21:04 ` Junio C Hamano
2025-11-27 19:21 ` Siddharth Asthana
2025-11-27 20:17 ` Junio C Hamano
2025-11-28 8:07 ` Elijah Newren
2025-11-28 8:24 ` Siddharth Asthana
2025-11-28 16:35 ` Junio C Hamano
2025-11-28 17:07 ` Elijah Newren
2025-11-28 20:50 ` Junio C Hamano
2025-11-28 22:03 ` Elijah Newren
2025-11-29 5:59 ` Junio C Hamano
2025-12-02 20:16 ` [PATCH v2 0/2] replay: add --revert mode " Siddharth Asthana
2025-12-02 20:16 ` [PATCH v2 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2025-12-05 11:33 ` Patrick Steinhardt
2025-12-07 23:00 ` Siddharth Asthana
2025-12-08 7:07 ` Patrick Steinhardt
2026-02-11 13:03 ` Toon Claes
2026-02-11 13:40 ` Patrick Steinhardt
2026-02-11 15:23 ` Kristoffer Haugsbakk
2026-02-11 17:41 ` Junio C Hamano
2026-02-18 22:53 ` Siddharth Asthana
2025-12-02 20:16 ` [PATCH v2 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
2025-12-05 11:33 ` Patrick Steinhardt
2025-12-07 23:03 ` Siddharth Asthana
2025-12-16 16:23 ` Phillip Wood
2026-02-18 23:42 ` [PATCH v3 0/2] " Siddharth Asthana
2026-02-18 23:42 ` [PATCH v3 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2026-02-20 17:01 ` Toon Claes
2026-02-25 21:53 ` Junio C Hamano
2026-03-06 4:55 ` Siddharth Asthana
2026-03-06 4:31 ` Siddharth Asthana
2026-02-26 14:27 ` Phillip Wood
2026-03-06 5:00 ` Siddharth Asthana
2026-02-18 23:42 ` [PATCH v3 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
2026-02-20 17:35 ` Toon Claes
2026-02-20 20:23 ` Junio C Hamano
2026-02-23 9:13 ` Christian Couder
2026-02-23 11:23 ` Toon Claes
2026-03-06 5:05 ` Siddharth Asthana
2026-02-26 14:45 ` Phillip Wood
2026-03-06 5:28 ` Siddharth Asthana
2026-03-06 15:52 ` Phillip Wood
2026-03-06 16:20 ` Siddharth Asthana
2026-03-13 5:40 ` [PATCH v4 0/2] " Siddharth Asthana
2026-03-13 5:40 ` [PATCH v4 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2026-03-13 15:53 ` Junio C Hamano
2026-03-16 19:12 ` Toon Claes
2026-03-16 16:57 ` Phillip Wood
2026-03-13 5:40 ` [PATCH v4 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
2026-03-16 16:57 ` Phillip Wood
2026-03-16 19:52 ` Toon Claes
2026-03-17 10:11 ` Phillip Wood
2026-03-16 16:59 ` [PATCH v4 0/2] " Phillip Wood
2026-03-16 19:53 ` Toon Claes
2026-03-24 22:03 ` [PATCH v5 " Siddharth Asthana
2026-03-24 22:04 ` [PATCH v5 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2026-03-24 22:04 ` [PATCH v5 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
2026-03-25 6:29 ` Junio C Hamano
2026-03-25 15:10 ` Toon Claes
2026-03-25 15:38 ` Siddharth Asthana
2026-03-25 16:44 ` Phillip Wood
2026-03-25 15:36 ` Siddharth Asthana
2026-03-25 20:23 ` [PATCH v6 0/2] " Siddharth Asthana
2026-03-25 20:23 ` [PATCH v6 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2026-03-25 20:23 ` [PATCH v6 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
2026-03-28 4:33 ` Tian Yuchen
2026-03-29 16:17 ` Siddharth Asthana
2026-03-30 17:23 ` Tian Yuchen
2026-03-31 8:08 ` Toon Claes
2026-03-31 8:11 ` Toon Claes
2026-03-25 20:23 ` [PATCH v6 1/2] sequencer: extract revert message formatting into shared function Siddharth Asthana
2026-03-25 20:23 ` [PATCH v6 2/2] replay: add --revert mode to reverse commit changes Siddharth Asthana
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=20251125170056.34489-2-siddharthasthana31@gmail.com \
--to=siddharthasthana31@gmail$(echo .)com \
--cc=christian.couder@gmail$(echo .)com \
--cc=code@khaugsbakk$(echo .)name \
--cc=git@vger$(echo .)kernel.org \
--cc=gitster@pobox$(echo .)com \
--cc=jltobler@gmail$(echo .)com \
--cc=johannes.schindelin@gmx$(echo .)de \
--cc=johncai86@gmail$(echo .)com \
--cc=karthik.188@gmail$(echo .)com \
--cc=newren@gmail$(echo .)com \
--cc=phillip.wood123@gmail$(echo .)com \
--cc=phillip.wood@dunelm$(echo .)org.uk \
--cc=ps@pks$(echo .)im \
--cc=rybak.a.v@gmail$(echo .)com \
--cc=toon@iotcl$(echo .)com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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