Rev 3973: Use historical context for file logging (Ian Clatworthy) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Jan 29 13:17:08 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3973
revision-id: pqm at pqm.ubuntu.com-20090129131703-lgus0aiclez3isj6
parent: pqm at pqm.ubuntu.com-20090129071857-l3ikkrm6b1rx96bx
parent: ian.clatworthy at canonical.com-20090129122429-irb67ivtr2gbvx2z
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-01-29 13:17:03 +0000
message:
  Use historical context for file logging (Ian Clatworthy)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3972.1.2
    revision-id: ian.clatworthy at canonical.com-20090129122429-irb67ivtr2gbvx2z
    parent: ian.clatworthy at canonical.com-20090129075743-5cs64pvnjwyrs5el
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Thu 2009-01-29 22:24:29 +1000
    message:
      fix failing test when history completely empty
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
    ------------------------------------------------------------
    revno: 3972.1.1
    revision-id: ian.clatworthy at canonical.com-20090129075743-5cs64pvnjwyrs5el
    parent: pqm at pqm.ubuntu.com-20090129071857-l3ikkrm6b1rx96bx
    parent: ian.clatworthy at canonical.com-20090129075346-4zyjjh9a0yw07t42
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Thu 2009-01-29 17:57:43 +1000
    message:
      Use historical context for file logging (Ian Clatworthy)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3943.6.4
    revision-id: ian.clatworthy at canonical.com-20090129075346-4zyjjh9a0yw07t42
    parent: ian.clatworthy at canonical.com-20090118061118-21mjqrjiaxwz1rdl
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-file-Y-fix
    timestamp: Thu 2009-01-29 17:53:46 +1000
    message:
      review feedback from vila
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3943.6.3
    revision-id: ian.clatworthy at canonical.com-20090118061118-21mjqrjiaxwz1rdl
    parent: ian.clatworthy at canonical.com-20090117232859-ydewp5rfmuf0fqdy
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-file-Y-fix
    timestamp: Sun 2009-01-18 16:11:18 +1000
    message:
      search the start tree if the end tree doesn't have a file
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3943.6.2
    revision-id: ian.clatworthy at canonical.com-20090117232859-ydewp5rfmuf0fqdy
    parent: ian.clatworthy at canonical.com-20090117232106-m831x0own422es1l
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-file-Y-fix
    timestamp: Sun 2009-01-18 09:28:59 +1000
    message:
      improve error message
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3943.6.1
    revision-id: ian.clatworthy at canonical.com-20090117232106-m831x0own422es1l
    parent: pqm at pqm.ubuntu.com-20090115233242-4bxyn4zcj2a0ksfk
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-file-Y-fix
    timestamp: Sun 2009-01-18 09:21:06 +1000
    message:
      find file using the end revision
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
=== modified file 'NEWS'
--- a/NEWS	2009-01-29 06:31:22 +0000
+++ b/NEWS	2009-01-29 07:57:43 +0000
@@ -72,6 +72,13 @@
       a change to FILE when the ``--short`` and ``--line`` log formats
       are used. (Ian Clatworthy, #317417)
 
+    * ``bzr log -rX..Y FILE`` now shows the history of FILE provided
+      it existed in Y or X, even if the file has since been deleted or
+      renamed. If no range is given, the current/basis tree and
+      initial tree are searched in that order. More generally, log
+      now interprets filenames in their historical context.
+      (Ian Clatworthy, #175520)
+
     * Don't require the present compression base in knits to be the same
       when adding records in knits. (Jelmer Vernooij, #307394)
 

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2009-01-29 06:31:22 +0000
+++ b/bzrlib/builtins.py	2009-01-29 07:57:43 +0000
@@ -1899,7 +1899,7 @@
             message=None,
             limit=None,
             show_diff=False):
-        from bzrlib.log import show_log
+        from bzrlib.log import show_log, _get_fileid_to_log
         direction = (forward and 'forward') or 'reverse'
 
         if change is not None:
@@ -1919,12 +1919,10 @@
             tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
                 location)
             if fp != '':
-                if tree is None:
-                    tree = b.basis_tree()
-                file_id = tree.path2id(fp)
+                file_id = _get_fileid_to_log(revision, tree, b, fp)
                 if file_id is None:
                     raise errors.BzrCommandError(
-                        "Path does not have any revision history: %s" %
+                        "Path unknown at end or start of revision range: %s" %
                         location)
         else:
             # local dir only
@@ -1961,6 +1959,7 @@
         finally:
             b.unlock()
 
+
 def _get_revision_range(revisionspec_list, branch, command_name):
     """Take the input of a revision option and turn it into a revision range.
 

=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2009-01-29 06:31:22 +0000
+++ b/bzrlib/log.py	2009-01-29 12:24:29 +0000
@@ -1222,6 +1222,57 @@
         lf.log_revision(lr)
 
 
+def _get_fileid_to_log(revision, tree, b, fp):
+    """Find the file-id to log for a file path in a revision range.
+
+    :param revision: the revision range as parsed on the command line
+    :param tree: the working tree, if any
+    :param b: the branch
+    :param fp: file path
+    """
+    if revision is None:
+        if tree is None:
+            tree = b.basis_tree()
+        file_id = tree.path2id(fp)
+        if file_id is None:
+            # go back to when time began
+            try:
+                rev1 = b.get_rev_id(1)
+            except errors.NoSuchRevision:
+                # No history at all
+                file_id = None
+            else:
+                tree = b.repository.revision_tree(rev1)
+                file_id = tree.path2id(fp)
+
+    elif len(revision) == 1:
+        # One revision given - file must exist in it
+        tree = revision[0].as_tree(b)
+        file_id = tree.path2id(fp)
+
+    elif len(revision) == 2:
+        # Revision range given. Get the file-id from the end tree.
+        # If that fails, try the start tree.
+        rev_id = revision[1].as_revision_id(b)
+        if rev_id is None:
+            tree = b.basis_tree()
+        else:
+            tree = revision[1].as_tree(b)
+        file_id = tree.path2id(fp)
+        if file_id is None:
+            rev_id = revision[0].as_revision_id(b)
+            if rev_id is None:
+                rev1 = b.get_rev_id(1)
+                tree = b.repository.revision_tree(rev1)
+            else:
+                tree = revision[0].as_tree(b)
+            file_id = tree.path2id(fp)
+    else:
+        raise errors.BzrCommandError(
+            'bzr log --revision takes one or two values.')
+    return file_id
+
+
 properties_handler_registry = registry.Registry()
 properties_handler_registry.register_lazy("foreign",
                                           "bzrlib.foreign",

=== modified file 'bzrlib/tests/blackbox/test_log.py'
--- a/bzrlib/tests/blackbox/test_log.py	2009-01-29 06:31:22 +0000
+++ b/bzrlib/tests/blackbox/test_log.py	2009-01-29 07:57:43 +0000
@@ -188,7 +188,7 @@
         wt = self.make_branch_and_tree('.')
         out, err = self.run_bzr('log does-not-exist', retcode=3)
         self.assertContainsRe(
-            err, 'Path does not have any revision history: does-not-exist')
+            err, 'Path unknown at end or start of revision range: does-not-exist')
 
     def test_log_with_tags(self):
         tree = self._prepare(format='dirstate-tags')
@@ -768,7 +768,8 @@
         tree.bzrdir.destroy_workingtree()
         self.run_bzr('log tree/file')
 
-    def prepare_tree(self):
+    def prepare_tree(self, complex=False):
+        # The complex configuration includes deletes and renames
         tree = self.make_branch_and_tree('parent')
         self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
         tree.add('file1')
@@ -782,6 +783,13 @@
         child_tree.commit(message='branch 1')
         tree.merge_from_branch(child_tree.branch)
         tree.commit(message='merge child branch')
+        if complex:
+            tree.remove('file2')
+            tree.commit('remove file2')
+            tree.rename_one('file3', 'file4')
+            tree.commit('file3 is now called file4')
+            tree.remove('file1')
+            tree.commit('remove file1')
         os.chdir('parent')
 
     def test_log_file(self):
@@ -830,6 +838,56 @@
         self.assertNotContainsRe(log, 'revno: 3.1.1\n')
         self.assertNotContainsRe(log, 'revno: 4\n')
 
+    def test_log_file_historical_missing(self):
+        # Check logging a deleted file gives an error if the
+        # file isn't found at the end or start of the revision range
+        self.prepare_tree(complex=True)
+        err_msg = "Path unknown at end or start of revision range: file2"
+        err = self.run_bzr('log file2', retcode=3)[1]
+        self.assertContainsRe(err, err_msg)
+
+    def test_log_file_historical_end(self):
+        # Check logging a deleted file is ok if the file existed
+        # at the end the revision range
+        self.prepare_tree(complex=True)
+        log, err = self.run_bzr('log -r..4 file2')
+        self.assertEquals('', err)
+        self.assertNotContainsRe(log, 'revno: 1\n')
+        self.assertContainsRe(log, 'revno: 2\n')
+        self.assertNotContainsRe(log, 'revno: 3\n')
+        self.assertContainsRe(log, 'revno: 3.1.1\n')
+        self.assertContainsRe(log, 'revno: 4\n')
+
+    def test_log_file_historical_start(self):
+        # Check logging a deleted file is ok if the file existed
+        # at the start of the revision range
+        self.prepare_tree(complex=True)
+        log, err = self.run_bzr('log file1')
+        self.assertEquals('', err)
+        self.assertContainsRe(log, 'revno: 1\n')
+        self.assertNotContainsRe(log, 'revno: 2\n')
+        self.assertNotContainsRe(log, 'revno: 3\n')
+        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
+        self.assertNotContainsRe(log, 'revno: 4\n')
+
+    def test_log_file_renamed(self):
+        """File matched against revision range, not current tree."""
+        self.prepare_tree(complex=True)
+
+        # Check logging a renamed file gives an error by default
+        err_msg = "Path unknown at end or start of revision range: file3"
+        err = self.run_bzr('log file3', retcode=3)[1]
+        self.assertContainsRe(err, err_msg)
+
+        # Check we can see a renamed file if we give the right end revision
+        log, err = self.run_bzr('log -r..4 file3')
+        self.assertEquals('', err)
+        self.assertNotContainsRe(log, 'revno: 1\n')
+        self.assertNotContainsRe(log, 'revno: 2\n')
+        self.assertContainsRe(log, 'revno: 3\n')
+        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
+        self.assertNotContainsRe(log, 'revno: 4\n')
+
     def test_line_log_file(self):
         """The line log for a file should only list relevant mainline revs"""
         # Note: this also implicitly  covers the short logging case.




More information about the bazaar-commits mailing list