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