Rev 481: Store bzr revnum in revision-id-vX property, should make revid-to-revno lookups a lot cheaper (and not scale by the size of history). in file:///home/jelmer/bzr-svn/0.4/
Jelmer Vernooij
jelmer at samba.org
Sun Jun 17 17:11:18 BST 2007
------------------------------------------------------------
revno: 481
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Sun 2007-06-17 18:10:27 +0200
message:
Store bzr revnum in revision-id-vX property, should make revid-to-revno lookups a lot cheaper (and not scale by the size of history).
modified:
TODO
branch.py
checkout.py
commit.py
errors.py
mapping.txt
repository.py
tests/test_branch.py
tests/test_commit.py
tests/test_errors.py
tests/test_push.py
tests/test_repos.py
=== modified file 'TODO'
--- a/TODO 2007-05-30 18:10:08 +0000
+++ b/TODO 2007-06-17 16:10:27 +0000
@@ -19,3 +19,4 @@
- more blackbox tests
- split fetch tests out of test_repos
- what happened to WorkingTree.add() ?
+- integrate bzr:merge into bzr:revision-info or rename to bzr:merge-vXX ?
=== modified file 'branch.py'
--- a/branch.py 2007-06-17 11:40:28 +0000
+++ b/branch.py 2007-06-17 16:10:27 +0000
@@ -159,6 +159,9 @@
last_revid = self.last_revision()
return self.revision_id_to_revno(last_revid), last_revid
+ def revno(self):
+ return self.last_revision_info()[0]
+
def revision_id_to_revno(self, revision_id):
if revision_id is None:
return 0
=== modified file 'checkout.py'
--- a/checkout.py 2007-06-16 23:43:38 +0000
+++ b/checkout.py 2007-06-17 16:10:27 +0000
@@ -428,7 +428,7 @@
self.client_ctx.log_msg_baton2 = log_message_func
if rev_id is not None:
- extra = "%s\n" % rev_id
+ extra = "%d %s\n" % (self.branch.revno()+1, rev_id)
else:
extra = ""
wc = self._get_wc(write_lock=True)
=== modified file 'commit.py'
--- a/commit.py 2007-06-01 13:30:34 +0000
+++ b/commit.py 2007-06-17 16:10:27 +0000
@@ -89,7 +89,8 @@
self._svnprops[SVN_PROP_SVK_MERGE] = old + new
if revision_id is not None:
- if branch.last_revision():
+ (previous_revno, previous_revid) = branch.last_revision_info()
+ if previous_revid is not None:
(bp, revnum) = repository.lookup_revision_id(branch.last_revision())
old = repository.branchprop_list.get_property(bp, revnum,
SVN_PROP_BZR_REVISION_ID, "")
@@ -97,7 +98,7 @@
old = ""
self._svnprops[SVN_PROP_BZR_REVISION_ID] = old + \
- "%s\n" % revision_id
+ "%d %s\n" % (previous_revno+1, revision_id)
# At least one of the parents has to be the last revision on the
# mainline in # Subversion.
=== modified file 'errors.py'
--- a/errors.py 2007-06-15 19:58:45 +0000
+++ b/errors.py 2007-06-17 16:10:27 +0000
@@ -65,3 +65,12 @@
class LocalCommitsUnsupported(BzrError):
_fmt = 'Local commits are not supported for lightweight Subversion checkouts.'
+
+
+class InvalidPropertyValue(BzrError):
+ _fmt = 'Invalid property value for Subversion property %(property)s: %(msg)s'
+
+ def __init__(self, property, msg):
+ BzrError.__init__(self)
+ self.property = property
+ self.msg = msg
=== modified file 'mapping.txt'
--- a/mapping.txt 2007-05-18 15:11:30 +0000
+++ b/mapping.txt 2007-06-17 16:10:27 +0000
@@ -76,9 +76,9 @@
bzr:revision-id-v%d (where %d is the current mapping version)
-to the revision id. This property should only be honored for the revision
-in which it was set, as subversion will not erase the property
-for subsequent commits.
+to the bzr revision number following by a space and the revision id. This o
+property should only be honored for the revision in which it was set, as
+subversion will not erase the property for subsequent commits.
A (path,revnum) tuple is valid if:
* path is valid according to the branching scheme
=== modified file 'repository.py'
--- a/repository.py 2007-06-16 23:43:38 +0000
+++ b/repository.py 2007-06-17 16:10:27 +0000
@@ -51,6 +51,20 @@
SVN_REVPROP_BZR_SIGNATURE = 'bzr:gpg-signature'
SVN_PROP_BZR_REVISION_ID = 'bzr:revision-id-v%d' % MAPPING_VERSION
+def parse_revid_property(line):
+ """Parse a (revnum, revid) tuple as set in revision id properties.
+ :param line: line to parse
+ :return: tuple with (bzr_revno, revid)
+ """
+ assert not '\n' in line
+ try:
+ (revno, revid) = line.split(' ', 1)
+ except ValueError:
+ raise errors.InvalidPropertyValue(SVN_PROP_BZR_REVISION_ID,
+ "missing space")
+ return (int(revno), revid)
+
+
def parse_revision_metadata(text, rev):
"""Parse a revision info text (as set in bzr:revision-info).
@@ -62,7 +76,8 @@
try:
key, value = l.split(": ", 2)
except ValueError:
- raise BzrError("Missing : in revision metadata")
+ raise errors.InvalidPropertyValue(SVN_PROP_BZR_REVISION_INFO,
+ "Missing : in revision metadata")
if key == "committer":
rev.committer = str(value)
elif key == "timestamp":
@@ -72,7 +87,8 @@
elif key[0] == "\t" and in_properties:
rev.properties[str(key[1:])] = str(value)
else:
- raise BzrError("Invalid key %r" % key)
+ raise errors.InvalidPropertyValue(SVN_PROP_BZR_REVISION_INFO,
+ "Invalid key %r" % key)
def generate_revision_metadata(timestamp, timezone, committer, revprops):
@@ -408,11 +424,13 @@
return revid
# Lookup the revision from the bzr:revision-id-vX property
- revid = self.branchprop_list.get_property_diff(path, revnum,
+ line = self.branchprop_list.get_property_diff(path, revnum,
SVN_PROP_BZR_REVISION_ID).strip("\n")
# Or generate it
- if revid == "":
+ if line == "":
revid = generate_svn_revision_id(self.uuid, revnum, path)
+ else:
+ (bzr_revno, revid) = parse_revid_property(line)
self.revmap.insert_revid(revid, path, revnum, revnum, "undefined")
@@ -450,13 +468,14 @@
# If there is no entry in the map, walk over all branches:
for (branch, revno, exists) in self.find_branches():
# Look at their bzr:revision-id-vX
- revids = self.branchprop_list.get_property(branch, revno,
- SVN_PROP_BZR_REVISION_ID, "").splitlines()
+ revids = map(parse_revid_property,
+ self.branchprop_list.get_property(branch, revno,
+ SVN_PROP_BZR_REVISION_ID, "").splitlines())
# If there are any new entries that are not yet in the cache,
# add them
- for r in revids:
- self.revmap.insert_revid(r, branch, 0, revno,
+ for (entry_revno, entry_revid) in revids:
+ self.revmap.insert_revid(entry_revid, branch, 0, revno,
"undefined")
if revid in revids:
@@ -469,7 +488,10 @@
# added revid
i = min_revnum
for (bp, rev) in self.follow_branch(branch_path, max_revnum):
- if self.branchprop_list.get_property_diff(bp, rev, SVN_PROP_BZR_REVISION_ID).strip("\n") == revid:
+ (entry_revno, entry_revid) = parse_revid_property(
+ self.branchprop_list.get_property_diff(bp, rev,
+ SVN_PROP_BZR_REVISION_ID).strip("\n"))
+ if entry_revid == revid:
self.revmap.insert_revid(revid, bp, rev, rev, scheme)
return (bp, rev)
=== modified file 'tests/test_branch.py'
--- a/tests/test_branch.py 2007-06-17 11:40:28 +0000
+++ b/tests/test_branch.py 2007-06-17 16:10:27 +0000
@@ -148,11 +148,12 @@
repos_url = self.make_client('a', 'dc')
branch = Branch.open("svn+"+repos_url)
- self.assertEqual([branch.generate_revision_id(0)], branch.revision_history())
+ self.assertEqual([branch.generate_revision_id(0)],
+ branch.revision_history())
self.build_tree({'dc/foo': "data"})
self.client_add("dc/foo")
- self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "mycommit\n")
+ self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "42 mycommit\n")
self.client_commit("dc", "My Message")
branch = Branch.open("svn+"+repos_url)
@@ -192,7 +193,7 @@
self.build_tree({'dc/foo': "data"})
self.client_add("dc/foo")
self.client_set_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION,
- "myrevid\n")
+ "2 myrevid\n")
self.client_commit("dc", "My Message")
branch = Branch.open(repos_url)
self.assertEquals(2, branch.revision_id_to_revno("myrevid"))
@@ -202,11 +203,11 @@
self.build_tree({'dc/foo': "data"})
self.client_add("dc/foo")
self.client_set_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION,
- "myrevid\n")
+ "2 myrevid\n")
self.client_commit("dc", "My Message")
self.build_tree({'dc/foo': "someotherdata"})
self.client_set_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION,
- "myrevid\nmysecondrevid\n")
+ "2 myrevid\n3 mysecondrevid\n")
self.client_commit("dc", "My Message")
branch = Branch.open(repos_url)
self.assertEquals(3, branch.revision_id_to_revno("mysecondrevid"))
=== modified file 'tests/test_commit.py'
--- a/tests/test_commit.py 2007-05-18 18:01:27 +0000
+++ b/tests/test_commit.py 2007-06-17 16:10:27 +0000
@@ -145,7 +145,7 @@
builder.finish_inventory()
builder.commit("foo")
- self.assertEqual("my-revision-id\n",
+ self.assertEqual("3 my-revision-id\n",
self.client_get_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION, 2))
def test_commit_metadata(self):
@@ -167,7 +167,7 @@
builder.finish_inventory()
builder.commit("foo")
- self.assertEqual("my-revision-id\n",
+ self.assertEqual("3 my-revision-id\n",
self.client_get_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION, 2))
self.assertEqual("timestamp: Thu 1970-01-01 01:15:36.000000000 +0000\ncommitter: fry\n",
=== modified file 'tests/test_errors.py'
--- a/tests/test_errors.py 2007-06-15 19:58:45 +0000
+++ b/tests/test_errors.py 2007-06-17 16:10:27 +0000
@@ -17,7 +17,7 @@
from bzrlib.errors import ConnectionReset, LockError, PermissionDenied
from bzrlib.tests import TestCase
-from errors import convert_svn_error, convert_error
+from errors import convert_svn_error, convert_error, InvalidPropertyValue
import svn.core
from svn.core import SubversionException
@@ -56,3 +56,9 @@
return foo+1
self.assertEqual(2, test_nothrow(1))
+ def test_invalid_property_value(self):
+ error = InvalidPropertyValue("svn:foobar", "corrupt")
+
+ self.assertEqual(
+ "Invalid property value for Subversion property svn:foobar: corrupt",
+ str(error))
=== modified file 'tests/test_push.py'
--- a/tests/test_push.py 2007-05-27 19:36:59 +0000
+++ b/tests/test_push.py 2007-06-17 16:10:27 +0000
@@ -182,7 +182,7 @@
self.svndir.open_branch().pull(self.bzrdir.open_branch())
self.client_update("sc")
- self.assertEqual("some-rid\n",
+ self.assertEqual("3 some-rid\n",
self.client_get_prop("sc", SVN_PROP_BZR_REVISION_ID))
def test_commit_check_rev_equal(self):
=== modified file 'tests/test_repos.py'
--- a/tests/test_repos.py 2007-06-16 23:43:38 +0000
+++ b/tests/test_repos.py 2007-06-17 16:10:27 +0000
@@ -29,6 +29,7 @@
import svn.fs
from convert import load_dumpfile
+from errors import InvalidPropertyValue
from fileids import generate_svn_file_id, generate_file_id
import format
from scheme import TrunkBranchingScheme, NoBranchingScheme
@@ -37,7 +38,8 @@
from tests.test_fileids import MockRepo
from repository import (svk_feature_to_revision_id, revision_id_to_svk_feature,
SvnRepositoryFormat, SVN_PROP_BZR_REVISION_ID,
- generate_revision_metadata, parse_revision_metadata)
+ generate_revision_metadata, parse_revision_metadata,
+ parse_revid_property)
from revids import (MAPPING_VERSION, escape_svn_path, unescape_svn_path,
parse_svn_revision_id, generate_svn_revision_id)
@@ -86,7 +88,7 @@
def test_generate_revision_id_forced_revid(self):
repos_url = self.make_client("a", "dc")
- self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "someid\n")
+ self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "2 someid\n")
self.client_commit("dc", "set id")
repos = Repository.open(repos_url)
revid = repos.generate_revision_id(1, "")
@@ -402,7 +404,8 @@
def test_get_revision(self):
repos_url = self.make_client('d', 'dc')
repository = Repository.open("svn+%s" % repos_url)
- self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
+ self.assertRaises(NoSuchRevision, repository.get_revision,
+ "nonexisting")
self.build_tree({'dc/foo': "data"})
self.client_add("dc/foo")
self.client_commit("dc", "My Message")
@@ -413,7 +416,8 @@
repository.generate_revision_id(2, ""))
self.assertEqual([repository.generate_revision_id(1, "")],
rev.parent_ids)
- self.assertEqual(rev.revision_id, repository.generate_revision_id(2, ""))
+ self.assertEqual(rev.revision_id,
+ repository.generate_revision_id(2, ""))
self.assertEqual(author, rev.committer)
self.assertIsInstance(rev.properties, dict)
@@ -426,7 +430,7 @@
self.client_commit("dc", "My Message")
self.build_tree({'dc/foo': "data2"})
self.client_set_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION,
- "myrevid\n")
+ "3 myrevid\n")
(num, date, author) = self.client_commit("dc", "Second Message")
repository = Repository.open("svn+%s" % repos_url)
revid = generate_svn_revision_id(repository.uuid, 2, "")
@@ -608,7 +612,8 @@
def test_get_inventory(self):
repos_url = self.make_client('d', 'dc')
repository = Repository.open("svn+%s" % repos_url)
- self.assertRaises(NoSuchRevision, repository.get_inventory, "nonexisting")
+ self.assertRaises(NoSuchRevision, repository.get_inventory,
+ "nonexisting")
self.build_tree({'dc/foo': "data", 'dc/blah': "other data"})
self.client_add("dc/foo")
self.client_add("dc/blah")
@@ -666,7 +671,7 @@
repos_url = self.make_client('d', 'dc')
self.build_tree({'dc/bloe': None})
self.client_add("dc/bloe")
- self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "myid\n")
+ self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "2 myid\n")
self.client_commit("dc", "foobar")
repository = Repository.open("svn+%s" % repos_url)
self.assertEqual(("", 1), repository.lookup_revision_id(
@@ -680,7 +685,7 @@
repos_url = self.make_client('d', 'dc')
self.build_tree({'dc/bloe': None})
self.client_add("dc/bloe")
- self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "myid\n")
+ self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID, "2 myid\n")
self.client_commit("dc", "foobar")
repository = Repository.open("svn+%s" % repos_url)
self.assertRaises(NoSuchRevision,
@@ -2347,8 +2352,20 @@
def test_parse_revision_metadata_no_colon(self):
rev = Revision('someid')
- self.assertRaises(BzrError, lambda: parse_revision_metadata("bla", rev))
+ self.assertRaises(InvalidPropertyValue,
+ lambda: parse_revision_metadata("bla", rev))
def test_parse_revision_metadata_invalid_name(self):
rev = Revision('someid')
- self.assertRaises(BzrError, lambda: parse_revision_metadata("bla: b", rev))
+ self.assertRaises(InvalidPropertyValue,
+ lambda: parse_revision_metadata("bla: b", rev))
+
+ def test_parse_revid_property(self):
+ self.assertEquals((1, "bloe"), parse_revid_property("1 bloe"))
+
+ def test_parse_revid_property_space(self):
+ self.assertEquals((42, "bloe bla"), parse_revid_property("42 bloe bla"))
+
+ def test_parse_revid_property_invalid(self):
+ self.assertRaises(InvalidPropertyValue,
+ lambda: parse_revid_property("blabla"))
More information about the bazaar-commits
mailing list