hgmerge
author mpm@selenic.com
Sat, 30 Jul 2005 09:00:14 -0800
changeset 814 0902ffece4b4021a2ce4dfe95e6309dad37619a7
parent 808 8f5637f0a0c049132edcb9ecfc91722b3ee79696
parent 547 4fc63e22b1fe707bb542ab1149403daa9a77cdf8
child 828 7a6acd56cd5a1e128a7db0c099bebb00e0c1820b
child 836 1fe3b14c704408d57e0b33efdaaf5adba6d87617
child 839 9c918287d10b4018e27f9148e247e68ff5fe952c
permissions -rwxr-xr-x
Merge with BOS

#!/bin/sh
#
# hgmerge - default merge helper for Mercurial
#
# This tries to find a way to do three-way merge on the current system.
# The result ought to end up in $1.

set -e # bail out quickly on failure

LOCAL="$1"
BASE="$2"
OTHER="$3"

if [ -z "$EDITOR" ]; then
    EDITOR="vi"
fi

# Back up our file
cp "$LOCAL" "$LOCAL.orig"

# Attempt to do a non-interactive merge
if type merge > /dev/null ; then
    if merge "$LOCAL" "$BASE" "$OTHER" 2> /dev/null; then
	# success!
	exit 0
    fi
    cp "$LOCAL.orig" "$LOCAL"
elif type diff3 > /dev/null ; then
    if diff3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" ; then
	# success
	exit 0
    fi
    cp "$LOCAL.orig" "$LOCAL"
fi

if [ -n "$DISPLAY" ]; then
    # try using kdiff3, which is fairly nice
    if type kdiff3 > /dev/null ; then
	if kdiff3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" ; then
	    exit 0
	else
	    exit 1
	fi
    fi

    # try using tkdiff, which is a bit less sophisticated
    if type tkdiff > /dev/null ; then
	if tkdiff "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" ; then
	    exit 0
	else
	    exit 1
	fi
    fi
fi

# Attempt to do a merge with $EDITOR
if type merge > /dev/null ; then
    echo "conflicts detected in $LOCAL"
    merge "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL"
    exit 0
fi

if type diff3 > /dev/null ; then
    echo "conflicts detected in $LOCAL"
    diff3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" || $EDITOR "$LOCAL"
    exit 0
fi

HGTMP=""
cleanup_exit() {
    rm -rf "$HGTMP"
    exit $1
}

# attempt to manually merge with diff and patch
if type diff > /dev/null ; then
    if type patch > /dev/null ; then
	# Remove temporary files even if we get interrupted
	trap "cleanup_exit 1" TERM KILL INT QUIT ABRT

	HGTMP="${TMPDIR-/tmp}/hgmerge.$RANDOM.$RANDOM.$RANDOM.$$"
	(umask 077 && mkdir "$HGTMP") || {
	    echo "Could not create temporary directory! Exiting." 1>&2
	    exit 1
	}

	diff -u "$BASE" "$OTHER" > "$HGTMP/diff"
	if patch "$LOCAL" < "$HGTMP/diff" ; then
	    cleanup_exit 0
	else
	    $EDITOR "$LOCAL" "$LOCAL.rej"
	fi
	cleanup_exit 1
    fi
fi

echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
exit 1