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