[PATCH] merge-recursive: configurable 'merge' program

Subsystems: the rest

STALE3708d

8 messages, 3 authors, 2016-08-11 · open the first message on its own page

[PATCH] merge-recursive: configurable 'merge' program

From: Sam Vilain <hidden>
Date: 2016-08-11 19:37:28

For those who like to spawn interactive merge tools on a merge failure
or otherwise run some kind of script, allow a "merge.tool" repo-config
option that will take arguments as merge(1) does.
---
 merge-recursive.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

Here's the script I use:

#!/bin/sh

output=`mktemp -p . .merge_file_XXXXXX`
branch1="$7"
branch2="$9"
ancestor="$8"

cp $branch1 $output

if merge -L $2 -L $4 -L $6 $output $ancestor $branch2
then
    mv $output $branch1
    exit 0
else

    rm $output

    emacs --eval "(ediff-merge-files-with-ancestor \"${branch1}\" 
\"${branch2}\" \"${ancestor}\" nil \"${output}\")"

    if [ -s "$output" ]
    then
        mv $output $branch1
        exit 0
    else
        exit 1
    fi
fi
diff --git a/merge-recursive.c b/merge-recursive.c
index 5a70a5c..0e2da57 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -627,6 +627,8 @@ static char *git_unpack_file(const unsigned char *sha1, char *path)
 	return path;
 }
 
+static char* merge_tool = "merge";
+
 static struct merge_file_info merge_file(struct diff_filespec *o,
 		struct diff_filespec *a, struct diff_filespec *b,
 		const char *branch1, const char *branch2)
@@ -661,12 +663,14 @@ static struct merge_file_info merge_file(struct diff_filespec *o,
 			char src1[PATH_MAX];
 			char src2[PATH_MAX];
 			const char *argv[] = {
-				"merge", "-L", NULL, "-L", NULL, "-L", NULL,
+				NULL, "-L", NULL, "-L", NULL, "-L", NULL,
 				NULL, NULL, NULL,
 				NULL
 			};
 			char *la, *lb, *lo;
 
+			argv[0] = merge_tool;
+
 			git_unpack_file(o->sha1, orig);
 			git_unpack_file(a->sha1, src1);
 			git_unpack_file(b->sha1, src2);
@@ -1134,6 +1138,21 @@ static int process_entry(const char *path, struct stage_data *entry,
 	return clean_merge;
 }
 
+static int
+git_merge_config(const char *key, const char *val)
+{
+	char merge_key[] = "merge.";
+	if (strncmp( key, merge_key, sizeof merge_key - 1 ))
+		return 0;
+	key += sizeof merge_key - 1;
+
+	if (!strcmp( "tool", key )) {
+	    merge_tool = xstrdup(val);
+	}
+
+	return 0;
+}
+
 static int merge_trees(struct tree *head,
 		       struct tree *merge,
 		       struct tree *common,
@@ -1148,6 +1167,8 @@ static int merge_trees(struct tree *head,
 		return 1;
 	}
 
+	git_config( git_merge_config );
+
 	code = git_merge_trees(index_only, common, head, merge);
 
 	if (code != 0)
-- 
1.4.4.1.ge918e-dirty

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Johannes Schindelin <hidden>
Date: 2016-08-11 19:17:15

Hi,

On Tue, 5 Dec 2006, Jakub Narebski wrote:
Hmmm... is there a way to pass merge.tool / merge.onefile program the 
info if it is invoked in final stage (here it is nice to invoke 
graphical merge tool to resolve conflicts in working area before 
commiting merge result) and in recursive stage (here it would be better 
to leave conflict markers to be resolved later)?
In a sense, you get that information: "merge" is called as

$ merge -L new1 -L orig -L new2 fnew1 forig fnew2

where few1 is the filename of the _temporary_ file, and new1 is the name 
that should be displayed instead. For every but the final stage, new1 
begins with "Temporary merge branch".
Hmmm... would it be possible to use xdl_merge() for recursion, and 
graphical merge tool for result? <Checks out earlier discussion>. I 
think yes, because of exposing xdl_merge() in git-merge-onefile...
In "next", only git-merge-recursive is converted to use xdl_merge(), and 
it did not use git-merge-one-file to begin with. Since this is a shell 
script (with a different syntax than merge), it would have to be converted 
to a C builtin first. But feasible: git-merge-one-file takes 7 parameters, 
the first 3 being SHA1s or empty strings. "merge" takes 3 filenames, with 
possibly up to three "-L <name>" pairs before them.

Ciao,
Dscho

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Johannes Schindelin <hidden>
Date: 2016-08-11 19:36:49

Hi,

On Tue, 5 Dec 2006, Jakub Narebski wrote:
Sam Vilain wrote:
quoted
For those who like to spawn interactive merge tools on a merge failure
or otherwise run some kind of script, allow a "merge.tool" repo-config
option that will take arguments as merge(1) does.
How it goes together with merge-recursive rewrite using built-in merge tool
quoted
from xdiff, xdl_merge?
Not a big problem. If people like Sam's patch, it is easy to integrate, 
since it only means that if merge.tool is set to something non-empty, 
xdl_merge is not called, but the merge.tool is forked.

Ciao,
Dscho

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Johannes Schindelin <hidden>
Date: 2016-08-11 19:58:40

Hi,

On Tue, 5 Dec 2006, Jakub Narebski wrote:
By the way, is it [ed: xdl_merge()] replacement for RCS merge, i.e. is 
it file-level merge tool, merge.onefile rather than merge.tool?
It is a C function, but yes, it does what RCS merge does.
What happens if there are multiple merge [contents] conflicts: is 
merge.tool invoked in parallel for each conflict, or is it waiting for 
earlier merge.tool to finish (well, in which case we can always do set 
merge.tool to "<program> &")?
Recursively. It is merge-recursive, so the merges are done sequentially. 
(Have to be, since the result of one merge is reused as one input for the 
next merge.)
And is merge.tool invoked for recursive part of recursive merge 
strategy?
Yes.
This merge startegy depended on resolving conflict markers, i.e. had 
built-in knowledge of 'merge'/'diff3 -E' output.
No. git-merge-recursive never resolved conflict markers, but treated them 
as text.
Besides, it would be useful not only to spawn interactive merge tools, 
but also to use mergers specific for file-type, for example 3DM or 
xmlcmp tools for merging XML files.
If you need that, write a wrapper script, which detects the file type and 
execs the corresponding merge program.

Ciao,
Dscho

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Jakub Narebski <hidden>
Date: 2016-08-11 20:11:04

Hi!

On Tue 5 Dec 2006 Johannes Schindelin wrote:
On Tue 5 Dec 2006 Jakub Narebski wrote:
quoted
By the way is it [ed: xdl_merge()] replacement for RCS merge i.e. is 
it file-level merge tool merge.onefile rather than merge.tool?
Actually by "it" I meant here the value of merge.tool configuration
variable. I think the name of configuration variable should be
merge.onefile and not merge.tool, but this are just details.
 
It is a C function but yes it does what RCS merge does.
And more if I remember correctly.
quoted
What happens if there are multiple merge [contents] conflicts: is 
merge.tool invoked in parallel for each conflict or is it waiting for 
earlier merge.tool to finish (well in which case we can always do set 
merge.tool to "<program> &")?
Recursively. It is merge-recursive so the merges are done sequentially. 
(Have to be since the result of one merge is reused as one input for the 
next merge.)
Hmmm... is there a way to pass merge.tool / merge.onefile program the
info if it is invoked in final stage (here it is nice to invoke graphical
merge tool to resolve conflicts in working area before commiting merge
result) and in recursive stage (here it would be better to leave conflict
markers to be resolved later)?
quoted
And is merge.tool invoked for recursive part of recursive merge 
strategy?
Yes.
Hmmm... would it be possible to use xdl_merge() for recursion, and
graphical merge tool for result? <Checks out earlier discussion>.
I think yes, because of exposing xdl_merge() in git-merge-onefile...
quoted
This merge startegy depended on resolving conflict markers i.e. had 
built-in knowledge of 'merge'/'diff3 -E' output.
No. git-merge-recursive never resolved conflict markers but treated them 
as text.
Hmmm... I wonder if anyone get in real life example conflict markers
to be resolved (in final file)...
quoted
Besides it would be useful not only to spawn interactive merge tools 
but also to use mergers specific for file-type for example 3DM or 
xmlcmp tools for merging XML files.
If you need that write a wrapper script which detects the file type and 
execs the corresponding merge program.
That was meant as an example why one might want to use 
merge.tool / merge.onefile feature.

-- 
Jakub Narebski

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Jakub Narebski <hidden>
Date: 2016-08-11 20:11:29

Johannes Schindelin wrote:
On Tue 5 Dec 2006 Jakub Narebski wrote:
quoted
Sam Vilain wrote:
quoted
For those who like to spawn interactive merge tools on a merge failure
or otherwise run some kind of script allow a "merge.tool" repo-config
option that will take arguments as merge(1) does.
How it goes together with merge-recursive rewrite using built-in merge tool
from xdiff xdl_merge?
Not a big problem. If people like Sam's patch it is easy to integrate 
since it only means that if merge.tool is set to something non-empty 
xdl_merge is not called but the merge.tool is forked.
Good idea. By the way, is it replacement for RCS merge, i.e. is it
file-level merge tool, merge.onefile rather than merge.tool? What happens
if there are multiple merge [contents] conflicts: is merge.tool invoked
in parallel for each conflict, or is it waiting for earlier merge.tool
to finish (well, in which case we can always do set merge.tool to 
"<program> &")? And is merge.tool invoked for recursive part of recursive
merge strategy? This merge startegy depended on resolving conflict
markers, i.e. had built-in knowledge of 'merge'/'diff3 -E' output.

Besides, it would be useful not only to spawn interactive merge tools,
but also to use mergers specific for file-type, for example 3DM or xmlcmp
tools for merging XML files.

-- 
Jakub Narebski

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Jakub Narebski <hidden>
Date: 2016-08-11 20:18:13

Sam Vilain wrote:
For those who like to spawn interactive merge tools on a merge failure
or otherwise run some kind of script, allow a "merge.tool" repo-config
option that will take arguments as merge(1) does.
How it goes together with merge-recursive rewrite using built-in merge tool
from xdiff, xdl_merge?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

Re: [PATCH] merge-recursive: configurable 'merge' program

From: Jakub Narebski <hidden>
Date: 2016-08-11 20:32:14

Dnia wtorek 5. grudnia 2006 15:48, Johannes Schindelin napisał:
On Tue, 5 Dec 2006, Jakub Narebski wrote:
quoted
Hmmm... would it be possible to use xdl_merge() for recursion, and 
graphical merge tool for result? <Checks out earlier discussion>. I 
think yes, because of exposing xdl_merge() in git-merge-onefile...
In "next", only git-merge-recursive is converted to use xdl_merge(), and 
it did not use git-merge-one-file to begin with. Since this is a shell 
script (with a different syntax than merge), it would have to be converted 
to a C builtin first. But feasible: git-merge-one-file takes 7 parameters, 
the first 3 being SHA1s or empty strings. "merge" takes 3 filenames, with 
possibly up to three "-L <name>" pairs before them.
I thought that Junio implemented (but perhaps not published) some script,
I thought that was git-merge-onefile with some non-standard options,
to function as replacement for RCS' merge, or Diffutils diff3. 

Guess I was wrong (at least there is nothing I can find in pu about this).
-- 
Jakub Narebski
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help