~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Marius Kruger
  • Date: 2007-04-16 01:00:20 UTC
  • mto: This revision was merged to the branch mainline in revision 2455.
  • Revision ID: amanic@gmail.com-20070416010020-3jan8hje4qmbwdsh
* Add utility method delta.get_changes_as_text to get the output of .show()
  as a string.
* Add new errors.BzrRemoveChangedFilesError to raise when 'bzr remove'
  should refuse to delete stuff.
* Add workingtree.canicalpath(filename) to normalize file names.
* Changed the working of workingtree.remove(...) to check if any files
  are changed before it starts deleting anything. Will raise exception
  now if changed files are passed to be removed.
* workingtree_implementations/test_remove.py
  - Checked all tests and add more cases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
363
363
    def abspath(self, filename):
364
364
        return pathjoin(self.basedir, filename)
365
365
    
 
366
    def canonicalpath(self, filename):
 
367
        """Normanize filename"""
 
368
        return self.relpath(self.abspath(filename))
 
369
    
366
370
    def basis_tree(self):
367
371
        """Return RevisionTree for the current last revision.
368
372
        
1779
1783
            files = [files]
1780
1784
 
1781
1785
        inv = self.inventory
1782
 
        changed_files=[]
1783
 
 
1784
 
        # Get file names into canonical form.
1785
 
        files = [self.relpath(self.abspath(filename))
1786
 
            for filename in files]
 
1786
 
 
1787
        new_files=set()
 
1788
        unknown_files_in_directory=set()
 
1789
 
 
1790
        def recurse_directory_to_add_files(directory):
 
1791
            # recurse directory and add all files 
 
1792
            # so we can check if they have changed.
 
1793
            for contained_dir_info in self.walkdirs(directory):
 
1794
                for file_info in contained_dir_info[1]:
 
1795
                    if file_info[2] == 'file':
 
1796
                        canonicalpath = self.canonicalpath(file_info[0])
 
1797
                        if file_info[4]: #is it versioned?
 
1798
                            new_files.add(canonicalpath)
 
1799
                        else:
 
1800
                            unknown_files_in_directory.add(
 
1801
                                (canonicalpath, None, file_info[2]))
 
1802
 
 
1803
        for filename in files:
 
1804
            # Get file name into canonical form.
 
1805
            filename = self.canonicalpath(filename)
 
1806
            if len(filename) > 0:
 
1807
                new_files.add(filename)
 
1808
                if osutils.isdir(filename):
 
1809
                    recurse_directory_to_add_files(filename)
 
1810
        files = [f for f in new_files]
1787
1811
 
1788
1812
        # Sort needed to first handle directory content before the directory
1789
1813
        files.sort(reverse=True)
1790
 
 
1791
1814
        if not keep_files and not force:
1792
 
            changes = self.changes_from(self.basis_tree(),
 
1815
            tree_delta = self.changes_from(self.basis_tree(),
1793
1816
                specific_files=files)
1794
 
            for f in changes.modified:
1795
 
                changed_files.append(f[0])
1796
 
            for f in changes.added:
1797
 
                changed_files.append(f[0])
 
1817
            for unknown_file in unknown_files_in_directory:
 
1818
                tree_delta.unversioned.extend((unknown_file,))
 
1819
            if bool(tree_delta.modified
 
1820
                    or tree_delta.added
 
1821
                    or tree_delta.renamed
 
1822
                    or tree_delta.kind_changed
 
1823
                    or tree_delta.unversioned):
 
1824
                raise errors.BzrRemoveChangedFilesError(tree_delta)
1798
1825
 
1799
1826
        # do this before any modifications
1800
1827
        for f in files:
1817
1844
 
1818
1845
            if not keep_files:
1819
1846
                if osutils.lexists(f):
1820
 
                    if force:
1821
 
                        # recursively delete f
1822
 
                        if osutils.isdir(f):
1823
 
                            osutils.rmtree(f)
1824
 
                        else:
1825
 
                            os.unlink(f)
 
1847
                    if osutils.isdir(f) and len(os.listdir(f)) > 0:
 
1848
                        message="%s is not empty directory "\
 
1849
                            "and won't be deleted." % (f,)
 
1850
                    else:
 
1851
                        osutils.delete_any(f)
1826
1852
                        message="deleted %s" % (f,)
1827
 
                    elif fid: 
1828
 
                        # only consider deleting versioned files
1829
 
                        if f in changed_files:
1830
 
                            message="%s has changed and won't be deleted."\
1831
 
                                % (f,)
1832
 
                        elif osutils.isdir(f) and len(os.listdir(f)) > 0:
1833
 
                            message="%s is not empty directory "\
1834
 
                                "and won't be deleted." % (f,)
1835
 
                        else:
1836
 
                            osutils.delete_any(f)
1837
 
                            message="deleted %s" % (f,)
1838
1853
                elif message is not None:
1839
1854
                    # only care if we haven't done anything yet.
1840
1855
                    message="%s does not exist." % (f,)
1841
 
                
 
1856
 
1842
1857
            # print only one message (if any) per file.
1843
1858
            if message is not None:
1844
1859
                note(message)
2144
2159
    def walkdirs(self, prefix=""):
2145
2160
        """Walk the directories of this tree.
2146
2161
 
 
2162
        returns a generator which yields items in the form:
 
2163
                ((curren_directory_path, fileid), 
 
2164
                 [(file1_path, file1_name, file1_kind, (lstat), file1_id,
 
2165
                   file1_kind), ... ])
 
2166
 
2147
2167
        This API returns a generator, which is only valid during the current
2148
2168
        tree transaction - within a single lock_read or lock_write duration.
2149
2169
 
2150
 
        If the tree is not locked, it may cause an error to be raised, depending
2151
 
        on the tree implementation.
 
2170
        If the tree is not locked, it may cause an error to be raised,
 
2171
        depending on the tree implementation.
2152
2172
        """
2153
2173
        disk_top = self.abspath(prefix)
2154
2174
        if disk_top.endswith('/'):
2245
2265
                    disk_finished = True
2246
2266
 
2247
2267
    def _walkdirs(self, prefix=""):
 
2268
        """Walk the directories of this tree.
 
2269
 
 
2270
           :prefix: is used as the directrory to start with.
 
2271
           returns a generator which yields items in the form:
 
2272
                ((curren_directory_path, fileid), 
 
2273
                 [(file1_path, file1_name, file1_kind, None, file1_id,
 
2274
                   file1_kind), ... ])
 
2275
        """
2248
2276
        _directory = 'directory'
2249
2277
        # get the root in the inventory
2250
2278
        inv = self.inventory