[PATCH] builtin-revert: Make use of merge_recursive()
From: Stephan Beyer <hidden>
Date: 2016-06-15 22:45:08
Subsystem:
the rest · Maintainer:
Linus Torvalds
Cherry-pick and revert always ran the merging in a separate process. This patch makes cherry-pick/revert call merge_recursive() instead of running git-merge-recursive. To be able to cherry-pick/revert -n (without committing) on a dirty index, make_virtual_commit() is needed and thus declared non-static. Also the GITHEAD_* environment definitions are not needed anymore, since the names are direct arguments to make_virtual_commit() and merge_recursive(). Signed-off-by: Stephan Beyer <redacted> --- Hi, so I give it a new try. builtin-merge-recursive.c | 2 +- builtin-revert.c | 56 +++++++++++++++++++++++++------------------- merge-recursive.h | 2 + 3 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/builtin-merge-recursive.c b/builtin-merge-recursive.c
index 09aa830..395bdf8 100644
--- a/builtin-merge-recursive.c
+++ b/builtin-merge-recursive.c@@ -42,7 +42,7 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two) * - *(int *)commit->object.sha1 set to the virtual id. */ -static struct commit *make_virtual_commit(struct tree *tree, const char *comment) +struct commit *make_virtual_commit(struct tree *tree, const char *comment) { struct commit *commit = xcalloc(1, sizeof(struct commit)); static unsigned virtual_id = 1;
diff --git a/builtin-revert.c b/builtin-revert.c
index 27881e9..dcee181 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c@@ -11,6 +11,7 @@ #include "cache-tree.h" #include "diff.h" #include "revision.h" +#include "merge-recursive.h" /* * This implements the builtins revert and cherry-pick.
@@ -200,18 +201,27 @@ static void set_author_ident_env(const char *message) sha1_to_hex(commit->object.sha1)); } -static int merge_recursive(const char *base_sha1, - const char *head_sha1, const char *head_name, - const char *next_sha1, const char *next_name) +static int merge_recursive_helper(const unsigned char *base_sha1, + const unsigned char *head_sha1, const char *head_name, + const unsigned char *next_sha1, const char *next_name) { - char buffer[256]; - const char *argv[6]; - int i = 0; - - sprintf(buffer, "GITHEAD_%s", head_sha1); - setenv(buffer, head_name, 1); - sprintf(buffer, "GITHEAD_%s", next_sha1); - setenv(buffer, next_name, 1); + int clean, index_fd; + struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); + struct commit *result; + struct commit *head_commit, *next_commit; + struct object *head_object = parse_object(head_sha1); + struct commit_list *ca = NULL; + + if (base_sha1) { + struct commit *base = lookup_commit_reference(base_sha1); + commit_list_insert(base, &ca); + } + if (head_object->type == OBJ_TREE) + head_commit = make_virtual_commit((struct tree *)head_object, + head_name); + else + head_commit = (struct commit *)head_object; + next_commit = lookup_commit_reference(next_sha1); /* * This three way merge is an interesting one. We are at
@@ -219,15 +229,15 @@ static int merge_recursive(const char *base_sha1, * and $prev on top of us (when reverting), or the change between * $prev and $commit on top of us (when cherry-picking or replaying). */ - argv[i++] = "merge-recursive"; - if (base_sha1) - argv[i++] = base_sha1; - argv[i++] = "--"; - argv[i++] = head_sha1; - argv[i++] = next_sha1; - argv[i++] = NULL; - - return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN | RUN_GIT_CMD); + index_fd = hold_locked_index(lock, 1); + clean = merge_recursive(head_commit, next_commit, + head_name, next_name, ca, &result); + if (active_cache_changed && + (write_cache(index_fd, active_cache, active_nr) || + commit_locked_index(lock))) + die("Unable to write index."); + + return clean ? 0 : 1; } static char *help_msg(const unsigned char *sha1)
@@ -373,10 +383,8 @@ static int revert_or_cherry_pick(int argc, const char **argv) } } - if (merge_recursive(base == NULL ? - NULL : sha1_to_hex(base->object.sha1), - sha1_to_hex(head), "HEAD", - sha1_to_hex(next->object.sha1), oneline) || + if (merge_recursive_helper(base == NULL ? NULL : base->object.sha1, + head, "HEAD", next->object.sha1, oneline) || write_cache_as_tree(head, 0, NULL)) { add_to_msg("\nConflicts:\n\n"); read_cache();
diff --git a/merge-recursive.h b/merge-recursive.h
index f37630a..a9eead3 100644
--- a/merge-recursive.h
+++ b/merge-recursive.h@@ -1,6 +1,8 @@ #ifndef MERGE_RECURSIVE_H #define MERGE_RECURSIVE_H +extern struct commit *make_virtual_commit(struct tree *tree, + const char *comment); int merge_recursive(struct commit *h1, struct commit *h2, const char *branch1,
--
1.6.0.rc2.267.g02e66a