From: Toon Claes Date: Fri, 26 Jun 2026 05:48:12 GMT Subject: [PATCH v5 2/3] replay: better explain how pick_regular_commit() picks a base Message-ID: <20260626-toon-git-replay-drop-merges-v5-2-5e120738b9d0@iotcl.com> In-Reply-To: <20260626-toon-git-replay-drop-merges-v5-0-5e120738b9d0@iotcl.com> The function pick_regular_commit() will replay the `pickme` commit. To determine the ancestor where to replay this commit on, it takes the parent of the commit and looks up its replayed result in `replayed_commits`. If no ancestor is found, the `onto` parameter is used as fallback. The name `onto` is rather confusing, so rename it to `default_base`. And while at it, shuffle the function parameters so `struct commit` parameters are immediate siblings. When in mode REPLAY_MODE_REVERT, the fallback `default_base` will always be used. This happens because commits are replayed in reverse order, so looking up the `pickme`'s parent in `replayed_commits` will always return empty. And to make these commits stack on top of each other, we need to pass in `last_commit`. Signed-off-by: Toon Claes --- replay.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/replay.c b/replay.c index 7bde1c7e93..86fba47fb9 100644 --- a/replay.c +++ b/replay.c @@ -280,8 +280,8 @@ static void put_mapped_commit(kh_oid_map_t *replayed_commits, static struct commit *pick_regular_commit(struct repository *repo, struct commit *pickme, + struct commit *default_base, kh_oid_map_t *replayed_commits, - struct commit *onto, struct merge_options *merge_opt, struct merge_result *result, enum replay_mode mode, @@ -298,7 +298,7 @@ static struct commit *pick_regular_commit(struct repository *repo, base_tree = lookup_tree(repo, repo->hash_algo->empty_tree); } - replayed_base = get_mapped_commit(replayed_commits, base, onto); + replayed_base = get_mapped_commit(replayed_commits, base, default_base); replayed_base_tree = repo_get_commit_tree(repo, replayed_base); pickme_tree = repo_get_commit_tree(repo, pickme); @@ -439,11 +439,23 @@ int replay_revisions(struct rev_info *revs, while ((commit = get_revision(revs))) { const struct name_decoration *decoration; + /* + * pick_regular_commit() looks up the parent of `commit` in + * `replayed_commits` to determine the ancestor to replay onto. + * The `default_base` parameter is used when no ancestor is found, + * which happens for the first commit in the revision range. + * When reverting, commits are replayed in reverse order, so the + * lookup never succeeds, and we need to pass `last_commit`. + */ + struct commit *base = onto; + if (mode == REPLAY_MODE_REVERT) + base = last_commit; + if (commit->parents && commit->parents->next) die(_("replaying merge commits is not supported yet!")); - last_commit = pick_regular_commit(revs->repo, commit, replayed_commits, - mode == REPLAY_MODE_REVERT ? last_commit : onto, + last_commit = pick_regular_commit(revs->repo, commit, base, + replayed_commits, &merge_opt, &result, mode, opts->empty); if (!last_commit) break; -- 2.53.0.1323.g189a785ab5