~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Aaron Bentley
  • Date: 2007-07-12 17:06:11 UTC
  • mto: This revision was merged to the branch mainline in revision 2617.
  • Revision ID: abentley@panoramicfeedback.com-20070712170611-rj70hbjdk5titkqt
Aggressively cache trees, use dirstate.  re-mplement _add_parent.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import warnings
21
21
 
22
22
from bzrlib import (
 
23
    errors,
23
24
    osutils,
24
25
    registry,
25
26
    )
52
53
 
53
54
# TODO: Report back as changes are merged in
54
55
 
55
 
def _get_tree(treespec, local_branch=None):
56
 
    from bzrlib import workingtree
57
 
    location, revno = treespec
58
 
    if revno is None:
59
 
        tree = workingtree.WorkingTree.open_containing(location)[0]
60
 
        return tree.branch, tree
61
 
    branch = Branch.open_containing(location)[0]
62
 
    if revno == -1:
63
 
        revision_id = branch.last_revision()
64
 
    else:
65
 
        revision_id = branch.get_rev_id(revno)
66
 
    if revision_id is None:
67
 
        revision_id = NULL_REVISION
68
 
    return branch, _get_revid_tree(branch, revision_id, local_branch)
69
 
 
70
 
 
71
 
def _get_revid_tree(branch, revision_id, local_branch):
72
 
    if revision_id is None:
73
 
        base_tree = branch.bzrdir.open_workingtree()
74
 
    else:
75
 
        if local_branch is not None:
76
 
            if local_branch.base != branch.base:
77
 
                local_branch.fetch(branch, revision_id)
78
 
            base_tree = local_branch.repository.revision_tree(revision_id)
79
 
        else:
80
 
            base_tree = branch.repository.revision_tree(revision_id)
81
 
    return base_tree
82
 
 
83
 
 
84
 
def _get_revid_tree_from_tree(tree, revision_id, local_branch):
85
 
    if revision_id is None:
86
 
        return tree
87
 
    if local_branch is not None:
88
 
        if local_branch.base != tree.branch.base:
89
 
            local_branch.fetch(tree.branch, revision_id)
90
 
        return local_branch.repository.revision_tree(revision_id)
91
 
    return tree.branch.repository.revision_tree(revision_id)
92
 
 
93
56
 
94
57
def transform_tree(from_tree, to_tree, interesting_ids=None):
95
58
    merge_inner(from_tree.branch, to_tree, from_tree, ignore_zero=True,
121
84
        self.pp = None
122
85
        self.recurse = recurse
123
86
        self.change_reporter = change_reporter
124
 
 
125
 
    def revision_tree(self, revision_id):
126
 
        return self.this_branch.repository.revision_tree(revision_id)
 
87
        self._cached_trees = {}
 
88
 
 
89
    def revision_tree(self, revision_id, branch=None):
 
90
        if revision_id not in self._cached_trees:
 
91
            if branch is None:
 
92
                branch = self.this_branch
 
93
            try:
 
94
                tree = self.this_tree.revision_tree(revision_id)
 
95
            except errors.NoSuchRevisionInTree:
 
96
                tree = branch.repository.revision_tree(revision_id)
 
97
            self._cached_trees[revision_id] = tree
 
98
        return self._cached_trees[revision_id]
 
99
 
 
100
    def _get_tree(self, treespec):
 
101
        from bzrlib import workingtree
 
102
        location, revno = treespec
 
103
        if revno is None:
 
104
            tree = workingtree.WorkingTree.open_containing(location)[0]
 
105
            return tree.branch, tree
 
106
        branch = Branch.open_containing(location)[0]
 
107
        if revno == -1:
 
108
            revision_id = branch.last_revision()
 
109
        else:
 
110
            revision_id = branch.get_rev_id(revno)
 
111
        if revision_id is None:
 
112
            revision_id = NULL_REVISION
 
113
        revision_id = ensure_null(revision_id)
 
114
        return branch, self.revision_tree(revision_id, branch)
127
115
 
128
116
    def ensure_revision_trees(self):
129
117
        if self.this_revision_tree is None:
130
 
            self.this_basis_tree = self.this_branch.repository.revision_tree(
131
 
                self.this_basis)
 
118
            self.this_basis_tree = self.revision_tree(self.this_basis)
132
119
            if self.this_basis == self.this_rev_id:
133
120
                self.this_revision_tree = self.this_basis_tree
134
121
 
164
151
                raise BzrCommandError("Working tree has uncommitted changes.")
165
152
 
166
153
    def compare_basis(self):
167
 
        changes = self.this_tree.changes_from(self.this_tree.basis_tree())
 
154
        changes = self.this_tree.changes_from(self.revision_tree(
 
155
            self.this_tree.last_revision()))
168
156
        if not changes.has_changed():
169
157
            self.this_rev_id = self.this_basis
170
158
 
202
190
            self.this_basis, topo_sorted=False))
203
191
        if self.other_rev_id in ancestry:
204
192
            return
205
 
        self.this_tree.add_parent_tree((self.other_rev_id, self.other_tree))
 
193
        self._add_parent()
 
194
 
 
195
    def _add_parent(self):
 
196
        new_parents = self.this_tree.get_parent_ids() + [self.other_rev_id]
 
197
        new_parent_trees = [(r, self.revision_tree(r)) for r in new_parents]
 
198
        for _revision_id, tree in new_parent_trees:
 
199
            tree.lock_read()
 
200
        try:
 
201
            self.this_tree.set_parent_trees(new_parent_trees)
 
202
        finally:
 
203
            for _revision_id, tree in new_parent_trees:
 
204
                tree.unlock()
206
205
 
207
206
    def set_other(self, other_revision):
208
207
        """Set the revision and tree to merge from.
211
210
 
212
211
        :param other_revision: The [path, revision] list to merge from.
213
212
        """
214
 
        self.other_branch, self.other_tree = _get_tree(other_revision,
215
 
                                                  self.this_branch)
 
213
        self.other_branch, self.other_tree = self._get_tree(other_revision)
216
214
        if other_revision[1] == -1:
217
215
            self.other_rev_id = self.other_branch.last_revision()
218
216
            if self.other_rev_id is None:
226
224
            self.other_basis = self.other_branch.last_revision()
227
225
            if self.other_basis is None:
228
226
                raise NoCommits(self.other_branch)
 
227
        if self.other_rev_id is not None:
 
228
            self._cached_trees[self.other_rev_id] = self.other_tree
229
229
        if self.other_branch.base != self.this_branch.base:
230
230
            self.this_branch.fetch(self.other_branch,
231
231
                                   last_revision=self.other_basis)
269
269
                    pb.finished()
270
270
            except NoCommonAncestor:
271
271
                raise UnrelatedBranches()
272
 
            self.base_tree = _get_revid_tree_from_tree(self.this_tree,
273
 
                                                       self.base_rev_id,
274
 
                                                       None)
 
272
            self.base_tree = self.revision_tree(self.base_rev_id)
275
273
            self.base_is_ancestor = True
276
274
        else:
277
 
            base_branch, self.base_tree = _get_tree(base_revision)
 
275
            base_branch, self.base_tree = self._get_tree(base_revision)
278
276
            if base_revision[1] == -1:
279
277
                self.base_rev_id = base_branch.last_revision()
280
278
            elif base_revision[1] is None: