git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] builtin-revert: Make use of merge_recursive()

From
Stephan Beyer <s-beyer@gmx.net>
Date
Aug 11, 2008, 21:44 UTC
Message-ID
<1218491096-28756-1-git-send-email-s-beyer@gmx.net>
In-Reply-To
<20080811190924.GR18960@genesis.frugalware.org>

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 <s-beyer@gmx.net>
---
	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
Previous: Miklos VajnaNext: Stephan Beyer
Message 17 of 38 in “Avoid run_command() for recursive in builtin-merge”
  1. 0/2 Avoid run_command() for recursive in builtin-mergeMiklos Vajna, Aug 10, 2008
  2. 1/2 merge-recursive: prepare merge_recursive() to be called from builtinsMiklos Vajna, Aug 10, 2008
  3. 2/2 builtin-merge: avoid run_command_v_opt() for recursiveMiklos Vajna, Aug 10, 2008
  4. Junio C HamanoAug 11, 2008
  5. Miklos VajnaAug 11, 2008
  6. Junio C HamanoAug 11, 2008
  7. Miklos VajnaAug 11, 2008
  8. Add a new test to ensure merging a submodule is handled properly.Miklos Vajna, Aug 11, 2008
  9. Stephan BeyerAug 11, 2008
  10. Miklos VajnaAug 11, 2008
  11. Junio C HamanoAug 11, 2008
  12. Stephan BeyerAug 11, 2008
  13. builtin-revert.c: Make use of merge_recursive()Stephan Beyer, Aug 11, 2008
  14. Johannes SchindelinAug 11, 2008
  15. Stephan BeyerAug 11, 2008
  16. Miklos VajnaAug 11, 2008
  17. builtin-revert: Make use of merge_recursive()Stephan Beyer, Aug 11, 2008
  18. Stephan BeyerAug 11, 2008
  19. Junio C HamanoAug 11, 2008
  20. Junio C HamanoAug 11, 2008
  21. Stephan BeyerAug 11, 2008
  22. Junio C HamanoAug 11, 2008
  23. Split out merge_recursive() to merge-recursive.cMiklos Vajna, Aug 12, 2008
  24. Stephan BeyerAug 12, 2008
  25. Miklos VajnaAug 12, 2008
  26. merge-recursive.c: Add more generic merge_recursive_generic()Stephan Beyer, Aug 12, 2008
  27. Make builtin-revert.c use merge_recursive_generic()Stephan Beyer, Aug 12, 2008
  28. Miklos VajnaAug 12, 2008
  29. Stephan BeyerAug 13, 2008
  30. Miklos VajnaAug 13, 2008
  31. Daniel BarkalowAug 13, 2008
  32. Stephan BeyerAug 13, 2008
  33. Daniel BarkalowAug 13, 2008
  34. Junio C HamanoAug 13, 2008
  35. Stephan BeyerAug 13, 2008
  36. Daniel BarkalowAug 13, 2008
  37. Junio C HamanoAug 13, 2008
  38. Junio C HamanoAug 14, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.