~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

[merge] jam-integration 1495

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import bzrlib.inventory as inventory
28
28
from bzrlib.trace import mutter, note
29
29
from bzrlib.osutils import (isdir, quotefn,
30
 
                            rename, splitpath, sha_file, appendpath, 
31
 
                            file_kind, abspath)
 
30
                            rename, splitpath, sha_file,
 
31
                            file_kind, abspath, normpath, pathjoin)
32
32
import bzrlib.errors as errors
33
33
from bzrlib.errors import (BzrError, InvalidRevisionNumber, InvalidRevisionId,
34
34
                           NoSuchRevision, HistoryMissing, NotBranchError,
133
133
        while True:
134
134
            try:
135
135
                return BzrBranch(t), t.relpath(url)
136
 
            except NotBranchError:
137
 
                pass
 
136
            except NotBranchError, e:
 
137
                mutter('not a branch in: %r %s', t.base, e)
138
138
            new_t = t.clone('..')
139
139
            if new_t.base == t.base:
140
140
                # reached the root, whatever that may be
518
518
    _lock = None
519
519
    _inventory_weave = None
520
520
    _master_branch = None
 
521
    # If set to False (by a plugin, etc) BzrBranch will not set the
 
522
    # mode on created files or directories
 
523
    _set_file_mode = True
 
524
    _set_dir_mode = True
521
525
    
522
526
    # Map some sort of prefix into a namespace
523
527
    # stuff like "revno:10", "revid:", etc.
568
572
        if init:
569
573
            self._make_control()
570
574
        self._check_format(relax_version_check)
 
575
        self._find_modes()
571
576
 
572
577
        def get_store(name, compressed=True, prefixed=False):
573
 
            # FIXME: This approach of assuming stores are all entirely compressed
574
 
            # or entirely uncompressed is tidy, but breaks upgrade from 
575
 
            # some existing branches where there's a mixture; we probably 
576
 
            # still want the option to look for both.
577
578
            relpath = self._rel_controlfilename(unicode(name))
578
579
            store = TextStore(self._transport.clone(relpath),
 
580
                              dir_mode=self._dir_mode,
 
581
                              file_mode=self._file_mode,
579
582
                              prefixed=prefixed,
580
583
                              compressed=compressed)
581
 
            #if self._transport.should_cache():
582
 
            #    cache_path = os.path.join(self.cache_root, name)
583
 
            #    os.mkdir(cache_path)
584
 
            #    store = bzrlib.store.CachedStore(store, cache_path)
585
584
            return store
586
585
 
587
586
        def get_weave(name, prefixed=False):
588
587
            relpath = self._rel_controlfilename(unicode(name))
589
 
            ws = WeaveStore(self._transport.clone(relpath), prefixed=prefixed)
 
588
            ws = WeaveStore(self._transport.clone(relpath),
 
589
                            prefixed=prefixed,
 
590
                            dir_mode=self._dir_mode,
 
591
                            file_mode=self._file_mode)
590
592
            if self._transport.should_cache():
591
593
                ws.enable_cache = True
592
594
            return ws
760
762
                    f = codecs.getwriter('utf-8')(f, errors='replace')
761
763
            path = self._rel_controlfilename(path)
762
764
            ctrl_files.append((path, f))
763
 
        self._transport.put_multi(ctrl_files)
 
765
        self._transport.put_multi(ctrl_files, mode=self._file_mode)
 
766
 
 
767
    def _find_modes(self, path=None):
 
768
        """Determine the appropriate modes for files and directories."""
 
769
        try:
 
770
            if path is None:
 
771
                path = self._rel_controlfilename('')
 
772
            st = self._transport.stat(path)
 
773
        except errors.TransportNotPossible:
 
774
            self._dir_mode = 0755
 
775
            self._file_mode = 0644
 
776
        else:
 
777
            self._dir_mode = st.st_mode & 07777
 
778
            # Remove the sticky and execute bits for files
 
779
            self._file_mode = self._dir_mode & ~07111
 
780
        if not self._set_dir_mode:
 
781
            self._dir_mode = None
 
782
        if not self._set_file_mode:
 
783
            self._file_mode = None
764
784
 
765
785
    def _make_control(self):
766
786
        from bzrlib.inventory import Inventory
778
798
        bzrlib.weavefile.write_weave_v5(Weave(), sio)
779
799
        empty_weave = sio.getvalue()
780
800
 
781
 
        dirs = [[], 'revision-store', 'weaves']
 
801
        cfn = self._rel_controlfilename
 
802
        # Since we don't have a .bzr directory, inherit the
 
803
        # mode from the root directory
 
804
        self._find_modes(u'.')
 
805
 
 
806
        dirs = ['', 'revision-store', 'weaves']
782
807
        files = [('README', 
783
808
            "This is a Bazaar-NG control directory.\n"
784
809
            "Do not change any files in this directory.\n"),
791
816
            ('inventory.weave', empty_weave),
792
817
            ('ancestry.weave', empty_weave)
793
818
        ]
794
 
        cfn = self._rel_controlfilename
795
 
        self._transport.mkdir_multi([cfn(d) for d in dirs])
 
819
        self._transport.mkdir_multi([cfn(d) for d in dirs], mode=self._dir_mode)
796
820
        self.put_controlfiles(files)
797
821
        mutter('created control directory in ' + self._transport.base)
798
822
 
1025
1049
            return EmptyTree()
1026
1050
        else:
1027
1051
            inv = self.get_revision_inventory(revision_id)
1028
 
            return RevisionTree(self.weave_store, inv, revision_id)
 
1052
            return RevisionTree(self, inv, revision_id)
1029
1053
 
1030
1054
    def basis_tree(self):
1031
1055
        """See Branch.basis_tree."""
1033
1057
            revision_id = self.revision_history()[-1]
1034
1058
            xml = self.working_tree().read_basis_inventory(revision_id)
1035
1059
            inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
1036
 
            return RevisionTree(self.weave_store, inv, revision_id)
 
1060
            return RevisionTree(self, inv, revision_id)
1037
1061
        except (IndexError, NoSuchFile, NoWorkingTree), e:
1038
1062
            return self.revision_tree(self.last_revision())
1039
1063
 
1283
1307
        ...   orig.base == clone.base
1284
1308
        ...
1285
1309
        False
1286
 
        >>> os.path.isfile(os.path.join(clone.base, "file1"))
 
1310
        >>> os.path.isfile(pathjoin(clone.base, "file1"))
1287
1311
        True
1288
1312
        """
1289
1313
        from shutil import copytree
1290
 
        from tempfile import mkdtemp
 
1314
        from bzrlib.osutils import mkdtemp
1291
1315
        base = mkdtemp()
1292
1316
        os.rmdir(base)
1293
1317
        copytree(self.base, base, symlinks=True)
1301
1325
 
1302
1326
def is_control_file(filename):
1303
1327
    ## FIXME: better check
1304
 
    filename = os.path.normpath(filename)
 
1328
    filename = normpath(filename)
1305
1329
    while filename != '':
1306
1330
        head, tail = os.path.split(filename)
1307
1331
        ## mutter('check %r for control file' % ((head, tail), ))