#!/bin/sh # # Copyright (c) 2005 Junio C Hamano # # Resolve two or more trees. # source git-sh-setup global LF := '' '' # The first parameters up to -- are merge bases; the rest are heads. global bases := '', head := '', remotes := '', sep_seen := ''for arg in @Argv { matchstr ",$sep_seen,$head,$arg," { *,--, { global sep_seen := 'yes' } ,yes,,* { global head := $arg } ,yes,* { global remotes := ""$remotes$arg "" } * { global bases := ""$bases$arg "" } } } # Reject if this is not an octopus -- resolve should be used instead. matchstr $remotes { ?*' '?* { } * { exit 2 } } # MRC is the current "merge reference commit" # MRT is the current "merge result tree" if ! git diff-index --quiet --cached HEAD -- { gettextln "Error: Your local changes to the following files would be overwritten by merge" git diff-index --cached --name-only HEAD -- | sed -e 's/^/ /' exit 2 } global MRC := $[git rev-parse --verify -q $head] global MRT := $[git write-tree] global NON_FF_MERGE := '0' global OCTOPUS_FAILURE := '0' for SHA1 in [$remotes] { matchstr $OCTOPUS_FAILURE { 1 { # We allow only last one to have a hand-resolvable # conflicts. Last round failed and we still had # a head to merge. gettextln "Automated merge did not work." gettextln "Should not be doing an octopus." exit 2 } } eval pretty_name='$'{GITHEAD_$SHA1:-$SHA1} if test $SHA1 = $pretty_name { global SHA1_UP := $[echo $SHA1 | tr a-z A-Z] eval pretty_name='$'{GITHEAD_$SHA1_UP:-$pretty_name} } global common := $[git merge-base --all $SHA1 $MRC] || die $[eval_gettext "Unable to find common commit with \$pretty_name] matchstr "$LF$common$LF" { *"$LF$SHA1$LF"* { eval_gettextln "Already up-to-date with \$pretty_name" continue } } if test "$common,$NON_FF_MERGE" = "$MRC,0" { # 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. eval_gettextln "Fast-forwarding to: \$pretty_name" git read-tree -u -m $head $SHA1 || exit global MRC := $SHA1, MRT := $[git write-tree] continue } global NON_FF_MERGE := '1' eval_gettextln "Trying simple merge with \$pretty_name" git read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 global next := $[git write-tree !2 >/dev/null] if test $Status -ne 0 { gettextln "Simple merge did not work, trying automatic merge." git-merge-index -o git-merge-one-file -a || global OCTOPUS_FAILURE := '1' global next := $[git write-tree !2 >/dev/null] } global MRC := ""$MRC $SHA1"" global MRT := $next } exit $OCTOPUS_FAILURE (CommandList children: [ (C {(.)} {(git-sh-setup)}) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:LF) op:Equal rhs:{(SQ <"\n">)} spids:[24])] spids: [24] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs:(LhsName name:bases) op:Equal rhs:{(SQ )} spids:[33]) (assign_pair lhs:(LhsName name:head) op:Equal rhs:{(SQ )} spids:[35]) (assign_pair lhs:(LhsName name:remotes) op:Equal rhs:{(SQ )} spids:[37]) (assign_pair lhs:(LhsName name:sep_seen) op:Equal rhs:{(SQ )} spids:[39]) ] spids: [33] ) (ForEach iter_name: arg do_arg_iter: True body: (DoGroup children: [ (Case to_match: { (DQ (",") ($ VSub_Name "$sep_seen") (",") ($ VSub_Name "$head") (",") ($ VSub_Name "$arg") (",") ) } arms: [ (case_arm pat_list: [{(Lit_Other "*") (Lit_Comma ",") (--) (Lit_Comma ",")}] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:sep_seen) op: Equal rhs: {(yes)} spids: [70] ) ] spids: [70] ) ] spids: [63 67 74 -1] ) (case_arm pat_list: [{(Lit_Comma ",") (yes) (Lit_Comma ",") (Lit_Comma ",") (Lit_Other "*")}] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:head) op: Equal rhs: {($ VSub_Name "$arg")} spids: [85] ) ] spids: [85] ) ] spids: [77 82 89 -1] ) (case_arm pat_list: [{(Lit_Comma ",") (yes) (Lit_Comma ",") (Lit_Other "*")}] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:remotes) op: Equal rhs: {(DQ ($ VSub_Name "$remotes") ($ VSub_Name "$arg") (" "))} spids: [99] ) ] spids: [99] ) ] spids: [92 96 107 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:bases) op: Equal rhs: {(DQ ($ VSub_Name "$bases") ($ VSub_Name "$arg") (" "))} spids: [114] ) ] spids: [114] ) ] spids: [110 111 122 -1] ) ] spids: [48 60 125] ) ] spids: [45 127] ) spids: [-1 -1] ) (Case to_match: {(DQ ($ VSub_Name "$remotes"))} arms: [ (case_arm pat_list: [{(Lit_Other "?") (Lit_Other "*") (SQ <" ">) (Lit_Other "?") (Lit_Other "*")}] spids: [141 148 151 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [(C {(exit)} {(2)})] spids: [153 154 161 -1] ) ] spids: [133 139 163] ) (If arms: [ (if_arm cond: [ (Pipeline children: [(C {(git)} {(diff-index)} {(--quiet)} {(--cached)} {(HEAD)} {(--)})] negated: True ) ] action: [ (C {(gettextln)} { (DQ ( "Error: Your local changes to the following files would be overwritten by merge" ) ) } ) (Pipeline children: [ (C {(git)} {(diff-index)} {(--cached)} {(--name-only)} {(HEAD)} {(--)}) (C {(sed)} {(-e)} {(SQ <"s/^/ /">)}) ] negated: False ) (C {(exit)} {(2)}) ] spids: [-1 189] ) ] spids: [-1 226] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MRC) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(git)} {(rev-parse)} {(--verify)} {(-q)} {($ VSub_Name "$head")})] ) left_token: spids: [229 239] ) } spids: [228] ) ] spids: [228] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MRT) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(git)} {(write-tree)})]) left_token: spids: [242 246] ) } spids: [241] ) ] spids: [241] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:NON_FF_MERGE) op:Equal rhs:{(0)} spids:[248])] spids: [248] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:OCTOPUS_FAILURE) op:Equal rhs:{(0)} spids:[251])] spids: [251] ) (ForEach iter_name: SHA1 iter_words: [{($ VSub_Name "$remotes")}] do_arg_iter: False body: (DoGroup children: [ (Case to_match: {(DQ ($ VSub_Name "$OCTOPUS_FAILURE"))} arms: [ (case_arm pat_list: [{(1)}] action: [ (C {(gettextln)} {(DQ ("Automated merge did not work."))}) (C {(gettextln)} {(DQ ("Should not be doing an octopus."))}) (C {(exit)} {(2)}) ] spids: [274 275 -1 309] ) ] spids: [265 271 309] ) (C {(eval)} {(Lit_VarLike "pretty_name=") (EscapedLiteralPart token:) (Lit_LBrace "{") (GITHEAD_) ($ VSub_Name "$SHA1") (Lit_Other ":") (-) ($ VSub_Name "$SHA1") (Lit_RBrace "}") } ) (If arms: [ (if_arm cond: [ (C {(test)} {(DQ ($ VSub_Name "$SHA1"))} {(Lit_Other "=")} {(DQ ($ VSub_Name "$pretty_name"))} ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SHA1_UP) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$SHA1"))}) (C {(tr)} {(a-z)} {(A-Z)}) ] negated: False ) ] ) left_token: spids: [346 360] ) ) } spids: [344] ) ] spids: [344] ) (C {(eval)} {(Lit_VarLike "pretty_name=") (EscapedLiteralPart token:) (Lit_LBrace "{") (GITHEAD_) ($ VSub_Name "$SHA1_UP") (Lit_Other ":") (-) ($ VSub_Name "$pretty_name") (Lit_RBrace "}") } ) ] spids: [-1 341] ) ] spids: [-1 377] ) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:common) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(merge-base)} {(--all)} {($ VSub_Name "$SHA1")} {($ VSub_Name "$MRC")} ) ] ) left_token: spids: [381 391] ) } spids: [380] ) ] spids: [380] ) (C {(die)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(eval_gettext)} { (DQ ("Unable to find common commit with ") (EscapedLiteralPart token: ) (pretty_name) ) } ) ] ) left_token: spids: [399 407] ) ) } ) ] op_id: Op_DPipe ) (Case to_match: {(DQ ($ VSub_Name "$LF") ($ VSub_Name "$common") ($ VSub_Name "$LF"))} arms: [ (case_arm pat_list: [ {(Lit_Other "*") (DQ ($ VSub_Name "$LF") ($ VSub_Name "$SHA1") ($ VSub_Name "$LF")) (Lit_Other "*") } ] action: [ (C {(eval_gettextln)} { (DQ ("Already up-to-date with ") (EscapedLiteralPart token:) (pretty_name) ) } ) (ControlFlow token:) ] spids: [423 430 445 -1] ) ] spids: [412 420 448] ) (If arms: [ (if_arm cond: [ (C {(test)} {(DQ ($ VSub_Name "$common") (",") ($ VSub_Name "$NON_FF_MERGE"))} {(Lit_Other "=")} {(DQ ($ VSub_Name "$MRC") (",0"))} ) ] action: [ (C {(eval_gettextln)} { (DQ ("Fast-forwarding to: ") (EscapedLiteralPart token:) (pretty_name) ) } ) (AndOr children: [ (C {(git)} {(read-tree)} {(-u)} {(-m)} {($ VSub_Name "$head")} {($ VSub_Name "$SHA1")} ) (C {(exit)}) ] op_id: Op_DPipe ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MRC) op: Equal rhs: {($ VSub_Name "$SHA1")} spids: [516] ) (assign_pair lhs: (LhsName name:MRT) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(git)} {(write-tree)})]) left_token: spids: [520 524] ) } spids: [519] ) ] spids: [516] ) (ControlFlow token:) ] spids: [-1 470] ) ] spids: [-1 530] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:NON_FF_MERGE) op:Equal rhs:{(1)} spids:[534])] spids: [534] ) (C {(eval_gettextln)} { (DQ ("Trying simple merge with ") (EscapedLiteralPart token:) (pretty_name) ) } ) (AndOr children: [ (C {(git)} {(read-tree)} {(-u)} {(-m)} {(--aggressive)} {($ VSub_Name "$common")} {($ VSub_Name "$MRT")} {($ VSub_Name "$SHA1")} ) (C {(exit)} {(2)}) ] op_id: Op_DPipe ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:next) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [{(git)} {(write-tree)}] redirects: [ (Redir op_id: Redir_Great fd: 2 arg_word: {(/dev/null)} spids: [577] ) ] ) ] ) left_token: spids: [572 579] ) } spids: [571] ) ] spids: [571] ) (If arms: [ (if_arm cond: [(C {(test)} {($ VSub_QMark "$?")} {(-ne)} {(0)})] action: [ (C {(gettextln)} {(DQ ("Simple merge did not work, trying automatic merge."))}) (AndOr children: [ (C {(git-merge-index)} {(-o)} {(git-merge-one-file)} {(-a)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:OCTOPUS_FAILURE) op: Equal rhs: {(1)} spids: [614] ) ] spids: [614] ) ] op_id: Op_DPipe ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:next) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [{(git)} {(write-tree)}] redirects: [ (Redir op_id: Redir_Great fd: 2 arg_word: {(/dev/null)} spids: [624] ) ] ) ] ) left_token: spids: [619 626] ) } spids: [618] ) ] spids: [618] ) ] spids: [-1 593] ) ] spids: [-1 629] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MRC) op: Equal rhs: {(DQ ($ VSub_Name "$MRC") (" ") ($ VSub_Name "$SHA1"))} spids: [633] ) ] spids: [633] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MRT) op: Equal rhs: {($ VSub_Name "$next")} spids: [641] ) ] spids: [641] ) ] spids: [262 644] ) spids: [259 -1] ) (C {(exit)} {(DQ ($ VSub_Name "$OCTOPUS_FAILURE"))}) ] )