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