]> git.ipfire.org Git - thirdparty/git.git/blob - git-pull.sh
Merge branch 'rs/work-around-grep-opt-insanity'
[thirdparty/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.
6
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
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 :
25 do
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 ;;
59 *)
60 strategy="$2"
61 shift ;;
62 esac
63 strategy_args="${strategy_args}-s $strategy "
64 ;;
65 -r|--r|--re|--reb|--reba|--rebas|--rebase)
66 rebase=true
67 ;;
68 --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
69 rebase=false
70 ;;
71 -h|--h|--he|--hel|--help)
72 usage
73 ;;
74 *)
75 # Pass thru anything that may be meant for fetch.
76 break
77 ;;
78 esac
79 shift
80 done
81
82 error_on_no_merge_candidates () {
83 exec >&2
84 for opt
85 do
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
93
94 curr_branch=${curr_branch#refs/heads/}
95 upstream=$(git config "branch.$curr_branch.merge")
96 remote=$(git config "branch.$curr_branch.remote")
97
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."
133 fi
134 exit 1
135 }
136
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"
144 fi
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"
150 fi
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)
156 do
157 if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
158 then
159 oldremoteref="$reflog"
160 break
161 fi
162 done
163 }
164 orig_head=$(git rev-parse -q --verify HEAD)
165 git fetch $verbosity --update-head-ok "$@" || exit 1
166
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.
171
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.
175
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.'
187
188 fi
189
190 merge_head=$(sed -e '/ not-for-merge /d' \
191 -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \
192 tr '\012' ' ')
193
194 case "$merge_head" in
195 '')
196 error_on_no_merge_candidates "$@"
197 ;;
198 ?*' '?*)
199 if test -z "$orig_head"
200 then
201 die "Cannot merge multiple branches into empty head"
202 fi
203 if test true = "$rebase"
204 then
205 die "Cannot rebase onto multiple branches"
206 fi
207 ;;
208 esac
209
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
215 fi
216
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 $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \
222 "$merge_name" HEAD $merge_head $verbosity