66d73eb59d0ce880df9fcf2d34ecc3069dab189d
   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
  16test -z "$(git ls-files -u)" ||
  17        die "You are in the middle of a conflicted merge."
  18
  19strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity=
  20curr_branch=$(git symbolic-ref -q HEAD)
  21curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
  22rebase=$(git config --bool branch.$curr_branch_short.rebase)
  23while :
  24do
  25        case "$1" in
  26        -q|--quiet)
  27                verbosity="$verbosity -q" ;;
  28        -v|--verbose)
  29                verbosity="$verbosity -v" ;;
  30        -n|--no-stat|--no-summary)
  31                diffstat=--no-stat ;;
  32        --stat|--summary)
  33                diffstat=--stat ;;
  34        --log|--no-log)
  35                log_arg=$1 ;;
  36        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
  37                no_commit=--no-commit ;;
  38        --c|--co|--com|--comm|--commi|--commit)
  39                no_commit=--commit ;;
  40        --sq|--squ|--squa|--squas|--squash)
  41                squash=--squash ;;
  42        --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
  43                squash=--no-squash ;;
  44        --ff)
  45                no_ff=--ff ;;
  46        --no-ff)
  47                no_ff=--no-ff ;;
  48        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
  49                --strateg=*|--strategy=*|\
  50        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
  51                case "$#,$1" in
  52                *,*=*)
  53                        strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
  54                1,*)
  55                        usage ;;
  56                *)
  57                        strategy="$2"
  58                        shift ;;
  59                esac
  60                strategy_args="${strategy_args}-s $strategy "
  61                ;;
  62        -r|--r|--re|--reb|--reba|--rebas|--rebase)
  63                rebase=true
  64                ;;
  65        --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
  66                rebase=false
  67                ;;
  68        -h|--h|--he|--hel|--help)
  69                usage
  70                ;;
  71        *)
  72                # Pass thru anything that may be meant for fetch.
  73                break
  74                ;;
  75        esac
  76        shift
  77done
  78
  79error_on_no_merge_candidates () {
  80        exec >&2
  81        for opt
  82        do
  83                case "$opt" in
  84                -t|--t|--ta|--tag|--tags)
  85                        echo "Fetching tags only, you probably meant:"
  86                        echo "  git fetch --tags"
  87                        exit 1
  88                esac
  89        done
  90
  91        curr_branch=${curr_branch#refs/heads/}
  92        upstream=$(git config "branch.$curr_branch.merge")
  93
  94        if [ -z "$curr_branch" ]; then
  95                echo "You are not currently on a branch, so I cannot use any"
  96                echo "'branch.<branchname>.merge' in your configuration file."
  97                echo "Please specify which branch you want to merge on the command"
  98                echo "line and try again (e.g. 'git pull <repository> <refspec>')."
  99                echo "See git-pull(1) for details."
 100        elif [ -z "$upstream" ]; then
 101                echo "You asked me to pull without telling me which branch you"
 102                echo "want to merge with, and 'branch.${curr_branch}.merge' in"
 103                echo "your configuration file does not tell me either.  Please"
 104                echo "specify which branch you want to merge on the command line and"
 105                echo "try again (e.g. 'git pull <repository> <refspec>')."
 106                echo "See git-pull(1) for details."
 107                echo
 108                echo "If you often merge with the same branch, you may want to"
 109                echo "configure the following variables in your configuration"
 110                echo "file:"
 111                echo
 112                echo "    branch.${curr_branch}.remote = <nickname>"
 113                echo "    branch.${curr_branch}.merge = <remote-ref>"
 114                echo "    remote.<nickname>.url = <url>"
 115                echo "    remote.<nickname>.fetch = <refspec>"
 116                echo
 117                echo "See git-config(1) for details."
 118        else
 119                echo "Your configuration specifies to merge the ref"
 120                echo "'${upstream#refs/heads/}' from the remote, but no such ref"
 121                echo "was fetched."
 122        fi
 123        exit 1
 124}
 125
 126test true = "$rebase" && {
 127        if ! git rev-parse -q --verify HEAD >/dev/null
 128        then
 129                # On an unborn branch
 130                if test -f "$GIT_DIR/index"
 131                then
 132                        die "updating an unborn branch with changes added to the index"
 133                fi
 134        else
 135                git update-index --ignore-submodules --refresh &&
 136                git diff-files --ignore-submodules --quiet &&
 137                git diff-index --ignore-submodules --cached --quiet HEAD -- ||
 138                die "refusing to pull with rebase: your working tree is not up-to-date"
 139        fi
 140        oldremoteref= &&
 141        . git-parse-remote &&
 142        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
 143        oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
 144        for reflog in $(git rev-list -g $remoteref 2>/dev/null)
 145        do
 146                if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
 147                then
 148                        oldremoteref="$reflog"
 149                        break
 150                fi
 151        done
 152}
 153orig_head=$(git rev-parse -q --verify HEAD)
 154git fetch $verbosity --update-head-ok "$@" || exit 1
 155
 156curr_head=$(git rev-parse -q --verify HEAD)
 157if test -n "$orig_head" && test "$curr_head" != "$orig_head"
 158then
 159        # The fetch involved updating the current branch.
 160
 161        # The working tree and the index file is still based on the
 162        # $orig_head commit, but we are merging into $curr_head.
 163        # First update the working tree to match $curr_head.
 164
 165        echo >&2 "Warning: fetch updated the current branch head."
 166        echo >&2 "Warning: fast forwarding your working tree from"
 167        echo >&2 "Warning: commit $orig_head."
 168        git update-index -q --refresh
 169        git read-tree -u -m "$orig_head" "$curr_head" ||
 170                die 'Cannot fast-forward your working tree.
 171After making sure that you saved anything precious from
 172$ git diff '$orig_head'
 173output, run
 174$ git reset --hard
 175to recover.'
 176
 177fi
 178
 179merge_head=$(sed -e '/  not-for-merge   /d' \
 180        -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
 181        tr '\012' ' ')
 182
 183case "$merge_head" in
 184'')
 185        error_on_no_merge_candidates "$@"
 186        ;;
 187?*' '?*)
 188        if test -z "$orig_head"
 189        then
 190                die "Cannot merge multiple branches into empty head"
 191        fi
 192        if test true = "$rebase"
 193        then
 194                die "Cannot rebase onto multiple branches"
 195        fi
 196        ;;
 197esac
 198
 199if test -z "$orig_head"
 200then
 201        git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
 202        git read-tree --reset -u HEAD || exit 1
 203        exit
 204fi
 205
 206merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
 207test true = "$rebase" &&
 208        exec git-rebase $diffstat $strategy_args --onto $merge_head \
 209        ${oldremoteref:-$merge_head}
 210exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \
 211        "$merge_name" HEAD $merge_head $verbosity