public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
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


             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