git-pull.shon commit fetch/pull: Add the --recurse-submodules option (7dce19d)
   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        --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
 112                dry_run=--dry-run
 113                ;;
 114        -h|--h|--he|--hel|--help)
 115                usage
 116                ;;
 117        *)
 118                # Pass thru anything that may be meant for fetch.
 119                break
 120                ;;
 121        esac
 122        shift
 123done
 124
 125error_on_no_merge_candidates () {
 126        exec >&2
 127        for opt
 128        do
 129                case "$opt" in
 130                -t|--t|--ta|--tag|--tags)
 131                        echo "Fetching tags only, you probably meant:"
 132                        echo "  git fetch --tags"
 133                        exit 1
 134                esac
 135        done
 136
 137        if test true = "$rebase"
 138        then
 139                op_type=rebase
 140                op_prep=against
 141        else
 142                op_type=merge
 143                op_prep=with
 144        fi
 145
 146        curr_branch=${curr_branch#refs/heads/}
 147        upstream=$(git config "branch.$curr_branch.merge")
 148        remote=$(git config "branch.$curr_branch.remote")
 149
 150        if [ $# -gt 1 ]; then
 151                if [ "$rebase" = true ]; then
 152                        printf "There is no candidate for rebasing against "
 153                else
 154                        printf "There are no candidates for merging "
 155                fi
 156                echo "among the refs that you just fetched."
 157                echo "Generally this means that you provided a wildcard refspec which had no"
 158                echo "matches on the remote end."
 159        elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
 160                echo "You asked to pull from the remote '$1', but did not specify"
 161                echo "a branch. Because this is not the default configured remote"
 162                echo "for your current branch, you must specify a branch on the command line."
 163        elif [ -z "$curr_branch" ]; then
 164                echo "You are not currently on a branch, so I cannot use any"
 165                echo "'branch.<branchname>.merge' in your configuration file."
 166                echo "Please specify which remote branch you want to use on the command"
 167                echo "line and try again (e.g. 'git pull <repository> <refspec>')."
 168                echo "See git-pull(1) for details."
 169        elif [ -z "$upstream" ]; then
 170                echo "You asked me to pull without telling me which branch you"
 171                echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
 172                echo "your configuration file does not tell me, either. Please"
 173                echo "specify which branch you want to use on the command line and"
 174                echo "try again (e.g. 'git pull <repository> <refspec>')."
 175                echo "See git-pull(1) for details."
 176                echo
 177                echo "If you often $op_type $op_prep the same branch, you may want to"
 178                echo "use something like the following in your configuration file:"
 179                echo
 180                echo "    [branch \"${curr_branch}\"]"
 181                echo "    remote = <nickname>"
 182                echo "    merge = <remote-ref>"
 183                test rebase = "$op_type" &&
 184                        echo "    rebase = true"
 185                echo
 186                echo "    [remote \"<nickname>\"]"
 187                echo "    url = <url>"
 188                echo "    fetch = <refspec>"
 189                echo
 190                echo "See git-config(1) for details."
 191        else
 192                echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
 193                echo "from the remote, but no such ref was fetched."
 194        fi
 195        exit 1
 196}
 197
 198test true = "$rebase" && {
 199        if ! git rev-parse -q --verify HEAD >/dev/null
 200        then
 201                # On an unborn branch
 202                if test -f "$GIT_DIR/index"
 203                then
 204                        die "updating an unborn branch with changes added to the index"
 205                fi
 206        else
 207                git update-index --ignore-submodules --refresh &&
 208                git diff-files --ignore-submodules --quiet &&
 209                git diff-index --ignore-submodules --cached --quiet HEAD -- ||
 210                die "refusing to pull with rebase: your working tree is not up-to-date"
 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"