diff --git a/builtin/merge-resolve.c b/builtin/merge-resolve.c
index 2c364fcdb0..59f734473b 100644
--- a/builtin/merge-resolve.c
+++ b/builtin/merge-resolve.c
@@ -10,92 +10,8 @@
  */
 
 #include "cache.h"
-#include "cache-tree.h"
 #include "builtin.h"
-#include "lockfile.h"
 #include "merge-strategies.h"
-#include "unpack-trees.h"
-
-static int add_tree(const struct object_id *oid, struct tree_desc *t)
-{
-	struct tree *tree;
-
-	tree = parse_tree_indirect(oid);
-	if (parse_tree(tree))
-		return -1;
-
-	init_tree_desc(t, tree->buffer, tree->size);
-	return 0;
-}
-
-static int merge_resolve(struct commit_list *bases, const char *head_arg,
-			 struct commit_list *remote)
-{
-	int i = 0;
-	struct lock_file lock = LOCK_INIT;
-	struct tree_desc t[MAX_UNPACK_TREES];
-	struct unpack_trees_options opts;
-	struct object_id head, oid;
-	struct commit_list *j;
-
-	if (head_arg)
-		get_oid(head_arg, &head);
-
-	repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
-	refresh_index(the_repository->index, 0, NULL, NULL, NULL);
-
-	memset(&opts, 0, sizeof(opts));
-	opts.head_idx = 1;
-	opts.src_index = the_repository->index;
-	opts.dst_index = the_repository->index;
-	opts.update = 1;
-	opts.merge = 1;
-	opts.aggressive = 1;
-
-	for (j = bases; j; j = j->next) {
-		if (add_tree(&j->item->object.oid, t + (i++)))
-			goto out;
-	}
-
-	if (head_arg && add_tree(&head, t + (i++)))
-		goto out;
-	if (remote && add_tree(&remote->item->object.oid, t + (i++)))
-		goto out;
-
-	if (i == 1)
-		opts.fn = oneway_merge;
-	else if (i == 2) {
-		opts.fn = twoway_merge;
-		opts.initial_checkout = is_index_unborn(the_repository->index);
-	} else if (i >= 3) {
-		opts.fn = threeway_merge;
-		opts.head_idx = i - 1;
-	}
-
-	if (unpack_trees(i, t, &opts))
-		goto out;
-
-	puts("Trying simple merge.");
-	write_locked_index(the_repository->index, &lock, COMMIT_LOCK);
-
-	if (write_index_as_tree(&oid, the_repository->index,
-				the_repository->index_file, 0, NULL)) {
-		int ret;
-
-		repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
-		ret = merge_all(the_repository->index, 0, 0,
-				merge_one_file_cb, the_repository);
-
-		write_locked_index(the_repository->index, &lock, COMMIT_LOCK);
-		return !!ret;
-	}
-
-	return 0;
-
- out:
-	rollback_lock_file(&lock);
-	return 2;
-}
 
 static const char builtin_merge_resolve_usage[] =
 	"git merge-resolve <bases>... -- <head> <remote>";
@@ -149,5 +65,5 @@ int cmd_merge_resolve(int argc, const char **argv, const char *prefix)
 	if (is_baseless)
 		return 2;
 
-	return merge_resolve(bases, head, remote);
+	return merge_strategies_resolve(the_repository, bases, head, remote);
 }
diff --git a/merge-strategies.c b/merge-strategies.c
index 39bfa1af7b..a12c575590 100644
--- a/merge-strategies.c
+++ b/merge-strategies.c
@@ -1,7 +1,10 @@
 #include "cache.h"
+#include "cache-tree.h"
 #include "dir.h"
+#include "lockfile.h"
 #include "merge-strategies.h"
 #include "run-command.h"
+#include "unpack-trees.h"
 #include "xdiff-interface.h"
 
 static int add_to_index_cacheinfo(struct index_state *istate,
@@ -299,3 +302,85 @@ int merge_all(struct index_state *istate, int oneshot, int quiet,
 
 	return err;
 }
+
+static int add_tree(const struct object_id *oid, struct tree_desc *t)
+{
+	struct tree *tree;
+
+	tree = parse_tree_indirect(oid);
+	if (parse_tree(tree))
+		return -1;
+
+	init_tree_desc(t, tree->buffer, tree->size);
+	return 0;
+}
+
+int merge_strategies_resolve(struct repository *r,
+			     struct commit_list *bases, const char *head_arg,
+			     struct commit_list *remote)
+{
+	int i = 0;
+	struct lock_file lock = LOCK_INIT;
+	struct tree_desc t[MAX_UNPACK_TREES];
+	struct unpack_trees_options opts;
+	struct object_id head, oid;
+	struct commit_list *j;
+
+	if (head_arg)
+		get_oid(head_arg, &head);
+
+	repo_hold_locked_index(r, &lock, LOCK_DIE_ON_ERROR);
+	refresh_index(r->index, 0, NULL, NULL, NULL);
+
+	memset(&opts, 0, sizeof(opts));
+	opts.head_idx = 1;
+	opts.src_index = r->index;
+	opts.dst_index = r->index;
+	opts.update = 1;
+	opts.merge = 1;
+	opts.aggressive = 1;
+
+	for (j = bases; j && j->item; j = j->next) {
+		if (add_tree(&j->item->object.oid, t + (i++)))
+			goto out;
+	}
+
+	if (head_arg && add_tree(&head, t + (i++)))
+		goto out;
+	if (remote && add_tree(&remote->item->object.oid, t + (i++)))
+		goto out;
+
+	if (i == 1)
+		opts.fn = oneway_merge;
+	else if (i == 2) {
+		opts.fn = twoway_merge;
+		opts.initial_checkout = is_index_unborn(r->index);
+	} else if (i >= 3) {
+		opts.fn = threeway_merge;
+		opts.head_idx = i - 1;
+	}
+
+	if (unpack_trees(i, t, &opts))
+		goto out;
+
+	puts("Trying simple merge.");
+	write_locked_index(r->index, &lock, COMMIT_LOCK);
+
+	if (write_index_as_tree(&oid, r->index, r->index_file,
+				WRITE_TREE_SILENT, NULL)) {
+		int ret;
+
+		puts("Simple merge failed, trying Automatic merge.");
+		repo_hold_locked_index(r, &lock, LOCK_DIE_ON_ERROR);
+		ret = merge_all(r->index, 0, 0, merge_one_file_cb, r);
+
+		write_locked_index(r->index, &lock, COMMIT_LOCK);
+		return !!ret;
+	}
+
+	return 0;
+
+ out:
+	rollback_lock_file(&lock);
+	return 2;
+}
diff --git a/merge-strategies.h b/merge-strategies.h
index 40e175ca39..778f8ce9d6 100644
--- a/merge-strategies.h
+++ b/merge-strategies.h
@@ -1,6 +1,7 @@
 #ifndef MERGE_STRATEGIES_H
 #define MERGE_STRATEGIES_H
 
+#include "commit.h"
 #include "object.h"
 
 int merge_strategies_one_file(struct repository *r,
@@ -33,4 +34,8 @@ int merge_one_path(struct index_state *istate, int oneshot, int quiet,
 int merge_all(struct index_state *istate, int oneshot, int quiet,
 	      merge_cb cb, void *data);
 
+int merge_strategies_resolve(struct repository *r,
+			     struct commit_list *bases, const char *head_arg,
+			     struct commit_list *remote);
+
 #endif /* MERGE_STRATEGIES_H */
