~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to apply_changeset.py

  • Committer: John Arbash Meinel
  • Date: 2005-07-04 06:51:52 UTC
  • mto: (0.5.85) (1185.82.1 bzr-w-changeset)
  • mto: This revision was merged to the branch mainline in revision 1738.
  • Revision ID: john@arbash-meinel.com-20050704065152-26d062ad7befd806
Working on apply_changeset

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
"""
5
5
 
6
6
import bzrlib
 
7
import os
 
8
 
 
9
def _install_info(branch, cset_info, cset_tree, cset_inv):
 
10
    """Make sure that there is a text entry for each 
 
11
    file in the changeset.
 
12
    """
 
13
    from bzrlib.xml import pack_xml
 
14
    from cStringIO import StringIO
 
15
 
 
16
    # First, install all required texts
 
17
    for file_id, text_id in cset_info.text_ids.iteritems():
 
18
        if text_id not in branch.text_store:
 
19
            branch.text_store.add(cset_tree.get_file(file_id), text_id)
 
20
 
 
21
    # Now install the final inventory
 
22
    if cset_info.target not in branch.inventory_store:
 
23
        # bzrlib.commit uses a temporary file, but store.add
 
24
        # reads in the entire file anyway
 
25
        sio = StringIO()
 
26
        pack_xml(cset_inv, sio)
 
27
        branch.inventory_store.add(sio.getvalue(), cset_info.target)
 
28
        del sio
 
29
 
 
30
    # Now that we have installed the inventory and texts
 
31
    # install the revision entries.
 
32
    for rev in cset_info.real_revisions:
 
33
        if rev.revision_id not in branch.revision_store:
 
34
            sio = StringIO()
 
35
            pack_xml(rev, sio)
 
36
            branch.inventory_store.add(sio.getvalue(), rev.revision_id)
 
37
            del sio
 
38
 
 
39
def get_tree(treespec, temp_root, label):
 
40
    location, revno = treespec
 
41
    branch = find_branch(location)
 
42
    if revno is None:
 
43
        base_tree = branch.working_tree()
 
44
    elif revno == -1:
 
45
        base_tree = branch.basis_tree()
 
46
    else:
 
47
        base_tree = branch.revision_tree(branch.lookup_revision(revno))
 
48
    temp_path = os.path.join(temp_root, label)
 
49
    os.mkdir(temp_path)
 
50
    return branch, MergeTree(base_tree, temp_path)
 
51
 
 
52
def merge_revs(branch, rev_base, rev_other,
 
53
        ignore_zero=False, check_clean=True):
 
54
    """This will merge the tree of rev_other into 
 
55
    the working tree of branch using the base given by rev_base.
 
56
    All the revision XML should be inside branch.
 
57
    """
 
58
    import tempfile, shutil
 
59
    from bzrlib.merge import merge_inner, MergeTree
 
60
    from bzrlib.errors import BzrCommandError
 
61
 
 
62
    tempdir = tempfile.mkdtemp(prefix='bzr-')
 
63
    try:
 
64
        if check_clean:
 
65
            from bzrlib.diff import compare_trees
 
66
            changes = compare_trees(branch.working_tree(), 
 
67
                                    branch.basis_tree(), False)
 
68
 
 
69
            if changes.has_changed():
 
70
                raise BzrCommandError("Working tree has uncommitted changes.")
 
71
 
 
72
        other_dir = os.path.join(tempdir, 'other')
 
73
        other_tree = MergeTree(branch.revision_tree(rev_other), other_dir)
 
74
 
 
75
        base_dir = os.path.join(tempdir, 'base')
 
76
        base_tree = MergeTree(branch.revision_tree(rev_base), base_dir)
 
77
 
 
78
        merge_inner(branch, other_tree, base_tree, tempdir,
 
79
            ignore_zero=ignore_zero)
 
80
    finally:
 
81
        shutil.rmtree(tempdir)
 
82
 
7
83
 
8
84
def apply_changeset(branch, from_file, auto_commit=False):
9
 
    from bzrlib.merge import merge_inner
10
85
    import sys, read_changeset
11
86
 
12
 
 
13
 
    cset_info, cset_tree, cset_inv = read_changeset.read_changeset(from_file)
 
87
    cset_info, cset_tree, cset_inv = \
 
88
            read_changeset.read_changeset(from_file)
 
89
 
 
90
    _install_info(branch, cset_info, cset_tree, cset_inv)
 
91
 
 
92
    # We could technically optimize more, by using the ChangesetTree
 
93
    # we already have in memory, but after installing revisions
 
94
    # this code can work the way merge should work in the
 
95
    # future.
 
96
    #
 
97
    # TODO:
 
98
    #   This shouldn't use the base of the changeset as the base
 
99
    #   for the merge, the merge code should pick the best merge
 
100
    #   based on the ancestry of both trees.
 
101
    #
 
102
    merge_revs(branch, cset_info.base, cset_info.target)
14
103
 
15
104
    if auto_commit:
16
105
        from bzrlib.commit import commit
17
 
        if branch.last_patch() == cset_info.precursor:
18
 
            # This patch can be applied directly
19
 
            commit(branch, message = cset_info.message,
20
 
                    timestamp=float(cset_info.timestamp),
21
 
                    timezone=float(cset_info.timezone),
22
 
                    committer=cset_info.committer,
23
 
                    rev_id=cset_info.revision)
24
 
 
 
106
 
 
107
        # When merging, if the revision to be merged has a parent
 
108
        # of the current revision, then it can be installed
 
109
        # directly.
 
110
        #
 
111
        # TODO: 
 
112
        #   There is actually a slightly stronger statement
 
113
        #   whereby if the current revision is in the ancestry
 
114
        #   of the merged revisions, it doesn't need to be the
 
115
        #   immediate ancestry, but that requires searching
 
116
        #   a potentially branching history.
 
117
        #
 
118
        target_has_parent = False
 
119
        target_rev = branch.get_revision(cset_info.target)
 
120
        lastrev_id = branch.last_patch()
 
121
        for parent in target_rev.parents:
 
122
            if parent.revision_id == lastrev_id:
 
123
                target_has_parent = True
 
124
 
 
125
        if target_has_parent:
 
126
            branch.append_revision(target_rev.revision_id)
 
127
        else:
 
128
            print '** Could not auto-commit.'
25
129