hgmerge
author "Wallace, Eric S" <eric.s.wallace@intel.com>
Thu, 04 Aug 2005 13:25:59 -0800
changeset 827 a61728b58dc0
parent 814 0902ffece4b4
child 828 7a6acd56cd5a
child 836 1fe3b14c7044
child 839 9c918287d10b
permissions -rwxr-xr-x
Fix array overflow bug in bdiff I ran into a bug while importing a large repository into mercurial. The diff algorithm does not allocate a big enough array of hunks for some test cases. This results in memory corruption, and possibly, as in my case, a seg fault. You should be able to reproduce this problem with any case of more than a few lines that follows this pattern: a b = = 1 1 2 2 3 4 3 5 . 4 . . 5 . . . I.e., "a" has blank lines on every other line that have been removed in "b". In this case, the number of matching hunks is equal to the number of lines in "b". This is more than ((an + bn)/4 + 2). I'm not sure what motivates this formula, but when I changed it to the smaller of an or bn (+ 1), it works. [comment added by mpm]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
544
3d4d5f2aba9a Remove bashisms and use /bin/sh instead of /bin/bash.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 306
diff changeset
     1
#!/bin/sh
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     2
#
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     3
# hgmerge - default merge helper for Mercurial
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     4
#
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     5
# This tries to find a way to do three-way merge on the current system.
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     6
# The result ought to end up in $1.
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     7
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     8
set -e # bail out quickly on failure
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
     9
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    10
LOCAL="$1"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    11
BASE="$2"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    12
OTHER="$3"
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    13
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    14
if [ -z "$EDITOR" ]; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    15
    EDITOR="vi"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    16
fi
304
38fb7d23b78d Use vi if $EDITOR is unset.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 303
diff changeset
    17
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    18
# Back up our file
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    19
cp "$LOCAL" "$LOCAL.orig"
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    20
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    21
# Attempt to do a non-interactive merge
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    22
if type merge > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    23
    if merge "$LOCAL" "$BASE" "$OTHER" 2> /dev/null; then
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    24
	# success!
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    25
	exit 0
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    26
    fi
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    27
    cp "$LOCAL.orig" "$LOCAL"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    28
elif type diff3 > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    29
    if diff3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" ; then
242
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    30
	# success
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    31
	exit 0
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    32
    fi
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    33
    cp "$LOCAL.orig" "$LOCAL"
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    34
fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    35
303
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    36
if [ -n "$DISPLAY" ]; then
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    37
    # try using kdiff3, which is fairly nice
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    38
    if type kdiff3 > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    39
	if kdiff3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" ; then
303
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    40
	    exit 0
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    41
	else
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    42
	    exit 1
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    43
	fi
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    44
    fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    45
303
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    46
    # try using tkdiff, which is a bit less sophisticated
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    47
    if type tkdiff > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    48
	if tkdiff "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" ; then
303
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    49
	    exit 0
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    50
	else
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    51
	    exit 1
15a9e55e7ea5 Check if $DISPLAY is set before using tkdiff or kdiff3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 280
diff changeset
    52
	fi
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    53
    fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    54
fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    55
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    56
# Attempt to do a merge with $EDITOR
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    57
if type merge > /dev/null ; then
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    58
    echo "conflicts detected in $LOCAL"
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    59
    merge "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL"
242
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    60
    exit 0
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    61
fi
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    62
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    63
if type diff3 > /dev/null ; then
242
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    64
    echo "conflicts detected in $LOCAL"
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    65
    diff3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" || $EDITOR "$LOCAL"
242
a2edb4481f19 hgmerge: use diff3 if available
mpm@selenic.com
parents: 240
diff changeset
    66
    exit 0
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    67
fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    68
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    69
HGTMP=""
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    70
cleanup_exit() {
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    71
    rm -rf "$HGTMP"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    72
    exit $1
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    73
}
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    74
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    75
# attempt to manually merge with diff and patch
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    76
if type diff > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    77
    if type patch > /dev/null ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    78
	# Remove temporary files even if we get interrupted
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    79
	trap "cleanup_exit 1" TERM KILL INT QUIT ABRT
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    80
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    81
	HGTMP="${TMPDIR-/tmp}/hgmerge.$RANDOM.$RANDOM.$RANDOM.$$"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    82
	(umask 077 && mkdir "$HGTMP") || {
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    83
	    echo "Could not create temporary directory! Exiting." 1>&2
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    84
	    exit 1
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    85
	}
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    86
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    87
	diff -u "$BASE" "$OTHER" > "$HGTMP/diff"
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    88
	if patch "$LOCAL" < "$HGTMP/diff" ; then
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    89
	    cleanup_exit 0
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    90
	else
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    91
	    $EDITOR "$LOCAL" "$LOCAL.rej"
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    92
	fi
795
cd0ad12d9e42 Remove usage of ${par:-word}, which and mktemp. Quote filenames.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 547
diff changeset
    93
	cleanup_exit 1
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    94
    fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    95
fi
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    96
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    97
echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents:
diff changeset
    98
exit 1