49
49
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock, quotefn
51
from bzrlib.osutils import appendpath, file_kind, isdir, splitpath, relpath
51
from bzrlib.osutils import (appendpath,
52
57
from bzrlib.errors import BzrCheckError, DivergedBranches, NotVersionedError
53
58
from bzrlib.trace import mutter
234
239
mode = os.lstat(self.abspath(path)).st_mode
235
240
return bool(stat.S_ISREG(mode) and stat.S_IEXEC&mode)
243
def add_pending_merge(self, *revision_ids):
244
# TODO: Perhaps should check at this point that the
245
# history of the revision is actually present?
246
p = self.pending_merges()
248
for rev_id in revision_ids:
254
self.set_pending_merges(p)
256
def pending_merges(self):
257
"""Return a list of pending merges.
259
These are revisions that have been merged into the working
260
directory but not yet committed.
262
cfn = self.branch._rel_controlfilename('pending-merges')
263
if not self.branch._transport.has(cfn):
266
for l in self.branch.controlfile('pending-merges', 'r').readlines():
267
p.append(l.rstrip('\n'))
271
def set_pending_merges(self, rev_list):
272
self.branch.put_controlfile('pending-merges', '\n'.join(rev_list))
237
274
def get_symlink_target(self, file_id):
238
275
return os.readlink(self.id2abspath(file_id))
503
540
show_status(new_status, inv[fid].kind, quotefn(f))
506
self.branch._write_inventory(inv)
543
self._write_inventory(inv)
508
545
@needs_write_lock
509
546
def revert(self, filenames, old_tree=None, backups=True):
510
"""Restore selected files to the versions from a previous tree.
513
If true (default) backups are made of files before
516
from bzrlib.atomicfile import AtomicFile
517
from bzrlib.osutils import backup_file
519
inv = self.read_working_inventory()
547
from bzrlib.merge import merge_inner
520
548
if old_tree is None:
521
549
old_tree = self.branch.basis_tree()
522
old_inv = old_tree.inventory
526
file_id = inv.path2id(fn)
528
raise NotVersionedError(path=fn)
529
if not old_inv.has_id(file_id):
530
raise BzrError("file not present in old tree", fn, file_id)
531
nids.append((fn, file_id))
533
# TODO: Rename back if it was previously at a different location
535
# TODO: If given a directory, restore the entire contents from
536
# the previous version.
538
# TODO: Make a backup to a temporary file.
540
# TODO: If the file previously didn't exist, delete it?
541
for fn, file_id in nids:
544
f = AtomicFile(fn, 'wb')
546
f.write(old_tree.get_file(file_id).read())
550
merge_inner(self.branch, old_tree,
551
self, ignore_zero=True,
552
backup_files=backups,
553
interesting_files=filenames)
554
if not len(filenames):
555
self.set_pending_merges([])
551
557
@needs_write_lock
552
558
def set_inventory(self, new_inventory_list):
569
575
inv.add(InventoryLink(file_id, name, parent))
571
577
raise BzrError("unknown kind %r" % kind)
572
self.branch._write_inventory(inv)
578
self._write_inventory(inv)
581
def set_root_id(self, file_id):
582
"""Set the root id for this tree."""
583
inv = self.read_working_inventory()
584
orig_root_id = inv.root.file_id
585
del inv._byid[inv.root.file_id]
586
inv.root.file_id = file_id
587
inv._byid[inv.root.file_id] = inv.root
590
if entry.parent_id in (None, orig_root_id):
591
entry.parent_id = inv.root.file_id
592
self._write_inventory(inv)
574
594
def unlock(self):
575
595
"""See Branch.unlock.
583
603
return self.branch.unlock()
606
def _write_inventory(self, inv):
607
"""Write inventory as the current inventory."""
608
from cStringIO import StringIO
609
from bzrlib.atomicfile import AtomicFile
611
bzrlib.xml5.serializer_v5.write_inventory(inv, sio)
613
f = AtomicFile(self.branch.controlfilename('inventory'))
619
mutter('wrote working inventory')
586
622
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
587
623
def get_conflicted_stem(path):