git-merge.shon commit git-svnimport: fix edge revisions double importing (6921677)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5
   6USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
   7
   8. git-sh-setup
   9set_reflog_action "merge $*"
  10
  11test -z "$(git ls-files -u)" ||
  12        die "You are in a middle of conflicted merge."
  13
  14LF='
  15'
  16
  17all_strategies='recur recursive octopus resolve stupid ours'
  18default_twohead_strategies='recursive'
  19default_octopus_strategies='octopus'
  20no_trivial_merge_strategies='ours'
  21use_strategies=
  22
  23index_merge=t
  24
  25dropsave() {
  26        rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
  27                 "$GIT_DIR/MERGE_SAVE" || exit 1
  28}
  29
  30savestate() {
  31        # Stash away any local modifications.
  32        git-diff-index -z --name-only $head |
  33        cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
  34}
  35
  36restorestate() {
  37        if test -f "$GIT_DIR/MERGE_SAVE"
  38        then
  39                git reset --hard $head >/dev/null
  40                cpio -iuv <"$GIT_DIR/MERGE_SAVE"
  41                git-update-index --refresh >/dev/null
  42        fi
  43}
  44
  45finish_up_to_date () {
  46        case "$squash" in
  47        t)
  48                echo "$1 (nothing to squash)" ;;
  49        '')
  50                echo "$1" ;;
  51        esac
  52        dropsave
  53}
  54
  55squash_message () {
  56        echo Squashed commit of the following:
  57        echo
  58        git-log --no-merges ^"$head" $remote
  59}
  60
  61finish () {
  62        if test '' = "$2"
  63        then
  64                rlogm="$GIT_REFLOG_ACTION"
  65        else
  66                echo "$2"
  67                rlogm="$GIT_REFLOG_ACTION: $2"
  68        fi
  69        case "$squash" in
  70        t)
  71                echo "Squash commit -- not updating HEAD"
  72                squash_message >"$GIT_DIR/SQUASH_MSG"
  73                ;;
  74        '')
  75                case "$merge_msg" in
  76                '')
  77                        echo "No merge message -- not updating HEAD"
  78                        ;;
  79                *)
  80                        git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
  81                        ;;
  82                esac
  83                ;;
  84        esac
  85        case "$1" in
  86        '')
  87                ;;
  88        ?*)
  89                case "$no_summary" in
  90                '')
  91                        git-diff-tree --stat --summary -M "$head" "$1"
  92                        ;;
  93                esac
  94                ;;
  95        esac
  96}
  97
  98merge_name () {
  99        remote="$1"
 100        rh=$(git-rev-parse --verify "$remote^0" 2>/dev/null) || return
 101        bh=$(git-show-ref -s --verify "refs/heads/$remote" 2>/dev/null)
 102        if test "$rh" = "$bh"
 103        then
 104                echo "$rh               branch '$remote' of ."
 105        elif truname=$(expr "$remote" : '\(.*\)~[1-9][0-9]*$') &&
 106                git-show-ref -q --verify "refs/heads/$truname" 2>/dev/null
 107        then
 108                echo "$rh               branch '$truname' (early part) of ."
 109        else
 110                echo "$rh               commit '$remote'"
 111        fi
 112}
 113
 114case "$#" in 0) usage ;; esac
 115
 116have_message=
 117while case "$#" in 0) break ;; esac
 118do
 119        case "$1" in
 120        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
 121                --no-summa|--no-summar|--no-summary)
 122                no_summary=t ;;
 123        --sq|--squ|--squa|--squas|--squash)
 124                squash=t no_commit=t ;;
 125        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
 126                no_commit=t ;;
 127        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 128                --strateg=*|--strategy=*|\
 129        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
 130                case "$#,$1" in
 131                *,*=*)
 132                        strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
 133                1,*)
 134                        usage ;;
 135                *)
 136                        strategy="$2"
 137                        shift ;;
 138                esac
 139                case " $all_strategies " in
 140                *" $strategy "*)
 141                        use_strategies="$use_strategies$strategy " ;;
 142                *)
 143                        die "available strategies are: $all_strategies" ;;
 144                esac
 145                ;;
 146        -m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
 147                merge_msg=`expr "z$1" : 'z-[^=]*=\(.*\)'`
 148                have_message=t
 149                ;;
 150        -m|--m|--me|--mes|--mess|--messa|--messag|--message)
 151                shift
 152                case "$#" in
 153                1)      usage ;;
 154                esac
 155                merge_msg="$1"
 156                have_message=t
 157                ;;
 158        -*)     usage ;;
 159        *)      break ;;
 160        esac
 161        shift
 162done
 163
 164# This could be traditional "merge <msg> HEAD <commit>..."  and the
 165# way we can tell it is to see if the second token is HEAD, but some
 166# people might have misused the interface and used a committish that
 167# is the same as HEAD there instead.  Traditional format never would
 168# have "-m" so it is an additional safety measure to check for it.
 169
 170if test -z "$have_message" &&
 171        second_token=$(git-rev-parse --verify "$2^0" 2>/dev/null) &&
 172        head_commit=$(git-rev-parse --verify "HEAD" 2>/dev/null) &&
 173        test "$second_token" = "$head_commit"
 174then
 175        merge_msg="$1"
 176        shift
 177        head_arg="$1"
 178        shift
 179elif ! git-rev-parse --verify HEAD >/dev/null 2>&1
 180then
 181        # If the merged head is a valid one there is no reason to
 182        # forbid "git merge" into a branch yet to be born.  We do
 183        # the same for "git pull".
 184        if test 1 -ne $#
 185        then
 186                echo >&2 "Can merge only exactly one commit into empty head"
 187                exit 1
 188        fi
 189
 190        rh=$(git rev-parse --verify "$1^0") ||
 191                die "$1 - not something we can merge"
 192
 193        git-update-ref -m "initial pull" HEAD "$rh" "" &&
 194        git-read-tree --reset -u HEAD
 195        exit
 196
 197else
 198        # We are invoked directly as the first-class UI.
 199        head_arg=HEAD
 200
 201        # All the rest are the commits being merged; prepare
 202        # the standard merge summary message to be appended to
 203        # the given message.  If remote is invalid we will die
 204        # later in the common codepath so we discard the error
 205        # in this loop.
 206        merge_name=$(for remote
 207                do
 208                        merge_name "$remote"
 209                done | git-fmt-merge-msg
 210        )
 211        merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name"
 212fi
 213head=$(git-rev-parse --verify "$head_arg"^0) || usage
 214
 215# All the rest are remote heads
 216test "$#" = 0 && usage ;# we need at least one remote head.
 217
 218remoteheads=
 219for remote
 220do
 221        remotehead=$(git-rev-parse --verify "$remote"^0 2>/dev/null) ||
 222            die "$remote - not something we can merge"
 223        remoteheads="${remoteheads}$remotehead "
 224        eval GITHEAD_$remotehead='"$remote"'
 225        export GITHEAD_$remotehead
 226done
 227set x $remoteheads ; shift
 228
 229case "$use_strategies" in
 230'')
 231        case "$#" in
 232        1)
 233                var="`git-repo-config --get pull.twohead`"
 234                if test -n "$var"
 235                then
 236                        use_strategies="$var"
 237                else
 238                        use_strategies="$default_twohead_strategies"
 239                fi ;;
 240        *)
 241                var="`git-repo-config --get pull.octopus`"
 242                if test -n "$var"
 243                then
 244                        use_strategies="$var"
 245                else
 246                        use_strategies="$default_octopus_strategies"
 247                fi ;;
 248        esac
 249        ;;
 250esac
 251
 252for s in $use_strategies
 253do
 254        case " $s " in
 255        *" $no_trivial_merge_strategies "*)
 256                index_merge=f
 257                break
 258                ;;
 259        esac
 260done
 261
 262case "$#" in
 2631)
 264        common=$(git-merge-base --all $head "$@")
 265        ;;
 266*)
 267        common=$(git-show-branch --merge-base $head "$@")
 268        ;;
 269esac
 270echo "$head" >"$GIT_DIR/ORIG_HEAD"
 271
 272case "$index_merge,$#,$common,$no_commit" in
 273f,*)
 274        # We've been told not to try anything clever.  Skip to real merge.
 275        ;;
 276?,*,'',*)
 277        # No common ancestors found. We need a real merge.
 278        ;;
 279?,1,"$1",*)
 280        # If head can reach all the merge then we are up to date.
 281        # but first the most common case of merging one remote.
 282        finish_up_to_date "Already up-to-date."
 283        exit 0
 284        ;;
 285?,1,"$head",*)
 286        # Again the most common case of merging one remote.
 287        echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $1)"
 288        git-update-index --refresh 2>/dev/null
 289        new_head=$(git-rev-parse --verify "$1^0") &&
 290        git-read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
 291        finish "$new_head" "Fast forward"
 292        dropsave
 293        exit 0
 294        ;;
 295?,1,?*"$LF"?*,*)
 296        # We are not doing octopus and not fast forward.  Need a
 297        # real merge.
 298        ;;
 299?,1,*,)
 300        # We are not doing octopus, not fast forward, and have only
 301        # one common.  See if it is really trivial.
 302        git var GIT_COMMITTER_IDENT >/dev/null || exit
 303
 304        echo "Trying really trivial in-index merge..."
 305        git-update-index --refresh 2>/dev/null
 306        if git-read-tree --trivial -m -u -v $common $head "$1" &&
 307           result_tree=$(git-write-tree)
 308        then
 309            echo "Wonderful."
 310            result_commit=$(
 311                echo "$merge_msg" |
 312                git-commit-tree $result_tree -p HEAD -p "$1"
 313            ) || exit
 314            finish "$result_commit" "In-index merge"
 315            dropsave
 316            exit 0
 317        fi
 318        echo "Nope."
 319        ;;
 320*)
 321        # An octopus.  If we can reach all the remote we are up to date.
 322        up_to_date=t
 323        for remote
 324        do
 325                common_one=$(git-merge-base --all $head $remote)
 326                if test "$common_one" != "$remote"
 327                then
 328                        up_to_date=f
 329                        break
 330                fi
 331        done
 332        if test "$up_to_date" = t
 333        then
 334                finish_up_to_date "Already up-to-date. Yeeah!"
 335                exit 0
 336        fi
 337        ;;
 338esac
 339
 340# We are going to make a new commit.
 341git var GIT_COMMITTER_IDENT >/dev/null || exit
 342
 343# At this point, we need a real merge.  No matter what strategy
 344# we use, it would operate on the index, possibly affecting the
 345# working tree, and when resolved cleanly, have the desired tree
 346# in the index -- this means that the index must be in sync with
 347# the $head commit.  The strategies are responsible to ensure this.
 348
 349case "$use_strategies" in
 350?*' '?*)
 351    # Stash away the local changes so that we can try more than one.
 352    savestate
 353    single_strategy=no
 354    ;;
 355*)
 356    rm -f "$GIT_DIR/MERGE_SAVE"
 357    single_strategy=yes
 358    ;;
 359esac
 360
 361result_tree= best_cnt=-1 best_strategy= wt_strategy=
 362merge_was_ok=
 363for strategy in $use_strategies
 364do
 365    test "$wt_strategy" = '' || {
 366        echo "Rewinding the tree to pristine..."
 367        restorestate
 368    }
 369    case "$single_strategy" in
 370    no)
 371        echo "Trying merge strategy $strategy..."
 372        ;;
 373    esac
 374
 375    # Remember which strategy left the state in the working tree
 376    wt_strategy=$strategy
 377
 378    git-merge-$strategy $common -- "$head_arg" "$@"
 379    exit=$?
 380    if test "$no_commit" = t && test "$exit" = 0
 381    then
 382        merge_was_ok=t
 383        exit=1 ;# pretend it left conflicts.
 384    fi
 385
 386    test "$exit" = 0 || {
 387
 388        # The backend exits with 1 when conflicts are left to be resolved,
 389        # with 2 when it does not handle the given merge at all.
 390
 391        if test "$exit" -eq 1
 392        then
 393            cnt=`{
 394                git-diff-files --name-only
 395                git-ls-files --unmerged
 396            } | wc -l`
 397            if test $best_cnt -le 0 -o $cnt -le $best_cnt
 398            then
 399                best_strategy=$strategy
 400                best_cnt=$cnt
 401            fi
 402        fi
 403        continue
 404    }
 405
 406    # Automerge succeeded.
 407    result_tree=$(git-write-tree) && break
 408done
 409
 410# If we have a resulting tree, that means the strategy module
 411# auto resolved the merge cleanly.
 412if test '' != "$result_tree"
 413then
 414    parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
 415    result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
 416    finish "$result_commit" "Merge made by $wt_strategy."
 417    dropsave
 418    exit 0
 419fi
 420
 421# Pick the result from the best strategy and have the user fix it up.
 422case "$best_strategy" in
 423'')
 424        restorestate
 425        case "$use_strategies" in
 426        ?*' '?*)
 427                echo >&2 "No merge strategy handled the merge."
 428                ;;
 429        *)
 430                echo >&2 "Merge with strategy $use_strategies failed."
 431                ;;
 432        esac
 433        exit 2
 434        ;;
 435"$wt_strategy")
 436        # We already have its result in the working tree.
 437        ;;
 438*)
 439        echo "Rewinding the tree to pristine..."
 440        restorestate
 441        echo "Using the $best_strategy to prepare resolving by hand."
 442        git-merge-$best_strategy $common -- "$head_arg" "$@"
 443        ;;
 444esac
 445
 446if test "$squash" = t
 447then
 448        finish
 449else
 450        for remote
 451        do
 452                echo $remote
 453        done >"$GIT_DIR/MERGE_HEAD"
 454        echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
 455fi
 456
 457if test "$merge_was_ok" = t
 458then
 459        echo >&2 \
 460        "Automatic merge went well; stopped before committing as requested"
 461        exit 0
 462else
 463        {
 464            echo '
 465Conflicts:
 466'
 467                git ls-files --unmerged |
 468                sed -e 's/^[^   ]*      /       /' |
 469                uniq
 470        } >>"$GIT_DIR/MERGE_MSG"
 471        if test -d "$GIT_DIR/rr-cache"
 472        then
 473                git-rerere
 474        fi
 475        die "Automatic merge failed; fix conflicts and then commit the result."
 476fi