Rev 1013: Merge 0.4. in file:///data/jelmer/bzr-svn/pyrex/
Jelmer Vernooij
jelmer at samba.org
Tue Mar 18 21:52:59 GMT 2008
At file:///data/jelmer/bzr-svn/pyrex/
------------------------------------------------------------
revno: 1013
revision-id:jelmer at samba.org-20080318215258-dcoi7wm4i4bioyoa
parent: jelmer at samba.org-20080318215041-vwt4yqbf90m5lksw
parent: jelmer at samba.org-20080318194550-jea4hwu2jqshsq9c
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: pyrex
timestamp: Tue 2008-03-18 22:52:58 +0100
message:
Merge 0.4.
modified:
Makefile makefile.other-20080311181537-5svhje3v1flh1n4f-1
__init__.py __init__.py-20051008155114-eae558e6cf149e1d
branch.py svnbranch.py-20051017135706-11c749eb0dab04a7
errors.py errors.py-20061226172623-w1sbj8ynpo0eojqp-1
fetch.py fetch.py-20060625004942-x2lfaib8ra707a8p-1
tests/test_tree.py test_tree.py-20070103204350-pr8nupes7e5sd2wr-1
tree.py tree.py-20060624222557-dudlwqcmkf22lt2s-1
------------------------------------------------------------
revno: 950.1.3
revision-id:jelmer at samba.org-20080318194550-jea4hwu2jqshsq9c
parent: jelmer at samba.org-20080316041437-dutaq8lj04m44pd5
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Tue 2008-03-18 20:45:50 +0100
message:
Cherrypick utility functions for svn:externals support.
modified:
branch.py svnbranch.py-20051017135706-11c749eb0dab04a7
errors.py errors.py-20061226172623-w1sbj8ynpo0eojqp-1
fetch.py fetch.py-20060625004942-x2lfaib8ra707a8p-1
tests/test_tree.py test_tree.py-20070103204350-pr8nupes7e5sd2wr-1
tree.py tree.py-20060624222557-dudlwqcmkf22lt2s-1
------------------------------------------------------------
revno: 950.1.2
revision-id:jelmer at samba.org-20080316041437-dutaq8lj04m44pd5
parent: jelmer at samba.org-20080315160050-9h1i4rm171xg4g6d
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Sun 2008-03-16 05:14:37 +0100
message:
Mark as only compatible with >= 1.3
modified:
__init__.py __init__.py-20051008155114-eae558e6cf149e1d
------------------------------------------------------------
revno: 950.1.1
revision-id:jelmer at samba.org-20080315160050-9h1i4rm171xg4g6d
parent: jelmer at samba.org-20080312190525-6yyhiqt4f5t1kbhm
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Sat 2008-03-15 17:00:50 +0100
message:
Make it easier to run in a debugger.
modified:
Makefile makefile.other-20080311181537-5svhje3v1flh1n4f-1
=== modified file 'Makefile'
--- a/Makefile 2008-03-18 20:34:11 +0000
+++ b/Makefile 2008-03-18 21:52:58 +0000
@@ -31,7 +31,7 @@
ln -sf `pwd` $(TMP_PLUGINS_DIR)/svn
check:: $(TMP_PLUGINS_DIR)/svn
- LD_LIBRARY_PATH=/usr/local/lib BZR_PLUGIN_PATH=$(TMP_PLUGINS_DIR) $(DEBUGGER) $(PYTHON) $(BZR) selftest $(TEST_OPTIONS) $(TESTS)
+ BZR_PLUGIN_PATH=$(TMP_PLUGINS_DIR) $(DEBUGGER) $(PYTHON) $(BZR) selftest $(TEST_OPTIONS) $(TESTS)
check-verbose::
$(MAKE) check TEST_OPTIONS=-v
=== modified file '__init__.py'
--- a/__init__.py 2008-03-14 00:47:07 +0000
+++ b/__init__.py 2008-03-18 21:52:58 +0000
@@ -39,7 +39,7 @@
version_string = '%d.%d.%d%s%d' % version_info
__version__ = version_string
-COMPATIBLE_BZR_VERSIONS = [(0, 93), (1, 0), (1, 1), (1, 2)]
+COMPATIBLE_BZR_VERSIONS = [(1, 3)]
def check_bzrlib_version(desired):
"""Check that bzrlib is compatible.
=== modified file 'branch.py'
--- a/branch.py 2008-03-18 21:50:41 +0000
+++ b/branch.py 2008-03-18 21:52:58 +0000
@@ -74,6 +74,7 @@
self._revision_history_revnum = None
self.mapping = self.repository.get_mapping()
self._branch_path = branch_path.strip("/")
+ assert isinstance(self._branch_path, str)
try:
if self.repository.transport.check_path(branch_path.strip("/"),
self.get_revnum()) != core.NODE_DIR:
@@ -129,11 +130,12 @@
"""
return BranchCheckResult(self)
- def _create_heavyweight_checkout(self, to_location, revision_id=None):
+ def _create_heavyweight_checkout(self, to_location, revision_id=None, hardlink=False):
"""Create a new heavyweight checkout of this branch.
:param to_location: URL of location to create the new checkout in.
:param revision_id: Revision that should be the tip of the checkout.
+ :param hardlink: Whether to hardlink
:return: WorkingTree object of checkout.
"""
checkout_branch = BzrDir.create_branch_convenience(
@@ -143,7 +145,7 @@
# pull up to the specified revision_id to set the initial
# branch tip correctly, and seed it with history.
checkout_branch.pull(self, stop_revision=revision_id)
- return checkout.create_workingtree(revision_id)
+ return checkout.create_workingtree(revision_id, hardlink=hardlink)
def lookup_revision_id(self, revid):
"""Look up the matching Subversion revision number on the mainline of
@@ -180,12 +182,12 @@
return wt
def create_checkout(self, to_location, revision_id=None, lightweight=False,
- accelerator_tree=None):
+ accelerator_tree=None, hardlink=False):
"""See Branch.create_checkout()."""
if lightweight:
return self._create_lightweight_checkout(to_location, revision_id)
else:
- return self._create_heavyweight_checkout(to_location, revision_id)
+ return self._create_heavyweight_checkout(to_location, revision_id, hardlink=hardlink)
def generate_revision_id(self, revnum):
"""Generate a new revision id for a revision on this branch."""
@@ -228,6 +230,13 @@
last_revid = self.last_revision()
return self.revision_id_to_revno(last_revid), last_revid
+ def get_root_id(self, revnum=None):
+ if revnum is None:
+ tree = self.basis_tree()
+ else:
+ tree = self.repository.revision_tree(self.get_rev_id(revnum))
+ return tree.get_root_id()
+
def revno(self):
"""See Branch.revno()."""
return self.last_revision_info()[0]
=== modified file 'errors.py'
--- a/errors.py 2008-03-15 20:33:59 +0000
+++ b/errors.py 2008-03-18 21:52:58 +0000
@@ -24,6 +24,11 @@
import core
from bzrlib.plugins.svn import constants
+
+class InvalidExternalsDescription(BzrError):
+ _fmt = """Unable to parse externals description."""
+
+
class NotSvnBranchPath(NotBranchError):
"""Error raised when a path was specified that did not exist."""
_fmt = """%(path)s is not a valid Subversion branch path.
=== modified file 'fetch.py'
--- a/fetch.py 2008-03-18 19:33:31 +0000
+++ b/fetch.py 2008-03-18 21:52:58 +0000
@@ -31,10 +31,12 @@
from mapping import (SVN_PROP_BZR_ANCESTRY, SVN_PROP_BZR_MERGE,
SVN_PROP_BZR_PREFIX, SVN_PROP_BZR_REVISION_INFO,
SVN_PROP_BZR_BRANCHING_SCHEME, SVN_PROP_BZR_REVISION_ID,
- SVN_PROP_BZR_FILEIDS, parse_merge_property)
+ SVN_PROP_BZR_FILEIDS, parse_merge_property,
+ parse_revision_metadata)
from repository import (SvnRepository, SvnRepositoryFormat)
from svk import SVN_PROP_SVK_MERGE
from delta import apply_txdelta_handler
+from tree import (parse_externals_description, inventory_add_external)
def _escape_commit_message(message):
@@ -388,6 +390,8 @@
pass
elif name.startswith(constants.PROP_WC_PREFIX):
pass
+ elif name == constants.PROP_EXTERNALS:
+ mutter('svn:externals property on file!')
elif (name.startswith(constants.PROP_PREFIX) or
name.startswith(SVN_PROP_BZR_PREFIX)):
mutter('unsupported file property %r' % name)
=== modified file 'tests/test_tree.py'
--- a/tests/test_tree.py 2008-03-12 15:01:25 +0000
+++ b/tests/test_tree.py 2008-03-18 19:45:50 +0000
@@ -13,15 +13,20 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
"""Basis and revision tree tests."""
+from bzrlib.inventory import Inventory, TreeReference
from bzrlib.osutils import has_symlinks
+from bzrlib.repository import Repository
+from bzrlib.revision import NULL_REVISION
+from bzrlib.tests import TestCase
from bzrlib.workingtree import WorkingTree
-import os, sys
-
-from tree import SvnBasisTree
+import errors
+import os
+from tree import (SvnBasisTree, parse_externals_description,
+ inventory_add_external)
+import sys
from tests import TestCaseWithSubversionRepository
class TestBasisTree(TestCaseWithSubversionRepository):
@@ -91,3 +96,91 @@
self.assertFalse(tree.inventory[tree.inventory.path2id("file")].executable)
self.assertFalse(wt.inventory[wt.inventory.path2id("file")].executable)
+
+class TestExternalsParser(TestCase):
+ def test_parse_externals(self):
+ self.assertEqual({
+ 'third-party/sounds': (None, "http://sounds.red-bean.com/repos"),
+ 'third-party/skins': (None, "http://skins.red-bean.com/repositories/skinproj"),
+ 'third-party/skins/toolkit': (21, "http://svn.red-bean.com/repos/skin-maker")},
+ parse_externals_description("http://example.com",
+"""third-party/sounds http://sounds.red-bean.com/repos
+third-party/skins http://skins.red-bean.com/repositories/skinproj
+third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker"""))
+
+ def test_parse_comment(self):
+ self.assertEqual({
+ 'third-party/sounds': (None, "http://sounds.red-bean.com/repos")
+ },
+ parse_externals_description("http://example.com/",
+"""
+
+third-party/sounds http://sounds.red-bean.com/repos
+#third-party/skins http://skins.red-bean.com/repositories/skinproj
+#third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker"""))
+
+ def test_parse_relative(self):
+ self.assertEqual({
+ 'third-party/sounds': (None, "http://example.com/branches/other"),
+ },
+ parse_externals_description("http://example.com/trunk",
+"third-party/sounds ../branches/other"))
+
+ def test_parse_invalid_missing_url(self):
+ """No URL specified."""
+ self.assertRaises(errors.InvalidExternalsDescription,
+ lambda: parse_externals_description("http://example.com/", "bla"))
+
+ def test_parse_invalid_too_much_data(self):
+ """No URL specified."""
+ self.assertRaises(errors.InvalidExternalsDescription,
+ lambda: parse_externals_description(None, "bla -R40 http://bla/"))
+
+
+class TestInventoryExternals(TestCaseWithSubversionRepository):
+ def test_add_nested_norev(self):
+ """Add a nested tree with no specific revision referenced."""
+ repos_url = self.make_client('d', 'dc')
+ repos = Repository.open(repos_url)
+ mapping = repos.get_mapping()
+ inv = Inventory(root_id='blabloe')
+ inventory_add_external(inv, 'blabloe', 'blie/bla',
+ mapping.generate_revision_id(repos.uuid, 1, ""),
+ None, repos_url)
+ self.assertEqual(TreeReference(
+ mapping.generate_file_id(repos.uuid, 0, "", u""),
+ 'bla', inv.path2id('blie'),
+ revision=mapping.generate_revision_id(repos.uuid, 1, "")),
+ inv[inv.path2id('blie/bla')])
+
+ def test_add_simple_norev(self):
+ repos_url = self.make_client('d', 'dc')
+ repos = Repository.open(repos_url)
+ mapping = repos.get_mapping()
+ inv = Inventory(root_id='blabloe')
+ inventory_add_external(inv, 'blabloe', 'bla',
+ mapping.generate_revision_id(repos.uuid, 1, ""), None,
+ repos_url)
+
+ self.assertEqual(TreeReference(
+ mapping.generate_file_id(repos.uuid, 0, "", u""),
+ 'bla', 'blabloe',
+ revision=mapping.generate_revision_id(repos.uuid, 1, "")),
+ inv[inv.path2id('bla')])
+
+ def test_add_simple_rev(self):
+ repos_url = self.make_client('d', 'dc')
+ repos = Repository.open(repos_url)
+ inv = Inventory(root_id='blabloe')
+ mapping = repos.get_mapping()
+ inventory_add_external(inv, 'blabloe', 'bla',
+ mapping.generate_revision_id(repos.uuid, 1, ""), 0, repos_url)
+ expected_ie = TreeReference(mapping.generate_file_id(repos.uuid, 0, "", u""),
+ 'bla', 'blabloe',
+ revision=mapping.generate_revision_id(repos.uuid, 1, ""),
+ reference_revision=NULL_REVISION)
+ ie = inv[inv.path2id('bla')]
+ self.assertEqual(NULL_REVISION, ie.reference_revision)
+ self.assertEqual(mapping.generate_revision_id(repos.uuid, 1, ""),
+ ie.revision)
+ self.assertEqual(expected_ie, inv[inv.path2id('bla')])
=== modified file 'tree.py'
--- a/tree.py 2008-03-18 19:33:31 +0000
+++ b/tree.py 2008-03-18 21:52:58 +0000
@@ -15,7 +15,9 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Access to stored Subversion basis trees."""
-from bzrlib.inventory import Inventory
+from bzrlib import urlutils
+from bzrlib.branch import Branch
+from bzrlib.inventory import Inventory, InventoryDirectory, TreeReference
from bzrlib import osutils, urlutils
from bzrlib.trace import mutter
@@ -29,6 +31,68 @@
import constants
import core, wc
from delta import apply_txdelta_handler
+import errors
+
+def parse_externals_description(base_url, val):
+ """Parse an svn:externals property value.
+
+ :param base_url: URL on which the property is set. Used for
+ relative externals.
+
+ :returns: dictionary with local names as keys, (revnum, url)
+ as value. revnum is the revision number and is
+ set to None if not applicable.
+ """
+ # TODO: Use svn.wc.parse_externals_description3 instead ?
+ ret = {}
+ for l in val.splitlines():
+ if l == "" or l[0] == "#":
+ continue
+ pts = l.rsplit(None, 2)
+ if len(pts) == 3:
+ if not pts[1].startswith("-r"):
+ raise errors.InvalidExternalsDescription()
+ ret[pts[0]] = (int(pts[1][2:]), urlutils.join(base_url, pts[2]))
+ elif len(pts) == 2:
+ ret[pts[0]] = (None, urlutils.join(base_url, pts[1]))
+ else:
+ raise errors.InvalidExternalsDescription()
+ return ret
+
+
+def inventory_add_external(inv, parent_id, path, revid, ref_revnum, url):
+ """Add an svn:externals entry to an inventory as a tree-reference.
+
+ :param inv: Inventory to add to.
+ :param parent_id: File id of directory the entry was set on.
+ :param path: Path of the entry, relative to entry with parent_id.
+ :param revid: Revision to store in newly created inventory entries.
+ :param ref_revnum: Referenced revision of tree that's being referenced, or
+ None if no specific revision is being referenced.
+ :param url: URL of referenced tree.
+ """
+ assert ref_revnum is None or isinstance(ref_revnum, int)
+ assert revid is None or isinstance(revid, str)
+ (dir, name) = os.path.split(path)
+ parent = inv[parent_id]
+ if dir != "":
+ for part in dir.split("/"):
+ if parent.children.has_key(part):
+ parent = parent.children[part]
+ else:
+ # Implicitly add directory if it doesn't exist yet
+ # TODO: Generate a file id
+ parent = inv.add(InventoryDirectory('someid', part,
+ parent_id=parent.file_id))
+ parent.revision = revid
+
+ reference_branch = Branch.open(url)
+ file_id = reference_branch.get_root_id()
+ ie = TreeReference(file_id, name, parent.file_id, revision=revid)
+ if ref_revnum is not None:
+ ie.reference_revision = reference_branch.get_rev_id(ref_revnum)
+ inv.add(ie)
+
class SvnRevisionTree(RevisionTree):
"""A tree that existed in a historical Subversion revision."""
@@ -143,6 +207,8 @@
self.is_executable = (value != None)
elif name == constants.PROP_SPECIAL:
self.is_symlink = (value != None)
+ elif name == svn.core.SVN_PROP_EXTERNALS:
+ mutter('%r property on file!' % name)
elif name == constants.PROP_ENTRY_COMMITTED_REV:
self.last_file_rev = int(value)
elif name in (constants.PROP_ENTRY_COMMITTED_DATE,
More information about the bazaar-commits
mailing list