Everyday: a bit more examples.
[git] / git-merge.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 . git-sh-setup
7
8 LF='
9 '
10
11 usage () {
12     die "git-merge [-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+"
13 }
14
15 all_strategies='recursive octopus resolve stupid ours'
16 default_strategies='recursive'
17 use_strategies=
18
19 dropsave() {
20         rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
21                  "$GIT_DIR/MERGE_SAVE" || exit 1
22 }
23
24 savestate() {
25         # Stash away any local modifications.
26         git-diff-index -z --name-only $head |
27         cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
28 }
29
30 restorestate() {
31         if test -f "$GIT_DIR/MERGE_SAVE"
32         then
33                 git reset --hard $head
34                 cpio -iuv <"$GIT_DIR/MERGE_SAVE"
35                 git-update-index --refresh >/dev/null
36         fi
37 }
38
39 finish () {
40         test '' = "$2" || echo "$2"
41         case "$merge_msg" in
42         '')
43                 echo "No merge message -- not updating HEAD"
44                 ;;
45         *)
46                 git-update-ref HEAD "$1" "$head" || exit 1
47                 ;;
48         esac
49
50         case "$no_summary" in
51         '')
52                 git-diff-tree -p -M "$head" "$1" |
53                 git-apply --stat --summary
54                 ;;
55         esac
56 }
57
58 while case "$#" in 0) break ;; esac
59 do
60         case "$1" in
61         -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
62                 --no-summa|--no-summar|--no-summary)
63                 no_summary=t ;;
64         --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
65                 no_commit=t ;;
66         -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
67                 --strateg=*|--strategy=*|\
68         -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
69                 case "$#,$1" in
70                 *,*=*)
71                         strategy=`expr "$1" : '-[^=]*=\(.*\)'` ;;
72                 1,*)
73                         usage ;;
74                 *)
75                         strategy="$2"
76                         shift ;;
77                 esac
78                 case " $all_strategies " in
79                 *" $strategy "*)
80                         use_strategies="$use_strategies$strategy " ;;
81                 *)
82                         die "available strategies are: $all_strategies" ;;
83                 esac
84                 ;;
85         -*)     usage ;;
86         *)      break ;;
87         esac
88         shift
89 done
90
91 test "$#" -le 2 && usage ;# we need at least two heads.
92
93 merge_msg="$1"
94 shift
95 head_arg="$1"
96 head=$(git-rev-parse --verify "$1"^0) || usage
97 shift
98
99 # All the rest are remote heads
100 remoteheads=
101 for remote
102 do
103         remotehead=$(git-rev-parse --verify "$remote"^0) ||
104             die "$remote - not something we can merge"
105         remoteheads="${remoteheads}$remotehead "
106 done
107 set x $remoteheads ; shift
108
109 case "$#" in
110 1)
111         common=$(git-merge-base --all $head "$@")
112         ;;
113 *)
114         common=$(git-show-branch --merge-base $head "$@")
115         ;;
116 esac
117 echo "$head" >"$GIT_DIR/ORIG_HEAD"
118
119 case "$#,$common,$no_commit" in
120 *,'',*)
121         # No common ancestors found. We need a real merge.
122         ;;
123 1,"$1",*)
124         # If head can reach all the merge then we are up to date.
125         # but first the most common case of merging one remote
126         echo "Already up-to-date."
127         dropsave
128         exit 0
129         ;;
130 1,"$head",*)
131         # Again the most common case of merging one remote.
132         echo "Updating from $head to $1."
133         git-update-index --refresh 2>/dev/null
134         new_head=$(git-rev-parse --verify "$1^0") &&
135         git-read-tree -u -m $head "$new_head" &&
136         finish "$new_head" "Fast forward"
137         dropsave
138         exit 0
139         ;;
140 1,?*"$LF"?*,*)
141         # We are not doing octopus and not fast forward.  Need a
142         # real merge.
143         ;;
144 1,*,)
145         # We are not doing octopus, not fast forward, and have only
146         # one common.  See if it is really trivial.
147         echo "Trying really trivial in-index merge..."
148         git-update-index --refresh 2>/dev/null
149         if git-read-tree --trivial -m -u $common $head "$1" &&
150            result_tree=$(git-write-tree)
151         then
152             echo "Wonderful."
153             result_commit=$(
154                 echo "$merge_msg" |
155                 git-commit-tree $result_tree -p HEAD -p "$1"
156             ) || exit
157             finish "$result_commit" "In-index merge"
158             dropsave
159             exit 0
160         fi
161         echo "Nope."
162         ;;
163 *)
164         # An octopus.  If we can reach all the remote we are up to date.
165         up_to_date=t
166         for remote
167         do
168                 common_one=$(git-merge-base --all $head $remote)
169                 if test "$common_one" != "$remote"
170                 then
171                         up_to_date=f
172                         break
173                 fi
174         done
175         if test "$up_to_date" = t
176         then
177                 echo "Already up-to-date. Yeeah!"
178                 dropsave
179                 exit 0
180         fi
181         ;;
182 esac
183
184 case "$use_strategies" in
185 '')
186         case "$#" in
187         1)
188                 use_strategies="$default_strategies" ;;
189         *)
190                 use_strategies=octopus ;;
191         esac            
192         ;;
193 esac
194
195 # At this point, we need a real merge.  No matter what strategy
196 # we use, it would operate on the index, possibly affecting the
197 # working tree, and when resolved cleanly, have the desired tree
198 # in the index -- this means that the index must be in sync with
199 # the $head commit.  The strategies are responsible to ensure this.
200
201 case "$use_strategies" in
202 ?*' '?*)
203     # Stash away the local changes so that we can try more than one.
204     savestate
205     single_strategy=no
206     ;;
207 *)
208     rm -f "$GIT_DIR/MERGE_SAVE"
209     single_strategy=yes
210     ;;
211 esac
212
213 result_tree= best_cnt=-1 best_strategy= wt_strategy=
214 for strategy in $use_strategies
215 do
216     test "$wt_strategy" = '' || {
217         echo "Rewinding the tree to pristine..."
218         restorestate
219     }
220     case "$single_strategy" in
221     no)
222         echo "Trying merge strategy $strategy..."
223         ;;
224     esac
225
226     # Remember which strategy left the state in the working tree
227     wt_strategy=$strategy
228
229     git-merge-$strategy $common -- "$head_arg" "$@"
230     exit=$?
231     if test "$no_commit" = t && test "$exit" = 0
232     then
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 die "Automatic merge failed/prevented; fix up by hand"