git-pull.sh 8.1 KB
Newer Older
1 2
#!/bin/sh
#
3 4 5 6
# Copyright (c) 2005 Junio C Hamano
#
# Fetch one or more remote refs and merge it/them into the current HEAD.

7
USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
8
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
9
SUBDIRECTORY_OK=Yes
10
OPTIONS_SPEC=
11
. git-sh-setup
12
set_reflog_action "pull $*"
13
require_work_tree
14
cd_to_toplevel
15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

die_conflict () {
    git diff-index --cached --name-status -r --ignore-submodules HEAD --
    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
	die "Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'."
    else
	die "Pull is not possible because you have unmerged files."
    fi
}

die_merge () {
    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
	die "You have not concluded your merge (MERGE_HEAD exists).
Please, commit your changes before you can merge."
    else
	die "You have not concluded your merge (MERGE_HEAD exists)."
    fi
}

test -z "$(git ls-files -u)" || die_conflict
test -f "$GIT_DIR/MERGE_HEAD" && die_merge
39

40
strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
41
log_arg= verbosity= progress= recurse_submodules=
42
merge_args=
43
curr_branch=$(git symbolic-ref -q HEAD)
44
curr_branch_short="${curr_branch#refs/heads/}"
45
rebase=$(git config --bool branch.$curr_branch_short.rebase)
J
Jeff King 已提交
46
dry_run=
47
while :
48 49
do
	case "$1" in
T
Tuncer Ayaz 已提交
50
	-q|--quiet)
51
		verbosity="$verbosity -q" ;;
T
Tuncer Ayaz 已提交
52
	-v|--verbose)
53
		verbosity="$verbosity -v" ;;
T
Tay Ray Chuan 已提交
54 55
	--progress)
		progress=--progress ;;
56
	-n|--no-stat|--no-summary)
57
		diffstat=--no-stat ;;
58
	--stat|--summary)
59
		diffstat=--stat ;;
60 61
	--log|--no-log)
		log_arg=$1 ;;
62 63
	--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
		no_commit=--no-commit ;;
64 65
	--c|--co|--com|--comm|--commi|--commit)
		no_commit=--commit ;;
J
Junio C Hamano 已提交
66 67
	--sq|--squ|--squa|--squas|--squash)
		squash=--squash ;;
68 69 70 71 72 73
	--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
		squash=--no-squash ;;
	--ff)
		no_ff=--ff ;;
	--no-ff)
		no_ff=--no-ff ;;
74 75
	--ff-only)
		ff_only=--ff-only ;;
76 77 78 79 80
	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
		--strateg=*|--strategy=*|\
	-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
		case "$#,$1" in
		*,*=*)
D
Dennis Stosberg 已提交
81
			strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
82 83 84 85 86 87 88 89
		1,*)
			usage ;;
		*)
			strategy="$2"
			shift ;;
		esac
		strategy_args="${strategy_args}-s $strategy "
		;;
90 91 92 93 94
	-X*)
		case "$#,$1" in
		1,-X)
			usage ;;
		*,-X)
J
Junio C Hamano 已提交
95
			xx="-X $(git rev-parse --sq-quote "$2")"
96 97
			shift ;;
		*,*)
J
Junio C Hamano 已提交
98
			xx=$(git rev-parse --sq-quote "$1") ;;
99 100 101
		esac
		merge_args="$merge_args$xx "
		;;
102 103 104 105 106 107
	-r|--r|--re|--reb|--reba|--rebas|--rebase)
		rebase=true
		;;
	--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
		rebase=false
		;;
108 109 110
	--recurse-submodules)
		recurse_submodules=--recurse-submodules
		;;
111 112 113
	--no-recurse-submodules)
		recurse_submodules=--no-recurse-submodules
		;;
J
Jeff King 已提交
114 115 116
	--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
		dry_run=--dry-run
		;;
117 118 119
	-h|--h|--he|--hel|--help)
		usage
		;;
120 121
	*)
		# Pass thru anything that may be meant for fetch.
122
		break
123 124 125 126 127
		;;
	esac
	shift
done

128 129 130 131 132 133 134 135 136 137 138 139
error_on_no_merge_candidates () {
	exec >&2
	for opt
	do
		case "$opt" in
		-t|--t|--ta|--tag|--tags)
			echo "Fetching tags only, you probably meant:"
			echo "  git fetch --tags"
			exit 1
		esac
	done

140 141 142 143 144 145 146 147 148
	if test true = "$rebase"
	then
		op_type=rebase
		op_prep=against
	else
		op_type=merge
		op_prep=with
	fi

149
	curr_branch=${curr_branch#refs/heads/}
150
	upstream=$(git config "branch.$curr_branch.merge")
151
	remote=$(git config "branch.$curr_branch.remote")
152

153
	if [ $# -gt 1 ]; then
154 155 156 157 158 159
		if [ "$rebase" = true ]; then
			printf "There is no candidate for rebasing against "
		else
			printf "There are no candidates for merging "
		fi
		echo "among the refs that you just fetched."
160 161 162 163
		echo "Generally this means that you provided a wildcard refspec which had no"
		echo "matches on the remote end."
	elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
		echo "You asked to pull from the remote '$1', but did not specify"
164
		echo "a branch. Because this is not the default configured remote"
165 166
		echo "for your current branch, you must specify a branch on the command line."
	elif [ -z "$curr_branch" ]; then
167 168
		echo "You are not currently on a branch, so I cannot use any"
		echo "'branch.<branchname>.merge' in your configuration file."
169
		echo "Please specify which remote branch you want to use on the command"
170 171
		echo "line and try again (e.g. 'git pull <repository> <refspec>')."
		echo "See git-pull(1) for details."
172
	elif [ -z "$upstream" ]; then
173
		echo "You asked me to pull without telling me which branch you"
174 175 176
		echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
		echo "your configuration file does not tell me, either. Please"
		echo "specify which branch you want to use on the command line and"
177 178 179
		echo "try again (e.g. 'git pull <repository> <refspec>')."
		echo "See git-pull(1) for details."
		echo
180 181 182 183 184 185 186 187
		echo "If you often $op_type $op_prep the same branch, you may want to"
		echo "use something like the following in your configuration file:"
		echo
		echo "    [branch \"${curr_branch}\"]"
		echo "    remote = <nickname>"
		echo "    merge = <remote-ref>"
		test rebase = "$op_type" &&
			echo "    rebase = true"
188
		echo
189 190 191
		echo "    [remote \"<nickname>\"]"
		echo "    url = <url>"
		echo "    fetch = <refspec>"
192 193
		echo
		echo "See git-config(1) for details."
194
	else
195 196
		echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
		echo "from the remote, but no such ref was fetched."
197
	fi
198 199 200
	exit 1
}

201
test true = "$rebase" && {
202 203 204 205 206 207 208 209
	if ! git rev-parse -q --verify HEAD >/dev/null
	then
		# On an unborn branch
		if test -f "$GIT_DIR/index"
		then
			die "updating an unborn branch with changes added to the index"
		fi
	else
210
		require_clean_work_tree "pull with rebase" "Please commit or stash them."
211
	fi
212
	oldremoteref= &&
213
	. git-parse-remote &&
214 215 216 217 218 219 220 221 222 223
	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
	oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
	for reflog in $(git rev-list -g $remoteref 2>/dev/null)
	do
		if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
		then
			oldremoteref="$reflog"
			break
		fi
	done
224
}
M
Miklos Vajna 已提交
225
orig_head=$(git rev-parse -q --verify HEAD)
226
git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
J
Jeff King 已提交
227
test -z "$dry_run" || exit 0
228

M
Miklos Vajna 已提交
229
curr_head=$(git rev-parse -q --verify HEAD)
230
if test -n "$orig_head" && test "$curr_head" != "$orig_head"
231 232 233 234 235 236 237 238
then
	# The fetch involved updating the current branch.

	# The working tree and the index file is still based on the
	# $orig_head commit, but we are merging into $curr_head.
	# First update the working tree to match $curr_head.

	echo >&2 "Warning: fetch updated the current branch head."
239
	echo >&2 "Warning: fast-forwarding your working tree from"
240
	echo >&2 "Warning: commit $orig_head."
241
	git update-index -q --refresh
242
	git read-tree -u -m "$orig_head" "$curr_head" ||
243 244 245 246 247 248 249
		die 'Cannot fast-forward your working tree.
After making sure that you saved anything precious from
$ git diff '$orig_head'
output, run
$ git reset --hard
to recover.'

250 251
fi

252 253 254
merge_head=$(sed -e '/	not-for-merge	/d' \
	-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
	tr '\012' ' ')
255 256

case "$merge_head" in
257
'')
J
Junio C Hamano 已提交
258
	error_on_no_merge_candidates "$@"
259
	;;
260
?*' '?*)
261 262
	if test -z "$orig_head"
	then
263
		die "Cannot merge multiple branches into empty head"
264
	fi
265 266
	if test true = "$rebase"
	then
267
		die "Cannot rebase onto multiple branches"
268
	fi
269 270 271
	;;
esac

272 273
if test -z "$orig_head"
then
274
	git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
275
	git read-tree --reset -u HEAD || exit 1
276 277 278
	exit
fi

279 280 281 282 283 284 285 286 287
if test true = "$rebase"
then
	o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
	if test "$oldremoteref" = "$o"
	then
		unset oldremoteref
	fi
fi

288
merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
J
Junio C Hamano 已提交
289 290 291 292 293 294 295 296
case "$rebase" in
true)
	eval="git-rebase $diffstat $strategy_args $merge_args"
	eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
	;;
*)
	eval="git-merge $diffstat $no_commit $squash $no_ff $ff_only"
	eval="$eval  $log_arg $strategy_args $merge_args"
297
	eval="$eval \"\$merge_name\" HEAD $merge_head $verbosity"
J
Junio C Hamano 已提交
298 299 300
	;;
esac
eval "exec $eval"