struct commit *onto,
struct merge_options *merge_opt,
struct merge_result *result,
- enum replay_mode mode)
+ enum replay_mode mode,
+ enum replay_empty_commit_action empty)
{
struct commit *base, *replayed_base;
struct tree *pickme_tree, *base_tree, *replayed_base_tree;
}
merge_opt->ancestor = NULL;
merge_opt->branch2 = NULL;
+
if (!result->clean)
return NULL;
- /* Drop commits that become empty */
+
+ /* Handle commits that become empty */
if (oideq(&replayed_base_tree->object.oid, &result->tree->object.oid) &&
- !oideq(&pickme_tree->object.oid, &base_tree->object.oid))
- return replayed_base;
+ !oideq(&pickme_tree->object.oid, &base_tree->object.oid)) {
+ switch (empty) {
+ case REPLAY_EMPTY_COMMIT_DROP:
+ return replayed_base;
+ case REPLAY_EMPTY_COMMIT_KEEP:
+ break;
+ case REPLAY_EMPTY_COMMIT_ABORT:
+ result->clean = error(_("commit %s became empty after replay"),
+ oid_to_hex(&pickme->object.oid));
+ return NULL;
+ }
+ }
+
return create_commit(repo, result->tree, pickme, replayed_base, mode);
}
last_commit = pick_regular_commit(revs->repo, commit, replayed_commits,
mode == REPLAY_MODE_REVERT ? last_commit : onto,
- &merge_opt, &result, mode);
+ &merge_opt, &result, mode, opts->empty);
if (!last_commit)
break;
}
}
+ if (result.clean < 0) {
+ ret = -1;
+ goto out;
+ }
+
if (!result.clean) {
ret = 1;
goto out;
struct repository;
struct rev_info;
+/*
+ * Controls what happens when a replayed commit becomes empty (i.e. its tree
+ * is identical to its parent's tree after the replay).
+ */
+enum replay_empty_commit_action {
+ /* Silently discard the empty commit. */
+ REPLAY_EMPTY_COMMIT_DROP,
+ /* Keep the empty commit as-is. */
+ REPLAY_EMPTY_COMMIT_KEEP,
+ /* Abort with an error. */
+ REPLAY_EMPTY_COMMIT_ABORT,
+};
+
/*
* A set of options that can be passed to `replay_revisions()`.
*/
* Requires `onto` to be set.
*/
int contained;
+
+ /*
+ * Controls what to do when a replayed commit becomes empty.
+ * Defaults to REPLAY_EMPTY_COMMIT_DROP.
+ */
+ enum replay_empty_commit_action empty;
};
/* This struct is used as an out-parameter by `replay_revisions()`. */