/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
"""\
This contains the apply changset function for bzr
"""

import bzrlib
import os

def _install_info(branch, cset_info, cset_tree, cset_inv):
    """Make sure that there is a text entry for each 
    file in the changeset.
    """
    from bzrlib.xml import pack_xml
    from cStringIO import StringIO

    # First, install all required texts
    for file_id, text_id in cset_info.text_ids.iteritems():
        if text_id not in branch.text_store:
            branch.text_store.add(cset_tree.get_file(file_id), text_id)

    # Now install the final inventory
    if cset_info.target not in branch.inventory_store:
        # bzrlib.commit uses a temporary file, but store.add
        # reads in the entire file anyway
        sio = StringIO()
        pack_xml(cset_inv, sio)
        branch.inventory_store.add(sio.getvalue(), cset_info.target)
        del sio

    # Now that we have installed the inventory and texts
    # install the revision entries.
    for rev in cset_info.real_revisions:
        if rev.revision_id not in branch.revision_store:
            sio = StringIO()
            pack_xml(rev, sio)
            branch.inventory_store.add(sio.getvalue(), rev.revision_id)
            del sio

def get_tree(treespec, temp_root, label):
    location, revno = treespec
    branch = find_branch(location)
    if revno is None:
        base_tree = branch.working_tree()
    elif revno == -1:
        base_tree = branch.basis_tree()
    else:
        base_tree = branch.revision_tree(branch.lookup_revision(revno))
    temp_path = os.path.join(temp_root, label)
    os.mkdir(temp_path)
    return branch, MergeTree(base_tree, temp_path)

def merge_revs(branch, rev_base, rev_other,
        ignore_zero=False, check_clean=True):
    """This will merge the tree of rev_other into 
    the working tree of branch using the base given by rev_base.
    All the revision XML should be inside branch.
    """
    import tempfile, shutil
    from bzrlib.merge import merge_inner, MergeTree
    from bzrlib.errors import BzrCommandError

    tempdir = tempfile.mkdtemp(prefix='bzr-')
    try:
        if check_clean:
            from bzrlib.diff import compare_trees
            changes = compare_trees(branch.working_tree(), 
                                    branch.basis_tree(), False)

            if changes.has_changed():
                raise BzrCommandError("Working tree has uncommitted changes.")

        other_dir = os.path.join(tempdir, 'other')
        other_tree = MergeTree(branch.revision_tree(rev_other), other_dir)

        base_dir = os.path.join(tempdir, 'base')
        base_tree = MergeTree(branch.revision_tree(rev_base), base_dir)

        merge_inner(branch, other_tree, base_tree, tempdir,
            ignore_zero=ignore_zero)
    finally:
        shutil.rmtree(tempdir)


def apply_changeset(branch, from_file, reverse=False, auto_commit=False):
    import sys, read_changeset

    if reverse:
        raise Exception('reverse not implemented yet')
        
    cset_info, cset_tree, cset_inv = \
            read_changeset.read_changeset(from_file, branch)

    _install_info(branch, cset_info, cset_tree, cset_inv)

    # We could technically optimize more, by using the ChangesetTree
    # we already have in memory, but after installing revisions
    # this code can work the way merge should work in the
    # future.
    #
    # TODO:
    #   This shouldn't use the base of the changeset as the base
    #   for the merge, the merge code should pick the best merge
    #   based on the ancestry of both trees.
    #
    merge_revs(branch, cset_info.base, cset_info.target)

    if auto_commit:
        from bzrlib.commit import commit

        # When merging, if the revision to be merged has a parent
        # of the current revision, then it can be installed
        # directly.
        #
        # TODO: 
        #   There is actually a slightly stronger statement
        #   whereby if the current revision is in the ancestry
        #   of the merged revisions, it doesn't need to be the
        #   immediate ancestry, but that requires searching
        #   a potentially branching history.
        #
        target_has_parent = False
        target_rev = branch.get_revision(cset_info.target)
        lastrev_id = branch.last_patch()
        for parent in target_rev.parents:
            if parent.revision_id == lastrev_id:
                target_has_parent = True

        if target_has_parent:
            branch.append_revision(target_rev.revision_id)
        else:
            print '** Could not auto-commit.'