##// END OF EJS Templates
hgmerge: fix diff+patch detection; cleanups...
Radoslaw Szkodzinski -
r1770:4eea6a74 default
parent child Browse files
Show More
@@ -1,167 +1,168 b''
1 #!/bin/sh
1 #!/bin/sh
2 #
2 #
3 # hgmerge - default merge helper for Mercurial
3 # hgmerge - default merge helper for Mercurial
4 #
4 #
5 # This tries to find a way to do three-way merge on the current system.
5 # This tries to find a way to do three-way merge on the current system.
6 # The result ought to end up in $1.
6 # The result ought to end up in $1.
7
7
8 set -e # bail out quickly on failure
8 set -e # bail out quickly on failure
9
9
10 LOCAL="$1"
10 LOCAL="$1"
11 BASE="$2"
11 BASE="$2"
12 OTHER="$3"
12 OTHER="$3"
13
13
14 if [ -z "$EDITOR" ]; then
14 if [ -z "$EDITOR" ]; then
15 EDITOR="vi"
15 EDITOR="vi"
16 fi
16 fi
17
17
18 # find decent versions of our utilities, insisting on the GNU versions where we
18 # find decent versions of our utilities, insisting on the GNU versions where we
19 # need to
19 # need to
20 MERGE=merge
20 MERGE="merge"
21 DIFF3=gdiff3
21 DIFF3="gdiff3"
22 DIFF=gdiff
22 DIFF="gdiff"
23 PATCH=gpatch
23 PATCH="gpatch"
24
24
25 type $MERGE >/dev/null 2>&1 || MERGE=
25 type "$MERGE" >/dev/null 2>&1 || MERGE=
26 type $DIFF3 >/dev/null 2>&1 || DIFF3=diff3
26 type "$DIFF3" >/dev/null 2>&1 || DIFF3="diff3"
27 type $DIFF >/dev/null 2>&1 || DIFF=diff
28 type $PATCH >/dev/null 2>&1 || PATCH=patch
29 $DIFF3 --version >/dev/null 2>&1 || DIFF3=
27 $DIFF3 --version >/dev/null 2>&1 || DIFF3=
28 type "$DIFF" >/dev/null 2>&1 || DIFF="diff"
29 type "$DIFF" >/dev/null 2>&1 || DIFF=
30 type "$PATCH" >/dev/null 2>&1 || PATCH="patch"
31 type "$PATCH" >/dev/null 2>&1 || PATCH=
30
32
31 # find optional visual utilities
33 # find optional visual utilities
32 FILEMERGE='/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge'
34 FILEMERGE="/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge"
33 KDIFF3=kdiff3
35 KDIFF3="kdiff3"
34 TKDIFF=tkdiff
36 TKDIFF="tkdiff"
35
37
36 type $FILEMERGE >/dev/null 2>&1 || FILEMERGE=
38 type "$FILEMERGE" >/dev/null 2>&1 || FILEMERGE=
37 type $KDIFF3 >/dev/null 2>&1 || KDIFF3=
39 type "$KDIFF3" >/dev/null 2>&1 || KDIFF3=
38 type $TKDIFF >/dev/null 2>&1 || TKDIFF=
40 type "$TKDIFF" >/dev/null 2>&1 || TKDIFF=
39
41
40 # random part of names
42 # random part of names
41 RAND="$RANDOM.$RANDOM.$RANDOM.$$"
43 RAND="$RANDOM$RANDOM"
42
44
43 # temporary directory for diff+patch merge
45 # temporary directory for diff+patch merge
44 HGTMP="${TMPDIR-/tmp}/hgmerge.$RAND"
46 HGTMP="${TMPDIR-'/tmp'}/hgmerge.$RAND"
45
47
46 # backup file
48 # backup file
47 BACKUP="$LOCAL.orig.$RAND"
49 BACKUP="$LOCAL.orig.$RAND"
48
50
49 # file used to test for file change
51 # file used to test for file change
50 CHGTEST="$LOCAL.chg.$RAND"
52 CHGTEST="$LOCAL.chg.$RAND"
51
53
52 # put all your required cleanup here
54 # put all your required cleanup here
53 cleanup() {
55 cleanup() {
54 rm -f "$BACKUP" "$CHGTEST"
56 rm -f "$BACKUP" "$CHGTEST"
55 rm -rf "$HGTMP"
57 rm -rf "$HGTMP"
56 }
58 }
57
59
58 # functions concerning program exit
60 # functions concerning program exit
59 success() {
61 success() {
60 cleanup
62 cleanup
61 exit 0
63 exit 0
62 }
64 }
63
65
64 failure() {
66 failure() {
65 echo "merge failed" 1>&2
67 echo "merge failed" 1>&2
66 mv "$BACKUP" "$LOCAL"
68 mv "$BACKUP" "$LOCAL"
67 cleanup
69 cleanup
68 exit 1
70 exit 1
69 }
71 }
70
72
71 # Clean up when interrupted
73 # Clean up when interrupted
72 trap "failure" 1 2 3 6 15 # HUP INT QUIT ABRT TERM
74 trap "failure" 1 2 3 6 15 # HUP INT QUIT ABRT TERM
73
75
74 # Back up our file (and try hard to keep the mtime unchanged)
76 # Back up our file (and try hard to keep the mtime unchanged)
75 mv "$LOCAL" "$BACKUP"
77 mv "$LOCAL" "$BACKUP"
76 cp "$BACKUP" "$LOCAL"
78 cp "$BACKUP" "$LOCAL"
77
79
78 # Attempt to do a non-interactive merge
80 # Attempt to do a non-interactive merge
81 if [ -n "$MERGE" -o -n "$DIFF3" ]; then
79 if [ -n "$MERGE" ]; then
82 if [ -n "$MERGE" ]; then
80 $MERGE "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && success
83 $MERGE "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && success
81 cp "$BACKUP" "$LOCAL"
82 elif [ -n "$DIFF3" ]; then
84 elif [ -n "$DIFF3" ]; then
83 echo $DIFF3 -m "$BACKUP" "$BASE" "$OTHER"
84 $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" && success
85 $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" && success
85 if [ $? -eq 2 ]; then
86 fi
86 echo "$DIFF3 failed! Exiting." 1>&2
87 if [ $? -gt 1 ]; then
87 cp "$BACKUP" "$LOCAL"
88 echo "automatic merge failed! Exiting." 1>&2
88 failure
89 failure
89 fi
90 fi
91 fi
90 cp "$BACKUP" "$LOCAL"
92 cp "$BACKUP" "$LOCAL"
91 fi
92
93
93 # on MacOS X try FileMerge.app, shipped with Apple's developer tools
94 # on MacOS X try FileMerge.app, shipped with Apple's developer tools
94 if [ -n "$FILEMERGE" ]; then
95 if [ -n "$FILEMERGE" ]; then
95 cp "$BACKUP" "$LOCAL"
96 cp "$BACKUP" "$LOCAL"
96 cp "$BACKUP" "$CHGTEST"
97 cp "$BACKUP" "$CHGTEST"
97 # filemerge prefers the right by default
98 # filemerge prefers the right by default
98 $FILEMERGE -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL"
99 $FILEMERGE -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL"
99 [ $? -ne 0 ] && echo "FileMerge failed to launch" && failure
100 [ $? -ne 0 ] && echo "FileMerge failed to launch" && failure
100 if test "$LOCAL" -nt "$CHGTEST"
101 if test "$LOCAL" -nt "$CHGTEST"
101 then
102 then
102 success
103 success
103 else
104 else
104 echo "$LOCAL seems unchanged. Was the merge successful?"
105 echo "$LOCAL seems unchanged. Was the merge successful?"
105 select answer in yes no
106 select answer in yes no
106 do
107 do
107 test "$answer" == "yes" && success || failure
108 test "$answer" == "yes" && success || failure
108 done
109 done
109 fi
110 fi
110 failure
111 failure
111 fi
112 fi
112
113
113 if [ -n "$DISPLAY" ]; then
114 if [ -n "$DISPLAY" ]; then
114 # try using kdiff3, which is fairly nice
115 # try using kdiff3, which is fairly nice
115 if [ -n "$KDIFF3" ]; then
116 if [ -n "$KDIFF3" ]; then
116 $KDIFF3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" || failure
117 $KDIFF3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" || failure
117 success
118 success
118 fi
119 fi
119
120
120 # try using tkdiff, which is a bit less sophisticated
121 # try using tkdiff, which is a bit less sophisticated
121 if [ -n "$TKDIFF" ]; then
122 if [ -n "$TKDIFF" ]; then
122 $TKDIFF "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" || failure
123 $TKDIFF "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" || failure
123 success
124 success
124 fi
125 fi
125 fi
126 fi
126
127
127 # Attempt to do a merge with $EDITOR
128 # Attempt to do a merge with $EDITOR
128 if [ -n "$MERGE" ]; then
129 if [ -n "$MERGE" ]; then
129 echo "conflicts detected in $LOCAL"
130 echo "conflicts detected in $LOCAL"
130 $MERGE "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL"
131 $MERGE "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL"
131 success
132 success
132 fi
133 fi
133
134
134 if [ -n "$DIFF3" ]; then
135 if [ -n "$DIFF3" ]; then
135 echo "conflicts detected in $LOCAL"
136 echo "conflicts detected in $LOCAL"
136 $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" || {
137 $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" || {
137 case $? in
138 case $? in
138 1)
139 1)
139 $EDITOR "$LOCAL" ;;
140 $EDITOR "$LOCAL" ;;
140 2) echo "$DIFF3 failed! Exiting." 1>&2
141 2) echo "$DIFF3 failed! Exiting." 1>&2
141 cp "$BACKUP" "$LOCAL"
142 cp "$BACKUP" "$LOCAL"
142 failure ;;
143 failure ;;
143 esac
144 esac
144 success
145 success
145 }
146 }
146 fi
147 fi
147
148
148 # attempt to manually merge with diff and patch
149 # attempt to manually merge with diff and patch
149 if [ -n "$DIFF" -a -n "$PATCH" ]; then
150 if [ -n "$DIFF" -a -n "$PATCH" ]; then
150
151
151 (umask 077 && mkdir "$HGTMP") || {
152 (umask 077 && mkdir "$HGTMP") || {
152 echo "Could not create temporary directory $HGTMP" 1>&2
153 echo "Could not create temporary directory $HGTMP" 1>&2
153 failure
154 failure
154 }
155 }
155
156
156 $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || :
157 $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || :
157 if $PATCH "$LOCAL" < "$HGTMP/diff"; then
158 if $PATCH "$LOCAL" < "$HGTMP/diff"; then
158 success
159 success
159 else
160 else
160 # If rejects are empty after using the editor, merge was ok
161 # If rejects are empty after using the editor, merge was ok
161 $EDITOR "$LOCAL" "$LOCAL.rej" && test -s "$LOCAL.rej" || success
162 $EDITOR "$LOCAL" "$LOCAL.rej" && test -s "$LOCAL.rej" || success
162 fi
163 fi
163 failure
164 failure
164 fi
165 fi
165
166
166 echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
167 echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
167 failure
168 failure
General Comments 0
You need to be logged in to leave comments. Login now