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