Exemplo n.º 1
0
def merge_trees(store, base, mine, theirs):
    ''' takes tree ids for base, mine, and theirs.  merge trees into current working tee'''
    num_conflicts = 0
    added = []
    removed = []
    w = walk_trees(store, [base, mine, theirs], True)
    count = 0
    for b, m, t in w:

        if _is_tree(b) or _is_tree(m) or _is_tree(t):
            #todo... handle mkdir, rmdir
            continue

        # if mine == theirs match, use either
        elif m == t:
            if not b.path:
                print '  ', m.path, 'was added, but matches already'
            continue  #leave workng tree alone
        # if base==theirs, but not mine, already deleted (do nothing)
        elif b == t and not m.path:
            print '   ', b.path, ' already deleted in head'
            continue
        # if base==mine, but not theirs, delete
        elif b == m and not t.path:
            print '  -', m.path, ' was deleted in theirs.'
            os.remove(m.path)
            removed.append(m.path)
        elif not b.path and m.path and not t.path:  #add in mine
            print '  ', m.path, 'added in mine'
            continue
        elif not b.path and t.path and not m.path:  # add theirs to mine
            # add theirs
            print '  +', t.path, ': adding to head'
            with open(t.path, 'w') as f:
                f.write(store[t.sha].data)
            added.append(t.path)
        elif not m == t:  # conflict
            print '  ?', m.path, ': merging conflicts'
            result = diff3.merge(
                store[m.sha].data.splitlines(True),
                store[b.sha].data.splitlines(True) if b.sha else [''],
                store[t.sha].data.splitlines(True))
            mergedfile = result['body']
            had_conflict = result['conflict']
            with open(m.path, 'w') as f:
                for line in mergedfile:
                    f.write(line)
            if had_conflict:
                num_conflicts += 1
                print(
                    '    !!! {} had a conflict that could not be resolved.\n    conflict markers added to file in working tree.\n    you need to resolve manually '
                    .format(m.path))
            added.append(m.path)
    return num_conflicts, added, removed
Exemplo n.º 2
0
def merge_trees(store, base, mine, theirs):
    ''' takes tree ids for base, mine, and theirs.  merge trees into current working tee'''
    num_conflicts=0
    added=[]
    removed=[]
    w=walk_trees(store,[base,mine, theirs],True)
    count = 0
    for b,m,t in w:
        
        if _is_tree(b) or _is_tree(m) or _is_tree(t):
        #todo... handle mkdir, rmdir
            continue 
        
        # if mine == theirs match, use either
        elif m==t: 
            if not b.path:
                print '  ',m.path, 'was added, but matches already'
            continue    #leave workng tree alone
        # if base==theirs, but not mine, already deleted (do nothing)
        elif b==t and not m.path:
            print '   ',b.path, ' already deleted in head'
            continue
        # if base==mine, but not theirs, delete
        elif b==m and not t.path:
            print '  -',m.path, ' was deleted in theirs.'
            os.remove(m.path)
            removed.append(m.path)
        elif not b.path and m.path and not t.path:  #add in mine
            print '  ',m.path ,'added in mine'
            continue 
        elif not b.path and t.path and not m.path: # add theirs to mine
            # add theirs
            print '  +',t.path, ': adding to head'
            with open(t.path,'w') as f:
                f.write(store[t.sha].data)
            added.append(t.path)
        elif not m == t: # conflict
            print '  ?',m.path, ': merging conflicts'
            result=diff3.merge(store[m.sha].data.splitlines(True)
                        ,store[b.sha].data.splitlines(True) if b.sha else ['']
                        ,store[t.sha].data.splitlines(True))
            mergedfile=result['body']
            had_conflict=result['conflict']
            with open(m.path,'w') as f:
                for line in mergedfile:
                    f.write(line)
            if had_conflict:
                num_conflicts+=1
                print('    !!! {} had a conflict that could not be resolved.\n    conflict markers added to file in working tree.\n    you need to resolve manually '.format(m.path))
            added.append(m.path)
    return num_conflicts, added, removed
Exemplo n.º 3
0
def walk_trees(store, tree_ids,prune_identical=False):
    """Recursively walk all the entries of N trees.

    Iteration is depth-first pre-order, as in e.g. os.walk.

    :param store: An ObjectStore for looking up objects.
    :param trees: iterable of SHAs for N trees
    :param prune_identical: If True, identical subtrees will not be walked.
    :return: Iterator over tuple contsining N TreeEntry objects for each of entries
        in the trees and their subtrees recursively. If an entry exists in one
        tree but not the other, the other entry will have all attributes set
        to None. If neither entry's path is None, they are guaranteed to
        match.
    """
    # This could be fairly easily generalized to >2 trees if we find a use
    # case.
    modes= [tree_id and stat.S_IFDIR or None for tree_id in tree_ids]
    todo = [[TreeEntry(b'', mode, tree_id) for mode,tree_id in zip(modes,tree_ids)]]

    while todo:
        entries = todo.pop()
        is_trees = [_is_tree(entry) for entry in entries]

        if prune_identical and all(is_trees) and all_eq(entries):
            continue

        trees = [is_tree and store[entry.sha] or None for is_tree,entry in zip(is_trees,entries)]

        path = first_nonempty([entry.path for entry in entries])
        todo.extend(reversed(_merge_entries(path, trees)))
        yield tuple(entries)