summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Claes <toon@iotcl.com>2026-08-31 15:13:48 +0200
committerJunio C Hamano <gitster@pobox.com>2026-08-31 10:29:06 -0700
commit446099ef7c6106a73143a651967a6424328c53dd (patch)
treeb86cc50f8f49e0bfb89ae3611319b6dd9ee0a2e9
parent98b33a62f604c608ae2648750de767b23e961e67 (diff)
replay: resolve the replay base outside pick_regular_commit()
Depending on what gets passed into the function pick_regular_commit(), it decides the new base for the replayed commit. It first tries to find the replayed results of `pickme`'s parent in the `replayed_commits` map. If not found, it falls back to `onto`. When using git-replay(1) with --onto, the fallback is the revision passed in with this option, but when using --revert, the fallback is `last_commit`. It's rather confusing the base is decided partly inside pick_regular_commit() and partly by its caller. Move the base selection completely into the caller: replay_revisions(). This bundles all the logic of deciding on the base together. Also, this reduces the number of parameters of pick_regular_commit(), making its interface cleaner. This refactoring doesn't bring any behavior changes. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--replay.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/replay.c b/replay.c
index 860e194ba0..7e35f40d37 100644
--- a/replay.c
+++ b/replay.c
@@ -284,25 +284,19 @@ static void put_mapped_commit(kh_oid_map_t *replayed_commits,
static struct commit *pick_regular_commit(struct repository *repo,
struct commit *pickme,
- kh_oid_map_t *replayed_commits,
- struct commit *onto,
+ struct commit *replayed_base,
struct merge_options *merge_opt,
struct merge_result *result,
enum replay_mode mode,
enum replay_empty_commit_action empty)
{
- struct commit *base, *replayed_base;
struct tree *pickme_tree, *base_tree, *replayed_base_tree;
- if (pickme->parents) {
- base = pickme->parents->item;
- base_tree = repo_get_commit_tree(repo, base);
- } else {
- base = NULL;
+ if (pickme->parents)
+ base_tree = repo_get_commit_tree(repo, pickme->parents->item);
+ else
base_tree = lookup_tree(repo, repo->hash_algo->empty_tree);
- }
- replayed_base = get_mapped_commit(replayed_commits, base, onto);
replayed_base_tree = repo_get_commit_tree(repo, replayed_base);
pickme_tree = repo_get_commit_tree(repo, pickme);
@@ -443,12 +437,26 @@ int replay_revisions(struct rev_info *revs,
while ((commit = get_revision(revs))) {
const struct name_decoration *decoration;
+ /*
+ * Decide where to replay this commit on.
+ * If the parent commit was replayed already, the replayed result
+ * can be found in `replayed_commits`. Otherwise fall back to `onto`.
+ * When reverting, commits are replayed in reverse order and thus
+ * its parent isn't replayed yet. Therefore revert commits are
+ * always replayed onto `last_commit`.
+ */
+ struct commit *parent = commit->parents ? commit->parents->item : NULL;
+ struct commit *base = get_mapped_commit(replayed_commits, parent, 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,
- &merge_opt, &result, mode, opts->empty);
+ last_commit = pick_regular_commit(revs->repo, commit, base,
+ &merge_opt, &result,
+ mode, opts->empty);
if (!last_commit)
break;