git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 0/2] replay: add --revert mode to reverse commit changes

From
Siddharth Asthana <siddharthasthana31@gmail.com>
Date
Feb 18, 2026, 23:42 UTC
Message-ID
<20260218234215.89326-1-siddharthasthana31@gmail.com>
In-Reply-To
<20251202201611.22137-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 (--advance) and rebasing (--onto), 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.

The implementation follows the same approach as sequencer.c where cherry-pick and revert are the same merge operation but with swapped arguments. For cherry-pick we merge(ancestor=parent, ours=current, theirs=commit), while for revert we merge(ancestor=commit, ours=current, theirs=parent). By swapping the base and pickme trees when calling merge_incore_nonrecursive(), we effectively reverse the diff direction.

The series is structured as follows:

Patch 1 extracts the revert message formatting logic into a shared sequencer_format_revert_header() function, eliminating code duplication between sequencer.c and the upcoming replay code. This follows Junio's suggestion to split the changes.

Patch 2 adds the --revert <branch> mode to git replay. Following the architectural pattern suggested by Elijah and Phillip, --revert is a standalone mode (like --onto and --advance) that takes a branch argument and updates that branch with the revert commits.

The series is based on top of 864f55e190 (The second batch, 2026-02-07).
CI: https://gitlab.com/gitlab-org/git/-/pipelines/2329880894
The Windows CI failures (t4041, t4059, t4060, t4205, t6006) are
pre-existing infrastructure issues (missing iconv, submodule pathspec
errors) unrelated to this series.
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
---
Changes in v3:
- Rebased on top of the latest upstream which refactored replay into
  a library (replay.c / replay.h). The --revert logic now lives in
  replay.c alongside the existing pick logic, while builtin/replay.c
  is a thin CLI wrapper.
- sequencer_format_revert_header() now takes an optional oid parameter
  so it can handle the full commit reference internally, per Patrick's
  suggestion about refer_to_commit()
- Removed now-unused `orig_subject` variable in do_pick_commit()
- Switched to die_for_incompatible_opt3() for --onto/--advance/--revert
  mutual exclusivity, per Patrick
- --contained now just checks "die(_("--contained requires --onto"))"
  instead of going through die_for_incompatible_opt2, per Phillip
- Added BUG() guards for unhandled replay_mode values, per Patrick
- Merged the separate advance/revert ref update blocks into one
- author is set to NULL for revert commits so commit_tree_extended()
  picks up the current user, per Phillip
- Factored out common --advance/--revert branch validation into a
  set_up_branch_mode() helper, per Phillip
- Doc wording fixes: "reverted commits", "they are prefixed",
  "hash" instead of "SHA", per Phillip
- Tests now reuse topic4 instead of creating new branches, use heredoc
  for test_commit_message, and the reflog check is folded into the
  main revert test
- Added tests for bare repo revert, error cases (argument validation,
  multiple sources)
- Link to v2: https://public-inbox.org/git/20251202201611.22137-1-siddharthasthana31@gmail.com/t/#u
- Link to v1: https://public-inbox.org/git/20251125170056.34489-1-siddharthasthana31@gmail.com/t/#u
---
 Documentation/git-replay.adoc |  37 +++++++-
 builtin/replay.c              |  25 ++++--
 replay.c                      | 162 ++++++++++++++++++++++++----------
 replay.h                      |  11 ++-
 sequencer.c                   |  47 ++++++----
 sequencer.h                   |  11 +++
 t/t3650-replay-basics.sh      | 107 ++++++++++++++++++++--
 7 files changed, 319 insertions(+), 81 deletions(-)
Siddharth Asthana (2):
  sequencer: extract revert message formatting into shared function
  replay: add --revert mode to reverse commit changes
Range-diff versus v2:
1:  bfd75484b4 ! 1:  9d686bcdfe sequencer: extract revert message formatting into shared function
    @@ Commit message
         Extract this logic into a new sequencer_format_revert_header() function
         that can be shared. The function handles both regular reverts ("Revert
         "<subject>"") and revert-of-revert cases ("Reapply "<subject>"").
    +    When an oid is provided, the function appends the full commit hash and
    +    period; otherwise the caller should append the commit reference.
    +
         Update do_pick_commit() to use the new helper, eliminating code
         duplication while preserving the special handling for commit_use_reference.
     
         Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
     
      ## sequencer.c ##
    +@@ sequencer.c: static int do_pick_commit(struct repository *r,
    + 	 */
    + 
    + 	if (command == TODO_REVERT) {
    +-		const char *orig_subject;
    +-
    + 		base = commit;
    + 		base_label = msg.label;
    + 		next = parent;
     @@ sequencer.c: static int do_pick_commit(struct repository *r,
      		if (opts->commit_use_reference) {
      			strbuf_commented_addf(&ctx->message, comment_line_str,
     @@ sequencer.c: static int do_pick_commit(struct repository *r,
     -			strbuf_addstr(&ctx->message, "Revert \"");
     -			strbuf_addstr(&ctx->message, msg.subject);
     -			strbuf_addstr(&ctx->message, "\"\n");
    -+			sequencer_format_revert_header(&ctx->message, msg.subject);
    ++			sequencer_format_revert_header(&ctx->message, msg.subject, NULL);
      		}
     -		strbuf_addstr(&ctx->message, "\nThis reverts commit ");
      		refer_to_commit(opts, &ctx->message, commit);
    @@ sequencer.c: int sequencer_pick_revisions(struct repository *r,
      	return res;
      }
      
    -+void sequencer_format_revert_header(struct strbuf *out, const char *orig_subject)
    ++void sequencer_format_revert_header(struct strbuf *out,
    ++				    const char *orig_subject,
    ++				    const struct object_id *oid)
     +{
     +	const char *revert_subject;
     +
    @@ sequencer.c: int sequencer_pick_revisions(struct repository *r,
     +	}
     +
     +	strbuf_addstr(out, "\nThis reverts commit ");
    ++	if (oid) {
    ++		strbuf_addstr(out, oid_to_hex(oid));
    ++		strbuf_addstr(out, ".\n");
    ++	}
     +}
     +
      void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
    @@ sequencer.h: int sequencer_determine_whence(struct repository *r, enum commit_wh
      int sequencer_get_update_refs_state(const char *wt_dir, struct string_list *refs);
      
     +/*
    -+ * Formats a revert commit message header following standard Git conventions.
    ++ * Formats a revert commit message 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.
    ++ * cases ("Reapply \"<subject>\""). Adds "This reverts commit <oid>." if oid
    ++ * is provided, otherwise just adds "This reverts commit " and the caller
    ++ * should append the commit reference.
     + */
    -+void sequencer_format_revert_header(struct strbuf *out, const char *orig_subject);
    ++void sequencer_format_revert_header(struct strbuf *out,
    ++				    const char *orig_subject,
    ++				    const struct object_id *oid);
     +
      #endif /* SEQUENCER_H */
2:  a2f99bc8c2 < -:  ---------- replay: add --revert mode to reverse commit changes
-:  ---------- > 2:  a8eae7b802 replay: add --revert mode to reverse commit changes
base-commit: 864f55e1906897b630333675a52874c0fec2a45c
Thanks
- Siddharth
Previous: Phillip WoodNext: Siddharth Asthana
Message 50 of 96 in “replay: add --revert option to reverse commit changes”
  1. 0/1 replay: add --revert option to reverse commit changesSiddharth Asthana, Nov 25, 2025
  2. 1/1 replay: add --revert option to reverse commit changesSiddharth Asthana, Nov 25, 2025
  3. Junio C HamanoNov 25, 2025
  4. Junio C HamanoNov 25, 2025
  5. Junio C HamanoNov 25, 2025
  6. Junio C HamanoNov 25, 2025
  7. Siddharth AsthanaNov 26, 2025
  8. Siddharth AsthanaNov 26, 2025
  9. Siddharth AsthanaNov 26, 2025
  10. Junio C HamanoNov 26, 2025
  11. Siddharth AsthanaNov 27, 2025
  12. Phillip WoodNov 26, 2025
  13. Elijah NewrenNov 26, 2025
  14. Junio C HamanoNov 26, 2025
  15. Junio C HamanoNov 26, 2025
  16. Elijah NewrenNov 26, 2025
  17. Junio C HamanoNov 26, 2025
  18. Elijah NewrenNov 26, 2025
  19. Siddharth AsthanaNov 26, 2025
  20. Siddharth AsthanaNov 26, 2025
  21. Phillip WoodNov 27, 2025
  22. Siddharth AsthanaNov 27, 2025
  23. Johannes SchindelinNov 25, 2025
  24. Junio C HamanoNov 25, 2025
  25. Siddharth AsthanaNov 26, 2025
  26. Junio C HamanoNov 26, 2025
  27. Siddharth AsthanaNov 27, 2025
  28. Junio C HamanoNov 27, 2025
  29. Elijah NewrenNov 28, 2025
  30. Siddharth AsthanaNov 28, 2025
  31. Junio C HamanoNov 28, 2025
  32. Elijah NewrenNov 28, 2025
  33. Junio C HamanoNov 28, 2025
  34. Elijah NewrenNov 28, 2025
  35. Junio C HamanoNov 29, 2025
  36. 0/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Dec 2, 2025
  37. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Dec 2, 2025
  38. Patrick SteinhardtDec 5, 2025
  39. Siddharth AsthanaDec 7, 2025
  40. Patrick SteinhardtDec 8, 2025
  41. Toon ClaesFeb 11, 2026
  42. Patrick SteinhardtFeb 11, 2026
  43. Kristoffer HaugsbakkFeb 11, 2026
  44. Junio C HamanoFeb 11, 2026
  45. Siddharth AsthanaFeb 18, 2026
  46. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Dec 2, 2025
  47. Patrick SteinhardtDec 5, 2025
  48. Siddharth AsthanaDec 7, 2025
  49. Phillip WoodDec 16, 2025
  50. 0/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Feb 18, 2026
  51. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Feb 18, 2026
  52. Toon ClaesFeb 20, 2026
  53. Junio C HamanoFeb 25, 2026
  54. Siddharth AsthanaMar 6, 2026
  55. Siddharth AsthanaMar 6, 2026
  56. Phillip WoodFeb 26, 2026
  57. Siddharth AsthanaMar 6, 2026
  58. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Feb 18, 2026
  59. Toon ClaesFeb 20, 2026
  60. Junio C HamanoFeb 20, 2026
  61. Christian CouderFeb 23, 2026
  62. Toon ClaesFeb 23, 2026
  63. Siddharth AsthanaMar 6, 2026
  64. Phillip WoodFeb 26, 2026
  65. Siddharth AsthanaMar 6, 2026
  66. Phillip WoodMar 6, 2026
  67. Siddharth AsthanaMar 6, 2026
  68. 0/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 13, 2026
  69. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Mar 13, 2026
  70. Junio C HamanoMar 13, 2026
  71. Toon ClaesMar 16, 2026
  72. Phillip WoodMar 16, 2026
  73. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 13, 2026
  74. Phillip WoodMar 16, 2026
  75. Toon ClaesMar 16, 2026
  76. Phillip WoodMar 17, 2026
  77. Phillip WoodMar 16, 2026
  78. Toon ClaesMar 16, 2026
  79. 0/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 24, 2026
  80. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Mar 24, 2026
  81. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 24, 2026
  82. Junio C HamanoMar 25, 2026
  83. Toon ClaesMar 25, 2026
  84. Siddharth AsthanaMar 25, 2026
  85. Phillip WoodMar 25, 2026
  86. Siddharth AsthanaMar 25, 2026
  87. 0/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 25, 2026
  88. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Mar 25, 2026
  89. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 25, 2026
  90. Tian YuchenMar 28, 2026
  91. Siddharth AsthanaMar 29, 2026
  92. Tian YuchenMar 30, 2026
  93. Toon ClaesMar 31, 2026
  94. Toon ClaesMar 31, 2026
  95. 1/2 sequencer: extract revert message formatting into shared functionSiddharth Asthana, Mar 25, 2026
  96. 2/2 replay: add --revert mode to reverse commit changesSiddharth Asthana, Mar 25, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.