Originally, with no base, Git gave P4Merge $LOCAL as a dummy base: p4merge "$LOCAL" "$LOCAL" "$REMOTE" "$MERGED" Commit 0a0ec7bd changed this to: p4merge "empty file" "$LOCAL" "$REMOTE" "$MERGED" to avoid the problem of being unable to save in some circumstances. Unfortunately this approach does not produce good results at all on differing inputs. P4Merge really regards the blank file as the base, and once you have just a couple of differences between the two branches you end up with one a massive full-file conflict. The diff is not readable, and you have to invoke "difftool MERGE_HEAD HEAD" manually to see a 2-way diff. The original form appears to have invoked special 2-way comparison behaviour that occurs only if the base filename is "" or equal to the left input. You get a good diff, and it does not auto-resolve in one direction or the other. (Normally if one branch equals the base, it would autoresolve to the other branch). But there appears to be no way of getting this 2-way behaviour and being able to reliably save. Having base=left appears to be triggering other assumptions. There are tricks the user can use to force the save icon on, but it's not intuitive. So we now follow a suggestion given in the original patch's discussion: generate a virtual base, consisting of the lines common to the two branches. It produces a much nicer 3-way diff view than either of the original forms, and than I suspect other mergetools are managing. Signed-off-by: Kevin Bracey <kevin@xxxxxxxxx> --- git-mergetool--lib.sh | 14 ++++++++++++++ mergetools/p4merge | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index e338be5..5b60cf5 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -108,6 +108,20 @@ check_unchanged () { fi } +make_virtual_base() { + # Copied from git-merge-one-file.sh. + # This starts with $LOCAL, and uses git apply to + # remove lines that are not in $REMOTE. + cp -- "$LOCAL" "$BASE" + sz0=`wc -c <"$BASE"` + @@DIFF@@ -u -L"a/$BASE" -L"b/$BASE" "$BASE" "$REMOTE" | git apply --no-add + sz1=`wc -c <"$BASE"` + + # If we do not have enough common material, it is not + # worth trying two-file merge using common subsections. + expr $sz0 \< $sz1 \* 2 >/dev/null || : >"$BASE" +} + valid_tool () { setup_tool "$1" && return 0 cmd=$(get_merge_tool_cmd "$1") diff --git a/mergetools/p4merge b/mergetools/p4merge index 46b3a5a..f0a893b 100644 --- a/mergetools/p4merge +++ b/mergetools/p4merge @@ -21,7 +21,7 @@ diff_cmd () { merge_cmd () { touch "$BACKUP" - $base_present || >"$BASE" + $base_present || make_virtual_base "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED" check_unchanged } -- 1.8.2.rc2.5.g1a80410.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html