Merge branch 'fm/fetch-raw-sha1'
[gitweb.git] / git-pull.sh
index f0df41c841644208c89230516677db162498be26..0917d0d056573912df60afd7b556efe04eeebae8 100755 (executable)
@@ -4,7 +4,7 @@
 #
 # Fetch one or more remote refs and merge it/them into the current HEAD.
 
-USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
+USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff|--ff-only] [--[no-]rebase|--rebase=preserve] [-s strategy]... [<fetch-options>] <repo> <head>...'
 LONG_USAGE='Fetch one or more remote refs and integrate it/them with the current HEAD.'
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
@@ -20,7 +20,7 @@ die_conflict () {
     if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
        die "$(gettext "Pull is not possible because you have unmerged files.
 Please, fix them up in the work tree, and then use 'git add/rm <file>'
-as appropriate to mark resolution, or use 'git commit -a'.")"
+as appropriate to mark resolution and make a commit.")"
     else
        die "$(gettext "Pull is not possible because you have unmerged files.")"
     fi
@@ -38,16 +38,36 @@ Please, commit your changes before you can merge.")"
 test -z "$(git ls-files -u)" || die_conflict
 test -f "$GIT_DIR/MERGE_HEAD" && die_merge
 
+bool_or_string_config () {
+       git config --bool "$1" 2>/dev/null || git config "$1"
+}
+
 strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
 log_arg= verbosity= progress= recurse_submodules= verify_signatures=
-merge_args= edit=
+merge_args= edit= rebase_args=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short="${curr_branch#refs/heads/}"
-rebase=$(git config --bool branch.$curr_branch_short.rebase)
+rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
 if test -z "$rebase"
 then
-       rebase=$(git config --bool pull.rebase)
+       rebase=$(bool_or_string_config pull.rebase)
 fi
+
+# Setup default fast-forward options via `pull.ff`
+pull_ff=$(bool_or_string_config pull.ff)
+case "$pull_ff" in
+true)
+       no_ff=--ff
+       ;;
+false)
+       no_ff=--no-ff
+       ;;
+only)
+       ff_only=--ff-only
+       ;;
+esac
+
+
 dry_run=
 while :
 do
@@ -64,8 +84,8 @@ do
                diffstat=--no-stat ;;
        --stat|--summary)
                diffstat=--stat ;;
-       --log|--no-log)
-               log_arg=$1 ;;
+       --log|--log=*|--no-log)
+               log_arg="$1" ;;
        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
                no_commit=--no-commit ;;
        --c|--co|--com|--comm|--commi|--commit)
@@ -89,7 +109,7 @@ do
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
                case "$#,$1" in
                *,*=*)
-                       strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
+                       strategy=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
                1,*)
                        usage ;;
                *)
@@ -110,6 +130,9 @@ do
                esac
                merge_args="$merge_args$xx "
                ;;
+       -r=*|--r=*|--re=*|--reb=*|--reba=*|--rebas=*|--rebase=*)
+               rebase="${1#*=}"
+               ;;
        -r|--r|--re|--reb|--reba|--rebas|--rebase)
                rebase=true
                ;;
@@ -131,6 +154,15 @@ do
        --no-verify-signatures)
                verify_signatures=--no-verify-signatures
                ;;
+       --gpg-sign|-S)
+               gpg_sign_args=-S
+               ;;
+       --gpg-sign=*)
+               gpg_sign_args=$(git rev-parse --sq-quote "-S${1#--gpg-sign=}")
+               ;;
+       -S*)
+               gpg_sign_args=$(git rev-parse --sq-quote "$1")
+               ;;
        --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
                dry_run=--dry-run
                ;;
@@ -145,17 +177,22 @@ do
        shift
 done
 
+case "$rebase" in
+preserve)
+       rebase=true
+       rebase_args=--preserve-merges
+       ;;
+true|false|'')
+       ;;
+*)
+       echo "Invalid value for --rebase, should be true, false, or preserve"
+       usage
+       exit 1
+       ;;
+esac
+
 error_on_no_merge_candidates () {
        exec >&2
-       for opt
-       do
-               case "$opt" in
-               -t|--t|--ta|--tag|--tags)
-                       echo "Fetching tags only, you probably meant:"
-                       echo "  git fetch --tags"
-                       exit 1
-               esac
-       done
 
        if test true = "$rebase"
        then
@@ -166,9 +203,8 @@ error_on_no_merge_candidates () {
                op_prep=with
        fi
 
-       curr_branch=${curr_branch#refs/heads/}
-       upstream=$(git config "branch.$curr_branch.merge")
-       remote=$(git config "branch.$curr_branch.remote")
+       upstream=$(git config "branch.$curr_branch_short.merge")
+       remote=$(git config "branch.$curr_branch_short.remote")
 
        if [ $# -gt 1 ]; then
                if [ "$rebase" = true ]; then
@@ -198,7 +234,7 @@ test true = "$rebase" && {
        if ! git rev-parse -q --verify HEAD >/dev/null
        then
                # On an unborn branch
-               if test -f "$GIT_DIR/index"
+               if test -f "$(git rev-parse --git-path index)"
                then
                        die "$(gettext "updating an unborn branch with changes added to the index")"
                fi
@@ -209,15 +245,7 @@ test true = "$rebase" && {
        test -n "$curr_branch" &&
        . git-parse-remote &&
        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
-       oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
-       for reflog in $(git rev-list -g $remoteref 2>/dev/null)
-       do
-               if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
-               then
-                       oldremoteref="$reflog"
-                       break
-               fi
-       done
+       oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
 }
 orig_head=$(git rev-parse -q --verify HEAD)
 git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
@@ -289,16 +317,17 @@ then
        fi
 fi
 
-merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
 case "$rebase" in
 true)
-       eval="git-rebase $diffstat $strategy_args $merge_args $verbosity"
+       eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
+       eval="$eval $gpg_sign_args"
        eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
        ;;
 *)
        eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only"
-       eval="$eval  $log_arg $strategy_args $merge_args $verbosity $progress"
-       eval="$eval \"\$merge_name\" HEAD $merge_head"
+       eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress"
+       eval="$eval $gpg_sign_args"
+       eval="$eval FETCH_HEAD"
        ;;
 esac
 eval "exec $eval"