Skip to content

Commit da54784

Browse files
committed
Merge branch 'tc/replay-down-to-root'
git replay now supports replaying down to the root commit. * tc/replay-down-to-root: replay: support replaying down from root commit
2 parents 03311dc + e8b79a9 commit da54784

2 files changed

Lines changed: 24 additions & 13 deletions

File tree

replay.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@ static struct commit *mapped_commit(kh_oid_map_t *replayed_commits,
254254
struct commit *commit,
255255
struct commit *fallback)
256256
{
257-
khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid);
257+
khint_t pos;
258+
if (!commit)
259+
return fallback;
260+
pos = kh_get_oid_map(replayed_commits, commit->object.oid);
258261
if (pos == kh_end(replayed_commits))
259262
return fallback;
260263
return kh_value(replayed_commits, pos);
@@ -271,18 +274,26 @@ static struct commit *pick_regular_commit(struct repository *repo,
271274
struct commit *base, *replayed_base;
272275
struct tree *pickme_tree, *base_tree, *replayed_base_tree;
273276

274-
base = pickme->parents->item;
275-
replayed_base = mapped_commit(replayed_commits, base, onto);
277+
if (pickme->parents) {
278+
base = pickme->parents->item;
279+
base_tree = repo_get_commit_tree(repo, base);
280+
} else {
281+
base = NULL;
282+
base_tree = lookup_tree(repo, repo->hash_algo->empty_tree);
283+
}
276284

285+
replayed_base = mapped_commit(replayed_commits, base, onto);
277286
replayed_base_tree = repo_get_commit_tree(repo, replayed_base);
278287
pickme_tree = repo_get_commit_tree(repo, pickme);
279-
base_tree = repo_get_commit_tree(repo, base);
280288

281289
if (mode == REPLAY_MODE_PICK) {
282290
/* Cherry-pick: normal order */
283291
merge_opt->branch1 = short_commit_name(repo, replayed_base);
284292
merge_opt->branch2 = short_commit_name(repo, pickme);
285-
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
293+
if (pickme->parents)
294+
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
295+
else
296+
merge_opt->ancestor = xstrdup("empty tree");
286297

287298
merge_incore_nonrecursive(merge_opt,
288299
base_tree,
@@ -364,8 +375,6 @@ int replay_revisions(struct rev_info *revs,
364375
set_up_replay_mode(revs->repo, &revs->cmdline, opts->onto,
365376
&detached_head, &advance, &revert, &onto, &update_refs);
366377

367-
/* FIXME: Should allow replaying commits with the first as a root commit */
368-
369378
if (prepare_revision_walk(revs) < 0) {
370379
ret = error(_("error preparing revisions"));
371380
goto out;
@@ -380,9 +389,7 @@ int replay_revisions(struct rev_info *revs,
380389
khint_t pos;
381390
int hr;
382391

383-
if (!commit->parents)
384-
die(_("replaying down from root commit is not supported yet!"));
385-
if (commit->parents->next)
392+
if (commit->parents && commit->parents->next)
386393
die(_("replaying merge commits is not supported yet!"));
387394

388395
last_commit = pick_regular_commit(revs->repo, commit, replayed_commits,

t/t3650-replay-basics.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,13 @@ test_expect_success 'exactly one of --onto, --advance, or --revert is required'
8181
test_cmp expect actual
8282
'
8383

84-
test_expect_success 'no base or negative ref gives no-replaying down to root error' '
85-
echo "fatal: replaying down from root commit is not supported yet!" >expect &&
86-
test_must_fail git replay --onto=topic1 topic2 2>actual &&
84+
test_expect_success 'replay down to root onto another branch' '
85+
git replay --ref-action=print --onto main topic2 >result &&
86+
87+
test_line_count = 1 result &&
88+
89+
git log --format=%s $(cut -f 3 -d " " result) >actual &&
90+
test_write_lines E D C M L B A >expect &&
8791
test_cmp expect actual
8892
'
8993

0 commit comments

Comments
 (0)