1#!/bin/sh 2# 3# Copyright (c) 2005 Junio C Hamano 4# 5# Fetch one or more remote refs and merge it/them into the current HEAD. 6 7USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...' 8LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.' 9SUBDIRECTORY_OK=Yes 10OPTIONS_SPEC= 11. git-sh-setup 12set_reflog_action "pull $*" 13require_work_tree 14cd_to_toplevel 15 16 17die_conflict () { 18 git diff-index --cached --name-status -r --ignore-submodules HEAD -- 19if[$(git config --bool --get advice.resolveConflict || echo true)="true"];then 20 die "Pull is not possible because you have unmerged files. 21Please, fix them up in the work tree, and then use 'git add/rm <file>' 22as appropriate to mark resolution, or use 'git commit -a'." 23else 24 die "Pull is not possible because you have unmerged files." 25fi 26} 27 28die_merge () { 29if[$(git config --bool --get advice.resolveConflict || echo true)="true"];then 30 die "You have not concluded your merge (MERGE_HEAD exists). 31Please, commit your changes before you can merge." 32else 33 die "You have not concluded your merge (MERGE_HEAD exists)." 34fi 35} 36 37test -z"$(git ls-files -u)"|| die_conflict 38test -f"$GIT_DIR/MERGE_HEAD"&& die_merge 39 40strategy_args= diffstat= no_commit= squash= no_ff= ff_only= 41log_arg= verbosity= progress= recurse_submodules= 42merge_args= 43curr_branch=$(git symbolic-ref -q HEAD) 44curr_branch_short="${curr_branch#refs/heads/}" 45rebase=$(git config --bool branch.$curr_branch_short.rebase) 46dry_run= 47while: 48do 49case"$1"in 50-q|--quiet) 51 verbosity="$verbosity-q";; 52-v|--verbose) 53 verbosity="$verbosity-v";; 54--progress) 55 progress=--progress;; 56-n|--no-stat|--no-summary) 57 diffstat=--no-stat;; 58--stat|--summary) 59 diffstat=--stat;; 60--log|--no-log) 61 log_arg=$1;; 62--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit) 63 no_commit=--no-commit;; 64--c|--co|--com|--comm|--commi|--commit) 65 no_commit=--commit;; 66--sq|--squ|--squa|--squas|--squash) 67 squash=--squash;; 68--no-sq|--no-squ|--no-squa|--no-squas|--no-squash) 69 squash=--no-squash;; 70--ff) 71 no_ff=--ff;; 72--no-ff) 73 no_ff=--no-ff;; 74--ff-only) 75 ff_only=--ff-only;; 76-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ 77--strateg=*|--strategy=*|\ 78-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy) 79case"$#,$1"in 80*,*=*) 81 strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'`;; 821,*) 83 usage ;; 84*) 85 strategy="$2" 86shift;; 87esac 88 strategy_args="${strategy_args}-s$strategy" 89;; 90-X*) 91case"$#,$1"in 921,-X) 93 usage ;; 94*,-X) 95 xx="-X$(git rev-parse --sq-quote "$2")" 96shift;; 97*,*) 98 xx=$(git rev-parse --sq-quote "$1");; 99esac 100 merge_args="$merge_args$xx" 101;; 102-r|--r|--re|--reb|--reba|--rebas|--rebase) 103 rebase=true 104;; 105--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase) 106 rebase=false 107;; 108--recurse-submodules) 109 recurse_submodules=--recurse-submodules 110;; 111--no-recurse-submodules) 112 recurse_submodules=--no-recurse-submodules 113;; 114--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) 115 dry_run=--dry-run 116;; 117-h|--h|--he|--hel|--help|--help-|--help-a|--help-al|--help-all) 118 usage 119;; 120*) 121# Pass thru anything that may be meant for fetch. 122break 123;; 124esac 125shift 126done 127 128error_on_no_merge_candidates () { 129exec>&2 130for opt 131do 132case"$opt"in 133-t|--t|--ta|--tag|--tags) 134echo"Fetching tags only, you probably meant:" 135echo" git fetch --tags" 136exit1 137esac 138done 139 140iftest true ="$rebase" 141then 142 op_type=rebase 143 op_prep=against 144else 145 op_type=merge 146 op_prep=with 147fi 148 149 curr_branch=${curr_branch#refs/heads/} 150 upstream=$(git config "branch.$curr_branch.merge") 151 remote=$(git config "branch.$curr_branch.remote") 152 153if[$#-gt1];then 154if["$rebase"= true ];then 155printf"There is no candidate for rebasing against " 156else 157printf"There are no candidates for merging " 158fi 159echo"among the refs that you just fetched." 160echo"Generally this means that you provided a wildcard refspec which had no" 161echo"matches on the remote end." 162elif[$#-gt0] && ["$1"!="$remote"];then 163echo"You asked to pull from the remote '$1', but did not specify" 164echo"a branch. Because this is not the default configured remote" 165echo"for your current branch, you must specify a branch on the command line." 166elif[-z"$curr_branch"];then 167echo"You are not currently on a branch, so I cannot use any" 168echo"'branch.<branchname>.merge' in your configuration file." 169echo"Please specify which remote branch you want to use on the command" 170echo"line and try again (e.g. 'git pull <repository> <refspec>')." 171echo"See git-pull(1) for details." 172elif[-z"$upstream"];then 173echo"You asked me to pull without telling me which branch you" 174echo"want to$op_type$op_prep, and 'branch.${curr_branch}.merge' in" 175echo"your configuration file does not tell me, either. Please" 176echo"specify which branch you want to use on the command line and" 177echo"try again (e.g. 'git pull <repository> <refspec>')." 178echo"See git-pull(1) for details." 179echo 180echo"If you often$op_type$op_prepthe same branch, you may want to" 181echo"use something like the following in your configuration file:" 182echo 183echo" [branch\"${curr_branch}\"]" 184echo" remote = <nickname>" 185echo" merge = <remote-ref>" 186test rebase ="$op_type"&& 187echo" rebase = true" 188echo 189echo" [remote\"<nickname>\"]" 190echo" url = <url>" 191echo" fetch = <refspec>" 192echo 193echo"See git-config(1) for details." 194else 195echo"Your configuration specifies to$op_type$op_prepthe ref '${upstream#refs/heads/}'" 196echo"from the remote, but no such ref was fetched." 197fi 198exit1 199} 200 201test true ="$rebase"&& { 202if! git rev-parse -q --verify HEAD >/dev/null 203then 204# On an unborn branch 205iftest -f"$GIT_DIR/index" 206then 207 die "updating an unborn branch with changes added to the index" 208fi 209else 210 require_clean_work_tree "pull with rebase""Please commit or stash them." 211fi 212 oldremoteref= && 213 . git-parse-remote&& 214 remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)"&& 215 oldremoteref="$(git rev-parse -q --verify "$remoteref")"&& 216for reflog in$(git rev-list -g $remoteref 2>/dev/null) 217do 218iftest"$reflog"="$(git merge-base $reflog $curr_branch)" 219then 220 oldremoteref="$reflog" 221break 222fi 223done 224} 225orig_head=$(git rev-parse -q --verify HEAD) 226git fetch $verbosity $progress $dry_run $recurse_submodules--update-head-ok"$@"||exit1 227test -z"$dry_run"||exit0 228 229curr_head=$(git rev-parse -q --verify HEAD) 230iftest -n"$orig_head"&&test"$curr_head"!="$orig_head" 231then 232# The fetch involved updating the current branch. 233 234# The working tree and the index file is still based on the 235# $orig_head commit, but we are merging into $curr_head. 236# First update the working tree to match $curr_head. 237 238echo>&2"Warning: fetch updated the current branch head." 239echo>&2"Warning: fast-forwarding your working tree from" 240echo>&2"Warning: commit$orig_head." 241 git update-index -q --refresh 242 git read-tree -u -m"$orig_head""$curr_head"|| 243 die 'Cannot fast-forward your working tree. 244After making sure that you saved anything precious from 245$ git diff '$orig_head' 246output, run 247$ git reset --hard 248to recover.' 249 250fi 251 252merge_head=$(sed-e'/ not-for-merge /d' \ 253-e's/ .*//'"$GIT_DIR"/FETCH_HEAD | \ 254tr'\012'' ') 255 256case"$merge_head"in 257'') 258 error_on_no_merge_candidates "$@" 259;; 260?*' '?*) 261iftest -z"$orig_head" 262then 263 die "Cannot merge multiple branches into empty head" 264fi 265iftest true ="$rebase" 266then 267 die "Cannot rebase onto multiple branches" 268fi 269;; 270esac 271 272iftest -z"$orig_head" 273then 274 git update-ref -m"initial pull" HEAD $merge_head"$curr_head"&& 275 git read-tree -m -u HEAD ||exit1 276exit 277fi 278 279iftest true ="$rebase" 280then 281 o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref) 282iftest"$oldremoteref"="$o" 283then 284unset oldremoteref 285fi 286fi 287 288merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD")||exit 289case"$rebase"in 290true) 291eval="git-rebase$diffstat$strategy_args$merge_args" 292eval="$eval--onto$merge_head${oldremoteref:-$merge_head}" 293;; 294*) 295eval="git-merge$diffstat$no_commit$squash$no_ff$ff_only" 296eval="$eval$log_arg$strategy_args$merge_args" 297eval="$eval\"\$merge_name\"HEAD$merge_head$verbosity" 298;; 299esac 300eval"exec$eval"