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