Code

pull: Fix parsing of -X<option>
[git.git] / git-pull.sh
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.
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 :
26 do
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 ;;
60                 *)
61                         strategy="$2"
62                         shift ;;
63                 esac
64                 strategy_args="${strategy_args}-s $strategy "
65                 ;;
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 "
77                 ;;
78         -r|--r|--re|--reb|--reba|--rebas|--rebase)
79                 rebase=true
80                 ;;
81         --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
82                 rebase=false
83                 ;;
84         -h|--h|--he|--hel|--help)
85                 usage
86                 ;;
87         *)
88                 # Pass thru anything that may be meant for fetch.
89                 break
90                 ;;
91         esac
92         shift
93 done
95 error_on_no_merge_candidates () {
96         exec >&2
97         for opt
98         do
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."
146         fi
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"
157                 fi
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"
163         fi
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)
169         do
170                 if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
171                 then
172                         oldremoteref="$reflog"
173                         break
174                 fi
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.'
201 fi
203 merge_head=$(sed -e '/  not-for-merge   /d' \
204         -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
205         tr '\012' ' ')
207 case "$merge_head" in
208 '')
209         error_on_no_merge_candidates "$@"
210         ;;
211 ?*' '?*)
212         if test -z "$orig_head"
213         then
214                 die "Cannot merge multiple branches into empty head"
215         fi
216         if test true = "$rebase"
217         then
218                 die "Cannot rebase onto multiple branches"
219         fi
220         ;;
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
228 fi
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}"
235         ;;
236 *)
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"
240         ;;
241 esac
242 eval "exec $eval"