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