~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Aaron Bentley
  • Date: 2006-03-07 05:59:14 UTC
  • mfrom: (1558.1.20 Aaron's integration)
  • mto: This revision was merged to the branch mainline in revision 1595.
  • Revision ID: aaron.bentley@utoronto.ca-20060307055914-a88728997afceb90
MergeĀ fromĀ mainline

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
                           NoSuchFile,
64
64
                           NotVersionedError)
65
65
from bzrlib.inventory import InventoryEntry, Inventory
66
 
from bzrlib.lockable_files import LockableFiles
 
66
from bzrlib.lockable_files import LockableFiles, TransportLock
67
67
from bzrlib.merge import merge_inner, transform_tree
68
 
from bzrlib.osutils import (appendpath,
 
68
from bzrlib.osutils import (
 
69
                            abspath,
 
70
                            appendpath,
69
71
                            compact_date,
70
72
                            file_kind,
71
73
                            isdir,
75
77
                            safe_unicode,
76
78
                            splitpath,
77
79
                            rand_bytes,
78
 
                            abspath,
79
80
                            normpath,
80
81
                            realpath,
81
82
                            relpath,
256
257
            assert isinstance(self._format, WorkingTreeFormat3)
257
258
            self._control_files = LockableFiles(
258
259
                self.bzrdir.get_workingtree_transport(None),
259
 
                'lock')
 
260
                'lock', TransportLock)
260
261
 
261
262
        # update the whole cache up front and write to disk if anything changed;
262
263
        # in the future we might want to do this more selectively
1193
1194
 
1194
1195
    @needs_write_lock
1195
1196
    def update(self):
 
1197
        """Update a working tree along its branch.
 
1198
 
 
1199
        This will update the branch if its bound too, which means we have multiple trees involved:
 
1200
        The new basis tree of the master.
 
1201
        The old basis tree of the branch.
 
1202
        The old basis tree of the working tree.
 
1203
        The current working tree state.
 
1204
        pathologically all three may be different, and non ancestors of each other.
 
1205
        Conceptually we want to:
 
1206
        Preserve the wt.basis->wt.state changes
 
1207
        Transform the wt.basis to the new master basis.
 
1208
        Apply a merge of the old branch basis to get any 'local' changes from it into the tree.
 
1209
        Restore the wt.basis->wt.state changes.
 
1210
 
 
1211
        There isn't a single operation at the moment to do that, so we:
 
1212
        Merge current state -> basis tree of the master w.r.t. the old tree basis.
 
1213
        Do a 'normal' merge of the old branch basis if it is relevant.
 
1214
        """
 
1215
        old_tip = self.branch.update()
 
1216
        if old_tip is not None:
 
1217
            self.add_pending_merge(old_tip)
1196
1218
        self.branch.lock_read()
1197
1219
        try:
1198
 
            if self.last_revision() == self.branch.last_revision():
1199
 
                return
1200
 
            basis = self.basis_tree()
1201
 
            to_tree = self.branch.basis_tree()
1202
 
            result = merge_inner(self.branch,
1203
 
                                 to_tree,
1204
 
                                 basis,
1205
 
                                 this_tree=self)
1206
 
            self.set_last_revision(self.branch.last_revision())
 
1220
            result = 0
 
1221
            if self.last_revision() != self.branch.last_revision():
 
1222
                # merge tree state up to new branch tip.
 
1223
                basis = self.basis_tree()
 
1224
                to_tree = self.branch.basis_tree()
 
1225
                result += merge_inner(self.branch,
 
1226
                                      to_tree,
 
1227
                                      basis,
 
1228
                                      this_tree=self)
 
1229
                self.set_last_revision(self.branch.last_revision())
 
1230
            if old_tip and old_tip != self.last_revision():
 
1231
                # our last revision was not the prior branch last reivison
 
1232
                # and we have converted that last revision to a pending merge.
 
1233
                # base is somewhere between the branch tip now
 
1234
                # and the now pending merge
 
1235
                from bzrlib.revision import common_ancestor
 
1236
                try:
 
1237
                    base_rev_id = common_ancestor(self.branch.last_revision(),
 
1238
                                                  old_tip,
 
1239
                                                  self.branch.repository)
 
1240
                except errors.NoCommonAncestor:
 
1241
                    base_rev_id = None
 
1242
                base_tree = self.branch.repository.revision_tree(base_rev_id)
 
1243
                other_tree = self.branch.repository.revision_tree(old_tip)
 
1244
                result += merge_inner(self.branch,
 
1245
                                      other_tree,
 
1246
                                      base_tree,
 
1247
                                      this_tree=self)
1207
1248
            return result
1208
1249
        finally:
1209
1250
            self.branch.unlock()
1420
1461
        if not isinstance(a_bzrdir.transport, LocalTransport):
1421
1462
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1422
1463
        transport = a_bzrdir.get_workingtree_transport(self)
1423
 
        control_files = LockableFiles(transport, 'lock')
 
1464
        control_files = LockableFiles(transport, 'lock', TransportLock)
1424
1465
        control_files.put_utf8('format', self.get_format_string())
1425
1466
        branch = a_bzrdir.open_branch()
1426
1467
        if revision_id is None: