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

118 119 120 121 122 123 124 125 126 127 128 129
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

130 131 132 133 134 135 136 137 138
	if test true = "$rebase"
	then
		op_type=rebase
		op_prep=against
	else
		op_type=merge
		op_prep=with
	fi

139
	curr_branch=${curr_branch#refs/heads/}
140
	upstream=$(git config "branch.$curr_branch.merge")
141
	remote=$(git config "branch.$curr_branch.remote")
142

143
	if [ $# -gt 1 ]; then
144 145 146 147 148 149
		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."
150 151 152 153
		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"
154
		echo "a branch. Because this is not the default configured remote"
155 156
		echo "for your current branch, you must specify a branch on the command line."
	elif [ -z "$curr_branch" ]; then
157 158
		echo "You are not currently on a branch, so I cannot use any"
		echo "'branch.<branchname>.merge' in your configuration file."
159
		echo "Please specify which remote branch you want to use on the command"
160 161
		echo "line and try again (e.g. 'git pull <repository> <refspec>')."
		echo "See git-pull(1) for details."
162
	elif [ -z "$upstream" ]; then
163
		echo "You asked me to pull without telling me which branch you"
164 165 166
		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"
167 168 169
		echo "try again (e.g. 'git pull <repository> <refspec>')."
		echo "See git-pull(1) for details."
		echo
170 171 172 173 174 175 176 177
		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"
178
		echo
179 180 181
		echo "    [remote \"<nickname>\"]"
		echo "    url = <url>"
		echo "    fetch = <refspec>"
182 183
		echo
		echo "See git-config(1) for details."
184
	else
185 186
		echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
		echo "from the remote, but no such ref was fetched."
187
	fi
188 189 190
	exit 1
}

191
test true = "$rebase" && {
192 193 194 195 196 197 198 199 200 201 202 203 204
	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
		git update-index --ignore-submodules --refresh &&
		git diff-files --ignore-submodules --quiet &&
		git diff-index --ignore-submodules --cached --quiet HEAD -- ||
		die "refusing to pull with rebase: your working tree is not up-to-date"
	fi
205
	oldremoteref= &&
206
	. git-parse-remote &&
207 208 209 210 211 212 213 214 215 216
	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
217
}
M
Miklos Vajna 已提交
218
orig_head=$(git rev-parse -q --verify HEAD)
T
Tay Ray Chuan 已提交
219
git fetch $verbosity $progress --update-head-ok "$@" || exit 1
220

M
Miklos Vajna 已提交
221
curr_head=$(git rev-parse -q --verify HEAD)
222
if test -n "$orig_head" && test "$curr_head" != "$orig_head"
223 224 225 226 227 228 229 230
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."
231
	echo >&2 "Warning: fast-forwarding your working tree from"
232
	echo >&2 "Warning: commit $orig_head."
233
	git update-index -q --refresh
234
	git read-tree -u -m "$orig_head" "$curr_head" ||
235 236 237 238 239 240 241
		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.'

242 243
fi

244 245 246
merge_head=$(sed -e '/	not-for-merge	/d' \
	-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
	tr '\012' ' ')
247 248

case "$merge_head" in
249
'')
J
Junio C Hamano 已提交
250
	error_on_no_merge_candidates "$@"
251
	;;
252
?*' '?*)
253 254
	if test -z "$orig_head"
	then
255
		die "Cannot merge multiple branches into empty head"
256
	fi
257 258
	if test true = "$rebase"
	then
259
		die "Cannot rebase onto multiple branches"
260
	fi
261 262 263
	;;
esac

264 265
if test -z "$orig_head"
then
266
	git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
267
	git read-tree --reset -u HEAD || exit 1
268 269 270
	exit
fi

271
merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
J
Junio C Hamano 已提交
272 273 274 275 276 277 278 279
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"
280
	eval="$eval \"\$merge_name\" HEAD $merge_head $verbosity"
J
Junio C Hamano 已提交
281 282 283
	;;
esac
eval "exec $eval"