[PATCH] More descriptive messages for conflict cases in merges
[git.git] / git-merge.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 . git-sh-setup || die "Not a git archive"
7
8 LF='
9 '
10
11 usage () {
12     die "git-merge [-n] [-s <strategy>]... <merge-message> <head> <remote>+"
13 }
14
15 # all_strategies='resolve recursive stupid octopus'
16
17 all_strategies='recursive octopus resolve stupid'
18 default_strategies='resolve octopus'
19 use_strategies=
20
21 dropheads() {
22         rm -f -- "$GIT_DIR/MERGE_HEAD" || exit 1
23 }
24
25 summary() {
26         case "$no_summary" in
27         '')
28                 git-diff-tree -p -M $head "$1" |
29                 git-apply --stat --summary
30                 ;;
31         esac
32 }
33
34 while case "$#" in 0) break ;; esac
35 do
36         case "$1" in
37         -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
38                 --no-summa|--no-summar|--no-summary)
39                 no_summary=t ;;
40         -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
41                 --strateg=*|--strategy=*|\
42         -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
43                 case "$#,$1" in
44                 *,*=*)
45                         strategy=`expr "$1" : '-[^=]*=\(.*\)'` ;;
46                 1,*)
47                         usage ;;
48                 *)
49                         strategy="$2"
50                         shift ;;
51                 esac
52                 case " $all_strategies " in
53                 *" $strategy "*)
54                         use_strategies="$use_strategies$strategy " ;;
55                 *)
56                         die "available strategies are: $all_strategies" ;;
57                 esac
58                 ;;
59         -*)     usage ;;
60         *)      break ;;
61         esac
62         shift
63 done
64
65 case "$use_strategies" in
66 '')
67         use_strategies=$default_strategies
68         ;;
69 esac
70 test "$#" -le 2 && usage ;# we need at least two heads.
71
72 merge_msg="$1"
73 shift
74 head_arg="$1"
75 head=$(git-rev-parse --verify "$1"^0) || usage
76 shift
77
78 # All the rest are remote heads
79 for remote
80 do
81         git-rev-parse --verify "$remote"^0 >/dev/null ||
82             die "$remote - not something we can merge"
83 done
84
85 common=$(git-show-branch --merge-base $head "$@")
86 echo "$head" >"$GIT_DIR/ORIG_HEAD"
87
88 case "$#,$common" in
89 *,'')
90         die "Unable to find common commit between $head_arg and $*"
91         ;;
92 1,"$1")
93         # If head can reach all the merge then we are up to date.
94         # but first the most common case of merging one remote
95         echo "Already up-to-date. Yeeah!"
96         dropheads
97         exit 0
98         ;;
99 1,"$head")
100         # Again the most common case of merging one remote.
101         echo "Updating from $head to $1."
102         git-update-index --refresh 2>/dev/null
103         git-read-tree -u -m $head "$1" || exit 1
104         git-rev-parse --verify "$1^0" > "$GIT_DIR/HEAD"
105         summary "$1"
106         dropheads
107         exit 0
108         ;;
109 1,*)
110         # We are not doing octopus and not fast forward.  Need a
111         # real merge.
112         ;;
113 *)
114         # An octopus.  If we can reach all the remote we are up to date.
115         up_to_date=t
116         for remote
117         do
118                 common_one=$(git-merge-base $head $remote)
119                 if test "$common_one" != "$remote"
120                 then
121                         up_to_date=f
122                         break
123                 fi
124         done
125         if test "$up_to_date" = t
126         then
127                 echo "Already up-to-date. Yeeah!"
128                 dropheads
129                 exit 0
130         fi
131         ;;
132 esac
133
134 # At this point we need a real merge.  Require that the tree matches
135 # exactly our head.
136
137 git-update-index --refresh &&
138 test '' = "`git-diff-index --cached --name-only $head`" || {
139         die "Need real merge but the working tree has local changes."
140 }
141
142 result_tree= best_cnt=-1 best_strategy= wt_strategy=
143 for strategy in $use_strategies
144 do
145     test "$wt_strategy" = '' || {
146         echo "Rewinding the tree to pristine..."
147         git reset --hard $head
148     }
149     echo "Trying merge strategy $strategy..."
150     wt_strategy=$strategy
151     git-merge-$strategy $common -- $head_arg "$@" || {
152
153         # The backend exits with 1 when conflicts are left to be resolved,
154         # with 2 when it does not handle the given merge at all.
155
156         exit=$?
157         if test "$exit" -eq 1
158         then
159             cnt=`{
160                 git-diff-files --name-only
161                 git-ls-files --unmerged
162             } | wc -l`
163             if test $best_cnt -le 0 -o $cnt -le $best_cnt
164             then
165                 best_strategy=$strategy
166                 best_cnt=$cnt
167             fi
168         fi
169         continue
170     }
171
172     # Automerge succeeded.
173     result_tree=$(git-write-tree) && break
174 done
175
176 # If we have a resulting tree, that means the strategy module
177 # auto resolved the merge cleanly.
178 if test '' != "$result_tree"
179 then
180     parents="-p $head"
181     for remote
182     do
183         parents="$parents -p $remote"
184     done
185     result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents)
186     echo "Committed merge $result_commit, made by $wt_strategy."
187     echo $result_commit >"$GIT_DIR/HEAD"
188     summary $result_commit
189     dropheads
190     exit 0
191 fi
192
193 # Pick the result from the best strategy and have the user fix it up.
194 case "$best_strategy" in
195 '')
196         git reset --hard $head
197         die "No merge strategy handled the merge."
198         ;;
199 "$wt_strategy")
200         # We already have its result in the working tree.
201         ;;
202 *)
203         echo "Rewinding the tree to pristine..."
204         git reset --hard $head
205         echo "Using the $best_strategy to prepare resolving by hand."
206         git-merge-$best_strategy $common -- $head_arg "$@"
207         ;;
208 esac
209 for remote
210 do
211         echo $remote
212 done >"$GIT_DIR/MERGE_HEAD"
213 die "Automatic merge failed; fix up by hand"