/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
1
#!/usr/bin/env python
2
"""\
3
This contains the apply changset function for bzr
4
"""
5
6
import bzrlib
0.5.67 by John Arbash Meinel
Working on apply_changeset
7
import os
8
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
9
from bzrlib.trace import mutter, warning
10
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
11
def _install_info(branch, cset_info, cset_tree):
0.5.67 by John Arbash Meinel
Working on apply_changeset
12
    """Make sure that there is a text entry for each 
13
    file in the changeset.
14
    """
15
    from bzrlib.xml import pack_xml
16
    from cStringIO import StringIO
17
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
18
    inv = cset_tree.inventory
0.5.67 by John Arbash Meinel
Working on apply_changeset
19
    # First, install all required texts
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
20
    for path, ie in inv.iter_entries():
21
        if ie.text_id is not None and ie.text_id not in branch.text_store:
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
22
            branch.text_store.add(cset_tree.get_file(ie.file_id), ie.text_id)
0.5.67 by John Arbash Meinel
Working on apply_changeset
23
24
    # Now install the final inventory
25
    if cset_info.target not in branch.inventory_store:
26
        # bzrlib.commit uses a temporary file, but store.add
27
        # reads in the entire file anyway
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
28
        if cset_info.target in branch.inventory_store:
29
            warning('Target inventory already exists in destination.')
30
        else:
31
            sio = StringIO()
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
32
            pack_xml(inv, sio)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
33
            branch.inventory_store.add(sio.getvalue(), cset_info.target)
34
            del sio
0.5.67 by John Arbash Meinel
Working on apply_changeset
35
36
    # Now that we have installed the inventory and texts
37
    # install the revision entries.
38
    for rev in cset_info.real_revisions:
39
        if rev.revision_id not in branch.revision_store:
40
            sio = StringIO()
41
            pack_xml(rev, sio)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
42
            branch.revision_store.add(sio.getvalue(), rev.revision_id)
0.5.67 by John Arbash Meinel
Working on apply_changeset
43
            del sio
44
45
def merge_revs(branch, rev_base, rev_other,
46
        ignore_zero=False, check_clean=True):
47
    """This will merge the tree of rev_other into 
48
    the working tree of branch using the base given by rev_base.
49
    All the revision XML should be inside branch.
50
    """
51
    import tempfile, shutil
52
    from bzrlib.merge import merge_inner, MergeTree
53
    from bzrlib.errors import BzrCommandError
54
55
    tempdir = tempfile.mkdtemp(prefix='bzr-')
56
    try:
57
        if check_clean:
58
            from bzrlib.diff import compare_trees
59
            changes = compare_trees(branch.working_tree(), 
60
                                    branch.basis_tree(), False)
61
62
            if changes.has_changed():
63
                raise BzrCommandError("Working tree has uncommitted changes.")
64
65
        other_dir = os.path.join(tempdir, 'other')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
66
        os.mkdir(other_dir)
0.5.67 by John Arbash Meinel
Working on apply_changeset
67
        other_tree = MergeTree(branch.revision_tree(rev_other), other_dir)
68
69
        base_dir = os.path.join(tempdir, 'base')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
70
        os.mkdir(base_dir)
0.5.67 by John Arbash Meinel
Working on apply_changeset
71
        base_tree = MergeTree(branch.revision_tree(rev_base), base_dir)
72
73
        merge_inner(branch, other_tree, base_tree, tempdir,
74
            ignore_zero=ignore_zero)
75
    finally:
76
        shutil.rmtree(tempdir)
77
0.5.69 by John Arbash Meinel
Applying patch from Robey Pointer to clean up apply_changeset.
78
def apply_changeset(branch, from_file, reverse=False, auto_commit=False):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
79
    """Read in a changeset from the given file, and apply it to
80
    the supplied branch.
81
    """
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
82
    import sys, read_changeset
83
0.5.69 by John Arbash Meinel
Applying patch from Robey Pointer to clean up apply_changeset.
84
    if reverse:
85
        raise Exception('reverse not implemented yet')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
86
87
    cset = read_changeset.read_changeset(from_file, branch)
88
89
    _apply_cset(branch, cset, reverse=reverse, auto_commit=auto_commit)
0.5.69 by John Arbash Meinel
Applying patch from Robey Pointer to clean up apply_changeset.
90
        
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
91
def _apply_cset(branch, cset, reverse=False, auto_commit=False):
92
    """Apply an in-memory changeset to a given branch.
93
    """
94
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
95
    cset_info, cset_tree = cset
0.5.67 by John Arbash Meinel
Working on apply_changeset
96
0.5.83 by John Arbash Meinel
Tests pass. Now ChangesetTree has it's own inventory.
97
    _install_info(branch, cset_info, cset_tree)
0.5.67 by John Arbash Meinel
Working on apply_changeset
98
99
    # We could technically optimize more, by using the ChangesetTree
100
    # we already have in memory, but after installing revisions
101
    # this code can work the way merge should work in the
102
    # future.
103
    #
104
    # TODO:
105
    #   This shouldn't use the base of the changeset as the base
106
    #   for the merge, the merge code should pick the best merge
107
    #   based on the ancestry of both trees.
108
    #
109
    merge_revs(branch, cset_info.base, cset_info.target)
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
110
111
    if auto_commit:
112
        from bzrlib.commit import commit
0.5.67 by John Arbash Meinel
Working on apply_changeset
113
114
        # When merging, if the revision to be merged has a parent
115
        # of the current revision, then it can be installed
116
        # directly.
117
        #
118
        # TODO: 
119
        #   There is actually a slightly stronger statement
120
        #   whereby if the current revision is in the ancestry
121
        #   of the merged revisions, it doesn't need to be the
122
        #   immediate ancestry, but that requires searching
123
        #   a potentially branching history.
124
        #
125
        target_has_parent = False
126
        target_rev = branch.get_revision(cset_info.target)
127
        lastrev_id = branch.last_patch()
128
        for parent in target_rev.parents:
129
            if parent.revision_id == lastrev_id:
130
                target_has_parent = True
131
132
        if target_has_parent:
133
            branch.append_revision(target_rev.revision_id)
134
        else:
135
            print '** Could not auto-commit.'
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
136