Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2005 Junio C Hamano |
| 4 | # |
| 5 | |
Junio C Hamano | ae2b0f1 | 2005-11-24 00:12:11 -0800 | [diff] [blame] | 6 | . git-sh-setup |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 7 | |
| 8 | LF=' |
| 9 | ' |
| 10 | |
| 11 | usage () { |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 12 | die "git-merge [-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+" |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 13 | } |
| 14 | |
Junio C Hamano | 64da9e6 | 2005-11-01 19:34:49 -0800 | [diff] [blame] | 15 | all_strategies='recursive octopus resolve stupid ours' |
Junio C Hamano | fbf8ac2 | 2005-11-23 16:23:11 -0800 | [diff] [blame] | 16 | default_strategies='recursive' |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 17 | use_strategies= |
| 18 | |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 19 | dropsave() { |
Junio C Hamano | deca7e8 | 2005-09-25 00:12:06 -0700 | [diff] [blame] | 20 | rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \ |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 21 | "$GIT_DIR/MERGE_SAVE" || exit 1 |
| 22 | } |
| 23 | |
| 24 | savestate() { |
Junio C Hamano | 60fa056 | 2005-09-28 16:29:11 -0700 | [diff] [blame] | 25 | # Stash away any local modifications. |
Chris Shoemaker | 50b8e35 | 2005-10-28 13:04:49 -0400 | [diff] [blame] | 26 | git-diff-index -z --name-only $head | |
Fredrik Kuivinen | 88f8f0a | 2005-10-03 08:13:09 +0200 | [diff] [blame] | 27 | cpio -0 -o >"$GIT_DIR/MERGE_SAVE" |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | restorestate() { |
Junio C Hamano | deca7e8 | 2005-09-25 00:12:06 -0700 | [diff] [blame] | 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 |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 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 | |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 50 | case "$no_summary" in |
| 51 | '') |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 52 | git-diff-tree -p -M "$head" "$1" | |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 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 ;; |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 64 | --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit) |
| 65 | no_commit=t ;; |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 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" : '-[^=]*=\(.*\)'` ;; |
Junio C Hamano | f88ed17 | 2005-09-12 22:20:42 -0700 | [diff] [blame] | 72 | 1,*) |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 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 | |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 91 | test "$#" -le 2 && usage ;# we need at least two heads. |
| 92 | |
| 93 | merge_msg="$1" |
| 94 | shift |
Fredrik Kuivinen | 8cc01e5 | 2005-09-25 16:49:02 +0200 | [diff] [blame] | 95 | head_arg="$1" |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 96 | head=$(git-rev-parse --verify "$1"^0) || usage |
| 97 | shift |
| 98 | |
| 99 | # All the rest are remote heads |
| 100 | for remote |
| 101 | do |
| 102 | git-rev-parse --verify "$remote"^0 >/dev/null || |
| 103 | die "$remote - not something we can merge" |
| 104 | done |
| 105 | |
Junio C Hamano | 1395667 | 2005-11-09 18:54:14 -0800 | [diff] [blame] | 106 | case "$#" in |
| 107 | 1) |
| 108 | common=$(git-merge-base --all $head "$@") |
| 109 | ;; |
| 110 | *) |
| 111 | common=$(git-show-branch --merge-base $head "$@") |
| 112 | ;; |
| 113 | esac |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 114 | echo "$head" >"$GIT_DIR/ORIG_HEAD" |
| 115 | |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 116 | case "$#,$common,$no_commit" in |
| 117 | *,'',*) |
Fredrik Kuivinen | 88f8f0a | 2005-10-03 08:13:09 +0200 | [diff] [blame] | 118 | # No common ancestors found. We need a real merge. |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 119 | ;; |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 120 | 1,"$1",*) |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 121 | # If head can reach all the merge then we are up to date. |
| 122 | # but first the most common case of merging one remote |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 123 | echo "Already up-to-date." |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 124 | dropsave |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 125 | exit 0 |
| 126 | ;; |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 127 | 1,"$head",*) |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 128 | # Again the most common case of merging one remote. |
| 129 | echo "Updating from $head to $1." |
| 130 | git-update-index --refresh 2>/dev/null |
Junio C Hamano | bf7960e | 2005-09-27 18:14:27 -0700 | [diff] [blame] | 131 | new_head=$(git-rev-parse --verify "$1^0") && |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 132 | git-read-tree -u -m $head "$new_head" && |
| 133 | finish "$new_head" "Fast forward" |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 134 | dropsave |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 135 | exit 0 |
| 136 | ;; |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 137 | 1,?*"$LF"?*,*) |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 138 | # We are not doing octopus and not fast forward. Need a |
| 139 | # real merge. |
| 140 | ;; |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 141 | 1,*,) |
Junio C Hamano | f9d7241 | 2005-10-02 11:13:44 -0700 | [diff] [blame] | 142 | # We are not doing octopus, not fast forward, and have only |
| 143 | # one common. See if it is really trivial. |
| 144 | echo "Trying really trivial in-index merge..." |
| 145 | git-update-index --refresh 2>/dev/null |
| 146 | if git-read-tree --trivial -m -u $common $head "$1" && |
| 147 | result_tree=$(git-write-tree) |
| 148 | then |
| 149 | echo "Wonderful." |
| 150 | result_commit=$( |
| 151 | echo "$merge_msg" | |
| 152 | git-commit-tree $result_tree -p HEAD -p "$1" |
| 153 | ) || exit |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 154 | finish "$result_commit" "In-index merge" |
Junio C Hamano | f9d7241 | 2005-10-02 11:13:44 -0700 | [diff] [blame] | 155 | dropsave |
| 156 | exit 0 |
| 157 | fi |
| 158 | echo "Nope." |
| 159 | ;; |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 160 | *) |
| 161 | # An octopus. If we can reach all the remote we are up to date. |
| 162 | up_to_date=t |
| 163 | for remote |
| 164 | do |
Junio C Hamano | 1395667 | 2005-11-09 18:54:14 -0800 | [diff] [blame] | 165 | common_one=$(git-merge-base --all $head $remote) |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 166 | if test "$common_one" != "$remote" |
| 167 | then |
| 168 | up_to_date=f |
| 169 | break |
| 170 | fi |
| 171 | done |
| 172 | if test "$up_to_date" = t |
| 173 | then |
| 174 | echo "Already up-to-date. Yeeah!" |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 175 | dropsave |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 176 | exit 0 |
| 177 | fi |
| 178 | ;; |
| 179 | esac |
| 180 | |
Junio C Hamano | fbf8ac2 | 2005-11-23 16:23:11 -0800 | [diff] [blame] | 181 | case "$use_strategies" in |
| 182 | '') |
| 183 | case "$#" in |
| 184 | 1) |
| 185 | use_strategies="$default_strategies" ;; |
| 186 | *) |
| 187 | use_strategies=octopus ;; |
| 188 | esac |
| 189 | ;; |
| 190 | esac |
| 191 | |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 192 | # At this point, we need a real merge. No matter what strategy |
| 193 | # we use, it would operate on the index, possibly affecting the |
| 194 | # working tree, and when resolved cleanly, have the desired tree |
| 195 | # in the index -- this means that the index must be in sync with |
Junio C Hamano | 60fa056 | 2005-09-28 16:29:11 -0700 | [diff] [blame] | 196 | # the $head commit. The strategies are responsible to ensure this. |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 197 | |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 198 | case "$use_strategies" in |
| 199 | ?*' '?*) |
| 200 | # Stash away the local changes so that we can try more than one. |
| 201 | savestate |
| 202 | single_strategy=no |
| 203 | ;; |
| 204 | *) |
Junio C Hamano | deca7e8 | 2005-09-25 00:12:06 -0700 | [diff] [blame] | 205 | rm -f "$GIT_DIR/MERGE_SAVE" |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 206 | single_strategy=yes |
| 207 | ;; |
| 208 | esac |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 209 | |
| 210 | result_tree= best_cnt=-1 best_strategy= wt_strategy= |
| 211 | for strategy in $use_strategies |
| 212 | do |
| 213 | test "$wt_strategy" = '' || { |
| 214 | echo "Rewinding the tree to pristine..." |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 215 | restorestate |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 216 | } |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 217 | case "$single_strategy" in |
| 218 | no) |
| 219 | echo "Trying merge strategy $strategy..." |
| 220 | ;; |
| 221 | esac |
| 222 | |
| 223 | # Remember which strategy left the state in the working tree |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 224 | wt_strategy=$strategy |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 225 | |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 226 | git-merge-$strategy $common -- "$head_arg" "$@" |
| 227 | exit=$? |
| 228 | if test "$no_commit" = t && test "$exit" = 0 |
| 229 | then |
| 230 | exit=1 ;# pretend it left conflicts. |
| 231 | fi |
| 232 | |
| 233 | test "$exit" = 0 || { |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 234 | |
| 235 | # The backend exits with 1 when conflicts are left to be resolved, |
| 236 | # with 2 when it does not handle the given merge at all. |
| 237 | |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 238 | if test "$exit" -eq 1 |
| 239 | then |
| 240 | cnt=`{ |
| 241 | git-diff-files --name-only |
| 242 | git-ls-files --unmerged |
| 243 | } | wc -l` |
| 244 | if test $best_cnt -le 0 -o $cnt -le $best_cnt |
| 245 | then |
| 246 | best_strategy=$strategy |
| 247 | best_cnt=$cnt |
| 248 | fi |
| 249 | fi |
| 250 | continue |
| 251 | } |
| 252 | |
| 253 | # Automerge succeeded. |
| 254 | result_tree=$(git-write-tree) && break |
| 255 | done |
| 256 | |
| 257 | # If we have a resulting tree, that means the strategy module |
| 258 | # auto resolved the merge cleanly. |
| 259 | if test '' != "$result_tree" |
| 260 | then |
| 261 | parents="-p $head" |
| 262 | for remote |
| 263 | do |
| 264 | parents="$parents -p $remote" |
| 265 | done |
Junio C Hamano | bf7960e | 2005-09-27 18:14:27 -0700 | [diff] [blame] | 266 | result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit |
Junio C Hamano | 4f692b1 | 2005-10-22 04:45:15 -0700 | [diff] [blame] | 267 | finish "$result_commit" "Merge $result_commit, made by $wt_strategy." |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 268 | dropsave |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 269 | exit 0 |
| 270 | fi |
| 271 | |
| 272 | # Pick the result from the best strategy and have the user fix it up. |
| 273 | case "$best_strategy" in |
| 274 | '') |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 275 | restorestate |
Fredrik Kuivinen | 4275df5 | 2005-12-03 11:40:21 +0100 | [diff] [blame] | 276 | echo >&2 "No merge strategy handled the merge." |
| 277 | exit 2 |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 278 | ;; |
| 279 | "$wt_strategy") |
| 280 | # We already have its result in the working tree. |
| 281 | ;; |
| 282 | *) |
| 283 | echo "Rewinding the tree to pristine..." |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 284 | restorestate |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 285 | echo "Using the $best_strategy to prepare resolving by hand." |
Junio C Hamano | a935824 | 2005-09-23 00:43:04 -0700 | [diff] [blame] | 286 | git-merge-$best_strategy $common -- "$head_arg" "$@" |
Junio C Hamano | 91063bb | 2005-09-08 13:47:12 -0700 | [diff] [blame] | 287 | ;; |
| 288 | esac |
| 289 | for remote |
| 290 | do |
| 291 | echo $remote |
| 292 | done >"$GIT_DIR/MERGE_HEAD" |
Junio C Hamano | deca7e8 | 2005-09-25 00:12:06 -0700 | [diff] [blame] | 293 | echo $merge_msg >"$GIT_DIR/MERGE_MSG" |
| 294 | |
Junio C Hamano | 123ee3c | 2005-11-01 19:30:11 -0800 | [diff] [blame] | 295 | die "Automatic merge failed/prevented; fix up by hand" |