13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""WorkingTree object and friends.
230
235
wt_trans = self.bzrdir.get_workingtree_transport(None)
231
236
cache_filename = wt_trans.local_abspath('stat-cache')
232
237
self._hashcache = hashcache.HashCache(basedir, cache_filename,
233
self.bzrdir._get_file_mode())
238
self.bzrdir._get_file_mode(),
239
self._content_filter_stack_provider())
234
240
hc = self._hashcache
236
242
# is this scan needed ? it makes things kinda slow.
413
419
return self.branch.repository.revision_tree(revision_id)
414
420
except (errors.RevisionNotPresent, errors.NoSuchRevision):
415
421
# the basis tree *may* be a ghost or a low level error may have
416
# occured. If the revision is present, its a problem, if its not
422
# occurred. If the revision is present, its a problem, if its not
418
424
if self.branch.repository.has_revision(revision_id):
435
441
def has_filename(self, filename):
436
442
return osutils.lexists(self.abspath(filename))
438
def get_file(self, file_id, path=None):
439
return self.get_file_with_stat(file_id, path)[0]
444
def get_file(self, file_id, path=None, filtered=True):
445
return self.get_file_with_stat(file_id, path, filtered=filtered)[0]
441
def get_file_with_stat(self, file_id, path=None, _fstat=os.fstat):
447
def get_file_with_stat(self, file_id, path=None, filtered=True,
442
449
"""See MutableTree.get_file_with_stat."""
444
451
path = self.id2path(file_id)
445
file_obj = self.get_file_byname(path)
446
return (file_obj, _fstat(file_obj.fileno()))
448
def get_file_byname(self, filename):
449
return file(self.abspath(filename), 'rb')
451
def get_file_lines(self, file_id, path=None):
452
file_obj = self.get_file_byname(path, filtered=False)
453
stat_value = _fstat(file_obj.fileno())
454
if self.supports_content_filtering() and filtered:
455
filters = self._content_filter_stack(path)
456
file_obj = filtered_input_file(file_obj, filters)
457
return (file_obj, stat_value)
459
def get_file_text(self, file_id, path=None, filtered=True):
460
return self.get_file(file_id, path=path, filtered=filtered).read()
462
def get_file_byname(self, filename, filtered=True):
463
path = self.abspath(filename)
465
if self.supports_content_filtering() and filtered:
466
filters = self._content_filter_stack(filename)
467
return filtered_input_file(f, filters)
471
def get_file_lines(self, file_id, path=None, filtered=True):
452
472
"""See Tree.get_file_lines()"""
453
file = self.get_file(file_id, path)
473
file = self.get_file(file_id, path, filtered=filtered)
455
475
return file.readlines()
729
749
kind = 'tree-reference'
730
750
return kind, None, None, None
731
751
elif kind == 'symlink':
732
return ('symlink', None, None,
733
os.readlink(abspath.encode(osutils._fs_enc)
734
).decode(osutils._fs_enc))
752
target = osutils.readlink(abspath)
753
return ('symlink', None, None, target)
736
755
return (kind, None, None, None)
750
769
def _set_merges_from_parent_ids(self, parent_ids):
751
770
merges = parent_ids[1:]
752
771
self._transport.put_bytes('pending-merges', '\n'.join(merges),
753
mode=self._control_files._file_mode)
772
mode=self.bzrdir._get_file_mode())
755
774
def _filter_parent_ids_by_ancestry(self, revision_ids):
756
775
"""Check that all merged revisions are proper 'heads'.
856
875
self._must_be_locked()
857
876
my_file = rio_file(stanzas, header)
858
877
self._transport.put_file(filename, my_file,
859
mode=self._control_files._file_mode)
878
mode=self.bzrdir._get_file_mode())
861
880
@needs_write_lock # because merge pulls data into the branch.
862
881
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
1088
1109
self._serialize(self._inventory, sio)
1090
1111
self._transport.put_file('inventory', sio,
1091
mode=self._control_files._file_mode)
1112
mode=self.bzrdir._get_file_mode())
1092
1113
self._inventory_is_modified = False
1094
1115
def _kind(self, relpath):
1511
1532
:raises: NoSuchId if any fileid is not currently versioned.
1513
1534
for file_id in file_ids:
1535
if file_id not in self._inventory:
1536
raise errors.NoSuchId(self, file_id)
1537
for file_id in file_ids:
1514
1538
if self._inventory.has_id(file_id):
1515
1539
self._inventory.remove_recursive_id(file_id)
1517
raise errors.NoSuchId(self, file_id)
1518
1540
if len(file_ids):
1519
1541
# in the future this should just set a dirty bit to wait for the
1520
1542
# final unlock. However, until all methods of workingtree start
1540
1562
@needs_write_lock
1541
1563
def pull(self, source, overwrite=False, stop_revision=None,
1542
change_reporter=None, possible_transports=None):
1564
change_reporter=None, possible_transports=None, local=False):
1543
1565
top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1544
1566
source.lock_read()
1548
1570
old_revision_info = self.branch.last_revision_info()
1549
1571
basis_tree = self.basis_tree()
1550
1572
count = self.branch.pull(source, overwrite, stop_revision,
1551
possible_transports=possible_transports)
1573
possible_transports=possible_transports,
1552
1575
new_revision_info = self.branch.last_revision_info()
1553
1576
if new_revision_info != old_revision_info:
1554
1577
pp.next_phase()
1811
1834
path = self._basis_inventory_name()
1812
1835
sio = StringIO(xml)
1813
1836
self._transport.put_file(path, sio,
1814
mode=self._control_files._file_mode)
1837
mode=self.bzrdir._get_file_mode())
1816
1839
def _create_basis_xml_from_inventory(self, revision_id, inventory):
1817
1840
"""Create the text that will be saved in basis-inventory"""
1945
1968
tree_delta.unversioned.extend((unknown_file,))
1946
1969
raise errors.BzrRemoveChangedFilesError(tree_delta)
1948
# Build inv_delta and delete files where applicaple,
1971
# Build inv_delta and delete files where applicable,
1949
1972
# do this before any modifications to inventory.
1950
1973
for f in files:
1951
1974
fid = self.path2id(f)
2202
2225
parent_trees = [(self.branch.last_revision(), to_tree)]
2203
2226
merges = self.get_parent_ids()[1:]
2204
2227
# Ideally we ask the tree for the trees here, that way the working
2205
# tree can decide whether to give us teh entire tree or give us a
2228
# tree can decide whether to give us the entire tree or give us a
2206
2229
# lazy initialised tree. dirstate for instance will have the trees
2207
2230
# in ram already, whereas a last-revision + basis-inventory tree
2208
2231
# will not, but also does not need them when setting parents.
2351
2374
bzrdir_loc = bisect_left(cur_disk_dir_content,
2352
2375
('.bzr', '.bzr'))
2353
2376
if (bzrdir_loc < len(cur_disk_dir_content)
2354
and cur_disk_dir_content[bzrdir_loc][0] == '.bzr'):
2377
and self.bzrdir.is_control_filename(
2378
cur_disk_dir_content[bzrdir_loc][0])):
2355
2379
# we dont yield the contents of, or, .bzr itself.
2356
2380
del cur_disk_dir_content[bzrdir_loc]
2357
2381
if inv_finished:
2888
2912
control_files.create_lock()
2889
2913
control_files.lock_write()
2890
2914
transport.put_bytes('format', self.get_format_string(),
2891
mode=control_files._file_mode)
2915
mode=a_bzrdir._get_file_mode())
2892
2916
if from_branch is not None:
2893
2917
branch = from_branch