run-command: optimize out useless shell calls
[git/kirr.git] / git-pull.sh
blob9e69ada413bd81948591a9e99287f97499573673
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 if test true = "$rebase"
95 then
96 op_type=rebase
97 op_prep=against
98 else
99 op_type=merge
100 op_prep=with
103 curr_branch=${curr_branch#refs/heads/}
104 upstream=$(git config "branch.$curr_branch.merge")
105 remote=$(git config "branch.$curr_branch.remote")
107 if [ $# -gt 1 ]; then
108 if [ "$rebase" = true ]; then
109 printf "There is no candidate for rebasing against "
110 else
111 printf "There are no candidates for merging "
113 echo "among the refs that you just fetched."
114 echo "Generally this means that you provided a wildcard refspec which had no"
115 echo "matches on the remote end."
116 elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
117 echo "You asked to pull from the remote '$1', but did not specify"
118 echo "a branch. Because this is not the default configured remote"
119 echo "for your current branch, you must specify a branch on the command line."
120 elif [ -z "$curr_branch" ]; then
121 echo "You are not currently on a branch, so I cannot use any"
122 echo "'branch.<branchname>.merge' in your configuration file."
123 echo "Please specify which remote branch you want to use on the command"
124 echo "line and try again (e.g. 'git pull <repository> <refspec>')."
125 echo "See git-pull(1) for details."
126 elif [ -z "$upstream" ]; then
127 echo "You asked me to pull without telling me which branch you"
128 echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
129 echo "your configuration file does not tell me, either. Please"
130 echo "specify which branch you want to use on the command line and"
131 echo "try again (e.g. 'git pull <repository> <refspec>')."
132 echo "See git-pull(1) for details."
133 echo
134 echo "If you often $op_type $op_prep the same branch, you may want to"
135 echo "use something like the following in your configuration file:"
136 echo
137 echo " [branch \"${curr_branch}\"]"
138 echo " remote = <nickname>"
139 echo " merge = <remote-ref>"
140 test rebase = "$op_type" &&
141 echo " rebase = true"
142 echo
143 echo " [remote \"<nickname>\"]"
144 echo " url = <url>"
145 echo " fetch = <refspec>"
146 echo
147 echo "See git-config(1) for details."
148 else
149 echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
150 echo "from the remote, but no such ref was fetched."
152 exit 1
155 test true = "$rebase" && {
156 if ! git rev-parse -q --verify HEAD >/dev/null
157 then
158 # On an unborn branch
159 if test -f "$GIT_DIR/index"
160 then
161 die "updating an unborn branch with changes added to the index"
163 else
164 git update-index --ignore-submodules --refresh &&
165 git diff-files --ignore-submodules --quiet &&
166 git diff-index --ignore-submodules --cached --quiet HEAD -- ||
167 die "refusing to pull with rebase: your working tree is not up-to-date"
169 oldremoteref= &&
170 . git-parse-remote &&
171 remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
172 oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
173 for reflog in $(git rev-list -g $remoteref 2>/dev/null)
175 if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
176 then
177 oldremoteref="$reflog"
178 break
180 done
182 orig_head=$(git rev-parse -q --verify HEAD)
183 git fetch $verbosity --update-head-ok "$@" || exit 1
185 curr_head=$(git rev-parse -q --verify HEAD)
186 if test -n "$orig_head" && test "$curr_head" != "$orig_head"
187 then
188 # The fetch involved updating the current branch.
190 # The working tree and the index file is still based on the
191 # $orig_head commit, but we are merging into $curr_head.
192 # First update the working tree to match $curr_head.
194 echo >&2 "Warning: fetch updated the current branch head."
195 echo >&2 "Warning: fast-forwarding your working tree from"
196 echo >&2 "Warning: commit $orig_head."
197 git update-index -q --refresh
198 git read-tree -u -m "$orig_head" "$curr_head" ||
199 die 'Cannot fast-forward your working tree.
200 After making sure that you saved anything precious from
201 $ git diff '$orig_head'
202 output, run
203 $ git reset --hard
204 to recover.'
208 merge_head=$(sed -e '/ not-for-merge /d' \
209 -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \
210 tr '\012' ' ')
212 case "$merge_head" in
214 error_on_no_merge_candidates "$@"
216 ?*' '?*)
217 if test -z "$orig_head"
218 then
219 die "Cannot merge multiple branches into empty head"
221 if test true = "$rebase"
222 then
223 die "Cannot rebase onto multiple branches"
226 esac
228 if test -z "$orig_head"
229 then
230 git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
231 git read-tree --reset -u HEAD || exit 1
232 exit
235 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
236 test true = "$rebase" &&
237 exec git-rebase $diffstat $strategy_args --onto $merge_head \
238 ${oldremoteref:-$merge_head}
239 exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \
240 "$merge_name" HEAD $merge_head $verbosity