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