/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

move move() from Branch to WorkingTree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
# copy, and making sure there's only one WorkingTree for any directory on disk.
43
43
# At the momenthey may alias the inventory and have old copies of it in memory.
44
44
 
 
45
from copy import deepcopy
45
46
import os
46
47
import stat
47
48
import fnmatch
500
501
            yield f
501
502
 
502
503
    @needs_write_lock
 
504
    def move(self, from_paths, to_name):
 
505
        """Rename files.
 
506
 
 
507
        to_name must exist in the inventory.
 
508
 
 
509
        If to_name exists and is a directory, the files are moved into
 
510
        it, keeping their old names.  
 
511
 
 
512
        Note that to_name is only the last component of the new name;
 
513
        this doesn't change the directory.
 
514
 
 
515
        This returns a list of (from_path, to_path) pairs for each
 
516
        entry that is moved.
 
517
        """
 
518
        result = []
 
519
        ## TODO: Option to move IDs only
 
520
        assert not isinstance(from_paths, basestring)
 
521
        inv = self.inventory
 
522
        to_abs = self.abspath(to_name)
 
523
        if not isdir(to_abs):
 
524
            raise BzrError("destination %r is not a directory" % to_abs)
 
525
        if not self.has_filename(to_name):
 
526
            raise BzrError("destination %r not in working directory" % to_abs)
 
527
        to_dir_id = inv.path2id(to_name)
 
528
        if to_dir_id == None and to_name != '':
 
529
            raise BzrError("destination %r is not a versioned directory" % to_name)
 
530
        to_dir_ie = inv[to_dir_id]
 
531
        if to_dir_ie.kind not in ('directory', 'root_directory'):
 
532
            raise BzrError("destination %r is not a directory" % to_abs)
 
533
 
 
534
        to_idpath = inv.get_idpath(to_dir_id)
 
535
 
 
536
        for f in from_paths:
 
537
            if not self.has_filename(f):
 
538
                raise BzrError("%r does not exist in working tree" % f)
 
539
            f_id = inv.path2id(f)
 
540
            if f_id == None:
 
541
                raise BzrError("%r is not versioned" % f)
 
542
            name_tail = splitpath(f)[-1]
 
543
            dest_path = appendpath(to_name, name_tail)
 
544
            if self.has_filename(dest_path):
 
545
                raise BzrError("destination %r already exists" % dest_path)
 
546
            if f_id in to_idpath:
 
547
                raise BzrError("can't move %r to a subdirectory of itself" % f)
 
548
 
 
549
        # OK, so there's a race here, it's possible that someone will
 
550
        # create a file in this interval and then the rename might be
 
551
        # left half-done.  But we should have caught most problems.
 
552
        orig_inv = deepcopy(self.inventory)
 
553
        try:
 
554
            for f in from_paths:
 
555
                name_tail = splitpath(f)[-1]
 
556
                dest_path = appendpath(to_name, name_tail)
 
557
                result.append((f, dest_path))
 
558
                inv.rename(inv.path2id(f), to_dir_id, name_tail)
 
559
                try:
 
560
                    rename(self.abspath(f), self.abspath(dest_path))
 
561
                except OSError, e:
 
562
                    raise BzrError("failed to rename %r to %r: %s" %
 
563
                                   (f, dest_path, e[1]),
 
564
                            ["rename rolled back"])
 
565
        except:
 
566
            # restore the inventory on error
 
567
            self._inventory = orig_inv
 
568
            raise
 
569
        self._write_inventory(inv)
 
570
        return result
 
571
 
 
572
    @needs_write_lock
503
573
    def rename_one(self, from_rel, to_rel):
504
574
        """Rename one file.
505
575