Rev 2503: Teach delta.report_changes about unversioned files, removing all inventory access during status --short. in http://bazaar.launchpad.net/~bzr/bzr/dirstate

Robert Collins robertc at robertcollins.net
Mon Mar 5 03:11:30 GMT 2007


At http://bazaar.launchpad.net/~bzr/bzr/dirstate

------------------------------------------------------------
revno: 2503
revision-id: robertc at robertcollins.net-20070305031021-ypbakvagbivyw5mu
parent: robertc at robertcollins.net-20070305011525-fakb9irlbxyxaukb
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate
timestamp: Mon 2007-03-05 14:10:21 +1100
message:
  Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
modified:
  bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
  bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
  bzrlib/tests/blackbox/test_status.py teststatus.py-20050712014354-508855eb9f29f7dc
  bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
=== modified file 'bzrlib/delta.py'
--- a/bzrlib/delta.py	2007-03-05 01:15:25 +0000
+++ b/bzrlib/delta.py	2007-03-05 03:10:21 +0000
@@ -269,7 +269,7 @@
     """Report changes between two trees"""
 
     def __init__(self, output=None, suppress_root_add=True,
-                 output_file=None):
+                 output_file=None, unversioned_filter=None):
         """Constructor
 
         :param output: a function with the signature of trace.note, i.e.
@@ -278,6 +278,9 @@
             (i.e. when a tree has just been initted)
         :param output_file: If supplied, a file-like object to write to.
             Only one of output and output_file may be supplied.
+        :param unversioned_filter: A filter function to be called on 
+            unversioned files. This should return True to ignore a path.
+            By default, no filtering takes place.
         """
         if output_file is not None:
             if output is not None:
@@ -294,9 +297,12 @@
                              'created': 'N',
                              'modified': 'M',
                              'deleted': 'D'}
-        self.versioned_map = {'added': '+',
-                              'unchanged': ' ',
-                              'removed': '-'}
+        self.versioned_map = {'added': '+', # versioned target
+                              'unchanged': ' ', # versioned in both
+                              'removed': '-', # versioned in source
+                              'unversioned': '?', # versioned in neither
+                              }
+        self.unversioned_filter = unversioned_filter
 
     def report(self, file_id, paths, versioned, renamed, modified, exe_change,
                kind):
@@ -304,7 +310,8 @@
 
         :param file_id: The file_id of the file
         :param path: The old and new paths as generated by Tree._iter_changes.
-        :param versioned: may be 'added', 'removed', or 'unchanged'
+        :param versioned: may be 'added', 'removed', 'unchanged', or
+            'unversioned.
         :param renamed: may be True or False
         :param modified: may be 'created', 'deleted', 'kind changed',
             'modified' or 'unchanged'.
@@ -314,6 +321,13 @@
         """
         if paths[1] == '' and versioned == 'added' and self.suppress_root_add:
             return
+        if versioned == 'unversioned':
+            # skip ignored unversioned files if needed.
+            if self.unversioned_filter is not None:
+                if self.unversioned_filter(paths[1]):
+                    return
+            # dont show a content change in the output.
+            modified = 'unchanged'
         # we show both paths in the following situations:
         # the file versioning is unchanged AND
         # ( the path is different OR
@@ -363,6 +377,12 @@
         generated by Tree._iter_changes
     :param reporter: The ChangeReporter that will report the changes.
     """
+    versioned_change_map = {
+        (True, True)  : 'unchanged',
+        (True, False) : 'removed',
+        (False, True) : 'added',
+        (False, False): 'unversioned',
+        }
     for (file_id, path, content_change, versioned, parent_id, name, kind,
          executable) in change_iterator:
         exe_change = False
@@ -387,12 +407,6 @@
                 modified = "unchanged"
             if kind[1] == "file":
                 exe_change = (executable[0] != executable[1])
-        if versioned[0] != versioned[1]:
-            if versioned[0]:
-                versioned_change = "removed"
-            else:
-                versioned_change = "added"
-        else:
-            versioned_change = "unchanged"
+        versioned_change = versioned_change_map[versioned]
         reporter.report(file_id, path, versioned_change, renamed, modified,
                         exe_change, kind)

=== modified file 'bzrlib/status.py'
--- a/bzrlib/status.py	2007-03-05 01:15:25 +0000
+++ b/bzrlib/status.py	2007-03-05 03:10:21 +0000
@@ -144,12 +144,10 @@
             _raise_if_nonexistent(specific_files, old, new)
             if short:
                 changes = new._iter_changes(old, show_unchanged, specific_files,
-                    require_versioned=False)
-                reporter = _mod_delta.ChangeReporter(output_file=to_file)
+                    require_versioned=False, want_unversioned=True)
+                reporter = _mod_delta.ChangeReporter(output_file=to_file,
+                    unversioned_filter=new.is_ignored)
                 _mod_delta.report_changes(changes, reporter)
-                short_status_letter = '? '
-                list_paths('unknown', new.unknowns(), specific_files, to_file,
-                           short_status_letter)
             else:
                 delta = new.changes_from(old, want_unchanged=show_unchanged,
                                       specific_files=specific_files,
@@ -233,13 +231,3 @@
             else:
                 prefix = ' '
             print >> to_file, prefix, merge
-        
-def list_paths(header, paths, specific_files, to_file, short_status_letter=''):
-    done_header = False
-    for path in paths:
-        if specific_files and not is_inside_any(specific_files, path):
-            continue
-        if not short_status_letter and not done_header:
-            print >>to_file, '%s:' % header
-            done_header = True
-        print >>to_file, '%s  %s' % (short_status_letter, path)

=== modified file 'bzrlib/tests/blackbox/test_status.py'
--- a/bzrlib/tests/blackbox/test_status.py	2007-03-02 04:40:12 +0000
+++ b/bzrlib/tests/blackbox/test_status.py	2007-03-05 03:10:21 +0000
@@ -155,7 +155,23 @@
         self.assert_("Empty commit 3" in message)
         self.assertEndsWith(message, "...\n")
 
-    def test_branch_status_specific_files(self): 
+    def test_tree_status_ignores(self):
+        """Tests branch status with ignores"""
+        wt = self.make_branch_and_tree('.')
+        self.run_bzr('ignore', '*~')
+        wt.commit('commit .bzrignore')
+        self.build_tree(['foo.c', 'foo.c~'])
+        self.assertStatus([
+                'unknown:\n',
+                '  foo.c\n',
+                ],
+                wt)
+        self.assertStatus([
+                '?   foo.c\n',
+                ],
+                wt, short=True)
+
+    def test_tree_status_specific_files(self):
         """Tests branch status with given specific files"""
         wt = self.make_branch_and_tree('.')
         b = wt.branch
@@ -175,7 +191,7 @@
 
         self.assertStatus([
                 '?   bye.c\n',
-                '?   dir2\n',
+                '?   dir2/\n',
                 '?   directory/hello.c\n'
                 ],
                 wt, short=True)
@@ -209,7 +225,7 @@
         tof = StringIO()
         show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
         tof.seek(0)
-        self.assertEquals(tof.readlines(), ['?   dir2\n'])
+        self.assertEquals(tof.readlines(), ['?   dir2/\n'])
 
     def test_status_nonexistent_file(self):
         # files that don't exist in either the basis tree or working tree

=== modified file 'bzrlib/tests/test_delta.py'
--- a/bzrlib/tests/test_delta.py	2007-03-05 01:15:25 +0000
+++ b/bzrlib/tests/test_delta.py	2007-03-05 03:10:21 +0000
@@ -39,14 +39,19 @@
     def assertReport(self, expected, file_id='fid', path='path',
                      versioned_change='unchanged', renamed=False,
                      modified='unchanged', exe_change=False,
-                     kind=('file', 'file'), old_path=None):
+                     kind=('file', 'file'), old_path=None,
+                     unversioned_filter=None):
         result = []
         def result_line(format, *args):
             result.append(format % args)
-        reporter = _mod_delta.ChangeReporter(result_line)
+        reporter = _mod_delta.ChangeReporter(result_line,
+            unversioned_filter=unversioned_filter)
         reporter.report(file_id, (old_path, path), versioned_change, renamed,
             modified, exe_change, kind)
-        self.assertEqualDiff(expected, result[0])
+        if expected is not None:
+            self.assertEqualDiff(expected, result[0])
+        else:
+            self.assertEqual([], result)
 
     def test_rename(self):
         self.assertReport('R   old => path', renamed=True, old_path='old')
@@ -86,9 +91,22 @@
         self.assertReport(' M  path', modified='modified')
         self.assertReport(' M* path', modified='modified', exe_change=True)
 
+    def test_unversioned(self):
+        # by default any unversioned file is output
+        self.assertReport('?   subdir/foo~', file_id=None, path='subdir/foo~',
+            old_path=None, versioned_change='unversioned',
+            renamed=False, modified='created', exe_change=False,
+            kind=(None, 'file'))
+        # but we can choose to filter these. Probably that should be done 
+        # close to the tree, but this is a reasonable starting point.
+        self.assertReport(None, file_id=None, path='subdir/foo~',
+            old_path=None, versioned_change='unversioned',
+            renamed=False, modified='created', exe_change=False,
+            kind=(None, 'file'), unversioned_filter=lambda x:True)
+
     def assertChangesEqual(self,
                            file_id='fid',
-                           path='path',
+                           paths=('path', 'path'),
                            content_change=False,
                            versioned=(True, True),
                            parent_id=('pid', 'pid'),
@@ -100,11 +118,11 @@
                            modified='unchanged',
                            exe_change=False):
         reporter = InstrumentedReporter()
-        _mod_delta.report_changes([(file_id, path, content_change, versioned,
+        _mod_delta.report_changes([(file_id, paths, content_change, versioned,
             parent_id, name, kind, executable)], reporter)
         output = reporter.calls[0]
         self.assertEqual(file_id, output[0])
-        self.assertEqual(path, output[1])
+        self.assertEqual(paths, output[1])
         self.assertEqual(versioned_change, output[2])
         self.assertEqual(renamed, output[3])
         self.assertEqual(modified, output[4])
@@ -152,6 +170,20 @@
                                 content_change=True, name=('old', 'new'),
                                 executable=(False, True))
 
+    def test_report_unversioned(self):
+        """Unversioned entries are reported well."""
+        self.assertChangesEqual(file_id=None, paths=(None, 'full/path'),
+                           content_change=True,
+                           versioned=(False, False),
+                           parent_id=(None, None),
+                           name=(None, 'path'),
+                           kind=(None, 'file'),
+                           executable=(None, False),
+                           versioned_change='unversioned',
+                           renamed=False,
+                           modified='created',
+                           exe_change=False)
+
 
 class TestChangesFrom (tests.TestCaseWithTransport):
 

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2007-03-05 01:15:25 +0000
+++ b/bzrlib/tree.py	2007-03-05 03:10:21 +0000
@@ -134,6 +134,14 @@
             return True
         return self.inventory.has_id(file_id)
 
+    def is_ignored(self, filename):
+        """Check whether the filename is ignored by this tree.
+
+        :param filename: The relative filename within the tree.
+        :return: True if the filename is ignored.
+        """
+        return False
+
     def __iter__(self):
         return iter(self.inventory)
 



More information about the bazaar-commits mailing list