Skip to content

Commit e8b79a9

Browse files
To1negitster
authored andcommitted
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>
1 parent ca1db8a commit e8b79a9

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
@@ -209,7 +209,10 @@ static struct commit *mapped_commit(kh_oid_map_t *replayed_commits,
209209
struct commit *commit,
210210
struct commit *fallback)
211211
{
212-
khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid);
212+
khint_t pos;
213+
if (!commit)
214+
return fallback;
215+
pos = kh_get_oid_map(replayed_commits, commit->object.oid);
213216
if (pos == kh_end(replayed_commits))
214217
return fallback;
215218
return kh_value(replayed_commits, pos);
@@ -225,16 +228,24 @@ static struct commit *pick_regular_commit(struct repository *repo,
225228
struct commit *base, *replayed_base;
226229
struct tree *pickme_tree, *base_tree, *replayed_base_tree;
227230

228-
base = pickme->parents->item;
229-
replayed_base = mapped_commit(replayed_commits, base, onto);
231+
if (pickme->parents) {
232+
base = pickme->parents->item;
233+
base_tree = repo_get_commit_tree(repo, base);
234+
} else {
235+
base = NULL;
236+
base_tree = lookup_tree(repo, repo->hash_algo->empty_tree);
237+
}
230238

239+
replayed_base = mapped_commit(replayed_commits, base, onto);
231240
replayed_base_tree = repo_get_commit_tree(repo, replayed_base);
232241
pickme_tree = repo_get_commit_tree(repo, pickme);
233-
base_tree = repo_get_commit_tree(repo, base);
234242

235243
merge_opt->branch1 = short_commit_name(repo, replayed_base);
236244
merge_opt->branch2 = short_commit_name(repo, pickme);
237-
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
245+
if (pickme->parents)
246+
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
247+
else
248+
merge_opt->ancestor = xstrdup("empty tree");
238249

239250
merge_incore_nonrecursive(merge_opt,
240251
base_tree,
@@ -293,8 +304,6 @@ int replay_revisions(struct rev_info *revs,
293304
set_up_replay_mode(revs->repo, &revs->cmdline, opts->onto,
294305
&detached_head, &advance, &onto, &update_refs);
295306

296-
/* FIXME: Should allow replaying commits with the first as a root commit */
297-
298307
if (prepare_revision_walk(revs) < 0) {
299308
ret = error(_("error preparing revisions"));
300309
goto out;
@@ -309,9 +318,7 @@ int replay_revisions(struct rev_info *revs,
309318
khint_t pos;
310319
int hr;
311320

312-
if (!commit->parents)
313-
die(_("replaying down from root commit is not supported yet!"));
314-
if (commit->parents->next)
321+
if (commit->parents && commit->parents->next)
315322
die(_("replaying merge commits is not supported yet!"));
316323

317324
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 'option --onto or --advance is mandatory' '
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)