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