pull: Fix parsing of -X<option>
[git/gitweb.git] / git-pull.sh
blobfc3536bdf1dc3b29b8d5c705891be8d1ae3db068
1 #!/bin/sh
3 # Copyright (c) 2005 Junio C Hamano
5 # 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
16 test -z "$(git ls-files -u)" ||
17 die "You are in the middle of a conflicted merge."
19 strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
20 log_arg= verbosity=
21 merge_args=
22 curr_branch=$(git symbolic-ref -q HEAD)
23 curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
24 rebase=$(git config --bool branch.$curr_branch_short.rebase)
25 while :
27 case "$1" in
28 -q|--quiet)
29 verbosity="$verbosity -q" ;;
30 -v|--verbose)
31 verbosity="$verbosity -v" ;;
32 -n|--no-stat|--no-summary)
33 diffstat=--no-stat ;;
34 --stat|--summary)
35 diffstat=--stat ;;
36 --log|--no-log)
37 log_arg=$1 ;;
38 --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
39 no_commit=--no-commit ;;
40 --c|--co|--com|--comm|--commi|--commit)
41 no_commit=--commit ;;
42 --sq|--squ|--squa|--squas|--squash)
43 squash=--squash ;;
44 --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
45 squash=--no-squash ;;
46 --ff)
47 no_ff=--ff ;;
48 --no-ff)
49 no_ff=--no-ff ;;
50 --ff-only)
51 ff_only=--ff-only ;;
52 -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
53 --strateg=*|--strategy=*|\
54 -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
55 case "$#,$1" in
56 *,*=*)
57 strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
58 1,*)
59 usage ;;
61 strategy="$2"
62 shift ;;
63 esac
64 strategy_args="${strategy_args}-s $strategy "
66 -X*)
67 case "$#,$1" in
68 1,-X)
69 usage ;;
70 *,-X)
71 xx="-X $(git rev-parse --sq-quote "$2")"
72 shift ;;
73 *,*)
74 xx=$(git rev-parse --sq-quote "$1") ;;
75 esac
76 merge_args="$merge_args$xx "
78 -r|--r|--re|--reb|--reba|--rebas|--rebase)
79 rebase=true
81 --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
82 rebase=false
84 -h|--h|--he|--hel|--help)
85 usage
88 # Pass thru anything that may be meant for fetch.
89 break
91 esac
92 shift
93 done
95 error_on_no_merge_candidates () {
96 exec >&2
97 for opt
99 case "$opt" in
100 -t|--t|--ta|--tag|--tags)
101 echo "Fetching tags only, you probably meant:"
102 echo " git fetch --tags"
103 exit 1
104 esac
105 done
107 curr_branch=${curr_branch#refs/heads/}
108 upstream=$(git config "branch.$curr_branch.merge")
109 remote=$(git config "branch.$curr_branch.remote")
111 if [ $# -gt 1 ]; then
112 echo "There are no candidates for merging in the refs that you just fetched."
113 echo "Generally this means that you provided a wildcard refspec which had no"
114 echo "matches on the remote end."
115 elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
116 echo "You asked to pull from the remote '$1', but did not specify"
117 echo "a branch to merge. Because this is not the default configured remote"
118 echo "for your current branch, you must specify a branch on the command line."
119 elif [ -z "$curr_branch" ]; then
120 echo "You are not currently on a branch, so I cannot use any"
121 echo "'branch.<branchname>.merge' in your configuration file."
122 echo "Please specify which branch you want to merge on the command"
123 echo "line and try again (e.g. 'git pull <repository> <refspec>')."
124 echo "See git-pull(1) for details."
125 elif [ -z "$upstream" ]; then
126 echo "You asked me to pull without telling me which branch you"
127 echo "want to merge with, and 'branch.${curr_branch}.merge' in"
128 echo "your configuration file does not tell me either. Please"
129 echo "specify which branch you want to merge on the command line and"
130 echo "try again (e.g. 'git pull <repository> <refspec>')."
131 echo "See git-pull(1) for details."
132 echo
133 echo "If you often merge with the same branch, you may want to"
134 echo "configure the following variables in your configuration"
135 echo "file:"
136 echo
137 echo " branch.${curr_branch}.remote = <nickname>"
138 echo " branch.${curr_branch}.merge = <remote-ref>"
139 echo " remote.<nickname>.url = <url>"
140 echo " remote.<nickname>.fetch = <refspec>"
141 echo
142 echo "See git-config(1) for details."
143 else
144 echo "Your configuration specifies to merge the ref '${upstream#refs/heads/}' from the"
145 echo "remote, but no such ref was fetched."
147 exit 1
150 test true = "$rebase" && {
151 if ! git rev-parse -q --verify HEAD >/dev/null
152 then
153 # On an unborn branch
154 if test -f "$GIT_DIR/index"
155 then
156 die "updating an unborn branch with changes added to the index"
158 else
159 git update-index --ignore-submodules --refresh &&
160 git diff-files --ignore-submodules --quiet &&
161 git diff-index --ignore-submodules --cached --quiet HEAD -- ||
162 die "refusing to pull with rebase: your working tree is not up-to-date"
164 oldremoteref= &&
165 . git-parse-remote &&
166 remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
167 oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
168 for reflog in $(git rev-list -g $remoteref 2>/dev/null)
170 if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
171 then
172 oldremoteref="$reflog"
173 break
175 done
177 orig_head=$(git rev-parse -q --verify HEAD)
178 git fetch $verbosity --update-head-ok "$@" || exit 1
180 curr_head=$(git rev-parse -q --verify HEAD)
181 if test -n "$orig_head" && test "$curr_head" != "$orig_head"
182 then
183 # The fetch involved updating the current branch.
185 # The working tree and the index file is still based on the
186 # $orig_head commit, but we are merging into $curr_head.
187 # First update the working tree to match $curr_head.
189 echo >&2 "Warning: fetch updated the current branch head."
190 echo >&2 "Warning: fast-forwarding your working tree from"
191 echo >&2 "Warning: commit $orig_head."
192 git update-index -q --refresh
193 git read-tree -u -m "$orig_head" "$curr_head" ||
194 die 'Cannot fast-forward your working tree.
195 After making sure that you saved anything precious from
196 $ git diff '$orig_head'
197 output, run
198 $ git reset --hard
199 to recover.'
203 merge_head=$(sed -e '/ not-for-merge /d' \
204 -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \
205 tr '\012' ' ')
207 case "$merge_head" in
209 error_on_no_merge_candidates "$@"
211 ?*' '?*)
212 if test -z "$orig_head"
213 then
214 die "Cannot merge multiple branches into empty head"
216 if test true = "$rebase"
217 then
218 die "Cannot rebase onto multiple branches"
221 esac
223 if test -z "$orig_head"
224 then
225 git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
226 git read-tree --reset -u HEAD || exit 1
227 exit
230 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
231 case "$rebase" in
232 true)
233 eval="git-rebase $diffstat $strategy_args $merge_args"
234 eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
237 eval="git-merge $diffstat $no_commit $squash $no_ff $ff_only"
238 eval="$eval $log_arg $strategy_args $merge_args"
239 eval="$eval \"$merge_name\" HEAD $merge_head $verbosity"
241 esac
242 eval "exec $eval"