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

[PATCH] Use diff3 instead of merge in merge-recursive.

From
Uwe Zeisberger <zeisberg@informatik.uni-freiburg.de>
Date
Oct 18, 2006, 08:59 UTC
Message-ID
<20061018085949.GA26501@cepheus.pub>
If no error occurs, merge (from rcs 5.7) is nothing but:
	diff3 -E -am -L label1 -L label2 -L label3 file1 file2 file3 > tmpfile
	cat tmpfile > file1
Using diff3 directly saves one fork per conflicting file.
Signed-off-by: Uwe Zeisberger <zeisberg@informatik.uni-freiburg.de>
---
 merge-recursive.c |   34 +++++++++++++++++++++++-----------
 1 files changed, 23 insertions(+), 11 deletions(-)

It passes `make test` when NO_SVN_TESTS is defined. (I'll write a separate mail about that.)

I didn't made any timing tests or further tests for correctness, but I hope Johannes still has the framework from the time when he converted the Python script to C?

@Johannes: If so, could you test this patch?

Best regards Uwe

diff --git a/merge-recursive.c b/merge-recursive.c
index 2ba43ae..9e3f9d7 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -657,8 +657,11 @@ static struct merge_file_info merge_file
 			char orig[PATH_MAX];
 			char src1[PATH_MAX];
 			char src2[PATH_MAX];
+			char tmppath[PATH_MAX];
+
 			const char *argv[] = {
-				"merge", "-L", NULL, "-L", NULL, "-L", NULL,
+				"diff3", "-E", "-am",
+				"-L", NULL, "-L", NULL, "-L", NULL,
 				NULL, NULL, NULL,
 				NULL
 			};
@@ -668,23 +671,31 @@ static struct merge_file_info merge_file
 			git_unpack_file(a->sha1, src1);
 			git_unpack_file(b->sha1, src2);
 
-			argv[2] = la = xstrdup(mkpath("%s/%s", branch1, a->path));
-			argv[6] = lb = xstrdup(mkpath("%s/%s", branch2, b->path));
-			argv[4] = lo = xstrdup(mkpath("orig/%s", o->path));
-			argv[7] = src1;
-			argv[8] = orig;
-			argv[9] = src2,
+			argv[4] = la = xstrdup(mkpath("%s/%s", branch1, a->path));
+			argv[8] = lb = xstrdup(mkpath("%s/%s", branch2, b->path));
+			argv[6] = lo = xstrdup(mkpath("orig/%s", o->path));
+			argv[9] = src1;
+			argv[10] = orig;
+			argv[11] = src2;
+
+			fd = git_mkstemp(tmppath, sizeof(tmppath),
+					".merge_file_XXXXXX");
+			if (fd < 0)
+				die("unable to create temp-file");
+
+			dup2(fd, 1);
+			close(fd);
 
-			code = run_command_v(10, argv);
+			code = run_command_v(12, argv);
 
 			free(la);
 			free(lb);
 			free(lo);
 			if (code && code < -256) {
-				die("Failed to execute 'merge'. merge(1) is used as the "
-				    "file-level merge tool. Is 'merge' in your path?");
+				die("Failed to execute 'diff3'. diff3(1) is used as the "
+				    "file-level merge tool. Is 'diff3' in your path?");
 			}
-			fd = open(src1, O_RDONLY);
+			fd = open(tmppath, O_RDONLY);
 			if (fd < 0 || fstat(fd, &st) < 0 ||
 					index_fd(result.sha, fd, &st, 1,
 						"blob"))
@@ -693,6 +704,7 @@ static struct merge_file_info merge_file
 			unlink(orig);
 			unlink(src1);
 			unlink(src2);
+			unlink(tmppath);
 
 			result.clean = WEXITSTATUS(code) == 0;
 		} else {
-- 
1.4.3.rc2

-- 
Uwe Zeisberger

http://www.google.com/search?q=1+newton+in+kg*m+%2F+s%5E2
Next: Jakub Narebski
Message 1 of 8 in “Use diff3 instead of merge in merge-recursive.”
  1. Use diff3 instead of merge in merge-recursive.Uwe Zeisberger, Oct 18, 2006
  2. Jakub NarebskiOct 18, 2006
  3. Johannes SchindelinOct 18, 2006
  4. Linus TorvaldsOct 18, 2006
  5. Daniel BarkalowOct 19, 2006
  6. Johannes SchindelinOct 18, 2006
  7. Uwe ZeisbergerOct 20, 2006
  8. Johannes SchindelinOct 21, 2006

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.