#NEWLINE# def aggressive_tree_merge( odb , tree_shas ) : #NEWLINE# #INDENT# "\n    :return: list of BaseIndexEntries representing the aggressive merge of the given\n        trees. All valid entries are on stage 0, whereas the conflicting ones are left\n        on stage 1, 2 or 3, whereas stage 1 corresponds to the common ancestor tree,\n        2 to our tree and 3 to 'their' tree.\n    :param tree_shas: 1, 2 or 3 trees as identified by their binary 20 byte shas\n        If 1 or two, the entries will effectively correspond to the last given tree\n        If 3 are given, a 3 way merge is performed" #NEWLINE# out = list ( ) #NEWLINE# out_append = out . append #NEWLINE# if ( len ( tree_shas ) in ( 1 , 2 ) ) : #NEWLINE# #INDENT# for entry in traverse_tree_recursive ( odb , tree_shas [ ( - 1 ) ] , '' ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( entry , 0 ) ) #NEWLINE# #UNINDENT# return out #NEWLINE# #UNINDENT# if ( len ( tree_shas ) > 3 ) : #NEWLINE# #INDENT# raise ValueError ( ( 'Cannot handle %i trees at once' % len ( tree_shas ) ) ) #NEWLINE# #UNINDENT# for ( base , ours , theirs ) in traverse_trees_recursive ( odb , tree_shas , '' ) : #NEWLINE# #INDENT# if ( base is not None ) : #NEWLINE# #INDENT# if ( ours is not None ) : #NEWLINE# #INDENT# if ( theirs is not None ) : #NEWLINE# #INDENT# if ( ( ( base [ 0 ] != ours [ 0 ] ) and ( base [ 0 ] != theirs [ 0 ] ) and ( ours [ 0 ] != theirs [ 0 ] ) ) or ( ( base [ 1 ] != ours [ 1 ] ) and ( base [ 1 ] != theirs [ 1 ] ) and ( ours [ 1 ] != theirs [ 1 ] ) ) ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( base , 1 ) ) #NEWLINE# out_append ( _tree_entry_to_baseindexentry ( ours , 2 ) ) #NEWLINE# out_append ( _tree_entry_to_baseindexentry ( theirs , 3 ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( base [ 0 ] != ours [ 0 ] ) or ( base [ 1 ] != ours [ 1 ] ) ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( ours , 0 ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( theirs , 0 ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( ours [ 0 ] != base [ 0 ] ) or ( ours [ 1 ] != base [ 1 ] ) ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( base , 1 ) ) #NEWLINE# out_append ( _tree_entry_to_baseindexentry ( ours , 2 ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( theirs is None ) : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( theirs [ 0 ] != base [ 0 ] ) or ( theirs [ 1 ] != base [ 1 ] ) ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( base , 1 ) ) #NEWLINE# out_append ( _tree_entry_to_baseindexentry ( theirs , 3 ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ours is None ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( theirs , 0 ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( theirs is None ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( ours , 0 ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( ours [ 0 ] != theirs [ 0 ] ) or ( ours [ 1 ] != theirs [ 1 ] ) ) : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( ours , 2 ) ) #NEWLINE# out_append ( _tree_entry_to_baseindexentry ( theirs , 3 ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# out_append ( _tree_entry_to_baseindexentry ( ours , 0 ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# return out