git-pull.shon commit compat: fall back on __va_copy if available (26db0f2)
   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
   7USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
   8LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
   9SUBDIRECTORY_OK=Yes
  10OPTIONS_SPEC=
  11. git-sh-setup
  12set_reflog_action "pull $*"
  13require_work_tree
  14cd_to_toplevel
  15
  16
  17die_conflict () {
  18    git diff-index --cached --name-status -r --ignore-submodules HEAD --
  19    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
  20        die "Pull is not possible because you have unmerged files.
  21Please, fix them up in the work tree, and then use 'git add/rm <file>'
  22as appropriate to mark resolution, or use 'git commit -a'."
  23    else
  24        die "Pull is not possible because you have unmerged files."
  25    fi
  26}
  27
  28die_merge () {
  29    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
  30        die "You have not concluded your merge (MERGE_HEAD exists).
  31Please, commit your changes before you can merge."
  32    else
  33        die "You have not concluded your merge (MERGE_HEAD exists)."
  34    fi
  35}
  36
  37test -z "$(git ls-files -u)" || die_conflict
  38test -f "$GIT_DIR/MERGE_HEAD" && die_merge
  39
  40strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
  41log_arg= verbosity= progress= recurse_submodules=
  42merge_args=
  43curr_branch=$(git symbolic-ref -q HEAD)
  44curr_branch_short="${curr_branch#refs/heads/}"
  45rebase=$(git config --bool branch.$curr_branch_short.rebase)
  46dry_run=
  47while :
  48do
  49        case "$1" in
  50        -q|--quiet)
  51                verbosity="$verbosity -q" ;;
  52        -v|--verbose)
  53                verbosity="$verbosity -v" ;;
  54        --progress)
  55                progress=--progress ;;
  56        -n|--no-stat|--no-summary)
  57                diffstat=--no-stat ;;
  58        --stat|--summary)
  59                diffstat=--stat ;;
  60        --log|--no-log)
  61                log_arg=$1 ;;
  62        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
  63                no_commit=--no-commit ;;
  64        --c|--co|--com|--comm|--commi|--commit)
  65                no_commit=--commit ;;
  66        --sq|--squ|--squa|--squas|--squash)
  67                squash=--squash ;;
  68        --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
  69                squash=--no-squash ;;
  70        --ff)
  71                no_ff=--ff ;;
  72        --no-ff)
  73                no_ff=--no-ff ;;
  74        --ff-only)
  75                ff_only=--ff-only ;;
  76        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
  77                --strateg=*|--strategy=*|\
  78        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
  79                case "$#,$1" in
  80                *,*=*)
  81                        strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
  82                1,*)
  83                        usage ;;
  84                *)
  85                        strategy="$2"
  86                        shift ;;
  87                esac
  88                strategy_args="${strategy_args}-s $strategy "
  89                ;;
  90        -X*)
  91                case "$#,$1" in
  92                1,-X)
  93                        usage ;;
  94                *,-X)
  95                        xx="-X $(git rev-parse --sq-quote "$2")"
  96                        shift ;;
  97                *,*)
  98                        xx=$(git rev-parse --sq-quote "$1") ;;
  99                esac
 100                merge_args="$merge_args$xx "
 101                ;;
 102        -r|--r|--re|--reb|--reba|--rebas|--rebase)
 103                rebase=true
 104                ;;
 105        --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
 106                rebase=false
 107                ;;
 108        --recurse-submodules)
 109                recurse_submodules=--recurse-submodules
 110                ;;
 111        --no-recurse-submodules)
 112                recurse_submodules=--no-recurse-submodules
 113                ;;
 114        --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
 115                dry_run=--dry-run
 116                ;;
 117        -h|--h|--he|--hel|--help|--help-|--help-a|--help-al|--help-all)
 118                usage
 119                ;;
 120        *)
 121                # Pass thru anything that may be meant for fetch.
 122                break
 123                ;;
 124        esac
 125        shift
 126done
 127
 128error_on_no_merge_candidates () {
 129        exec >&2
 130        for opt
 131        do
 132                case "$opt" in
 133                -t|--t|--ta|--tag|--tags)
 134                        echo "Fetching tags only, you probably meant:"
 135                        echo "  git fetch --tags"
 136                        exit 1
 137                esac
 138        done
 139
 140        if test true = "$rebase"
 141        then
 142                op_type=rebase
 143                op_prep=against
 144        else
 145                op_type=merge
 146                op_prep=with
 147        fi
 148
 149        curr_branch=${curr_branch#refs/heads/}
 150        upstream=$(git config "branch.$curr_branch.merge")
 151        remote=$(git config "branch.$curr_branch.remote")
 152
 153        if [ $# -gt 1 ]; then
 154                if [ "$rebase" = true ]; then
 155                        printf "There is no candidate for rebasing against "
 156                else
 157                        printf "There are no candidates for merging "
 158                fi
 159                echo "among the refs that you just fetched."
 160                echo "Generally this means that you provided a wildcard refspec which had no"
 161                echo "matches on the remote end."
 162        elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
 163                echo "You asked to pull from the remote '$1', but did not specify"
 164                echo "a branch. Because this is not the default configured remote"
 165                echo "for your current branch, you must specify a branch on the command line."
 166        elif [ -z "$curr_branch" ]; then
 167                echo "You are not currently on a branch, so I cannot use any"
 168                echo "'branch.<branchname>.merge' in your configuration file."
 169                echo "Please specify which remote branch you want to use on the command"
 170                echo "line and try again (e.g. 'git pull <repository> <refspec>')."
 171                echo "See git-pull(1) for details."
 172        elif [ -z "$upstream" ]; then
 173                echo "You asked me to pull without telling me which branch you"
 174                echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
 175                echo "your configuration file does not tell me, either. Please"
 176                echo "specify which branch you want to use on the command line and"
 177                echo "try again (e.g. 'git pull <repository> <refspec>')."
 178                echo "See git-pull(1) for details."
 179                echo
 180                echo "If you often $op_type $op_prep the same branch, you may want to"
 181                echo "use something like the following in your configuration file:"
 182                echo
 183                echo "    [branch \"${curr_branch}\"]"
 184                echo "    remote = <nickname>"
 185                echo "    merge = <remote-ref>"
 186                test rebase = "$op_type" &&
 187                        echo "    rebase = true"
 188                echo
 189                echo "    [remote \"<nickname>\"]"
 190                echo "    url = <url>"
 191                echo "    fetch = <refspec>"
 192                echo
 193                echo "See git-config(1) for details."
 194        else
 195                echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
 196                echo "from the remote, but no such ref was fetched."
 197        fi
 198        exit 1
 199}
 200
 201test true = "$rebase" && {
 202        if ! git rev-parse -q --verify HEAD >/dev/null
 203        then
 204                # On an unborn branch
 205                if test -f "$GIT_DIR/index"
 206                then
 207                        die "updating an unborn branch with changes added to the index"
 208                fi
 209        else
 210                require_clean_work_tree "pull with rebase" "Please commit or stash them."
 211        fi
 212        oldremoteref= &&
 213        . git-parse-remote &&
 214        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
 215        oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
 216        for reflog in $(git rev-list -g $remoteref 2>/dev/null)
 217        do
 218                if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
 219                then
 220                        oldremoteref="$reflog"
 221                        break
 222                fi
 223        done
 224}
 225orig_head=$(git rev-parse -q --verify HEAD)
 226git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
 227test -z "$dry_run" || exit 0
 228
 229curr_head=$(git rev-parse -q --verify HEAD)
 230if test -n "$orig_head" && test "$curr_head" != "$orig_head"
 231then
 232        # The fetch involved updating the current branch.
 233
 234        # The working tree and the index file is still based on the
 235        # $orig_head commit, but we are merging into $curr_head.
 236        # First update the working tree to match $curr_head.
 237
 238        echo >&2 "Warning: fetch updated the current branch head."
 239        echo >&2 "Warning: fast-forwarding your working tree from"
 240        echo >&2 "Warning: commit $orig_head."
 241        git update-index -q --refresh
 242        git read-tree -u -m "$orig_head" "$curr_head" ||
 243                die 'Cannot fast-forward your working tree.
 244After making sure that you saved anything precious from
 245$ git diff '$orig_head'
 246output, run
 247$ git reset --hard
 248to recover.'
 249
 250fi
 251
 252merge_head=$(sed -e '/  not-for-merge   /d' \
 253        -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
 254        tr '\012' ' ')
 255
 256case "$merge_head" in
 257'')
 258        error_on_no_merge_candidates "$@"
 259        ;;
 260?*' '?*)
 261        if test -z "$orig_head"
 262        then
 263                die "Cannot merge multiple branches into empty head"
 264        fi
 265        if test true = "$rebase"
 266        then
 267                die "Cannot rebase onto multiple branches"
 268        fi
 269        ;;
 270esac
 271
 272if test -z "$orig_head"
 273then
 274        git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
 275        git read-tree --reset -u HEAD || exit 1
 276        exit
 277fi
 278
 279if test true = "$rebase"
 280then
 281        o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
 282        if test "$oldremoteref" = "$o"
 283        then
 284                unset oldremoteref
 285        fi
 286fi
 287
 288merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
 289case "$rebase" in
 290true)
 291        eval="git-rebase $diffstat $strategy_args $merge_args"
 292        eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
 293        ;;
 294*)
 295        eval="git-merge $diffstat $no_commit $squash $no_ff $ff_only"
 296        eval="$eval  $log_arg $strategy_args $merge_args"
 297        eval="$eval \"\$merge_name\" HEAD $merge_head $verbosity"
 298        ;;
 299esac
 300eval "exec $eval"