25
# If set to False (by a plugin, etc) BzrBranch will not set the
26
# mode on created files or directories
26
def __init__(self, transport, base, lock_name):
30
def __init__(self, transport, lock_name):
27
31
object.__init__(self)
28
32
self._transport = transport
30
33
self.lock_name = lock_name
31
34
self._transaction = None
34
38
if self._lock_mode or self._lock:
38
42
warn("file group %r was not explicitly unlocked" % self)
39
43
self._lock.unlock()
41
def _rel_controlfilename(self, file_or_path):
45
def _escape(self, file_or_path):
42
46
if not isinstance(file_or_path, basestring):
43
47
file_or_path = '/'.join(file_or_path)
44
48
if file_or_path == '':
45
return unicode(self.base)
46
return bzrlib.transport.urlescape(unicode(self.base + '/' +
50
return bzrlib.transport.urlescape(unicode(file_or_path))
52
def _find_modes(self):
53
"""Determine the appropriate modes for files and directories."""
56
st = self._transport.stat(u'.')
57
except errors.NoSuchFile:
58
# The .bzr/ directory doesn't exist, try to
59
# inherit the permissions from the parent directory
60
# but only try 1 level up
61
temp_transport = self._transport.clone('..')
62
st = temp_transport.stat(u'.')
63
except (errors.TransportNotPossible, errors.NoSuchFile):
65
self._file_mode = 0644
67
self._dir_mode = st.st_mode & 07777
68
# Remove the sticky and execute bits for files
69
self._file_mode = self._dir_mode & ~07111
70
if not self._set_dir_mode:
72
if not self._set_file_mode:
73
self._file_mode = None
49
75
def controlfilename(self, file_or_path):
50
76
"""Return location relative to branch."""
51
return self._transport.abspath(self._rel_controlfilename(file_or_path))
77
return self._transport.abspath(self._escape(file_or_path))
53
79
def controlfile(self, file_or_path, mode='r'):
54
80
"""Open a control file for this branch.
66
relpath = self._rel_controlfilename(file_or_path)
92
relpath = self._escape(file_or_path)
67
93
#TODO: codecs.open() buffers linewise, so it was overloaded with
68
94
# a much larger buffer, do we need to do the same for getreader/getwriter?
91
117
if not self._lock_mode == 'w':
92
118
raise ReadOnlyError()
93
self._transport.put(self._rel_controlfilename(path), file)
119
self._transport.put(self._escape(path), file, mode=self._file_mode)
95
121
def put_utf8(self, path, file, mode=None):
96
122
"""Write a file, encoding as utf-8.
110
136
# instead of files. ADHB 2005-12-25
111
137
# RBC 20060103 surely its not needed anyway, with codecs transcode
113
encoded_file = IterableFile(b.encode('utf-8', 'replace') for b in
139
# JAM 20060103 We definitely don't want encode(..., 'replace')
140
# these are valuable files which should have exact contents.
141
encoded_file = IterableFile(b.encode('utf-8') for b in
115
143
self.put(path, encoded_file)