~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-12-20 16:16:34 UTC
  • mfrom: (3123.5.18 hardlinks)
  • Revision ID: pqm@pqm.ubuntu.com-20071220161634-2kcjb650o21ydko4
Accelerate build_tree using similar workingtrees (abentley)

Show diffs side-by-side

added added

removed removed

Lines of Context:
111
111
        deprecated_method,
112
112
        deprecated_function,
113
113
        DEPRECATED_PARAMETER,
 
114
        zero_eight,
 
115
        zero_eleven,
 
116
        zero_thirteen,
114
117
        )
115
118
 
116
119
 
120
123
ERROR_PATH_NOT_FOUND = 3    # WindowsError errno code, equivalent to ENOENT
121
124
 
122
125
 
 
126
@deprecated_function(zero_thirteen)
 
127
def gen_file_id(name):
 
128
    """Return new file id for the basename 'name'.
 
129
 
 
130
    Use bzrlib.generate_ids.gen_file_id() instead
 
131
    """
 
132
    return generate_ids.gen_file_id(name)
 
133
 
 
134
 
 
135
@deprecated_function(zero_thirteen)
 
136
def gen_root_id():
 
137
    """Return a new tree-root file id.
 
138
 
 
139
    This has been deprecated in favor of bzrlib.generate_ids.gen_root_id()
 
140
    """
 
141
    return generate_ids.gen_root_id()
 
142
 
 
143
 
123
144
class TreeEntry(object):
124
145
    """An entry that implements the minimum interface used by commands.
125
146
 
201
222
        if not _internal:
202
223
            raise errors.BzrError("Please use bzrdir.open_workingtree or "
203
224
                "WorkingTree.open() to obtain a WorkingTree.")
 
225
        assert isinstance(basedir, basestring), \
 
226
            "base directory %r is not a string" % basedir
204
227
        basedir = safe_unicode(basedir)
205
228
        mutter("opening working tree %r", basedir)
206
229
        if deprecated_passed(branch):
214
237
            self._control_files = self.branch.control_files
215
238
        else:
216
239
            # assume all other formats have their own control files.
 
240
            assert isinstance(_control_files, LockableFiles), \
 
241
                    "_control_files must be a LockableFiles, not %r" \
 
242
                    % _control_files
217
243
            self._control_files = _control_files
218
 
        self._transport = self._control_files._transport
219
244
        # update the whole cache up front and write to disk if anything changed;
220
245
        # in the future we might want to do this more selectively
221
246
        # two possible ways offer themselves : in self._unlock, write the cache
225
250
        wt_trans = self.bzrdir.get_workingtree_transport(None)
226
251
        cache_filename = wt_trans.local_abspath('stat-cache')
227
252
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
228
 
            self.bzrdir._get_file_mode())
 
253
                                              self._control_files._file_mode)
229
254
        hc = self._hashcache
230
255
        hc.read()
231
256
        # is this scan needed ? it makes things kinda slow.
246
271
            # permitted to do this.
247
272
            self._set_inventory(_inventory, dirty=False)
248
273
        self._detect_case_handling()
249
 
        self._rules_searcher = None
250
274
 
251
275
    def _detect_case_handling(self):
252
276
        wt_trans = self.bzrdir.get_workingtree_transport(None)
294
318
            False then the inventory is the same as that on disk and any
295
319
            serialisation would be unneeded overhead.
296
320
        """
 
321
        assert inv.root is not None
297
322
        self._inventory = inv
298
323
        self._inventory_is_modified = dirty
299
324
 
334
359
        """
335
360
        return WorkingTree.open(path, _unsupported=True)
336
361
 
337
 
    @staticmethod
338
 
    def find_trees(location):
339
 
        def list_current(transport):
340
 
            return [d for d in transport.list_dir('') if d != '.bzr']
341
 
        def evaluate(bzrdir):
342
 
            try:
343
 
                tree = bzrdir.open_workingtree()
344
 
            except errors.NoWorkingTree:
345
 
                return True, None
346
 
            else:
347
 
                return True, tree
348
 
        transport = get_transport(location)
349
 
        iterator = bzrdir.BzrDir.find_bzrdirs(transport, evaluate=evaluate,
350
 
                                              list_current=list_current)
351
 
        return [t for t in iterator if t is not None]
352
 
 
353
362
    # should be deprecated - this is slow and in any case treating them as a
354
363
    # container is (we now know) bad style -- mbp 20070302
355
364
    ## @deprecated_method(zero_fifteen)
364
373
            if osutils.lexists(self.abspath(path)):
365
374
                yield ie.file_id
366
375
 
367
 
    def all_file_ids(self):
368
 
        """See Tree.iter_all_file_ids"""
369
 
        return set(self.inventory)
370
 
 
371
376
    def __repr__(self):
372
377
        return "<%s of %s>" % (self.__class__.__name__,
373
378
                               getattr(self, 'basedir', None))
397
402
        # at this point ?
398
403
        try:
399
404
            return self.branch.repository.revision_tree(revision_id)
400
 
        except (errors.RevisionNotPresent, errors.NoSuchRevision):
 
405
        except errors.RevisionNotPresent:
401
406
            # the basis tree *may* be a ghost or a low level error may have
402
407
            # occured. If the revision is present, its a problem, if its not
403
408
            # its a ghost.
409
414
    def _cleanup(self):
410
415
        self._flush_ignore_list_cache()
411
416
 
 
417
    @staticmethod
 
418
    @deprecated_method(zero_eight)
 
419
    def create(branch, directory):
 
420
        """Create a workingtree for branch at directory.
 
421
 
 
422
        If existing_directory already exists it must have a .bzr directory.
 
423
        If it does not exist, it will be created.
 
424
 
 
425
        This returns a new WorkingTree object for the new checkout.
 
426
 
 
427
        TODO FIXME RBC 20060124 when we have checkout formats in place this
 
428
        should accept an optional revisionid to checkout [and reject this if
 
429
        checking out into the same dir as a pre-checkout-aware branch format.]
 
430
 
 
431
        XXX: When BzrDir is present, these should be created through that 
 
432
        interface instead.
 
433
        """
 
434
        warnings.warn('delete WorkingTree.create', stacklevel=3)
 
435
        transport = get_transport(directory)
 
436
        if branch.bzrdir.root_transport.base == transport.base:
 
437
            # same dir 
 
438
            return branch.bzrdir.create_workingtree()
 
439
        # different directory, 
 
440
        # create a branch reference
 
441
        # and now a working tree.
 
442
        raise NotImplementedError
 
443
 
 
444
    @staticmethod
 
445
    @deprecated_method(zero_eight)
 
446
    def create_standalone(directory):
 
447
        """Create a checkout and a branch and a repo at directory.
 
448
 
 
449
        Directory must exist and be empty.
 
450
 
 
451
        please use BzrDir.create_standalone_workingtree
 
452
        """
 
453
        return bzrdir.BzrDir.create_standalone_workingtree(directory)
 
454
 
412
455
    def relpath(self, path):
413
456
        """Return the local path portion from a given path.
414
457
        
445
488
        basis = self.basis_tree()
446
489
        basis.lock_read()
447
490
        try:
448
 
            changes = self.iter_changes(basis, True, [self.id2path(file_id)],
 
491
            changes = self._iter_changes(basis, True, [self.id2path(file_id)],
449
492
                require_versioned=True).next()
450
493
            changed_content, kind = changes[2], changes[6]
451
494
            if not changed_content:
487
530
        else:
488
531
            parents = [last_rev]
489
532
        try:
490
 
            merges_file = self._transport.get('pending-merges')
 
533
            merges_file = self._control_files.get('pending-merges')
491
534
        except errors.NoSuchFile:
492
535
            pass
493
536
        else:
555
598
    __contains__ = has_id
556
599
 
557
600
    def get_file_size(self, file_id):
558
 
        """See Tree.get_file_size"""
559
 
        try:
560
 
            return os.path.getsize(self.id2abspath(file_id))
561
 
        except OSError, e:
562
 
            if e.errno != errno.ENOENT:
563
 
                raise
564
 
            else:
565
 
                return None
 
601
        return os.path.getsize(self.id2abspath(file_id))
566
602
 
567
603
    @needs_read_lock
568
604
    def get_file_sha1(self, file_id, path=None, stat_value=None):
608
644
        # function - they should be part of lock_write and unlock.
609
645
        inv = self.inventory
610
646
        for f, file_id, kind in zip(files, ids, kinds):
 
647
            assert kind is not None
611
648
            if file_id is None:
612
649
                inv.add_path(f, kind=kind)
613
650
            else:
708
745
        else:
709
746
            return (kind, None, None, None)
710
747
 
 
748
    @deprecated_method(zero_eleven)
 
749
    @needs_read_lock
 
750
    def pending_merges(self):
 
751
        """Return a list of pending merges.
 
752
 
 
753
        These are revisions that have been merged into the working
 
754
        directory but not yet committed.
 
755
 
 
756
        As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
 
757
        instead - which is available on all tree objects.
 
758
        """
 
759
        return self.get_parent_ids()[1:]
 
760
 
711
761
    def _check_parents_for_ghosts(self, revision_ids, allow_leftmost_as_ghost):
712
762
        """Common ghost checking functionality from set_parent_*.
713
763
 
722
772
 
723
773
    def _set_merges_from_parent_ids(self, parent_ids):
724
774
        merges = parent_ids[1:]
725
 
        self._transport.put_bytes('pending-merges', '\n'.join(merges),
726
 
            mode=self._control_files._file_mode)
727
 
 
728
 
    def _filter_parent_ids_by_ancestry(self, revision_ids):
729
 
        """Check that all merged revisions are proper 'heads'.
730
 
 
731
 
        This will always return the first revision_id, and any merged revisions
732
 
        which are 
733
 
        """
734
 
        if len(revision_ids) == 0:
735
 
            return revision_ids
736
 
        graph = self.branch.repository.get_graph()
737
 
        heads = graph.heads(revision_ids)
738
 
        new_revision_ids = revision_ids[:1]
739
 
        for revision_id in revision_ids[1:]:
740
 
            if revision_id in heads and revision_id not in new_revision_ids:
741
 
                new_revision_ids.append(revision_id)
742
 
        if new_revision_ids != revision_ids:
743
 
            trace.mutter('requested to set revision_ids = %s,'
744
 
                         ' but filtered to %s', revision_ids, new_revision_ids)
745
 
        return new_revision_ids
 
775
        self._control_files.put_bytes('pending-merges', '\n'.join(merges))
746
776
 
747
777
    @needs_tree_write_lock
748
778
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
762
792
        for revision_id in revision_ids:
763
793
            _mod_revision.check_not_reserved_id(revision_id)
764
794
 
765
 
        revision_ids = self._filter_parent_ids_by_ancestry(revision_ids)
766
 
 
767
795
        if len(revision_ids) > 0:
768
796
            self.set_last_revision(revision_ids[0])
769
797
        else:
781
809
        self._check_parents_for_ghosts(parent_ids,
782
810
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
783
811
 
784
 
        parent_ids = self._filter_parent_ids_by_ancestry(parent_ids)
785
 
 
786
812
        if len(parent_ids) == 0:
787
813
            leftmost_parent_id = _mod_revision.NULL_REVISION
788
814
            leftmost_parent_tree = None
828
854
    def _put_rio(self, filename, stanzas, header):
829
855
        self._must_be_locked()
830
856
        my_file = rio_file(stanzas, header)
831
 
        self._transport.put_file(filename, my_file,
832
 
            mode=self._control_files._file_mode)
 
857
        self._control_files.put(filename, my_file)
833
858
 
834
859
    @needs_write_lock # because merge pulls data into the branch.
835
860
    def merge_from_branch(self, branch, to_revision=None, from_revision=None,
894
919
        still in the working inventory and have that text hash.
895
920
        """
896
921
        try:
897
 
            hashfile = self._transport.get('merge-hashes')
 
922
            hashfile = self._control_files.get('merge-hashes')
898
923
        except errors.NoSuchFile:
899
924
            return {}
900
925
        merge_hashes = {}
1057
1082
        sio = StringIO()
1058
1083
        self._serialize(self._inventory, sio)
1059
1084
        sio.seek(0)
1060
 
        self._transport.put_file('inventory', sio,
1061
 
            mode=self._control_files._file_mode)
 
1085
        self._control_files.put('inventory', sio)
1062
1086
        self._inventory_is_modified = False
1063
1087
 
1064
1088
    def _kind(self, relpath):
1225
1249
                                       DeprecationWarning)
1226
1250
 
1227
1251
        # check destination directory
1228
 
        if isinstance(from_paths, basestring):
1229
 
            raise ValueError()
 
1252
        assert not isinstance(from_paths, basestring)
1230
1253
        inv = self.inventory
1231
1254
        to_abs = self.abspath(to_dir)
1232
1255
        if not isdir(to_abs):
1496
1519
            # - RBC 20060907
1497
1520
            self._write_inventory(self._inventory)
1498
1521
    
 
1522
    @deprecated_method(zero_eight)
 
1523
    def iter_conflicts(self):
 
1524
        """List all files in the tree that have text or content conflicts.
 
1525
        DEPRECATED.  Use conflicts instead."""
 
1526
        return self._iter_conflicts()
 
1527
 
1499
1528
    def _iter_conflicts(self):
1500
1529
        conflicted = set()
1501
1530
        for info in self.list_files():
1592
1621
                if subf == '.bzr':
1593
1622
                    continue
1594
1623
                if subf not in dir_entry.children:
1595
 
                    try:
1596
 
                        (subf_norm,
1597
 
                         can_access) = osutils.normalized_filename(subf)
1598
 
                    except UnicodeDecodeError:
1599
 
                        path_os_enc = path.encode(osutils._fs_enc)
1600
 
                        relpath = path_os_enc + '/' + subf
1601
 
                        raise errors.BadFilenameEncoding(relpath,
1602
 
                                                         osutils._fs_enc)
 
1624
                    subf_norm, can_access = osutils.normalized_filename(subf)
1603
1625
                    if subf_norm != subf and can_access:
1604
1626
                        if subf_norm not in dir_entry.children:
1605
1627
                            fl.append(subf_norm)
1660
1682
    def kind(self, file_id):
1661
1683
        return file_kind(self.id2abspath(file_id))
1662
1684
 
1663
 
    def stored_kind(self, file_id):
1664
 
        """See Tree.stored_kind"""
1665
 
        return self.inventory[file_id].kind
1666
 
 
1667
1685
    def _comparison_data(self, entry, path):
1668
1686
        abspath = self.abspath(path)
1669
1687
        try:
1751
1769
    def _reset_data(self):
1752
1770
        """Reset transient data that cannot be revalidated."""
1753
1771
        self._inventory_is_modified = False
1754
 
        result = self._deserialize(self._transport.get('inventory'))
 
1772
        result = self._deserialize(self._control_files.get('inventory'))
1755
1773
        self._set_inventory(result, dirty=False)
1756
1774
 
1757
1775
    @needs_tree_write_lock
1778
1796
 
1779
1797
    def _write_basis_inventory(self, xml):
1780
1798
        """Write the basis inventory XML to the basis-inventory file"""
 
1799
        assert isinstance(xml, str), 'serialised xml must be bytestring.'
1781
1800
        path = self._basis_inventory_name()
1782
1801
        sio = StringIO(xml)
1783
 
        self._transport.put_file(path, sio,
1784
 
            mode=self._control_files._file_mode)
 
1802
        self._control_files.put(path, sio)
1785
1803
 
1786
1804
    def _create_basis_xml_from_inventory(self, revision_id, inventory):
1787
1805
        """Create the text that will be saved in basis-inventory"""
1818
1836
    def read_basis_inventory(self):
1819
1837
        """Read the cached basis inventory."""
1820
1838
        path = self._basis_inventory_name()
1821
 
        return self._transport.get_bytes(path)
 
1839
        return self._control_files.get(path).read()
1822
1840
        
1823
1841
    @needs_read_lock
1824
1842
    def read_working_inventory(self):
1833
1851
        # binary.
1834
1852
        if self._inventory_is_modified:
1835
1853
            raise errors.InventoryModified(self)
1836
 
        result = self._deserialize(self._transport.get('inventory'))
 
1854
        result = self._deserialize(self._control_files.get('inventory'))
1837
1855
        self._set_inventory(result, dirty=False)
1838
1856
        return result
1839
1857
 
1859
1877
            # Recurse directory and add all files
1860
1878
            # so we can check if they have changed.
1861
1879
            for parent_info, file_infos in\
1862
 
                self.walkdirs(directory):
1863
 
                for relpath, basename, kind, lstat, fileid, kind in file_infos:
 
1880
                osutils.walkdirs(self.abspath(directory),
 
1881
                    directory):
 
1882
                for relpath, basename, kind, lstat, abspath in file_infos:
1864
1883
                    # Is it versioned or ignored?
1865
1884
                    if self.path2id(relpath) or self.is_ignored(relpath):
1866
1885
                        # Add nested content for deletion.
1876
1895
            filename = self.relpath(abspath)
1877
1896
            if len(filename) > 0:
1878
1897
                new_files.add(filename)
1879
 
                recurse_directory_to_add_files(filename)
 
1898
                if osutils.isdir(abspath):
 
1899
                    recurse_directory_to_add_files(filename)
1880
1900
 
1881
1901
        files = list(new_files)
1882
1902
 
1891
1911
            has_changed_files = len(unknown_nested_files) > 0
1892
1912
            if not has_changed_files:
1893
1913
                for (file_id, path, content_change, versioned, parent_id, name,
1894
 
                     kind, executable) in self.iter_changes(self.basis_tree(),
 
1914
                     kind, executable) in self._iter_changes(self.basis_tree(),
1895
1915
                         include_unchanged=True, require_versioned=False,
1896
1916
                         want_unversioned=True, specific_files=files):
1897
1917
                    if versioned == (False, False):
1900
1920
                            # ... but not ignored
1901
1921
                            has_changed_files = True
1902
1922
                            break
1903
 
                    elif content_change and (kind[1] is not None):
 
1923
                    elif content_change and (kind[1] != None):
1904
1924
                        # Versioned and changed, but not deleted
1905
1925
                        has_changed_files = True
1906
1926
                        break
2046
2066
        """Set the root id for this tree."""
2047
2067
        # for compatability 
2048
2068
        if file_id is None:
2049
 
            raise ValueError(
2050
 
                'WorkingTree.set_root_id with fileid=None')
2051
 
        file_id = osutils.safe_file_id(file_id)
 
2069
            symbol_versioning.warn(symbol_versioning.zero_twelve
 
2070
                % 'WorkingTree.set_root_id with fileid=None',
 
2071
                DeprecationWarning,
 
2072
                stacklevel=3)
 
2073
            file_id = ROOT_ID
 
2074
        else:
 
2075
            file_id = osutils.safe_file_id(file_id)
2052
2076
        self._set_root_id(file_id)
2053
2077
 
2054
2078
    def _set_root_id(self, file_id):
2113
2137
          basis.
2114
2138
        - Do a 'normal' merge of the old branch basis if it is relevant.
2115
2139
        """
2116
 
        if self.branch.get_bound_location() is not None:
 
2140
        if self.branch.get_master_branch(possible_transports) is not None:
2117
2141
            self.lock_write()
2118
2142
            update_branch = True
2119
2143
        else:
2416
2440
                relroot = ""
2417
2441
            # FIXME: stash the node in pending
2418
2442
            entry = inv[top_id]
2419
 
            if entry.kind == 'directory':
2420
 
                for name, child in entry.sorted_children():
2421
 
                    dirblock.append((relroot + name, name, child.kind, None,
2422
 
                        child.file_id, child.kind
2423
 
                        ))
 
2443
            for name, child in entry.sorted_children():
 
2444
                dirblock.append((relroot + name, name, child.kind, None,
 
2445
                    child.file_id, child.kind
 
2446
                    ))
2424
2447
            yield (currentdir[0], entry.file_id), dirblock
2425
2448
            # push the user specified dirs from dirblock
2426
2449
            for dir in reversed(dirblock):
2459
2482
        self.set_conflicts(un_resolved)
2460
2483
        return un_resolved, resolved
2461
2484
 
2462
 
    @needs_read_lock
2463
 
    def _check(self):
2464
 
        tree_basis = self.basis_tree()
2465
 
        tree_basis.lock_read()
2466
 
        try:
2467
 
            repo_basis = self.branch.repository.revision_tree(
2468
 
                self.last_revision())
2469
 
            if len(list(repo_basis.iter_changes(tree_basis))) > 0:
2470
 
                raise errors.BzrCheckError(
2471
 
                    "Mismatched basis inventory content.")
2472
 
            self._validate()
2473
 
        finally:
2474
 
            tree_basis.unlock()
2475
 
 
2476
2485
    def _validate(self):
2477
2486
        """Validate internal structures.
2478
2487
 
2484
2493
        """
2485
2494
        return
2486
2495
 
2487
 
    @needs_read_lock
2488
 
    def _get_rules_searcher(self, default_searcher):
2489
 
        """See Tree._get_rules_searcher."""
2490
 
        if self._rules_searcher is None:
2491
 
            self._rules_searcher = super(WorkingTree,
2492
 
                self)._get_rules_searcher(default_searcher)
2493
 
        return self._rules_searcher
2494
 
 
2495
2496
 
2496
2497
class WorkingTree2(WorkingTree):
2497
2498
    """This is the Format 2 working tree.
2557
2558
    def _last_revision(self):
2558
2559
        """See Mutable.last_revision."""
2559
2560
        try:
2560
 
            return self._transport.get_bytes('last-revision')
 
2561
            return self._control_files.get('last-revision').read()
2561
2562
        except errors.NoSuchFile:
2562
2563
            return _mod_revision.NULL_REVISION
2563
2564
 
2565
2566
        """See WorkingTree._change_last_revision."""
2566
2567
        if revision_id is None or revision_id == NULL_REVISION:
2567
2568
            try:
2568
 
                self._transport.delete('last-revision')
 
2569
                self._control_files._transport.delete('last-revision')
2569
2570
            except errors.NoSuchFile:
2570
2571
                pass
2571
2572
            return False
2572
2573
        else:
2573
 
            self._transport.put_bytes('last-revision', revision_id,
2574
 
                mode=self._control_files._file_mode)
 
2574
            self._control_files.put_bytes('last-revision', revision_id)
2575
2575
            return True
2576
2576
 
2577
2577
    @needs_tree_write_lock
2589
2589
    @needs_read_lock
2590
2590
    def conflicts(self):
2591
2591
        try:
2592
 
            confile = self._transport.get('conflicts')
 
2592
            confile = self._control_files.get('conflicts')
2593
2593
        except errors.NoSuchFile:
2594
2594
            return _mod_conflicts.ConflictList()
2595
2595
        try:
2620
2620
            return path[:-len(suffix)]
2621
2621
 
2622
2622
 
 
2623
@deprecated_function(zero_eight)
 
2624
def is_control_file(filename):
 
2625
    """See WorkingTree.is_control_filename(filename)."""
 
2626
    ## FIXME: better check
 
2627
    filename = normpath(filename)
 
2628
    while filename != '':
 
2629
        head, tail = os.path.split(filename)
 
2630
        ## mutter('check %r for control file' % ((head, tail),))
 
2631
        if tail == '.bzr':
 
2632
            return True
 
2633
        if filename == head:
 
2634
            break
 
2635
        filename = head
 
2636
    return False
 
2637
 
 
2638
 
2623
2639
class WorkingTreeFormat(object):
2624
2640
    """An encapsulation of the initialization and open routines for a format.
2625
2641
 
2658
2674
        except errors.NoSuchFile:
2659
2675
            raise errors.NoWorkingTree(base=transport.base)
2660
2676
        except KeyError:
2661
 
            raise errors.UnknownFormatError(format=format_string,
2662
 
                                            kind="working tree")
 
2677
            raise errors.UnknownFormatError(format=format_string)
2663
2678
 
2664
2679
    def __eq__(self, other):
2665
2680
        return self.__class__ is other.__class__
2699
2714
 
2700
2715
    @classmethod
2701
2716
    def unregister_format(klass, format):
 
2717
        assert klass._formats[format.get_format_string()] is format
2702
2718
        del klass._formats[format.get_format_string()]
2703
2719
 
2704
2720
 
2714
2730
        """See WorkingTreeFormat.get_format_description()."""
2715
2731
        return "Working tree format 2"
2716
2732
 
2717
 
    def _stub_initialize_remote(self, branch):
2718
 
        """As a special workaround create critical control files for a remote working tree.
 
2733
    def stub_initialize_remote(self, control_files):
 
2734
        """As a special workaround create critical control files for a remote working tree
2719
2735
        
2720
2736
        This ensures that it can later be updated and dealt with locally,
2721
2737
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with 
2725
2741
        inv = Inventory()
2726
2742
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
2727
2743
        sio.seek(0)
2728
 
        branch._transport.put_file('inventory', sio,
2729
 
            mode=branch.control_files._file_mode)
2730
 
        branch._transport.put_bytes('pending-merges', '',
2731
 
            mode=branch.control_files._file_mode)
 
2744
        control_files.put('inventory', sio)
 
2745
 
 
2746
        control_files.put_bytes('pending-merges', '')
2732
2747
        
2733
2748
 
2734
2749
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2735
 
                   accelerator_tree=None, hardlink=False):
 
2750
                   accelerator_tree=None):
2736
2751
        """See WorkingTreeFormat.initialize()."""
2737
2752
        if not isinstance(a_bzrdir.transport, LocalTransport):
2738
2753
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
2825
2840
                             self._lock_class)
2826
2841
 
2827
2842
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2828
 
                   accelerator_tree=None, hardlink=False):
 
2843
                   accelerator_tree=None):
2829
2844
        """See WorkingTreeFormat.initialize().
2830
2845
        
2831
2846
        :param revision_id: if supplied, create a working tree at a different
2834
2849
            contents more quickly than the revision tree, i.e. a workingtree.
2835
2850
            The revision tree will be used for cases where accelerator_tree's
2836
2851
            content is different.
2837
 
        :param hardlink: If true, hard-link files from accelerator_tree,
2838
 
            where possible.
2839
2852
        """
2840
2853
        if not isinstance(a_bzrdir.transport, LocalTransport):
2841
2854
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
2843
2856
        control_files = self._open_control_files(a_bzrdir)
2844
2857
        control_files.create_lock()
2845
2858
        control_files.lock_write()
2846
 
        transport.put_bytes('format', self.get_format_string(),
2847
 
            mode=control_files._file_mode)
 
2859
        control_files.put_utf8('format', self.get_format_string())
2848
2860
        if from_branch is not None:
2849
2861
            branch = from_branch
2850
2862
        else: