From: Tian Yuchen <cat@malon.dev>
To: git@vger.kernel.org
Cc: Tian Yuchen <cat@malon.dev>
Subject: [PATCH v1] replay.c: support replaying root commits
Date: Sat, 28 Mar 2026 02:09:30 +0800 [thread overview]
Message-ID: <20260327180930.104563-1-cat@malon.dev> (raw)
'git replay' does not support replaying root commits, as indicated by
the FIXME comment. If a user attempts to replay a root commit, the 'die()'
in 'replay_revisions()' will be called.
The reason for this is that the call 'base = pickme->parents->item' in
'pick_regular_commit()' will cause a null pointer dereference error in the
case of a root commit.
Fix this by adding new conditional statements: the difference between the
root commit its 'common ancestor' is equivalent to the difference from
an empty tree object, and it must be placed on the user-specified target
branch 'onto'. Therefore, We set 'base' to 'NULL', 'replayed_base' to
'onto', and use 'lookup_tree()' to instantiate the OID of the empty tree
in order to pass it to 'base_tree'.
Signed-off-by: Tian Yuchen <cat@malon.dev>
---
To be honest, I'm not sure whether setting 'base = NULL' is proper or
not. Feel free to give feedback and suggestions!
replay.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/replay.c b/replay.c
index a63f6714c4..80497191a8 100644
--- a/replay.c
+++ b/replay.c
@@ -225,12 +225,21 @@ static struct commit *pick_regular_commit(struct repository *repo,
struct commit *base, *replayed_base;
struct tree *pickme_tree, *base_tree, *replayed_base_tree;
- base = pickme->parents->item;
- replayed_base = mapped_commit(replayed_commits, base, onto);
-
+ if (pickme->parents) {
+ base = pickme->parents->item;
+ replayed_base = mapped_commit(replayed_commits, base, onto);
+ base_tree = repo_get_commit_tree(repo, base);
+ } else {
+ /*
+ * Root commits have no parents. Their base is the empty tree,
+ * and they should be replayed directly onto the target 'onto' commit.
+ */
+ base = NULL;
+ replayed_base = onto;
+ base_tree = lookup_tree(repo, repo->hash_algo->empty_tree);
+ }
replayed_base_tree = repo_get_commit_tree(repo, replayed_base);
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);
@@ -293,8 +302,6 @@ int replay_revisions(struct rev_info *revs,
set_up_replay_mode(revs->repo, &revs->cmdline, opts->onto,
&detached_head, &advance, &onto, &update_refs);
- /* FIXME: Should allow replaying commits with the first as a root commit */
-
if (prepare_revision_walk(revs) < 0) {
ret = error(_("error preparing revisions"));
goto out;
@@ -309,9 +316,7 @@ int replay_revisions(struct rev_info *revs,
khint_t pos;
int hr;
- if (!commit->parents)
- die(_("replaying down from root commit is not supported yet!"));
- if (commit->parents->next)
+ if (commit->parents && commit->parents->next)
die(_("replaying merge commits is not supported yet!"));
last_commit = pick_regular_commit(revs->repo, commit, replayed_commits,
--
2.43.0
next reply other threads:[~2026-03-27 18:09 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 18:09 Tian Yuchen [this message]
2026-03-27 18:28 ` [PATCH v1] replay.c: support replaying root commits Junio C Hamano
2026-03-27 18:55 ` Junio C Hamano
2026-03-28 3:24 ` Tian Yuchen
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=20260327180930.104563-1-cat@malon.dev \
--to=cat@malon.dev \
--cc=git@vger.kernel.org \
/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