octopus: do not do AND'ed merge base.
[git.git] / git-merge-octopus.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5 # Resolve two or more trees.
6 #
7
8 LF='
9 '
10
11 # The first parameters up to -- are merge bases; the rest are heads.
12 bases= head= remotes= sep_seen=
13 for arg
14 do
15         case ",$sep_seen,$head,$arg," in
16         *,--,)
17                 sep_seen=yes
18                 ;;
19         ,yes,,*)
20                 head=$arg
21                 ;;
22         ,yes,*)
23                 remotes="$remotes$arg "
24                 ;;
25         *)
26                 bases="$bases$arg "
27                 ;;
28         esac
29 done
30
31 # Reject if this is not an Octopus -- resolve should be used instead.
32 case "$remotes" in
33 ?*' '?*)
34         ;;
35 *)
36         exit 2 ;;
37 esac
38
39 # MRC is the current "merge reference commit"
40 # MRT is the current "merge result tree"
41
42 MRC=$head MSG= PARENT="-p $head"
43 MRT=$(git-write-tree)
44 CNT=1 ;# counting our head
45 NON_FF_MERGE=0
46 for SHA1 in $remotes
47 do
48         common=$(git-merge-base --all $MRC $SHA1) ||
49                 die "Unable to find common commit with $SHA1"
50
51         case "$common" in
52         ?*"$LF"?*)
53                 die "Not trivially mergeable."
54                 ;;
55         $SHA1)
56                 echo "Already up-to-date with $SHA1"
57                 continue
58                 ;;
59         esac
60
61         CNT=`expr $CNT + 1`
62         PARENT="$PARENT -p $SHA1"
63
64         if test "$common,$NON_FF_MERGE" = "$MRC,0"
65         then
66                 # The first head being merged was a fast-forward.
67                 # Advance MRC to the head being merged, and use that
68                 # tree as the intermediate result of the merge.
69                 # We still need to count this as part of the parent set.
70
71                 echo "Fast forwarding to: $SHA1"
72                 git-read-tree -u -m $head $SHA1 || exit
73                 MRC=$SHA1 MRT=$(git-write-tree)
74                 continue
75         fi
76
77         NON_FF_MERGE=1
78
79         echo "Trying simple merge with $SHA1"
80         git-read-tree -u -m $common $MRT $SHA1 || exit 2
81         next=$(git-write-tree 2>/dev/null)
82         if test $? -ne 0
83         then
84                 echo "Simple merge did not work, trying automatic merge."
85                 git-merge-index -o git-merge-one-file -a ||
86                 exit 2 ; # Automatic merge failed; should not be doing Octopus
87                 next=$(git-write-tree 2>/dev/null)
88         fi
89
90         # We have merged the other branch successfully.  Ideally
91         # we could implement OR'ed heads in merge-base, and keep
92         # a list of commits we have merged so far in MRC to feed
93         # them to merge-base, but we approximate it by keep using
94         # the current MRC.  We used to update it to $common, which
95         # was incorrectly doing AND'ed merge-base here, which was
96         # unneeded.
97
98         MRT=$next
99 done
100
101 exit 0