aboutsummaryrefslogtreecommitdiff
path: root/replay.c
diff options
context:
space:
mode:
authorToon Claes <toon@iotcl.com>2026-03-24 20:35:41 +0100
committerJunio C Hamano <gitster@pobox.com>2026-03-24 12:41:13 -0700
commite8b79a96ebaa2113391d14bfcdabe239f6ff8611 (patch)
tree12385678a71ea3ca97c33ee0ecfde1d439209d60 /replay.c
parentca1db8a0f7dc0dbea892e99f5b37c5fe5861be71 (diff)
downloadgit-e8b79a96ebaa2113391d14bfcdabe239f6ff8611.tar.xz
replay: support replaying down from root commit
git-replay(1) doesn't allow replaying commits all the way down to the root commit. Fix that. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'replay.c')
-rw-r--r--replay.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/replay.c b/replay.c
index a63f6714c4..92f2279156 100644
--- a/replay.c
+++ b/replay.c
@@ -209,7 +209,10 @@ static struct commit *mapped_commit(kh_oid_map_t *replayed_commits,
struct commit *commit,
struct commit *fallback)
{
- khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid);
+ khint_t pos;
+ if (!commit)
+ return fallback;
+ pos = kh_get_oid_map(replayed_commits, commit->object.oid);
if (pos == kh_end(replayed_commits))
return fallback;
return kh_value(replayed_commits, pos);
@@ -225,16 +228,24 @@ 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;
+ base_tree = repo_get_commit_tree(repo, base);
+ } else {
+ base = NULL;
+ base_tree = lookup_tree(repo, repo->hash_algo->empty_tree);
+ }
+ replayed_base = mapped_commit(replayed_commits, base, onto);
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);
- merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
+ if (pickme->parents)
+ merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
+ else
+ merge_opt->ancestor = xstrdup("empty tree");
merge_incore_nonrecursive(merge_opt,
base_tree,
@@ -293,8 +304,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 +318,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,