Show More
@@ -1,120 +1,143 b'' | |||
|
1 | 1 | #!/bin/sh |
|
2 | 2 | # |
|
3 | 3 | # hgmerge - default merge helper for Mercurial |
|
4 | 4 | # |
|
5 | 5 | # This tries to find a way to do three-way merge on the current system. |
|
6 | 6 | # The result ought to end up in $1. |
|
7 | 7 | |
|
8 | 8 | set -e # bail out quickly on failure |
|
9 | 9 | |
|
10 | 10 | LOCAL="$1" |
|
11 | 11 | BASE="$2" |
|
12 | 12 | OTHER="$3" |
|
13 | 13 | |
|
14 | 14 | if [ -z "$EDITOR" ]; then |
|
15 | 15 | EDITOR="vi" |
|
16 | 16 | fi |
|
17 | 17 | |
|
18 | 18 | # find decent versions of our utilities, insisting on the GNU versions where we |
|
19 | 19 | # need to |
|
20 | 20 | DIFF3=gdiff3 |
|
21 | 21 | DIFF=gdiff |
|
22 | 22 | PATCH=gpatch |
|
23 | 23 | |
|
24 | 24 | type $DIFF3 >/dev/null 2>&1 || DIFF3=diff3 |
|
25 | 25 | type $DIFF >/dev/null 2>&1 || DIFF=diff |
|
26 | 26 | type $PATCH >/dev/null 2>&1 || PATCH=patch |
|
27 | 27 | $DIFF3 --version >/dev/null 2>&1 || DIFF3= |
|
28 | 28 | |
|
29 | 29 | # Back up our file |
|
30 | 30 | cp "$LOCAL" "$LOCAL.orig" |
|
31 | 31 | |
|
32 | 32 | # Attempt to do a non-interactive merge |
|
33 | 33 | if type merge > /dev/null 2>&1; then |
|
34 | 34 | merge "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && exit 0 |
|
35 | 35 | cp "$LOCAL.orig" "$LOCAL" |
|
36 | 36 | elif [ -n "$DIFF3" ]; then |
|
37 | 37 | echo $DIFF3 -m "$LOCAL.orig" "$BASE" "$OTHER" |
|
38 | 38 | $DIFF3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" && exit 0 |
|
39 | 39 | if [ $? -eq 2 ]; then |
|
40 | 40 | echo "$DIFF3 failed! Exiting." 1>&2 |
|
41 | 41 | cp "$LOCAL.orig" "$LOCAL" |
|
42 | 42 | exit 1 |
|
43 | 43 | fi |
|
44 | 44 | cp "$LOCAL.orig" "$LOCAL" |
|
45 | 45 | fi |
|
46 | 46 | |
|
47 | # on MacOS X try opendiff | |
|
48 | # (uses FileMerge.app, shipped with Apple's developer tools) | |
|
49 | if type opendiff > /dev/null 2>&1; then | |
|
50 | opendiff "$LOCAL.orig" "$OTHER" -ancestor "$BASE" -merge "$LOCAL" || exit 1 | |
|
51 | # prevent $OTHER from being removed too early | |
|
52 | # can surely be done in a more elegant way | |
|
53 | sleep 1 | |
|
54 | exit 0 | |
|
47 | # on MacOS X try FileMerge.app, shipped with Apple's developer tools | |
|
48 | # TODO: make proper temp files. foo.orig and foo.link are dangerous | |
|
49 | FILEMERGE='/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge' | |
|
50 | if type "$FILEMERGE" > /dev/null 2>&1; then | |
|
51 | cp "$LOCAL.orig" "$LOCAL" | |
|
52 | ln "$LOCAL" "$LOCAL.link" | |
|
53 | # filemerge prefers the right by default | |
|
54 | if ! "$FILEMERGE" -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL" | |
|
55 | then | |
|
56 | echo "FileMerge failed to launch" | |
|
57 | exit 1 | |
|
58 | fi | |
|
59 | if ! test "$LOCAL" -ef "$LOCAL.link" | |
|
60 | then | |
|
61 | rm "$LOCAL.orig" "$LOCAL.link" | |
|
62 | exit 0 | |
|
63 | else | |
|
64 | rm "$LOCAL.link" | |
|
65 | echo "$LOCAL is unchanged. Was the merge successful?" | |
|
66 | select answer in yes no | |
|
67 | do | |
|
68 | if test "$answer" == "yes" | |
|
69 | then | |
|
70 | rm "$LOCAL.orig" | |
|
71 | exit 0 | |
|
72 | else | |
|
73 | exit 1 | |
|
74 | fi | |
|
75 | done | |
|
76 | exit 1 | |
|
77 | fi | |
|
55 | 78 | fi |
|
56 | 79 | |
|
57 | 80 | if [ -n "$DISPLAY" ]; then |
|
58 | 81 | # try using kdiff3, which is fairly nice |
|
59 | 82 | if type kdiff3 > /dev/null 2>&1; then |
|
60 | 83 | kdiff3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" || exit 1 |
|
61 | 84 | exit 0 |
|
62 | 85 | fi |
|
63 | 86 | |
|
64 | 87 | # try using tkdiff, which is a bit less sophisticated |
|
65 | 88 | if type tkdiff > /dev/null 2>&1; then |
|
66 | 89 | tkdiff "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" || exit 1 |
|
67 | 90 | exit 0 |
|
68 | 91 | fi |
|
69 | 92 | fi |
|
70 | 93 | |
|
71 | 94 | # Attempt to do a merge with $EDITOR |
|
72 | 95 | if type merge > /dev/null 2>&1; then |
|
73 | 96 | echo "conflicts detected in $LOCAL" |
|
74 | 97 | merge "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL" |
|
75 | 98 | exit 0 |
|
76 | 99 | fi |
|
77 | 100 | |
|
78 | 101 | if [ -n "$DIFF3" ]; then |
|
79 | 102 | echo "conflicts detected in $LOCAL" |
|
80 | 103 | $DIFF3 -m "$LOCAL.orig" "$BASE" "$OTHER" > "$LOCAL" || { |
|
81 | 104 | case $? in |
|
82 | 105 | 1) |
|
83 | 106 | $EDITOR "$LOCAL" ;; |
|
84 | 107 | 2) echo "$DIFF3 failed! Exiting." 1>&2 |
|
85 | 108 | cp "$LOCAL.orig" "$LOCAL" |
|
86 | 109 | exit 1 ;; |
|
87 | 110 | esac |
|
88 | 111 | exit 0 |
|
89 | 112 | } |
|
90 | 113 | fi |
|
91 | 114 | |
|
92 | 115 | HGTMP="" |
|
93 | 116 | cleanup_exit() { |
|
94 | 117 | rm -rf "$HGTMP" |
|
95 | 118 | } |
|
96 | 119 | |
|
97 | 120 | # attempt to manually merge with diff and patch |
|
98 | 121 | if [ -n "$DIFF" -a -n "$PATCH" ]; then |
|
99 | 122 | # Remove temporary files even if we get interrupted |
|
100 | 123 | trap "cleanup_exit" 0 # normal exit |
|
101 | 124 | trap "exit 1" 1 2 3 6 15 # HUP INT QUIT ABRT TERM |
|
102 | 125 | |
|
103 | 126 | HGTMP="${TMPDIR-/tmp}/hgmerge.$RANDOM.$RANDOM.$RANDOM.$$" |
|
104 | 127 | (umask 077 && mkdir "$HGTMP") || { |
|
105 | 128 | echo "Could not create temporary directory! Exiting." 1>&2 |
|
106 | 129 | exit 1 |
|
107 | 130 | } |
|
108 | 131 | |
|
109 | 132 | $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || : |
|
110 | 133 | if $PATCH "$LOCAL" < "$HGTMP/diff"; then |
|
111 | 134 | exit 0 |
|
112 | 135 | else |
|
113 | 136 | # If rejects are empty after using the editor, merge was ok |
|
114 | 137 | $EDITOR "$LOCAL" "$LOCAL.rej" && test -s "$LOCAL.rej" || exit 0 |
|
115 | 138 | fi |
|
116 | 139 | exit 1 |
|
117 | 140 | fi |
|
118 | 141 | |
|
119 | 142 | echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!" |
|
120 | 143 | exit 1 |
General Comments 0
You need to be logged in to leave comments.
Login now