struct commit *head_commit, *merge_commit, *i;
struct commit_list *common, *j, *reversed = NULL;
struct merge_options o;
- int ret;
+ int can_fast_forward, ret;
static struct lock_file lock;
for (merge_arg_len = 0; merge_arg_len < arg_len; merge_arg_len++)
strbuf_release(&buf);
}
+ /*
+ * If HEAD is not identical to the parent of the original merge commit,
+ * we cannot fast-forward.
+ */
+ can_fast_forward = opts->allow_ff && commit && commit->parents &&
+ !oidcmp(&commit->parents->item->object.oid,
+ &head_commit->object.oid);
+
strbuf_addf(&ref_name, "refs/rewritten/%.*s", merge_arg_len, arg);
merge_commit = lookup_commit_reference_by_name(ref_name.buf);
if (!merge_commit) {
rollback_lock_file(&lock);
return -1;
}
+
+ if (can_fast_forward && commit->parents->next &&
+ !commit->parents->next->next &&
+ !oidcmp(&commit->parents->next->item->object.oid,
+ &merge_commit->object.oid)) {
+ strbuf_release(&ref_name);
+ rollback_lock_file(&lock);
+ return fast_forward_to(&commit->object.oid,
+ &head_commit->object.oid, 0, opts);
+ }
+
write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
git_path_merge_head(), 0);
write_message("no-ff", 5, git_path_merge_mode(), 0);