]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/sh | |
2 | # | |
3 | # Copyright (c) 2005 Junio C Hamano | |
4 | # | |
5 | ||
6 | ||
7 | USAGE='[-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+' | |
8 | . git-sh-setup | |
9 | ||
10 | LF=' | |
11 | ' | |
12 | ||
13 | all_strategies='recursive octopus resolve stupid ours' | |
14 | default_strategies='recursive' | |
15 | use_strategies= | |
16 | ||
17 | dropsave() { | |
18 | rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \ | |
19 | "$GIT_DIR/MERGE_SAVE" || exit 1 | |
20 | } | |
21 | ||
22 | savestate() { | |
23 | # Stash away any local modifications. | |
24 | git-diff-index -z --name-only $head | | |
25 | cpio -0 -o >"$GIT_DIR/MERGE_SAVE" | |
26 | } | |
27 | ||
28 | restorestate() { | |
29 | if test -f "$GIT_DIR/MERGE_SAVE" | |
30 | then | |
31 | git reset --hard $head | |
32 | cpio -iuv <"$GIT_DIR/MERGE_SAVE" | |
33 | git-update-index --refresh >/dev/null | |
34 | fi | |
35 | } | |
36 | ||
37 | finish () { | |
38 | test '' = "$2" || echo "$2" | |
39 | case "$merge_msg" in | |
40 | '') | |
41 | echo "No merge message -- not updating HEAD" | |
42 | ;; | |
43 | *) | |
44 | git-update-ref HEAD "$1" "$head" || exit 1 | |
45 | ;; | |
46 | esac | |
47 | ||
48 | case "$no_summary" in | |
49 | '') | |
50 | git-diff-tree -p -M "$head" "$1" | | |
51 | git-apply --stat --summary | |
52 | ;; | |
53 | esac | |
54 | } | |
55 | ||
56 | while case "$#" in 0) break ;; esac | |
57 | do | |
58 | case "$1" in | |
59 | -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\ | |
60 | --no-summa|--no-summar|--no-summary) | |
61 | no_summary=t ;; | |
62 | --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit) | |
63 | no_commit=t ;; | |
64 | -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ | |
65 | --strateg=*|--strategy=*|\ | |
66 | -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy) | |
67 | case "$#,$1" in | |
68 | *,*=*) | |
69 | strategy=`expr "$1" : '-[^=]*=\(.*\)'` ;; | |
70 | 1,*) | |
71 | usage ;; | |
72 | *) | |
73 | strategy="$2" | |
74 | shift ;; | |
75 | esac | |
76 | case " $all_strategies " in | |
77 | *" $strategy "*) | |
78 | use_strategies="$use_strategies$strategy " ;; | |
79 | *) | |
80 | die "available strategies are: $all_strategies" ;; | |
81 | esac | |
82 | ;; | |
83 | -*) usage ;; | |
84 | *) break ;; | |
85 | esac | |
86 | shift | |
87 | done | |
88 | ||
89 | test "$#" -le 2 && usage ;# we need at least two heads. | |
90 | ||
91 | merge_msg="$1" | |
92 | shift | |
93 | head_arg="$1" | |
94 | head=$(git-rev-parse --verify "$1"^0) || usage | |
95 | shift | |
96 | ||
97 | # All the rest are remote heads | |
98 | remoteheads= | |
99 | for remote | |
100 | do | |
101 | remotehead=$(git-rev-parse --verify "$remote"^0) || | |
102 | die "$remote - not something we can merge" | |
103 | remoteheads="${remoteheads}$remotehead " | |
104 | done | |
105 | set x $remoteheads ; shift | |
106 | ||
107 | case "$#" in | |
108 | 1) | |
109 | common=$(git-merge-base --all $head "$@") | |
110 | ;; | |
111 | *) | |
112 | common=$(git-show-branch --merge-base $head "$@") | |
113 | ;; | |
114 | esac | |
115 | echo "$head" >"$GIT_DIR/ORIG_HEAD" | |
116 | ||
117 | case "$#,$common,$no_commit" in | |
118 | *,'',*) | |
119 | # No common ancestors found. We need a real merge. | |
120 | ;; | |
121 | 1,"$1",*) | |
122 | # If head can reach all the merge then we are up to date. | |
123 | # but first the most common case of merging one remote | |
124 | echo "Already up-to-date." | |
125 | dropsave | |
126 | exit 0 | |
127 | ;; | |
128 | 1,"$head",*) | |
129 | # Again the most common case of merging one remote. | |
130 | echo "Updating from $head to $1." | |
131 | git-update-index --refresh 2>/dev/null | |
132 | new_head=$(git-rev-parse --verify "$1^0") && | |
133 | git-read-tree -u -m $head "$new_head" && | |
134 | finish "$new_head" "Fast forward" | |
135 | dropsave | |
136 | exit 0 | |
137 | ;; | |
138 | 1,?*"$LF"?*,*) | |
139 | # We are not doing octopus and not fast forward. Need a | |
140 | # real merge. | |
141 | ;; | |
142 | 1,*,) | |
143 | # We are not doing octopus, not fast forward, and have only | |
144 | # one common. See if it is really trivial. | |
145 | echo "Trying really trivial in-index merge..." | |
146 | git-update-index --refresh 2>/dev/null | |
147 | if git-read-tree --trivial -m -u $common $head "$1" && | |
148 | result_tree=$(git-write-tree) | |
149 | then | |
150 | echo "Wonderful." | |
151 | result_commit=$( | |
152 | echo "$merge_msg" | | |
153 | git-commit-tree $result_tree -p HEAD -p "$1" | |
154 | ) || exit | |
155 | finish "$result_commit" "In-index merge" | |
156 | dropsave | |
157 | exit 0 | |
158 | fi | |
159 | echo "Nope." | |
160 | ;; | |
161 | *) | |
162 | # An octopus. If we can reach all the remote we are up to date. | |
163 | up_to_date=t | |
164 | for remote | |
165 | do | |
166 | common_one=$(git-merge-base --all $head $remote) | |
167 | if test "$common_one" != "$remote" | |
168 | then | |
169 | up_to_date=f | |
170 | break | |
171 | fi | |
172 | done | |
173 | if test "$up_to_date" = t | |
174 | then | |
175 | echo "Already up-to-date. Yeeah!" | |
176 | dropsave | |
177 | exit 0 | |
178 | fi | |
179 | ;; | |
180 | esac | |
181 | ||
182 | case "$use_strategies" in | |
183 | '') | |
184 | case "$#" in | |
185 | 1) | |
186 | use_strategies="$default_strategies" ;; | |
187 | *) | |
188 | use_strategies=octopus ;; | |
189 | esac | |
190 | ;; | |
191 | esac | |
192 | ||
193 | # At this point, we need a real merge. No matter what strategy | |
194 | # we use, it would operate on the index, possibly affecting the | |
195 | # working tree, and when resolved cleanly, have the desired tree | |
196 | # in the index -- this means that the index must be in sync with | |
197 | # the $head commit. The strategies are responsible to ensure this. | |
198 | ||
199 | case "$use_strategies" in | |
200 | ?*' '?*) | |
201 | # Stash away the local changes so that we can try more than one. | |
202 | savestate | |
203 | single_strategy=no | |
204 | ;; | |
205 | *) | |
206 | rm -f "$GIT_DIR/MERGE_SAVE" | |
207 | single_strategy=yes | |
208 | ;; | |
209 | esac | |
210 | ||
211 | result_tree= best_cnt=-1 best_strategy= wt_strategy= | |
212 | merge_was_ok= | |
213 | for strategy in $use_strategies | |
214 | do | |
215 | test "$wt_strategy" = '' || { | |
216 | echo "Rewinding the tree to pristine..." | |
217 | restorestate | |
218 | } | |
219 | case "$single_strategy" in | |
220 | no) | |
221 | echo "Trying merge strategy $strategy..." | |
222 | ;; | |
223 | esac | |
224 | ||
225 | # Remember which strategy left the state in the working tree | |
226 | wt_strategy=$strategy | |
227 | ||
228 | git-merge-$strategy $common -- "$head_arg" "$@" | |
229 | exit=$? | |
230 | if test "$no_commit" = t && test "$exit" = 0 | |
231 | then | |
232 | merge_was_ok=t | |
233 | exit=1 ;# pretend it left conflicts. | |
234 | fi | |
235 | ||
236 | test "$exit" = 0 || { | |
237 | ||
238 | # The backend exits with 1 when conflicts are left to be resolved, | |
239 | # with 2 when it does not handle the given merge at all. | |
240 | ||
241 | if test "$exit" -eq 1 | |
242 | then | |
243 | cnt=`{ | |
244 | git-diff-files --name-only | |
245 | git-ls-files --unmerged | |
246 | } | wc -l` | |
247 | if test $best_cnt -le 0 -o $cnt -le $best_cnt | |
248 | then | |
249 | best_strategy=$strategy | |
250 | best_cnt=$cnt | |
251 | fi | |
252 | fi | |
253 | continue | |
254 | } | |
255 | ||
256 | # Automerge succeeded. | |
257 | result_tree=$(git-write-tree) && break | |
258 | done | |
259 | ||
260 | # If we have a resulting tree, that means the strategy module | |
261 | # auto resolved the merge cleanly. | |
262 | if test '' != "$result_tree" | |
263 | then | |
264 | parents="-p $head" | |
265 | for remote | |
266 | do | |
267 | parents="$parents -p $remote" | |
268 | done | |
269 | result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit | |
270 | finish "$result_commit" "Merge $result_commit, made by $wt_strategy." | |
271 | dropsave | |
272 | exit 0 | |
273 | fi | |
274 | ||
275 | # Pick the result from the best strategy and have the user fix it up. | |
276 | case "$best_strategy" in | |
277 | '') | |
278 | restorestate | |
279 | echo >&2 "No merge strategy handled the merge." | |
280 | exit 2 | |
281 | ;; | |
282 | "$wt_strategy") | |
283 | # We already have its result in the working tree. | |
284 | ;; | |
285 | *) | |
286 | echo "Rewinding the tree to pristine..." | |
287 | restorestate | |
288 | echo "Using the $best_strategy to prepare resolving by hand." | |
289 | git-merge-$best_strategy $common -- "$head_arg" "$@" | |
290 | ;; | |
291 | esac | |
292 | for remote | |
293 | do | |
294 | echo $remote | |
295 | done >"$GIT_DIR/MERGE_HEAD" | |
296 | echo $merge_msg >"$GIT_DIR/MERGE_MSG" | |
297 | ||
298 | if test "$merge_was_ok" = t | |
299 | then | |
300 | echo >&2 \ | |
301 | "Automatic merge went well; stopped before committing as requested" | |
302 | exit 0 | |
303 | else | |
304 | die "Automatic merge failed; fix up by hand" | |
305 | fi |