Esempio n. 1
0
def main(repo):
    if repo.index.conflicts:
        print("You need to resolve merge conflicts first.")
        return 1

    try:
        repo.lookup_reference('MERGE_HEAD')
        print("Not running mapmerge for merge commit.")
        return 0
    except KeyError:
        pass

    changed = 0
    for path, status in repo.status().items():
        if path.endswith(".dmm") and (
                status &
            (pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_INDEX_NEW)):
            # read the index
            index_entry = repo.index[path]
            index_map = dmm.DMM.from_bytes(repo[index_entry.id].read_raw())

            try:
                head_blob = repo[repo[repo.head.target].tree[path].id]
            except KeyError:
                # New map, no entry in HEAD
                print(f"Converting new map: {path}", flush=True)
                assert (status & pygit2.GIT_STATUS_INDEX_NEW)
                merged_map = index_map
            else:
                # Entry in HEAD, merge the index over it
                print(f"Merging map: {path}", flush=True)
                assert not (status & pygit2.GIT_STATUS_INDEX_NEW)
                head_map = dmm.DMM.from_bytes(head_blob.read_raw())
                merged_map = merge_map(index_map, head_map)

            # write to the index
            blob_id = repo.create_blob(merged_map.to_bytes())
            repo.index.add(pygit2.IndexEntry(path, blob_id, index_entry.mode))
            changed += 1

            # write to the working directory if that's clean
            if status & (pygit2.GIT_STATUS_WT_DELETED
                         | pygit2.GIT_STATUS_WT_MODIFIED):
                print(
                    f"Warning: {path} has unindexed changes, not overwriting them"
                )
            else:
                merged_map.to_file(os.path.join(repo.workdir, path))

    if changed:
        repo.index.write()
        print(f"Merged {changed} maps.")
    return 0
Esempio n. 2
0
def main(repo):
    if repo.index.conflicts:
        print("You need to resolve merge conflicts first.")
        return 1

    try:
        repo.lookup_reference('MERGE_HEAD')
        print("Not running mapmerge for merge commit.")
        return 0
    except KeyError:
        pass

    changed = 0
    for path, status in repo.status().items():
        if path.endswith(".dmm") and (status & (pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_INDEX_NEW)):
            # read the index
            index_entry = repo.index[path]
            index_map = dmm.DMM.from_bytes(repo[index_entry.id].read_raw())

            try:
                head_blob = repo[repo[repo.head.target].tree[path].id]
            except KeyError:
                # New map, no entry in HEAD
                print(f"Converting new map: {path}")
                assert (status & pygit2.GIT_STATUS_INDEX_NEW)
                merged_map = index_map
            else:
                # Entry in HEAD, merge the index over it
                print(f"Merging map: {path}")
                assert not (status & pygit2.GIT_STATUS_INDEX_NEW)
                head_map = dmm.DMM.from_bytes(head_blob.read_raw())
                merged_map = merge_map(index_map, head_map)

            # write to the index
            blob_id = repo.create_blob(merged_map.to_bytes())
            repo.index.add(pygit2.IndexEntry(path, blob_id, index_entry.mode))
            changed += 1

            # write to the working directory if that's clean
            if status & (pygit2.GIT_STATUS_WT_DELETED | pygit2.GIT_STATUS_WT_MODIFIED):
                print(f"Warning: {path} has unindexed changes, not overwriting them")
            else:
                merged_map.to_file(os.path.join(repo.workdir, path))

    if changed:
        repo.index.write()
        print(f"Merged {changed} maps.")
    return 0
Esempio n. 3
0
def three_way_merge(base, left, right):
    if base.size != left.size or base.size != right.size:
        print("Dimensions have changed:")
        print(f"    Base: {base.size}")
        print(f"    Ours: {left.size}")
        print(f"    Theirs: {right.size}")
        return True, None

    trouble = False
    merged = dmm.DMM(base.key_length, base.size)
    merged.dictionary = base.dictionary.copy()

    for (z, y, x) in base.coords_zyx:
        coord = x, y, z
        base_tile = base.get_tile(coord)
        left_tile = left.get_tile(coord)
        right_tile = right.get_tile(coord)

        # try to merge the whole tiles
        whole_tile_merge = select(base_tile,
                                  left_tile,
                                  right_tile,
                                  debug='tile')
        if whole_tile_merge is not None:
            merged.set_tile(coord, whole_tile_merge)
            continue

        # try to merge each group independently (movables, turfs, areas)
        base_movables, base_turfs, base_areas = dmm.split_atom_groups(
            base_tile)
        left_movables, left_turfs, left_areas = dmm.split_atom_groups(
            left_tile)
        right_movables, right_turfs, right_areas = dmm.split_atom_groups(
            right_tile)

        merged_movables = select(base_movables,
                                 left_movables,
                                 right_movables,
                                 debug='movable')
        merged_turfs = select(base_turfs,
                              left_turfs,
                              right_turfs,
                              debug='turf')
        merged_areas = select(base_areas,
                              left_areas,
                              right_areas,
                              debug='area')

        if merged_movables is not None and merged_turfs is not None and merged_areas is not None:
            merged.set_tile(coord,
                            merged_movables + merged_turfs + merged_areas)
            continue

        # TODO: more advanced strategies?

        # fall back to requiring manual conflict resolution
        trouble = True
        print(f" C: Both sides touch the tile at {coord}")

        if merged_movables is None:
            merged_movables = left_movables + ['/obj'] + right_movables
            print(
                f"    Left and right movable groups are split by a generic `/obj`"
            )
        if merged_turfs is None:
            merged_turfs = left_turfs
            print(f"    Saving turf: {', '.join(left_turfs)}")
            print(f"    Alternative: {', '.join(right_turfs)}")
            print(f"    Original:    {', '.join(base_turfs)}")
        if merged_areas is None:
            merged_areas = left_areas
            print(f"    Saving area: {', '.join(left_areas)}")
            print(f"    Alternative: {', '.join(right_areas)}")
            print(f"    Original:    {', '.join(base_areas)}")

        merged.set_tile(coord, merged_movables + merged_turfs + merged_areas)

    merged = mapmerge.merge_map(merged, base)
    return trouble, merged