~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

Merge from integration.

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
155
155
 
156
156
    def _get_nick(self):
157
157
        cfg = self.tree_config()
158
 
        return cfg.get_option(u"nickname", default=self.base.split('/')[-1])
 
158
        return cfg.get_option(u"nickname", default=self.base.split('/')[-2])
159
159
 
160
160
    def _set_nick(self, nick):
161
161
        cfg = self.tree_config()
512
512
    _lock_count = None
513
513
    _lock = None
514
514
    _inventory_weave = None
 
515
    # If set to False (by a plugin, etc) BzrBranch will not set the
 
516
    # mode on created files or directories
 
517
    _set_file_mode = True
 
518
    _set_dir_mode = True
515
519
    
516
520
    # Map some sort of prefix into a namespace
517
521
    # stuff like "revno:10", "revid:", etc.
562
566
        if init:
563
567
            self._make_control()
564
568
        self._check_format(relax_version_check)
 
569
        self._find_modes()
565
570
 
566
571
        def get_store(name, compressed=True, prefixed=False):
567
 
            # FIXME: This approach of assuming stores are all entirely compressed
568
 
            # or entirely uncompressed is tidy, but breaks upgrade from 
569
 
            # some existing branches where there's a mixture; we probably 
570
 
            # still want the option to look for both.
571
572
            relpath = self._rel_controlfilename(unicode(name))
572
573
            store = TextStore(self._transport.clone(relpath),
 
574
                              dir_mode=self._dir_mode,
 
575
                              file_mode=self._file_mode,
573
576
                              prefixed=prefixed,
574
577
                              compressed=compressed)
575
 
            #if self._transport.should_cache():
576
 
            #    cache_path = os.path.join(self.cache_root, name)
577
 
            #    os.mkdir(cache_path)
578
 
            #    store = bzrlib.store.CachedStore(store, cache_path)
579
578
            return store
580
579
 
581
580
        def get_weave(name, prefixed=False):
582
581
            relpath = self._rel_controlfilename(unicode(name))
583
 
            ws = WeaveStore(self._transport.clone(relpath), prefixed=prefixed)
 
582
            ws = WeaveStore(self._transport.clone(relpath),
 
583
                            prefixed=prefixed,
 
584
                            dir_mode=self._dir_mode,
 
585
                            file_mode=self._file_mode)
584
586
            if self._transport.should_cache():
585
587
                ws.enable_cache = True
586
588
            return ws
753
755
                    f = codecs.getwriter('utf-8')(f, errors='replace')
754
756
            path = self._rel_controlfilename(path)
755
757
            ctrl_files.append((path, f))
756
 
        self._transport.put_multi(ctrl_files)
 
758
        self._transport.put_multi(ctrl_files, mode=self._file_mode)
 
759
 
 
760
    def _find_modes(self, path=None):
 
761
        """Determine the appropriate modes for files and directories."""
 
762
        try:
 
763
            if path is None:
 
764
                path = self._rel_controlfilename('')
 
765
            st = self._transport.stat(path)
 
766
        except errors.TransportNotPossible:
 
767
            self._dir_mode = 0755
 
768
            self._file_mode = 0644
 
769
        else:
 
770
            self._dir_mode = st.st_mode & 07777
 
771
            # Remove the sticky and execute bits for files
 
772
            self._file_mode = self._dir_mode & ~07111
 
773
        if not self._set_dir_mode:
 
774
            self._dir_mode = None
 
775
        if not self._set_file_mode:
 
776
            self._file_mode = None
757
777
 
758
778
    def _make_control(self):
759
779
        from bzrlib.inventory import Inventory
771
791
        bzrlib.weavefile.write_weave_v5(Weave(), sio)
772
792
        empty_weave = sio.getvalue()
773
793
 
774
 
        dirs = [[], 'revision-store', 'weaves']
 
794
        cfn = self._rel_controlfilename
 
795
        # Since we don't have a .bzr directory, inherit the
 
796
        # mode from the root directory
 
797
        self._find_modes(u'.')
 
798
 
 
799
        dirs = ['', 'revision-store', 'weaves']
775
800
        files = [('README', 
776
801
            "This is a Bazaar-NG control directory.\n"
777
802
            "Do not change any files in this directory.\n"),
784
809
            ('inventory.weave', empty_weave),
785
810
            ('ancestry.weave', empty_weave)
786
811
        ]
787
 
        cfn = self._rel_controlfilename
788
 
        self._transport.mkdir_multi([cfn(d) for d in dirs])
 
812
        self._transport.mkdir_multi([cfn(d) for d in dirs], mode=self._dir_mode)
789
813
        self.put_controlfiles(files)
790
814
        mutter('created control directory in ' + self._transport.base)
791
815
 
1006
1030
            return EmptyTree()
1007
1031
        else:
1008
1032
            inv = self.get_revision_inventory(revision_id)
1009
 
            return RevisionTree(self.weave_store, inv, revision_id)
 
1033
            return RevisionTree(self, inv, revision_id)
1010
1034
 
1011
1035
    def basis_tree(self):
1012
1036
        """See Branch.basis_tree."""
1014
1038
            revision_id = self.revision_history()[-1]
1015
1039
            xml = self.working_tree().read_basis_inventory(revision_id)
1016
1040
            inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
1017
 
            return RevisionTree(self.weave_store, inv, revision_id)
 
1041
            return RevisionTree(self, inv, revision_id)
1018
1042
        except (IndexError, NoSuchFile, NoWorkingTree), e:
1019
1043
            return self.revision_tree(self.last_revision())
1020
1044
 
1134
1158
        ...   orig.base == clone.base
1135
1159
        ...
1136
1160
        False
1137
 
        >>> os.path.isfile(os.path.join(clone.base, "file1"))
 
1161
        >>> os.path.isfile(pathjoin(clone.base, "file1"))
1138
1162
        True
1139
1163
        """
1140
1164
        from shutil import copytree
1141
 
        from tempfile import mkdtemp
 
1165
        from bzrlib.osutils import mkdtemp
1142
1166
        base = mkdtemp()
1143
1167
        os.rmdir(base)
1144
1168
        copytree(self.base, base, symlinks=True)
1152
1176
 
1153
1177
def is_control_file(filename):
1154
1178
    ## FIXME: better check
1155
 
    filename = os.path.normpath(filename)
 
1179
    filename = normpath(filename)
1156
1180
    while filename != '':
1157
1181
        head, tail = os.path.split(filename)
1158
1182
        ## mutter('check %r for control file' % ((head, tail), ))