git-merge-octopus.shon commit Git 2.22-rc0 (ab15ad1)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5# Resolve two or more trees.
   6#
   7
   8. git-sh-setup
   9
  10LF='
  11'
  12
  13# The first parameters up to -- are merge bases; the rest are heads.
  14bases= head= remotes= sep_seen=
  15for arg
  16do
  17        case ",$sep_seen,$head,$arg," in
  18        *,--,)
  19                sep_seen=yes
  20                ;;
  21        ,yes,,*)
  22                head=$arg
  23                ;;
  24        ,yes,*)
  25                remotes="$remotes$arg "
  26                ;;
  27        *)
  28                bases="$bases$arg "
  29                ;;
  30        esac
  31done
  32
  33# Reject if this is not an octopus -- resolve should be used instead.
  34case "$remotes" in
  35?*' '?*)
  36        ;;
  37*)
  38        exit 2 ;;
  39esac
  40
  41# MRC is the current "merge reference commit"
  42# MRT is the current "merge result tree"
  43
  44if ! git diff-index --quiet --cached HEAD --
  45then
  46    gettextln "Error: Your local changes to the following files would be overwritten by merge"
  47    git diff-index --cached --name-only HEAD -- | sed -e 's/^/    /'
  48    exit 2
  49fi
  50MRC=$(git rev-parse --verify -q $head)
  51MRT=$(git write-tree)
  52NON_FF_MERGE=0
  53OCTOPUS_FAILURE=0
  54for SHA1 in $remotes
  55do
  56        case "$OCTOPUS_FAILURE" in
  57        1)
  58                # We allow only last one to have a hand-resolvable
  59                # conflicts.  Last round failed and we still had
  60                # a head to merge.
  61                gettextln "Automated merge did not work."
  62                gettextln "Should not be doing an octopus."
  63                exit 2
  64        esac
  65
  66        eval pretty_name=\${GITHEAD_$SHA1:-$SHA1}
  67        if test "$SHA1" = "$pretty_name"
  68        then
  69                SHA1_UP="$(echo "$SHA1" | tr a-z A-Z)"
  70                eval pretty_name=\${GITHEAD_$SHA1_UP:-$pretty_name}
  71        fi
  72        common=$(git merge-base --all $SHA1 $MRC) ||
  73                die "$(eval_gettext "Unable to find common commit with \$pretty_name")"
  74
  75        case "$LF$common$LF" in
  76        *"$LF$SHA1$LF"*)
  77                eval_gettextln "Already up to date with \$pretty_name"
  78                continue
  79                ;;
  80        esac
  81
  82        if test "$common,$NON_FF_MERGE" = "$MRC,0"
  83        then
  84                # The first head being merged was a fast-forward.
  85                # Advance MRC to the head being merged, and use that
  86                # tree as the intermediate result of the merge.
  87                # We still need to count this as part of the parent set.
  88
  89                eval_gettextln "Fast-forwarding to: \$pretty_name"
  90                git read-tree -u -m $head $SHA1 || exit
  91                MRC=$SHA1 MRT=$(git write-tree)
  92                continue
  93        fi
  94
  95        NON_FF_MERGE=1
  96
  97        eval_gettextln "Trying simple merge with \$pretty_name"
  98        git read-tree -u -m --aggressive  $common $MRT $SHA1 || exit 2
  99        next=$(git write-tree 2>/dev/null)
 100        if test $? -ne 0
 101        then
 102                gettextln "Simple merge did not work, trying automatic merge."
 103                git merge-index -o git-merge-one-file -a ||
 104                OCTOPUS_FAILURE=1
 105                next=$(git write-tree 2>/dev/null)
 106        fi
 107
 108        MRC="$MRC $SHA1"
 109        MRT=$next
 110done
 111
 112exit "$OCTOPUS_FAILURE"