git-merge.shon commit Merge branch 'fixes' (d92ddb5)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5
   6. git-sh-setup || die "Not a git archive"
   7
   8LF='
   9'
  10
  11usage () {
  12    die "git-merge [-n] [-s <strategy>]... <merge-message> <head> <remote>+"
  13}
  14
  15# all_strategies='resolve recursive stupid octopus'
  16
  17all_strategies='recursive octopus resolve stupid'
  18default_strategies='resolve octopus'
  19use_strategies=
  20
  21dropsave() {
  22        rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
  23                 "$GIT_DIR/MERGE_SAVE" || exit 1
  24}
  25
  26savestate() {
  27        # Stash away any local modifications.
  28        git-diff-index -z --name-only $head |
  29        cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
  30}
  31
  32restorestate() {
  33        if test -f "$GIT_DIR/MERGE_SAVE"
  34        then
  35                git reset --hard $head
  36                cpio -iuv <"$GIT_DIR/MERGE_SAVE"
  37                git-update-index --refresh >/dev/null
  38        fi
  39}
  40
  41finish () {
  42        test '' = "$2" || echo "$2"
  43        case "$merge_msg" in
  44        '')
  45                echo "No merge message -- not updating HEAD"
  46                ;;
  47        *)
  48                git-update-ref HEAD "$1" "$head" || exit 1
  49                ;;
  50        esac
  51
  52        case "$no_summary" in
  53        '')
  54                git-diff-tree -p -M "$head" "$1" |
  55                git-apply --stat --summary
  56                ;;
  57        esac
  58}
  59
  60while case "$#" in 0) break ;; esac
  61do
  62        case "$1" in
  63        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
  64                --no-summa|--no-summar|--no-summary)
  65                no_summary=t ;;
  66        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
  67                --strateg=*|--strategy=*|\
  68        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
  69                case "$#,$1" in
  70                *,*=*)
  71                        strategy=`expr "$1" : '-[^=]*=\(.*\)'` ;;
  72                1,*)
  73                        usage ;;
  74                *)
  75                        strategy="$2"
  76                        shift ;;
  77                esac
  78                case " $all_strategies " in
  79                *" $strategy "*)
  80                        use_strategies="$use_strategies$strategy " ;;
  81                *)
  82                        die "available strategies are: $all_strategies" ;;
  83                esac
  84                ;;
  85        -*)     usage ;;
  86        *)      break ;;
  87        esac
  88        shift
  89done
  90
  91case "$use_strategies" in
  92'')
  93        use_strategies=$default_strategies
  94        ;;
  95esac
  96test "$#" -le 2 && usage ;# we need at least two heads.
  97
  98merge_msg="$1"
  99shift
 100head_arg="$1"
 101head=$(git-rev-parse --verify "$1"^0) || usage
 102shift
 103
 104# All the rest are remote heads
 105for remote
 106do
 107        git-rev-parse --verify "$remote"^0 >/dev/null ||
 108            die "$remote - not something we can merge"
 109done
 110
 111common=$(git-show-branch --merge-base $head "$@")
 112echo "$head" >"$GIT_DIR/ORIG_HEAD"
 113
 114case "$#,$common" in
 115*,'')
 116        # No common ancestors found. We need a real merge.
 117        ;;
 1181,"$1")
 119        # If head can reach all the merge then we are up to date.
 120        # but first the most common case of merging one remote
 121        echo "Already up-to-date."
 122        dropsave
 123        exit 0
 124        ;;
 1251,"$head")
 126        # Again the most common case of merging one remote.
 127        echo "Updating from $head to $1."
 128        git-update-index --refresh 2>/dev/null
 129        new_head=$(git-rev-parse --verify "$1^0") &&
 130        git-read-tree -u -m $head "$new_head" &&
 131        finish "$new_head" "Fast forward"
 132        dropsave
 133        exit 0
 134        ;;
 1351,?*"$LF"?*)
 136        # We are not doing octopus and not fast forward.  Need a
 137        # real merge.
 138        ;;
 1391,*)
 140        # We are not doing octopus, not fast forward, and have only
 141        # one common.  See if it is really trivial.
 142        echo "Trying really trivial in-index merge..."
 143        git-update-index --refresh 2>/dev/null
 144        if git-read-tree --trivial -m -u $common $head "$1" &&
 145           result_tree=$(git-write-tree)
 146        then
 147            echo "Wonderful."
 148            result_commit=$(
 149                echo "$merge_msg" |
 150                git-commit-tree $result_tree -p HEAD -p "$1"
 151            ) || exit
 152            finish "$result_commit" "In-index merge"
 153            dropsave
 154            exit 0
 155        fi
 156        echo "Nope."
 157        ;;
 158*)
 159        # An octopus.  If we can reach all the remote we are up to date.
 160        up_to_date=t
 161        for remote
 162        do
 163                common_one=$(git-merge-base $head $remote)
 164                if test "$common_one" != "$remote"
 165                then
 166                        up_to_date=f
 167                        break
 168                fi
 169        done
 170        if test "$up_to_date" = t
 171        then
 172                echo "Already up-to-date. Yeeah!"
 173                dropsave
 174                exit 0
 175        fi
 176        ;;
 177esac
 178
 179# At this point, we need a real merge.  No matter what strategy
 180# we use, it would operate on the index, possibly affecting the
 181# working tree, and when resolved cleanly, have the desired tree
 182# in the index -- this means that the index must be in sync with
 183# the $head commit.  The strategies are responsible to ensure this.
 184
 185case "$use_strategies" in
 186?*' '?*)
 187    # Stash away the local changes so that we can try more than one.
 188    savestate
 189    single_strategy=no
 190    ;;
 191*)
 192    rm -f "$GIT_DIR/MERGE_SAVE"
 193    single_strategy=yes
 194    ;;
 195esac
 196
 197result_tree= best_cnt=-1 best_strategy= wt_strategy=
 198for strategy in $use_strategies
 199do
 200    test "$wt_strategy" = '' || {
 201        echo "Rewinding the tree to pristine..."
 202        restorestate
 203    }
 204    case "$single_strategy" in
 205    no)
 206        echo "Trying merge strategy $strategy..."
 207        ;;
 208    esac
 209
 210    # Remember which strategy left the state in the working tree
 211    wt_strategy=$strategy
 212
 213    git-merge-$strategy $common -- "$head_arg" "$@" || {
 214
 215        # The backend exits with 1 when conflicts are left to be resolved,
 216        # with 2 when it does not handle the given merge at all.
 217
 218        exit=$?
 219        if test "$exit" -eq 1
 220        then
 221            cnt=`{
 222                git-diff-files --name-only
 223                git-ls-files --unmerged
 224            } | wc -l`
 225            if test $best_cnt -le 0 -o $cnt -le $best_cnt
 226            then
 227                best_strategy=$strategy
 228                best_cnt=$cnt
 229            fi
 230        fi
 231        continue
 232    }
 233
 234    # Automerge succeeded.
 235    result_tree=$(git-write-tree) && break
 236done
 237
 238# If we have a resulting tree, that means the strategy module
 239# auto resolved the merge cleanly.
 240if test '' != "$result_tree"
 241then
 242    parents="-p $head"
 243    for remote
 244    do
 245        parents="$parents -p $remote"
 246    done
 247    result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
 248    finish "$result_commit" "Merge $result_commit, made by $wt_strategy."
 249    dropsave
 250    exit 0
 251fi
 252
 253# Pick the result from the best strategy and have the user fix it up.
 254case "$best_strategy" in
 255'')
 256        restorestate
 257        die "No merge strategy handled the merge."
 258        ;;
 259"$wt_strategy")
 260        # We already have its result in the working tree.
 261        ;;
 262*)
 263        echo "Rewinding the tree to pristine..."
 264        restorestate
 265        echo "Using the $best_strategy to prepare resolving by hand."
 266        git-merge-$best_strategy $common -- "$head_arg" "$@"
 267        ;;
 268esac
 269for remote
 270do
 271        echo $remote
 272done >"$GIT_DIR/MERGE_HEAD"
 273echo $merge_msg >"$GIT_DIR/MERGE_MSG"
 274
 275die "Automatic merge failed; fix up by hand"