Merge branch 'kb/p4merge'

Adjust the order mergetools feeds the files to the p4merge backend
to match the p4 convention.

* kb/p4merge:
  merge-one-file: force content conflict for "both sides added" case
  git-merge-one-file: send "ERROR:" messages to stderr
  git-merge-one-file: style cleanup
  merge-one-file: remove stale comment
  mergetools/p4merge: create a base if none available
  mergetools/p4merge: swap LOCAL and REMOTE
This commit is contained in:
Junio C Hamano 2013-03-26 13:15:24 -07:00
commit 183f88018a
4 changed files with 52 additions and 35 deletions

View File

@ -82,6 +82,12 @@ get_author_ident_from_commit::
outputs code for use with eval to set the GIT_AUTHOR_NAME, outputs code for use with eval to set the GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE variables for a given commit. GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE variables for a given commit.
create_virtual_base::
modifies the first file so only lines in common with the
second file remain. If there is insufficient common material,
then the first file is left empty. The result is suitable
as a virtual base input for a 3-way merge.
GIT GIT
--- ---
Part of the linkgit:git[1] suite Part of the linkgit:git[1] suite

View File

@ -27,7 +27,7 @@ SUBDIRECTORY_OK=Yes
cd_to_toplevel cd_to_toplevel
require_work_tree require_work_tree
if ! test "$#" -eq 7 if test $# != 7
then then
echo "$LONG_USAGE" echo "$LONG_USAGE"
exit 1 exit 1
@ -38,7 +38,8 @@ case "${1:-.}${2:-.}${3:-.}" in
# Deleted in both or deleted in one and unchanged in the other # Deleted in both or deleted in one and unchanged in the other
# #
"$1.." | "$1.$1" | "$1$1.") "$1.." | "$1.$1" | "$1$1.")
if [ "$2" ]; then if test -n "$2"
then
echo "Removing $4" echo "Removing $4"
else else
# read-tree checked that index matches HEAD already, # read-tree checked that index matches HEAD already,
@ -48,7 +49,8 @@ case "${1:-.}${2:-.}${3:-.}" in
# we do not have it in the index, though. # we do not have it in the index, though.
exec git update-index --remove -- "$4" exec git update-index --remove -- "$4"
fi fi
if test -f "$4"; then if test -f "$4"
then
rm -f -- "$4" && rm -f -- "$4" &&
rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || : rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || :
fi && fi &&
@ -67,7 +69,7 @@ case "${1:-.}${2:-.}${3:-.}" in
echo "Adding $4" echo "Adding $4"
if test -f "$4" if test -f "$4"
then then
echo "ERROR: untracked $4 is overwritten by the merge." echo "ERROR: untracked $4 is overwritten by the merge." >&2
exit 1 exit 1
fi fi
git update-index --add --cacheinfo "$7" "$3" "$4" && git update-index --add --cacheinfo "$7" "$3" "$4" &&
@ -78,9 +80,10 @@ case "${1:-.}${2:-.}${3:-.}" in
# Added in both, identically (check for same permissions). # Added in both, identically (check for same permissions).
# #
".$3$2") ".$3$2")
if [ "$6" != "$7" ]; then if test "$6" != "$7"
echo "ERROR: File $4 added identically in both branches," then
echo "ERROR: but permissions conflict $6->$7." echo "ERROR: File $4 added identically in both branches," >&2
echo "ERROR: but permissions conflict $6->$7." >&2
exit 1 exit 1
fi fi
echo "Adding $4" echo "Adding $4"
@ -95,44 +98,36 @@ case "${1:-.}${2:-.}${3:-.}" in
case ",$6,$7," in case ",$6,$7," in
*,120000,*) *,120000,*)
echo "ERROR: $4: Not merging symbolic link changes." echo "ERROR: $4: Not merging symbolic link changes." >&2
exit 1 exit 1
;; ;;
*,160000,*) *,160000,*)
echo "ERROR: $4: Not merging conflicting submodule changes." echo "ERROR: $4: Not merging conflicting submodule changes." >&2
exit 1 exit 1
;; ;;
esac esac
src2=`git-unpack-file $3` src1=$(git-unpack-file $2)
src2=$(git-unpack-file $3)
case "$1" in case "$1" in
'') '')
echo "Added $4 in both, but differently." echo "Added $4 in both, but differently."
# This extracts OUR file in $orig, and uses git apply to orig=$(git-unpack-file $2)
# remove lines that are unique to ours. create_virtual_base "$orig" "$src2"
orig=`git-unpack-file $2`
sz0=`wc -c <"$orig"`
@@DIFF@@ -u -La/$orig -Lb/$orig $orig $src2 | git apply --no-add
sz1=`wc -c <"$orig"`
# 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 || : >$orig
;; ;;
*) *)
echo "Auto-merging $4" echo "Auto-merging $4"
orig=`git-unpack-file $1` orig=$(git-unpack-file $1)
;; ;;
esac esac
# Be careful for funny filename such as "-L" in "$4", which
# would confuse "merge" greatly.
src1=`git-unpack-file $2`
git merge-file "$src1" "$orig" "$src2" git merge-file "$src1" "$orig" "$src2"
ret=$? ret=$?
msg= msg=
if [ $ret -ne 0 ]; then if test $ret != 0 || test -z "$1"
then
msg='content conflict' msg='content conflict'
ret=1
fi fi
# Create the working tree file, using "our tree" version from the # Create the working tree file, using "our tree" version from the
@ -140,26 +135,26 @@ case "${1:-.}${2:-.}${3:-.}" in
git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1 git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1
rm -f -- "$orig" "$src1" "$src2" rm -f -- "$orig" "$src1" "$src2"
if [ "$6" != "$7" ]; then if test "$6" != "$7"
if [ -n "$msg" ]; then then
if test -n "$msg"
then
msg="$msg, " msg="$msg, "
fi fi
msg="${msg}permissions conflict: $5->$6,$7" msg="${msg}permissions conflict: $5->$6,$7"
ret=1 ret=1
fi fi
if [ "$1" = '' ]; then
ret=1
fi
if [ $ret -ne 0 ]; then if test $ret != 0
echo "ERROR: $msg in $4" then
echo "ERROR: $msg in $4" >&2
exit 1 exit 1
fi fi
exec git update-index -- "$4" exec git update-index -- "$4"
;; ;;
*) *)
echo "ERROR: $4: Not handling case $1 -> $2 -> $3" echo "ERROR: $4: Not handling case $1 -> $2 -> $3" >&2
;; ;;
esac esac
exit 1 exit 1

View File

@ -249,6 +249,18 @@ clear_local_git_env() {
unset $(git rev-parse --local-env-vars) unset $(git rev-parse --local-env-vars)
} }
# Generate a virtual base file for a two-file merge. Uses git apply to
# remove lines from $1 that are not in $2, leaving only common lines.
create_virtual_base() {
sz0=$(wc -c <"$1")
@@DIFF@@ -u -La/"$1" -Lb/"$1" "$1" "$2" | git apply --no-add
sz1=$(wc -c <"$1")
# 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 || : >"$1"
}
# Platform specific tweaks to work around some commands # Platform specific tweaks to work around some commands
case $(uname -s) in case $(uname -s) in

View File

@ -21,8 +21,12 @@ diff_cmd () {
merge_cmd () { merge_cmd () {
touch "$BACKUP" touch "$BACKUP"
$base_present || >"$BASE" if ! $base_present
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED" then
cp -- "$LOCAL" "$BASE"
create_virtual_base "$BASE" "$REMOTE"
fi
"$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
check_unchanged check_unchanged
} }