/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

first cut at merge from integration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
from bzrlib.atomicfile import AtomicFile
51
51
from bzrlib.branch import (Branch,
 
52
                           BzrBranchFormat4,
 
53
                           BzrBranchFormat5,
 
54
                           BzrBranchFormat6,
52
55
                           is_control_file,
53
 
                           needs_read_lock,
54
 
                           needs_write_lock,
55
56
                           quotefn)
 
57
from bzrlib.decorators import needs_read_lock, needs_write_lock
56
58
from bzrlib.errors import (BzrCheckError,
57
59
                           BzrError,
58
60
                           DivergedBranches,
59
61
                           WeaveRevisionNotPresent,
60
62
                           NotBranchError,
 
63
                           NoSuchFile,
61
64
                           NotVersionedError)
62
65
from bzrlib.inventory import InventoryEntry
 
66
from bzrlib.lockable_files import LockableFiles
63
67
from bzrlib.osutils import (appendpath,
64
68
                            compact_date,
65
69
                            file_kind,
79
83
from bzrlib.textui import show_status
80
84
import bzrlib.tree
81
85
from bzrlib.trace import mutter
 
86
from bzrlib.transport import get_transport
82
87
import bzrlib.xml5
83
88
 
84
89
 
181
186
    not listed in the Inventory and vice versa.
182
187
    """
183
188
 
184
 
    def __init__(self, basedir='.', branch=None, _inventory=None):
 
189
    def __init__(self, basedir='.', branch=None, _inventory=None, _control_files=None):
185
190
        """Construct a WorkingTree for basedir.
186
191
 
187
192
        If the branch is not supplied, it is opened automatically.
194
199
        assert isinstance(basedir, basestring), \
195
200
            "base directory %r is not a string" % basedir
196
201
        basedir = safe_unicode(basedir)
 
202
        mutter("openeing working tree %r", basedir)
197
203
        if branch is None:
198
204
            branch = Branch.open(basedir)
199
205
        assert isinstance(branch, Branch), \
200
206
            "branch %r is not a Branch" % branch
201
207
        self.branch = branch
202
208
        self.basedir = realpath(basedir)
 
209
        # if branch is at our basedir and is a format 6 or less
 
210
        if (isinstance(self.branch._branch_format,
 
211
                       (BzrBranchFormat4, BzrBranchFormat5, BzrBranchFormat6))
 
212
            # might be able to share control object
 
213
            and self.branch.base.split('/')[-2] == self.basedir.split('/')[-1]):
 
214
            self._control_files = self.branch.control_files
 
215
        elif _control_files is not None:
 
216
            assert False, "not done yet"
 
217
#            self._control_files = _control_files
 
218
        else:
 
219
            self._control_files = LockableFiles(
 
220
                get_transport(self.basedir).clone(bzrlib.BZRDIR), 'branch-lock')
203
221
 
204
222
        # update the whole cache up front and write to disk if anything changed;
205
223
        # in the future we might want to do this more selectively
300
318
        except OSError, e:
301
319
            if e.errno != errno.EEXIST:
302
320
                raise
303
 
        inv = branch.revision_tree(branch.last_revision()).inventory
 
321
        inv = branch.repository.revision_tree(branch.last_revision()).inventory
304
322
        wt = WorkingTree(directory, branch, inv)
305
323
        wt._write_inventory(inv)
306
324
        if branch.last_revision() is not None:
464
482
        if updated:
465
483
            self.set_pending_merges(p)
466
484
 
 
485
    @needs_read_lock
467
486
    def pending_merges(self):
468
487
        """Return a list of pending merges.
469
488
 
471
490
        directory but not yet committed.
472
491
        """
473
492
        try:
474
 
            merges_file = self._controlfile('pending-merges')
 
493
            merges_file = self._control_files.get_utf8('pending-merges')
475
494
        except OSError, e:
476
495
            if e.errno != errno.ENOENT:
477
496
                raise
481
500
            p.append(l.rstrip('\n'))
482
501
        return p
483
502
 
484
 
    def _abs_controlfilename(self, name):
485
 
        """return the path for the controlfile name in the workingtree."""
486
 
        return pathjoin(self.basedir, '.bzr', name)
487
 
 
488
 
    def _controlfile(self, name, encoding='utf-8'):
489
 
        """Get a control file for the checkout.
490
 
 
491
 
        FIXME RBC 20060123 when storage comes in this should be a lockable
492
 
        files group ?.
493
 
        """
494
 
        import codecs
495
 
        return codecs.open(self._abs_controlfilename(name), encoding=encoding)
496
 
 
497
503
    @needs_write_lock
498
504
    def set_pending_merges(self, rev_list):
499
 
        sio = StringIO()
500
 
        sio.write('\n'.join(rev_list).encode('utf-8'))
501
 
        sio.seek(0)
502
 
        f = AtomicFile(self._abs_controlfilename('pending-merges'))
503
 
        try:
504
 
            pumpfile(sio, f)
505
 
            f.commit()
506
 
        finally:
507
 
            f.close()
 
505
        self._control_files.put_utf8('pending-merges', '\n'.join(rev_list))
508
506
 
509
507
    def get_symlink_target(self, file_id):
510
508
        return os.readlink(self.id2abspath(file_id))
753
751
                    other_revision = old_revision_history[-1]
754
752
                else:
755
753
                    other_revision = None
 
754
                repository = self.branch.repository
756
755
                merge_inner(self.branch,
757
756
                            self.branch.basis_tree(), 
758
 
                            self.branch.revision_tree(other_revision),
 
757
                            repository.revision_tree(other_revision),
759
758
                            this_tree=self)
760
759
                self.set_last_revision(self.branch.last_revision())
761
760
            return count
868
867
        return 'basis-inventory.%s' % revision_id
869
868
 
870
869
    def set_last_revision(self, new_revision, old_revision=None):
871
 
        if old_revision:
 
870
        if old_revision is not None:
872
871
            try:
873
872
                path = self._basis_inventory_name(old_revision)
874
 
                path = self.branch._rel_controlfilename(path)
875
 
                self.branch._transport.delete(path)
876
 
            except:
 
873
                path = self.branch.control_files._escape(path)
 
874
                self.branch.control_files._transport.delete(path)
 
875
            except NoSuchFile:
877
876
                pass
878
877
        try:
879
 
            xml = self.branch.get_inventory_xml(new_revision)
 
878
            xml = self.branch.repository.get_inventory_xml(new_revision)
880
879
            path = self._basis_inventory_name(new_revision)
881
 
            self.branch.put_controlfile(path, xml)
 
880
            self.branch.control_files.put_utf8(path, xml)
882
881
        except WeaveRevisionNotPresent:
883
882
            pass
884
883
 
885
884
    def read_basis_inventory(self, revision_id):
886
885
        """Read the cached basis inventory."""
887
886
        path = self._basis_inventory_name(revision_id)
888
 
        return self.branch.controlfile(path, 'r').read()
 
887
        return self.branch.control_files.get_utf8(path).read()
889
888
        
890
889
    @needs_read_lock
891
890
    def read_working_inventory(self):
893
892
        # ElementTree does its own conversion from UTF-8, so open in
894
893
        # binary.
895
894
        return bzrlib.xml5.serializer_v5.read_inventory(
896
 
            self._controlfile('inventory', encoding=None))
 
895
            self._control_files.get('inventory'))
897
896
 
898
897
    @needs_write_lock
899
898
    def remove(self, files, verbose=False):
995
994
        between multiple working trees, i.e. via shared storage, then we 
996
995
        would probably want to lock both the local tree, and the branch.
997
996
        """
998
 
        if self._hashcache.needs_write and self.branch._lock_count==1:
 
997
        # FIXME: We want to write out the hashcache only when the last lock on
 
998
        # this working copy is released.  Peeking at the lock count is a bit
 
999
        # of a nasty hack; probably it's better to have a transaction object,
 
1000
        # which can do some finalization when it's either successfully or
 
1001
        # unsuccessfully completed.  (Denys's original patch did that.)
 
1002
        if self._hashcache.needs_write and self.branch.control_files._lock_count==1:
999
1003
            self._hashcache.write()
1000
1004
        return self.branch.unlock()
1001
1005
 
1005
1009
        sio = StringIO()
1006
1010
        bzrlib.xml5.serializer_v5.write_inventory(inv, sio)
1007
1011
        sio.seek(0)
1008
 
        f = AtomicFile(self._abs_controlfilename('inventory'))
1009
 
        try:
1010
 
            pumpfile(sio, f)
1011
 
            f.commit()
1012
 
        finally:
1013
 
            f.close()
 
1012
        self._control_files.put('inventory', sio)
1014
1013
        self._set_inventory(inv)
1015
1014
        mutter('wrote working inventory')
1016
1015