git-merge-octopus.sh 2.16 KB
Newer Older
Junio C Hamano's avatar
Junio C Hamano committed
1 2 3 4 5 6 7
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
# Resolve two or more trees.
#

8 9 10
LF='
'

11 12 13 14 15
die () {
    echo >&2 "$*"
    exit 1
}

Junio C Hamano's avatar
Junio C Hamano committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
# The first parameters up to -- are merge bases; the rest are heads.
bases= head= remotes= sep_seen=
for arg
do
	case ",$sep_seen,$head,$arg," in
	*,--,)
		sep_seen=yes
		;;
	,yes,,*)
		head=$arg
		;;
	,yes,*)
		remotes="$remotes$arg "
		;;
	*)
		bases="$bases$arg "
		;;
	esac
done

# Reject if this is not an Octopus -- resolve should be used instead.
case "$remotes" in
?*' '?*)
	;;
*)
	exit 2 ;;
esac

# MRC is the current "merge reference commit"
# MRT is the current "merge result tree"

Stephen Boyd's avatar
Stephen Boyd committed
47
MRC=$(git rev-parse --verify -q $head)
48
MRT=$(git write-tree)
Junio C Hamano's avatar
Junio C Hamano committed
49
NON_FF_MERGE=0
50
OCTOPUS_FAILURE=0
Junio C Hamano's avatar
Junio C Hamano committed
51 52
for SHA1 in $remotes
do
53 54 55 56 57 58 59 60 61 62
	case "$OCTOPUS_FAILURE" in
	1)
		# We allow only last one to have a hand-resolvable
		# conflicts.  Last round failed and we still had
		# a head to merge.
		echo "Automated merge did not work."
		echo "Should not be doing an Octopus."
		exit 2
	esac

63
	eval pretty_name=\${GITHEAD_$SHA1:-$SHA1}
64 65 66 67 68
	if test "$SHA1" = "$pretty_name"
	then
		SHA1_UP="$(echo "$SHA1" | tr a-z A-Z)"
		eval pretty_name=\${GITHEAD_$SHA1_UP:-$pretty_name}
	fi
69
	common=$(git merge-base --all $SHA1 $MRC) ||
70
		die "Unable to find common commit with $pretty_name"
Junio C Hamano's avatar
Junio C Hamano committed
71

72 73
	case "$LF$common$LF" in
	*"$LF$SHA1$LF"*)
74
		echo "Already up-to-date with $pretty_name"
Junio C Hamano's avatar
Junio C Hamano committed
75
		continue
76 77
		;;
	esac
Junio C Hamano's avatar
Junio C Hamano committed
78 79 80 81 82 83 84 85

	if test "$common,$NON_FF_MERGE" = "$MRC,0"
	then
		# The first head being merged was a fast-forward.
		# Advance MRC to the head being merged, and use that
		# tree as the intermediate result of the merge.
		# We still need to count this as part of the parent set.

86
		echo "Fast-forwarding to: $pretty_name"
87 88
		git read-tree -u -m $head $SHA1 || exit
		MRC=$SHA1 MRT=$(git write-tree)
Junio C Hamano's avatar
Junio C Hamano committed
89 90 91 92 93
		continue
	fi

	NON_FF_MERGE=1

94
	echo "Trying simple merge with $pretty_name"
95 96
	git read-tree -u -m --aggressive  $common $MRT $SHA1 || exit 2
	next=$(git write-tree 2>/dev/null)
Junio C Hamano's avatar
Junio C Hamano committed
97 98 99
	if test $? -ne 0
	then
		echo "Simple merge did not work, trying automatic merge."
100 101
		git-merge-index -o git-merge-one-file -a ||
		OCTOPUS_FAILURE=1
102
		next=$(git write-tree 2>/dev/null)
Junio C Hamano's avatar
Junio C Hamano committed
103
	fi
104

105
	MRC="$MRC $SHA1"
Junio C Hamano's avatar
Junio C Hamano committed
106 107 108
	MRT=$next
done

109
exit "$OCTOPUS_FAILURE"