~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

partial merge from Martin, fixed conflicts with bzrlib/tree.py and revno 1391

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 
49
49
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock, quotefn
50
50
import bzrlib.tree
51
 
from bzrlib.osutils import appendpath, file_kind, isdir, splitpath, relpath
 
51
from bzrlib.osutils import (appendpath,
 
52
                            file_kind,
 
53
                            isdir,
 
54
                            pumpfile,
 
55
                            splitpath,
 
56
                            relpath)
52
57
from bzrlib.errors import BzrCheckError, DivergedBranches, NotVersionedError
53
58
from bzrlib.trace import mutter
54
59
import bzrlib.xml5
197
202
        ## XXX: badly named; this isn't in the store at all
198
203
        return self.abspath(self.id2path(file_id))
199
204
 
 
205
    @needs_write_lock
 
206
    def commit(self, *args, **kw):
 
207
        from bzrlib.commit import Commit
 
208
        Commit().commit(self.branch, *args, **kw)
 
209
        self._inventory = self.read_working_inventory()
200
210
 
201
211
    def id2abspath(self, file_id):
202
212
        return self.abspath(self.id2path(file_id))
234
244
            mode = os.lstat(self.abspath(path)).st_mode
235
245
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC&mode)
236
246
 
 
247
    @needs_write_lock
 
248
    def add_pending_merge(self, *revision_ids):
 
249
        # TODO: Perhaps should check at this point that the
 
250
        # history of the revision is actually present?
 
251
        p = self.pending_merges()
 
252
        updated = False
 
253
        for rev_id in revision_ids:
 
254
            if rev_id in p:
 
255
                continue
 
256
            p.append(rev_id)
 
257
            updated = True
 
258
        if updated:
 
259
            self.set_pending_merges(p)
 
260
 
 
261
    def pending_merges(self):
 
262
        """Return a list of pending merges.
 
263
 
 
264
        These are revisions that have been merged into the working
 
265
        directory but not yet committed.
 
266
        """
 
267
        cfn = self.branch._rel_controlfilename('pending-merges')
 
268
        if not self.branch._transport.has(cfn):
 
269
            return []
 
270
        p = []
 
271
        for l in self.branch.controlfile('pending-merges', 'r').readlines():
 
272
            p.append(l.rstrip('\n'))
 
273
        return p
 
274
 
 
275
    @needs_write_lock
 
276
    def set_pending_merges(self, rev_list):
 
277
        self.branch.put_controlfile('pending-merges', '\n'.join(rev_list))
 
278
 
237
279
    def get_symlink_target(self, file_id):
238
280
        return os.readlink(self.id2abspath(file_id))
239
281
 
365
407
        """
366
408
        ## TODO: Work from given directory downwards
367
409
        for path, dir_entry in self.inventory.directories():
368
 
            mutter("search for unknowns in %r" % path)
 
410
            mutter("search for unknowns in %r", path)
369
411
            dirabs = self.abspath(path)
370
412
            if not isdir(dirabs):
371
413
                # e.g. directory deleted
493
535
                # TODO: Perhaps make this just a warning, and continue?
494
536
                # This tends to happen when 
495
537
                raise NotVersionedError(path=f)
496
 
            mutter("remove inventory entry %s {%s}" % (quotefn(f), fid))
 
538
            mutter("remove inventory entry %s {%s}", quotefn(f), fid)
497
539
            if verbose:
498
540
                # having remove it, it must be either ignored or unknown
499
541
                if self.is_ignored(f):
503
545
                show_status(new_status, inv[fid].kind, quotefn(f))
504
546
            del inv[fid]
505
547
 
506
 
        self.branch._write_inventory(inv)
 
548
        self._write_inventory(inv)
 
549
 
 
550
    @needs_write_lock
 
551
    def revert(self, filenames, old_tree=None, backups=True):
 
552
        from bzrlib.merge import merge_inner
 
553
        if old_tree is None:
 
554
            old_tree = self.branch.basis_tree()
 
555
        merge_inner(self.branch, old_tree,
 
556
                    self, ignore_zero=True,
 
557
                    backup_files=backups, 
 
558
                    interesting_files=filenames)
 
559
        if not len(filenames):
 
560
            self.set_pending_merges([])
507
561
 
508
562
    @needs_write_lock
509
563
    def set_inventory(self, new_inventory_list):
526
580
                inv.add(InventoryLink(file_id, name, parent))
527
581
            else:
528
582
                raise BzrError("unknown kind %r" % kind)
529
 
        self.branch._write_inventory(inv)
 
583
        self._write_inventory(inv)
 
584
 
 
585
    @needs_write_lock
 
586
    def set_root_id(self, file_id):
 
587
        """Set the root id for this tree."""
 
588
        inv = self.read_working_inventory()
 
589
        orig_root_id = inv.root.file_id
 
590
        del inv._byid[inv.root.file_id]
 
591
        inv.root.file_id = file_id
 
592
        inv._byid[inv.root.file_id] = inv.root
 
593
        for fid in inv:
 
594
            entry = inv[fid]
 
595
            if entry.parent_id in (None, orig_root_id):
 
596
                entry.parent_id = inv.root.file_id
 
597
        self._write_inventory(inv)
530
598
 
531
599
    def unlock(self):
532
600
        """See Branch.unlock.
539
607
        """
540
608
        return self.branch.unlock()
541
609
 
 
610
    @needs_write_lock
 
611
    def _write_inventory(self, inv):
 
612
        """Write inventory as the current inventory."""
 
613
        from cStringIO import StringIO
 
614
        from bzrlib.atomicfile import AtomicFile
 
615
        sio = StringIO()
 
616
        bzrlib.xml5.serializer_v5.write_inventory(inv, sio)
 
617
        sio.seek(0)
 
618
        f = AtomicFile(self.branch.controlfilename('inventory'))
 
619
        try:
 
620
            pumpfile(sio, f)
 
621
            f.commit()
 
622
        finally:
 
623
            f.close()
 
624
        mutter('wrote working inventory')
 
625
            
542
626
 
543
627
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
544
628
def get_conflicted_stem(path):