3 # Copyright (C) 2014 Felipe Contreras
4 # Copyright (C) 2005 Junio C Hamano
6 # Fetch upstream and update the current branch.
8 USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [--[no-]rebase|--rebase=preserve] [-s strategy]...'
9 LONG_USAGE='Fetch upstram and update the current branch.'
14 set_reflog_action "update${1+ $*}"
15 require_work_tree_exists
20 printf >&2 'warning: %s\n' "$*"
24 git diff-index --cached --name-status -r --ignore-submodules HEAD --
25 die "$(gettext "Update is not possible because you have instaged files.")"
29 die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).")"
32 test -z "$(git ls-files -u)" || die_conflict
33 test -f "$GIT_DIR/MERGE_HEAD" && die_merge
35 bool_or_string_config () {
36 git config --bool "$1" 2>/dev/null || git config "$1"
39 strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
40 log_arg= verbosity= progress= recurse_submodules= verify_signatures=
41 merge_args= edit= rebase_args=
42 curr_branch=$(git symbolic-ref -q HEAD)
43 curr_branch_short="${curr_branch#refs/heads/}"
44 mode=$(git config branch.${curr_branch_short}.updatemode)
47 mode=$(git config update.mode)
50 merge|rebase|ff-only|'')
54 rebase_args="--preserve-merges"
57 echo "Invalid value for 'mode'"
62 # compatibility with pull configuration
65 rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
68 rebase=$(bool_or_string_config pull.rebase)
71 test -z "$mode" && mode=ff-only
77 verbosity="$verbosity -q" ;;
79 verbosity="$verbosity -v" ;;
81 progress=--progress ;;
83 progress=--no-progress ;;
84 -n|--no-stat|--no-summary)
96 no_commit=--no-commit ;;
102 squash=--no-squash ;;
109 -s=*|--strategy=*|-s|--strategy)
112 strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
119 strategy_args="${strategy_args}-s $strategy "
126 xx="-X $(git rev-parse --sq-quote "$2")"
129 xx=$(git rev-parse --sq-quote "$1") ;;
131 merge_args="$merge_args$xx "
142 --recurse-submodules)
143 recurse_submodules=--recurse-submodules
145 --recurse-submodules=*)
146 recurse_submodules="$1"
148 --no-recurse-submodules)
149 recurse_submodules=--no-recurse-submodules
152 verify_signatures=--verify-signatures
154 --no-verify-signatures)
155 verify_signatures=--no-verify-signatures
164 # Pass thru anything that may be meant for fetch.
182 rebase_args=--preserve-merges
185 echo "Invalid value for --rebase, should be true, false, or preserve"
192 test -z "$curr_branch" &&
193 die "$(gettext "You are not currently on a branch.")"
195 get_remote_branch () {
198 ref=$(git rev-parse --symbolic-full-name $1)
200 git config --get-regexp 'remote.*.fetch' | while read key value
202 remote=${key#remote.}
203 remote=${remote%.fetch}
208 branch=${ref#$prefix}
209 echo "remote=$remote branch=$branch"
218 branch=$(git config "branch.$curr_branch_short.merge")
219 remote=$(git config "branch.$curr_branch_short.remote")
221 test -z "$branch" && branch=$curr_branch
222 test -z "$remote" && remote="origin"
228 eval $(get_remote_branch $1)
236 branch="${branch#refs/heads/}"
238 test "$mode" = rebase && {
239 require_clean_work_tree "update with rebase" "Please commit or stash them."
240 oldremoteref=$(git merge-base --fork-point $branch $curr_branch 2>/dev/null)
242 orig_head=$(git rev-parse -q --verify HEAD)
244 if test $remote = "."
249 git fetch $verbosity $progress $dry_run $recurse_submodules $remote $branch $extra || exit 1
251 test -z "$dry_run" || exit 0
253 merge_head=$(sed -e '/ not-for-merge /d' -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD)
255 test -z "$merge_head" &&
256 die "$(gettext "Couldnot fetch branch '${branch#refs/heads/}'.")"
258 if test "$mode" = 'ff-only' && test -z "$no_ff$ff_only${squash#--no-squash}"
260 # check if a non-fast-forward merge would be needed
261 if ! git merge-base --is-ancestor "$orig_head" "$merge_head" &&
262 ! git merge-base --is-ancestor "$merge_head" "$orig_head"
264 die "$(gettext "The update was not fast-forward, please either merge or rebase.
265 If unsure, run 'git update --merge'.")"
270 if test "$mode" = rebase
272 o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
273 test "$oldremoteref" = "$o" && unset oldremoteref
277 if test "$curr_branch_short" = "$branch"
279 echo "Update branch '$curr_branch_short'"
282 msg="${msg} branch '$curr_branch_short'"
283 test "$branch" != "master" && msg="${msg} into $branch"
295 eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
296 eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
300 merge_msg=$(git fmt-merge-msg $log_arg < "$GIT_DIR"/FETCH_HEAD | fix_msg) || exit
301 eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only"
302 eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress"
303 eval="$eval --reverse-parents -m \"\$merge_msg\" $merge_head"