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