]>
Commit | Line | Data |
---|---|---|
91063bbc JH |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2005 Junio C Hamano | |
4 | # | |
5 | ||
7d0c6887 | 6 | USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+' |
ae2b0f15 | 7 | . git-sh-setup |
91063bbc JH |
8 | |
9 | LF=' | |
10 | ' | |
11 | ||
06d30f4f JH |
12 | all_strategies='recursive recur octopus resolve stupid ours' |
13 | case "${GIT_USE_RECUR_FOR_RECURSIVE}" in | |
14 | '') | |
15 | default_twohead_strategies=recursive ;; | |
16 | ?*) | |
17 | default_twohead_strategies=recur ;; | |
18 | esac | |
6ea23343 JH |
19 | default_octopus_strategies='octopus' |
20 | no_trivial_merge_strategies='ours' | |
91063bbc | 21 | use_strategies= |
6ea23343 JH |
22 | |
23 | index_merge=t | |
abb7c7b3 | 24 | if test "@@NO_PYTHON@@"; then |
6d297f81 | 25 | all_strategies='recur resolve octopus stupid ours' |
6ea23343 | 26 | default_twohead_strategies='resolve' |
abb7c7b3 | 27 | fi |
91063bbc | 28 | |
a9358240 | 29 | dropsave() { |
deca7e8c | 30 | rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \ |
a9358240 JH |
31 | "$GIT_DIR/MERGE_SAVE" || exit 1 |
32 | } | |
33 | ||
34 | savestate() { | |
60fa0560 | 35 | # Stash away any local modifications. |
50b8e355 | 36 | git-diff-index -z --name-only $head | |
88f8f0a5 | 37 | cpio -0 -o >"$GIT_DIR/MERGE_SAVE" |
a9358240 JH |
38 | } |
39 | ||
40 | restorestate() { | |
deca7e8c JH |
41 | if test -f "$GIT_DIR/MERGE_SAVE" |
42 | then | |
43 | git reset --hard $head | |
44 | cpio -iuv <"$GIT_DIR/MERGE_SAVE" | |
45 | git-update-index --refresh >/dev/null | |
46 | fi | |
91063bbc JH |
47 | } |
48 | ||
7d0c6887 JH |
49 | finish_up_to_date () { |
50 | case "$squash" in | |
51 | t) | |
52 | echo "$1 (nothing to squash)" ;; | |
53 | '') | |
54 | echo "$1" ;; | |
55 | esac | |
56 | dropsave | |
57 | } | |
58 | ||
59 | squash_message () { | |
60 | echo Squashed commit of the following: | |
61 | echo | |
62 | git-log --no-merges ^"$head" $remote | |
63 | } | |
64 | ||
4f692b19 | 65 | finish () { |
e1447e38 SP |
66 | if test '' = "$2" |
67 | then | |
68 | rlogm="$rloga" | |
69 | else | |
70 | echo "$2" | |
71 | rlogm="$rloga: $2" | |
72 | fi | |
7d0c6887 JH |
73 | case "$squash" in |
74 | t) | |
75 | echo "Squash commit -- not updating HEAD" | |
76 | squash_message >"$GIT_DIR/SQUASH_MSG" | |
4f692b19 | 77 | ;; |
7d0c6887 JH |
78 | '') |
79 | case "$merge_msg" in | |
80 | '') | |
81 | echo "No merge message -- not updating HEAD" | |
82 | ;; | |
83 | *) | |
e1447e38 | 84 | git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1 |
7d0c6887 JH |
85 | ;; |
86 | esac | |
4f692b19 JH |
87 | ;; |
88 | esac | |
7d0c6887 | 89 | case "$1" in |
91063bbc | 90 | '') |
7d0c6887 JH |
91 | ;; |
92 | ?*) | |
93 | case "$no_summary" in | |
94 | '') | |
95 | git-diff-tree --stat --summary -M "$head" "$1" | |
96 | ;; | |
97 | esac | |
91063bbc JH |
98 | ;; |
99 | esac | |
100 | } | |
101 | ||
e1447e38 | 102 | rloga= |
91063bbc JH |
103 | while case "$#" in 0) break ;; esac |
104 | do | |
105 | case "$1" in | |
106 | -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\ | |
107 | --no-summa|--no-summar|--no-summary) | |
108 | no_summary=t ;; | |
7d0c6887 JH |
109 | --sq|--squ|--squa|--squas|--squash) |
110 | squash=t no_commit=t ;; | |
123ee3ca JH |
111 | --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit) |
112 | no_commit=t ;; | |
91063bbc JH |
113 | -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ |
114 | --strateg=*|--strategy=*|\ | |
115 | -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy) | |
116 | case "$#,$1" in | |
117 | *,*=*) | |
8096fae7 | 118 | strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;; |
f88ed172 | 119 | 1,*) |
91063bbc JH |
120 | usage ;; |
121 | *) | |
122 | strategy="$2" | |
123 | shift ;; | |
124 | esac | |
06d30f4f JH |
125 | case "$strategy,${GIT_USE_RECUR_FOR_RECURSIVE}" in |
126 | recursive,?*) | |
127 | strategy=recur ;; | |
128 | esac | |
91063bbc JH |
129 | case " $all_strategies " in |
130 | *" $strategy "*) | |
131 | use_strategies="$use_strategies$strategy " ;; | |
132 | *) | |
133 | die "available strategies are: $all_strategies" ;; | |
134 | esac | |
135 | ;; | |
e1447e38 SP |
136 | --reflog-action=*) |
137 | rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'` | |
138 | ;; | |
91063bbc JH |
139 | -*) usage ;; |
140 | *) break ;; | |
141 | esac | |
142 | shift | |
143 | done | |
144 | ||
91063bbc JH |
145 | merge_msg="$1" |
146 | shift | |
8cc01e50 | 147 | head_arg="$1" |
91063bbc JH |
148 | head=$(git-rev-parse --verify "$1"^0) || usage |
149 | shift | |
150 | ||
151 | # All the rest are remote heads | |
6ea23343 | 152 | test "$#" = 0 && usage ;# we need at least one remote head. |
e1447e38 | 153 | test "$rloga" = '' && rloga="merge: $@" |
6ea23343 | 154 | |
9954f5b8 | 155 | remoteheads= |
91063bbc JH |
156 | for remote |
157 | do | |
9954f5b8 | 158 | remotehead=$(git-rev-parse --verify "$remote"^0) || |
91063bbc | 159 | die "$remote - not something we can merge" |
9954f5b8 | 160 | remoteheads="${remoteheads}$remotehead " |
91063bbc | 161 | done |
9954f5b8 | 162 | set x $remoteheads ; shift |
91063bbc | 163 | |
6ea23343 JH |
164 | case "$use_strategies" in |
165 | '') | |
166 | case "$#" in | |
167 | 1) | |
168 | use_strategies="$default_twohead_strategies" ;; | |
169 | *) | |
170 | use_strategies="$default_octopus_strategies" ;; | |
171 | esac | |
172 | ;; | |
173 | esac | |
174 | ||
175 | for s in $use_strategies | |
176 | do | |
177 | case " $s " in | |
178 | *" $no_trivial_merge_strategies "*) | |
179 | index_merge=f | |
180 | break | |
181 | ;; | |
182 | esac | |
183 | done | |
184 | ||
13956670 JH |
185 | case "$#" in |
186 | 1) | |
187 | common=$(git-merge-base --all $head "$@") | |
188 | ;; | |
189 | *) | |
190 | common=$(git-show-branch --merge-base $head "$@") | |
191 | ;; | |
192 | esac | |
91063bbc JH |
193 | echo "$head" >"$GIT_DIR/ORIG_HEAD" |
194 | ||
6ea23343 JH |
195 | case "$index_merge,$#,$common,$no_commit" in |
196 | f,*) | |
197 | # We've been told not to try anything clever. Skip to real merge. | |
198 | ;; | |
199 | ?,*,'',*) | |
88f8f0a5 | 200 | # No common ancestors found. We need a real merge. |
91063bbc | 201 | ;; |
6ea23343 | 202 | ?,1,"$1",*) |
91063bbc | 203 | # If head can reach all the merge then we are up to date. |
6ea23343 | 204 | # but first the most common case of merging one remote. |
7d0c6887 | 205 | finish_up_to_date "Already up-to-date." |
91063bbc JH |
206 | exit 0 |
207 | ;; | |
6ea23343 | 208 | ?,1,"$head",*) |
91063bbc | 209 | # Again the most common case of merging one remote. |
180b0d74 | 210 | echo "Updating from $head to $1" |
91063bbc | 211 | git-update-index --refresh 2>/dev/null |
bf7960eb | 212 | new_head=$(git-rev-parse --verify "$1^0") && |
744633cb | 213 | git-read-tree -u -v -m $head "$new_head" && |
4f692b19 | 214 | finish "$new_head" "Fast forward" |
a9358240 | 215 | dropsave |
91063bbc JH |
216 | exit 0 |
217 | ;; | |
6ea23343 | 218 | ?,1,?*"$LF"?*,*) |
91063bbc JH |
219 | # We are not doing octopus and not fast forward. Need a |
220 | # real merge. | |
221 | ;; | |
6ea23343 | 222 | ?,1,*,) |
f9d72413 JH |
223 | # We are not doing octopus, not fast forward, and have only |
224 | # one common. See if it is really trivial. | |
e3b59a44 JH |
225 | git var GIT_COMMITTER_IDENT >/dev/null || exit |
226 | ||
f9d72413 JH |
227 | echo "Trying really trivial in-index merge..." |
228 | git-update-index --refresh 2>/dev/null | |
744633cb | 229 | if git-read-tree --trivial -m -u -v $common $head "$1" && |
f9d72413 JH |
230 | result_tree=$(git-write-tree) |
231 | then | |
232 | echo "Wonderful." | |
233 | result_commit=$( | |
234 | echo "$merge_msg" | | |
235 | git-commit-tree $result_tree -p HEAD -p "$1" | |
236 | ) || exit | |
4f692b19 | 237 | finish "$result_commit" "In-index merge" |
f9d72413 JH |
238 | dropsave |
239 | exit 0 | |
240 | fi | |
241 | echo "Nope." | |
242 | ;; | |
91063bbc JH |
243 | *) |
244 | # An octopus. If we can reach all the remote we are up to date. | |
245 | up_to_date=t | |
246 | for remote | |
247 | do | |
13956670 | 248 | common_one=$(git-merge-base --all $head $remote) |
91063bbc JH |
249 | if test "$common_one" != "$remote" |
250 | then | |
251 | up_to_date=f | |
252 | break | |
253 | fi | |
254 | done | |
255 | if test "$up_to_date" = t | |
256 | then | |
7d0c6887 | 257 | finish_up_to_date "Already up-to-date. Yeeah!" |
91063bbc JH |
258 | exit 0 |
259 | fi | |
260 | ;; | |
261 | esac | |
262 | ||
e3b59a44 JH |
263 | # We are going to make a new commit. |
264 | git var GIT_COMMITTER_IDENT >/dev/null || exit | |
265 | ||
a9358240 JH |
266 | # At this point, we need a real merge. No matter what strategy |
267 | # we use, it would operate on the index, possibly affecting the | |
268 | # working tree, and when resolved cleanly, have the desired tree | |
269 | # in the index -- this means that the index must be in sync with | |
60fa0560 | 270 | # the $head commit. The strategies are responsible to ensure this. |
91063bbc | 271 | |
a9358240 JH |
272 | case "$use_strategies" in |
273 | ?*' '?*) | |
274 | # Stash away the local changes so that we can try more than one. | |
275 | savestate | |
276 | single_strategy=no | |
277 | ;; | |
278 | *) | |
deca7e8c | 279 | rm -f "$GIT_DIR/MERGE_SAVE" |
a9358240 JH |
280 | single_strategy=yes |
281 | ;; | |
282 | esac | |
91063bbc JH |
283 | |
284 | result_tree= best_cnt=-1 best_strategy= wt_strategy= | |
695bf722 | 285 | merge_was_ok= |
91063bbc JH |
286 | for strategy in $use_strategies |
287 | do | |
288 | test "$wt_strategy" = '' || { | |
289 | echo "Rewinding the tree to pristine..." | |
a9358240 | 290 | restorestate |
91063bbc | 291 | } |
a9358240 JH |
292 | case "$single_strategy" in |
293 | no) | |
294 | echo "Trying merge strategy $strategy..." | |
295 | ;; | |
296 | esac | |
297 | ||
298 | # Remember which strategy left the state in the working tree | |
91063bbc | 299 | wt_strategy=$strategy |
a9358240 | 300 | |
123ee3ca JH |
301 | git-merge-$strategy $common -- "$head_arg" "$@" |
302 | exit=$? | |
303 | if test "$no_commit" = t && test "$exit" = 0 | |
304 | then | |
695bf722 | 305 | merge_was_ok=t |
123ee3ca JH |
306 | exit=1 ;# pretend it left conflicts. |
307 | fi | |
308 | ||
309 | test "$exit" = 0 || { | |
91063bbc JH |
310 | |
311 | # The backend exits with 1 when conflicts are left to be resolved, | |
312 | # with 2 when it does not handle the given merge at all. | |
313 | ||
91063bbc JH |
314 | if test "$exit" -eq 1 |
315 | then | |
316 | cnt=`{ | |
317 | git-diff-files --name-only | |
318 | git-ls-files --unmerged | |
319 | } | wc -l` | |
320 | if test $best_cnt -le 0 -o $cnt -le $best_cnt | |
321 | then | |
322 | best_strategy=$strategy | |
323 | best_cnt=$cnt | |
324 | fi | |
325 | fi | |
326 | continue | |
327 | } | |
328 | ||
329 | # Automerge succeeded. | |
330 | result_tree=$(git-write-tree) && break | |
331 | done | |
332 | ||
333 | # If we have a resulting tree, that means the strategy module | |
334 | # auto resolved the merge cleanly. | |
335 | if test '' != "$result_tree" | |
336 | then | |
6ea23343 | 337 | parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /') |
bf7960eb | 338 | result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit |
e1447e38 | 339 | finish "$result_commit" "Merge made by $wt_strategy." |
a9358240 | 340 | dropsave |
91063bbc JH |
341 | exit 0 |
342 | fi | |
343 | ||
344 | # Pick the result from the best strategy and have the user fix it up. | |
345 | case "$best_strategy" in | |
346 | '') | |
a9358240 | 347 | restorestate |
4275df51 FK |
348 | echo >&2 "No merge strategy handled the merge." |
349 | exit 2 | |
91063bbc JH |
350 | ;; |
351 | "$wt_strategy") | |
352 | # We already have its result in the working tree. | |
353 | ;; | |
354 | *) | |
355 | echo "Rewinding the tree to pristine..." | |
a9358240 | 356 | restorestate |
91063bbc | 357 | echo "Using the $best_strategy to prepare resolving by hand." |
a9358240 | 358 | git-merge-$best_strategy $common -- "$head_arg" "$@" |
91063bbc JH |
359 | ;; |
360 | esac | |
7d0c6887 JH |
361 | |
362 | if test "$squash" = t | |
363 | then | |
364 | finish | |
365 | else | |
366 | for remote | |
367 | do | |
368 | echo $remote | |
369 | done >"$GIT_DIR/MERGE_HEAD" | |
370 | echo "$merge_msg" >"$GIT_DIR/MERGE_MSG" | |
371 | fi | |
deca7e8c | 372 | |
695bf722 JH |
373 | if test "$merge_was_ok" = t |
374 | then | |
375 | echo >&2 \ | |
376 | "Automatic merge went well; stopped before committing as requested" | |
377 | exit 0 | |
378 | else | |
6b94f1e4 JH |
379 | { |
380 | echo ' | |
381 | Conflicts: | |
382 | ' | |
383 | git ls-files --unmerged | | |
384 | sed -e 's/^[^ ]* / /' | | |
385 | uniq | |
386 | } >>"$GIT_DIR/MERGE_MSG" | |
1536dd9c JH |
387 | if test -d "$GIT_DIR/rr-cache" |
388 | then | |
389 | git-rerere | |
390 | fi | |
50ac7408 | 391 | die "Automatic merge failed; fix conflicts and then commit the result." |
695bf722 | 392 | fi |