~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Robert Collins
  • Date: 2005-10-18 06:42:17 UTC
  • mfrom: (0.2.1)
  • mto: This revision was merged to the branch mainline in revision 1463.
  • Revision ID: robertc@robertcollins.net-20051018064217-e810bd94c74a9ad1
Factor out the guts of 'pull' from the command into WorkingTree.pull().
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
"""WorkingTree object and friends.
18
 
 
19
 
A WorkingTree represents the editable working copy of a branch.
20
 
Operations which represent the WorkingTree are also done here, 
21
 
such as renaming or adding files.  The WorkingTree has an inventory 
22
 
which is updated by these operations.  A commit produces a 
23
 
new revision based on the workingtree and its inventory.
24
 
 
25
 
At the moment every WorkingTree has its own branch.  Remote
26
 
WorkingTrees aren't supported.
27
 
 
28
 
To get a WorkingTree, call Branch.working_tree():
29
 
"""
30
 
 
31
 
 
32
 
# TODO: Don't allow WorkingTrees to be constructed for remote branches if 
33
 
# they don't work.
 
17
# TODO: Don't allow WorkingTrees to be constructed for remote branches.
34
18
 
35
19
# FIXME: I don't know if writing out the cache from the destructor is really a
36
 
# good idea, because destructors are considered poor taste in Python, and it's
37
 
# not predictable when it will be written out.
38
 
 
39
 
# TODO: Give the workingtree sole responsibility for the working inventory;
40
 
# remove the variable and references to it from the branch.  This may require
41
 
# updating the commit code so as to update the inventory within the working
42
 
# copy, and making sure there's only one WorkingTree for any directory on disk.
43
 
# At the momenthey may alias the inventory and have old copies of it in memory.
 
20
# good idea, because destructors are considered poor taste in Python, and
 
21
# it's not predictable when it will be written out.
44
22
 
45
23
import os
46
24
import stat
49
27
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock, quotefn
50
28
import bzrlib.tree
51
29
from bzrlib.osutils import appendpath, file_kind, isdir, splitpath, relpath
52
 
from bzrlib.errors import BzrCheckError, DivergedBranches, NotVersionedError
 
30
from bzrlib.errors import BzrCheckError, DivergedBranches
53
31
from bzrlib.trace import mutter
54
32
 
55
 
 
56
33
class TreeEntry(object):
57
34
    """An entry that implements the minium interface used by commands.
58
35
 
128
105
        """
129
106
        from bzrlib.hashcache import HashCache
130
107
        from bzrlib.trace import note, mutter
131
 
        assert isinstance(basedir, basestring), \
132
 
            "base directory %r is not a string" % basedir
 
108
 
133
109
        if branch is None:
134
110
            branch = Branch.open(basedir)
135
 
        assert isinstance(branch, Branch), \
136
 
            "branch %r is not a Branch" % branch
137
111
        self._inventory = branch.inventory
138
112
        self.path2id = self._inventory.path2id
139
113
        self.branch = branch
141
115
 
142
116
        # update the whole cache up front and write to disk if anything changed;
143
117
        # in the future we might want to do this more selectively
144
 
        # two possible ways offer themselves : in self._unlock, write the cache
145
 
        # if needed, or, when the cache sees a change, append it to the hash
146
 
        # cache file, and have the parser take the most recent entry for a
147
 
        # given path only.
148
118
        hc = self._hashcache = HashCache(basedir)
149
119
        hc.read()
150
120
        hc.scan()
152
122
        if hc.needs_write:
153
123
            mutter("write hc")
154
124
            hc.write()
 
125
            
 
126
            
 
127
    def __del__(self):
 
128
        if self._hashcache.needs_write:
 
129
            self._hashcache.write()
 
130
 
155
131
 
156
132
    def __iter__(self):
157
133
        """Iterate through file_ids for this tree.
330
306
                yield stem
331
307
 
332
308
    @needs_write_lock
333
 
    def pull(self, source, overwrite=False):
334
 
        from bzrlib.merge import merge_inner
 
309
    def pull(self, source, remember=False):
 
310
        from bzrlib.merge import merge
335
311
        source.lock_read()
336
312
        try:
 
313
            old_revno = self.branch.revno()
337
314
            old_revision_history = self.branch.revision_history()
338
 
            self.branch.pull(source, overwrite)
 
315
            try:
 
316
                self.branch.update_revisions(source)
 
317
            except DivergedBranches:
 
318
                if True:
 
319
                    raise
339
320
            new_revision_history = self.branch.revision_history()
340
321
            if new_revision_history != old_revision_history:
341
 
                if len(old_revision_history):
342
 
                    other_revision = old_revision_history[-1]
343
 
                else:
344
 
                    other_revision = None
345
 
                merge_inner(self.branch,
346
 
                            self.branch.basis_tree(), 
347
 
                            self.branch.revision_tree(other_revision))
 
322
                merge((self.basedir, -1), (self.basedir, old_revno), check_clean=False)
 
323
            if self.branch.get_parent() is None or remember:
 
324
                self.branch.set_parent(source.base)
348
325
        finally:
349
326
            source.unlock()
350
327
 
476
453
        for f in files:
477
454
            fid = inv.path2id(f)
478
455
            if not fid:
479
 
                # TODO: Perhaps make this just a warning, and continue?
480
 
                # This tends to happen when 
481
 
                raise NotVersionedError(path=f)
 
456
                raise BzrError("cannot remove unversioned file %s" % quotefn(f))
482
457
            mutter("remove inventory entry %s {%s}" % (quotefn(f), fid))
483
458
            if verbose:
484
459
                # having remove it, it must be either ignored or unknown