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