git-merge.shon commit Add write_or_die(), a helper function (7230e6d)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5
   6USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+'
   7. git-sh-setup
   8
   9LF='
  10'
  11
  12all_strategies='recursive octopus resolve stupid ours'
  13default_twohead_strategies='recursive'
  14default_octopus_strategies='octopus'
  15no_trivial_merge_strategies='ours'
  16use_strategies=
  17
  18index_merge=t
  19if test "@@NO_PYTHON@@"; then
  20        all_strategies='resolve octopus stupid ours'
  21        default_twohead_strategies='resolve'
  22fi
  23
  24dropsave() {
  25        rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
  26                 "$GIT_DIR/MERGE_SAVE" || exit 1
  27}
  28
  29savestate() {
  30        # Stash away any local modifications.
  31        git-diff-index -z --name-only $head |
  32        cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
  33}
  34
  35restorestate() {
  36        if test -f "$GIT_DIR/MERGE_SAVE"
  37        then
  38                git reset --hard $head
  39                cpio -iuv <"$GIT_DIR/MERGE_SAVE"
  40                git-update-index --refresh >/dev/null
  41        fi
  42}
  43
  44finish_up_to_date () {
  45        case "$squash" in
  46        t)
  47                echo "$1 (nothing to squash)" ;;
  48        '')
  49                echo "$1" ;;
  50        esac
  51        dropsave
  52}
  53
  54squash_message () {
  55        echo Squashed commit of the following:
  56        echo
  57        git-log --no-merges ^"$head" $remote
  58}
  59
  60finish () {
  61        if test '' = "$2"
  62        then
  63                rlogm="$rloga"
  64        else
  65                echo "$2"
  66                rlogm="$rloga: $2"
  67        fi
  68        case "$squash" in
  69        t)
  70                echo "Squash commit -- not updating HEAD"
  71                squash_message >"$GIT_DIR/SQUASH_MSG"
  72                ;;
  73        '')
  74                case "$merge_msg" in
  75                '')
  76                        echo "No merge message -- not updating HEAD"
  77                        ;;
  78                *)
  79                        git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
  80                        ;;
  81                esac
  82                ;;
  83        esac
  84        case "$1" in
  85        '')
  86                ;;
  87        ?*)
  88                case "$no_summary" in
  89                '')
  90                        git-diff-tree --stat --summary -M "$head" "$1"
  91                        ;;
  92                esac
  93                ;;
  94        esac
  95}
  96
  97rloga=
  98while case "$#" in 0) break ;; esac
  99do
 100        case "$1" in
 101        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
 102                --no-summa|--no-summar|--no-summary)
 103                no_summary=t ;;
 104        --sq|--squ|--squa|--squas|--squash)
 105                squash=t no_commit=t ;;
 106        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
 107                no_commit=t ;;
 108        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 109                --strateg=*|--strategy=*|\
 110        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
 111                case "$#,$1" in
 112                *,*=*)
 113                        strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
 114                1,*)
 115                        usage ;;
 116                *)
 117                        strategy="$2"
 118                        shift ;;
 119                esac
 120                case " $all_strategies " in
 121                *" $strategy "*)
 122                        use_strategies="$use_strategies$strategy " ;;
 123                *)
 124                        die "available strategies are: $all_strategies" ;;
 125                esac
 126                ;;
 127        --reflog-action=*)
 128                rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
 129                ;;
 130        -*)     usage ;;
 131        *)      break ;;
 132        esac
 133        shift
 134done
 135
 136merge_msg="$1"
 137shift
 138head_arg="$1"
 139head=$(git-rev-parse --verify "$1"^0) || usage
 140shift
 141
 142# All the rest are remote heads
 143test "$#" = 0 && usage ;# we need at least one remote head.
 144test "$rloga" = '' && rloga="merge: $@"
 145
 146remoteheads=
 147for remote
 148do
 149        remotehead=$(git-rev-parse --verify "$remote"^0) ||
 150            die "$remote - not something we can merge"
 151        remoteheads="${remoteheads}$remotehead "
 152done
 153set x $remoteheads ; shift
 154
 155case "$use_strategies" in
 156'')
 157        case "$#" in
 158        1)
 159                use_strategies="$default_twohead_strategies" ;;
 160        *)
 161                use_strategies="$default_octopus_strategies" ;;
 162        esac
 163        ;;
 164esac
 165
 166for s in $use_strategies
 167do
 168        case " $s " in
 169        *" $no_trivial_merge_strategies "*)
 170                index_merge=f
 171                break
 172                ;;
 173        esac
 174done
 175
 176case "$#" in
 1771)
 178        common=$(git-merge-base --all $head "$@")
 179        ;;
 180*)
 181        common=$(git-show-branch --merge-base $head "$@")
 182        ;;
 183esac
 184echo "$head" >"$GIT_DIR/ORIG_HEAD"
 185
 186case "$index_merge,$#,$common,$no_commit" in
 187f,*)
 188        # We've been told not to try anything clever.  Skip to real merge.
 189        ;;
 190?,*,'',*)
 191        # No common ancestors found. We need a real merge.
 192        ;;
 193?,1,"$1",*)
 194        # If head can reach all the merge then we are up to date.
 195        # but first the most common case of merging one remote.
 196        finish_up_to_date "Already up-to-date."
 197        exit 0
 198        ;;
 199?,1,"$head",*)
 200        # Again the most common case of merging one remote.
 201        echo "Updating from $head to $1"
 202        git-update-index --refresh 2>/dev/null
 203        new_head=$(git-rev-parse --verify "$1^0") &&
 204        git-read-tree -u -v -m $head "$new_head" &&
 205        finish "$new_head" "Fast forward"
 206        dropsave
 207        exit 0
 208        ;;
 209?,1,?*"$LF"?*,*)
 210        # We are not doing octopus and not fast forward.  Need a
 211        # real merge.
 212        ;;
 213?,1,*,)
 214        # We are not doing octopus, not fast forward, and have only
 215        # one common.  See if it is really trivial.
 216        git var GIT_COMMITTER_IDENT >/dev/null || exit
 217
 218        echo "Trying really trivial in-index merge..."
 219        git-update-index --refresh 2>/dev/null
 220        if git-read-tree --trivial -m -u -v $common $head "$1" &&
 221           result_tree=$(git-write-tree)
 222        then
 223            echo "Wonderful."
 224            result_commit=$(
 225                echo "$merge_msg" |
 226                git-commit-tree $result_tree -p HEAD -p "$1"
 227            ) || exit
 228            finish "$result_commit" "In-index merge"
 229            dropsave
 230            exit 0
 231        fi
 232        echo "Nope."
 233        ;;
 234*)
 235        # An octopus.  If we can reach all the remote we are up to date.
 236        up_to_date=t
 237        for remote
 238        do
 239                common_one=$(git-merge-base --all $head $remote)
 240                if test "$common_one" != "$remote"
 241                then
 242                        up_to_date=f
 243                        break
 244                fi
 245        done
 246        if test "$up_to_date" = t
 247        then
 248                finish_up_to_date "Already up-to-date. Yeeah!"
 249                exit 0
 250        fi
 251        ;;
 252esac
 253
 254# We are going to make a new commit.
 255git var GIT_COMMITTER_IDENT >/dev/null || exit
 256
 257# At this point, we need a real merge.  No matter what strategy
 258# we use, it would operate on the index, possibly affecting the
 259# working tree, and when resolved cleanly, have the desired tree
 260# in the index -- this means that the index must be in sync with
 261# the $head commit.  The strategies are responsible to ensure this.
 262
 263case "$use_strategies" in
 264?*' '?*)
 265    # Stash away the local changes so that we can try more than one.
 266    savestate
 267    single_strategy=no
 268    ;;
 269*)
 270    rm -f "$GIT_DIR/MERGE_SAVE"
 271    single_strategy=yes
 272    ;;
 273esac
 274
 275result_tree= best_cnt=-1 best_strategy= wt_strategy=
 276merge_was_ok=
 277for strategy in $use_strategies
 278do
 279    test "$wt_strategy" = '' || {
 280        echo "Rewinding the tree to pristine..."
 281        restorestate
 282    }
 283    case "$single_strategy" in
 284    no)
 285        echo "Trying merge strategy $strategy..."
 286        ;;
 287    esac
 288
 289    # Remember which strategy left the state in the working tree
 290    wt_strategy=$strategy
 291
 292    git-merge-$strategy $common -- "$head_arg" "$@"
 293    exit=$?
 294    if test "$no_commit" = t && test "$exit" = 0
 295    then
 296        merge_was_ok=t
 297        exit=1 ;# pretend it left conflicts.
 298    fi
 299
 300    test "$exit" = 0 || {
 301
 302        # The backend exits with 1 when conflicts are left to be resolved,
 303        # with 2 when it does not handle the given merge at all.
 304
 305        if test "$exit" -eq 1
 306        then
 307            cnt=`{
 308                git-diff-files --name-only
 309                git-ls-files --unmerged
 310            } | wc -l`
 311            if test $best_cnt -le 0 -o $cnt -le $best_cnt
 312            then
 313                best_strategy=$strategy
 314                best_cnt=$cnt
 315            fi
 316        fi
 317        continue
 318    }
 319
 320    # Automerge succeeded.
 321    result_tree=$(git-write-tree) && break
 322done
 323
 324# If we have a resulting tree, that means the strategy module
 325# auto resolved the merge cleanly.
 326if test '' != "$result_tree"
 327then
 328    parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
 329    result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
 330    finish "$result_commit" "Merge made by $wt_strategy."
 331    dropsave
 332    exit 0
 333fi
 334
 335# Pick the result from the best strategy and have the user fix it up.
 336case "$best_strategy" in
 337'')
 338        restorestate
 339        echo >&2 "No merge strategy handled the merge."
 340        exit 2
 341        ;;
 342"$wt_strategy")
 343        # We already have its result in the working tree.
 344        ;;
 345*)
 346        echo "Rewinding the tree to pristine..."
 347        restorestate
 348        echo "Using the $best_strategy to prepare resolving by hand."
 349        git-merge-$best_strategy $common -- "$head_arg" "$@"
 350        ;;
 351esac
 352
 353if test "$squash" = t
 354then
 355        finish
 356else
 357        for remote
 358        do
 359                echo $remote
 360        done >"$GIT_DIR/MERGE_HEAD"
 361        echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
 362fi
 363
 364if test "$merge_was_ok" = t
 365then
 366        echo >&2 \
 367        "Automatic merge went well; stopped before committing as requested"
 368        exit 0
 369else
 370        {
 371            echo '
 372Conflicts:
 373'
 374                git ls-files --unmerged |
 375                sed -e 's/^[^   ]*      /       /' |
 376                uniq
 377        } >>"$GIT_DIR/MERGE_MSG"
 378        if test -d "$GIT_DIR/rr-cache"
 379        then
 380                git-rerere
 381        fi
 382        die "Automatic merge failed; fix conflicts and then commit the result."
 383fi