git-pull.sh 5.2 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
test -z "$(git ls-files -u)" ||
17
	die "You are in the middle of a conflicted merge."
18

T
Tuncer Ayaz 已提交
19
strategy_args= no_stat= no_commit= squash= no_ff= log_arg= verbosity=
20 21 22
curr_branch=$(git symbolic-ref -q HEAD)
curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
rebase=$(git config --bool branch.$curr_branch_short.rebase)
23
while :
24 25
do
	case "$1" in
T
Tuncer Ayaz 已提交
26 27 28 29
	-q|--quiet)
		verbosity=-q ;;
	-v|--verbose)
		verbosity=-v ;;
30 31 32 33
	-n|--no-stat|--no-summary)
		no_stat=-n ;;
	--stat|--summary)
		no_stat=$1 ;;
34 35
	--log|--no-log)
		log_arg=$1 ;;
36 37
	--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
		no_commit=--no-commit ;;
38 39
	--c|--co|--com|--comm|--commi|--commit)
		no_commit=--commit ;;
J
Junio C Hamano 已提交
40 41
	--sq|--squ|--squa|--squas|--squash)
		squash=--squash ;;
42 43 44 45 46 47
	--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
		squash=--no-squash ;;
	--ff)
		no_ff=--ff ;;
	--no-ff)
		no_ff=--no-ff ;;
48 49 50 51 52
	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
		--strateg=*|--strategy=*|\
	-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
		case "$#,$1" in
		*,*=*)
D
Dennis Stosberg 已提交
53
			strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
54 55 56 57 58 59 60 61
		1,*)
			usage ;;
		*)
			strategy="$2"
			shift ;;
		esac
		strategy_args="${strategy_args}-s $strategy "
		;;
62 63 64 65 66 67
	-r|--r|--re|--reb|--reba|--rebas|--rebase)
		rebase=true
		;;
	--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
		rebase=false
		;;
68 69 70
	-h|--h|--he|--hel|--help)
		usage
		;;
71 72
	*)
		# Pass thru anything that may be meant for fetch.
73
		break
74 75 76 77 78
		;;
	esac
	shift
done

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
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

	curr_branch=${curr_branch#refs/heads/}

	echo "You asked me to pull without telling me which branch you"
	echo "want to merge with, and 'branch.${curr_branch}.merge' in"
	echo "your configuration file does not tell me either.  Please"
	echo "name which branch you want to merge on the command line and"
	echo "try again (e.g. 'git pull <repository> <refspec>')."
	echo "See git-pull(1) for details on the refspec."
	echo
	echo "If you often merge with the same branch, you may want to"
	echo "configure the following variables in your configuration"
	echo "file:"
	echo
	echo "    branch.${curr_branch}.remote = <nickname>"
	echo "    branch.${curr_branch}.merge = <remote-ref>"
	echo "    remote.<nickname>.url = <url>"
	echo "    remote.<nickname>.fetch = <refspec>"
	echo
	echo "See git-config(1) for details."
	exit 1
}

113
test true = "$rebase" && {
114 115 116
	git update-index --ignore-submodules --refresh &&
	git diff-files --ignore-submodules --quiet &&
	git diff-index --ignore-submodules --cached --quiet HEAD -- ||
117 118
	die "refusing to pull with rebase: your working tree is not up-to-date"

119 120 121 122 123 124 125 126
	. git-parse-remote &&
	origin="$1"
	test -z "$origin" && origin=$(get_default_remote)
	reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
		sed "s|refs/heads/\(.*\):|\1|")" &&
	oldremoteref="$(git rev-parse --verify \
		"refs/remotes/$origin/$reflist" 2>/dev/null)"
}
127
orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
T
Tuncer Ayaz 已提交
128
git fetch $verbosity --update-head-ok "$@" || exit 1
129

130
curr_head=$(git rev-parse --verify HEAD 2>/dev/null)
131
if test -n "$orig_head" && test "$curr_head" != "$orig_head"
132 133 134 135 136 137 138 139
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."
140
	echo >&2 "Warning: fast forwarding your working tree from"
141
	echo >&2 "Warning: commit $orig_head."
142 143
	git update-index --refresh 2>/dev/null
	git read-tree -u -m "$orig_head" "$curr_head" ||
144 145 146 147 148 149 150
		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.'

151 152
fi

153 154 155
merge_head=$(sed -e '/	not-for-merge	/d' \
	-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
	tr '\012' ' ')
156 157

case "$merge_head" in
158
'')
159
	case $? in
160 161 162 163 164 165
	0) error_on_no_merge_candidates "$@";;
	1) echo >&2 "You are not currently on a branch; you must explicitly"
	   echo >&2 "specify which branch you wish to merge:"
	   echo >&2 "  git pull <remote> <branch>"
	   exit 1;;
	*) exit $?;;
166
	esac
167
	;;
168
?*' '?*)
169 170 171 172 173
	if test -z "$orig_head"
	then
		echo >&2 "Cannot merge multiple branches into empty head"
		exit 1
	fi
174 175 176
	;;
esac

177 178
if test -z "$orig_head"
then
179
	git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
180
	git read-tree --reset -u HEAD || exit 1
181 182 183
	exit
fi

184
merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
185
test true = "$rebase" &&
186 187
	exec git-rebase $strategy_args --onto $merge_head \
	${oldremoteref:-$merge_head}
188
exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \
T
Tuncer Ayaz 已提交
189
	"$merge_name" HEAD $merge_head $verbosity