Rev 950: Merge 0.4. in file:///data/jelmer/bzr-svn/revisionloader/
Jelmer Vernooij
jelmer at samba.org
Tue Mar 18 19:54:31 GMT 2008
At file:///data/jelmer/bzr-svn/revisionloader/
------------------------------------------------------------
revno: 950
revision-id:jelmer at samba.org-20080318195429-npub72gcqzs6xqfb
parent: jelmer at samba.org-20080312184954-ayb1gi3yjtqyjoez
parent: jelmer at samba.org-20080318194550-jea4hwu2jqshsq9c
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: revisionloader
timestamp: Tue 2008-03-18 20:54:29 +0100
message:
Merge 0.4.
modified:
Makefile makefile.other-20080311181537-5svhje3v1flh1n4f-1
NEWS news-20061231030336-h9fhq245ie0de8bs-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: 948.1.5
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: 948.1.4
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: 948.1.3
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
------------------------------------------------------------
revno: 948.1.2
revision-id:jelmer at samba.org-20080312190525-6yyhiqt4f5t1kbhm
parent: jelmer at samba.org-20080312190508-qu9ahy02tzjogea6
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Wed 2008-03-12 20:05:25 +0100
message:
Deal with newer versions of bzr passing in unicode strings.
modified:
__init__.py __init__.py-20051008155114-eae558e6cf149e1d
------------------------------------------------------------
revno: 948.1.1
revision-id:jelmer at samba.org-20080312190508-qu9ahy02tzjogea6
parent: jelmer at samba.org-20080312150357-87y32kta69anlqjg
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Wed 2008-03-12 20:05:08 +0100
message:
Add bug #
modified:
NEWS news-20061231030336-h9fhq245ie0de8bs-1
=== modified file 'Makefile'
--- a/Makefile 2008-03-11 18:16:09 +0000
+++ b/Makefile 2008-03-15 16:00:50 +0000
@@ -1,14 +1,20 @@
-BZR ?= bzr
+DEBUGGER ?=
+BZR ?= $(shell which bzr)
+PYTHON ?= $(shell which python)
SETUP ?= ./setup.py
PYDOCTOR ?= pydoctor
-CTAGS = ?= ctags
+CTAGS ?= ctags
PYLINT ?= pylint
+TESTS ?= svn
all:: build
build::
$(SETUP) build
+build-inplace::
+ $(SETUP) build_ext --inplace
+
install::
$(SETUP) install
@@ -20,11 +26,11 @@
$(TMP_PLUGINS_DIR):
mkdir -p $@
-$(TMP_PLUGINS_DIR)/svn: $(TMP_PLUGINS_DIR)
+$(TMP_PLUGINS_DIR)/svn: build-inplace $(TMP_PLUGINS_DIR)
ln -sf `pwd` $(TMP_PLUGINS_DIR)/svn
check:: $(TMP_PLUGINS_DIR)/svn
- BZR_PLUGIN_PATH=$(TMP_PLUGINS_DIR) $(BZR) selftest $(TEST_OPTIONS) svn
+ BZR_PLUGIN_PATH=$(TMP_PLUGINS_DIR) $(DEBUGGER) $(PYTHON) $(BZR) selftest $(TEST_OPTIONS) $(TESTS)
check-verbose::
$(MAKE) check TEST_OPTIONS=-v
@@ -32,6 +38,9 @@
check-one::
$(MAKE) check TEST_OPTIONS=--one
+show-plugins::
+ BZR_PLUGIN_PATH=$(TMP_PLUGINS_DIR) $(BZR) plugins
+
lint::
$(PYLINT) -f parseable *.py */*.py
=== modified file 'NEWS'
--- a/NEWS 2008-03-12 15:03:57 +0000
+++ b/NEWS 2008-03-12 19:05:08 +0000
@@ -18,7 +18,7 @@
BUG FIXES
- * Fix compatibility with Bazaar 1.2.
+ * Fix compatibility with Bazaar 1.2. (#196002)
* Don't provide find_repository() implementation. (#193814)
=== modified file '__init__.py'
--- a/__init__.py 2008-03-12 15:01:25 +0000
+++ b/__init__.py 2008-03-16 04:14:37 +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.
@@ -143,6 +143,8 @@
:param schemename: Name of the scheme to retrieve.
"""
+ if isinstance(schemename, unicode):
+ schemename = schemename.encode("ascii")
from scheme import BranchingScheme
from bzrlib.errors import BzrCommandError
=== modified file 'branch.py'
--- a/branch.py 2008-02-04 03:21:32 +0000
+++ b/branch.py 2008-03-18 19:45:50 +0000
@@ -73,6 +73,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()) != svn.core.svn_node_dir:
@@ -128,11 +129,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(
@@ -142,7 +144,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
@@ -183,12 +185,12 @@
return WorkingTree.open(to_location)
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."""
@@ -231,6 +233,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-12 15:01:25 +0000
+++ b/errors.py 2008-03-18 19:45:50 +0000
@@ -23,6 +23,11 @@
import urllib
import svn.core
+
+class InvalidExternalsDescription(BzrError):
+ _fmt = """Unable to parse externals description."""
+
+
# APR define, not in svn.core
SVN_ERR_UNKNOWN_HOSTNAME = 670002
=== modified file 'fetch.py'
--- a/fetch.py 2008-03-12 18:49:54 +0000
+++ b/fetch.py 2008-03-18 19:54:29 +0000
@@ -32,10 +32,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 tree import apply_txdelta_handler
+from tree import (apply_txdelta_handler, parse_externals_description,
+ inventory_add_external)
def _escape_commit_message(message):
@@ -301,6 +303,8 @@
self.is_symlink = (value != None)
elif name == svn.core.SVN_PROP_ENTRY_COMMITTED_REV:
self.last_file_rev = int(value)
+ elif name == svn.core.SVN_PROP_EXTERNALS:
+ mutter('svn:externals property on file!')
elif name in (svn.core.SVN_PROP_ENTRY_COMMITTED_DATE,
svn.core.SVN_PROP_ENTRY_LAST_AUTHOR,
svn.core.SVN_PROP_ENTRY_LOCK_TOKEN,
=== 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-02-03 03:08:33 +0000
+++ b/tree.py 2008-03-18 19:45:50 +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,69 @@
import svn.core, svn.wc, svn.delta
from svn.core import Pool
+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)
+
+
# Deal with Subversion 1.5 and the patched Subversion 1.4 (which are
# slightly different).
@@ -148,6 +213,8 @@
self.is_executable = (value != None)
elif name == svn.core.SVN_PROP_SPECIAL:
self.is_symlink = (value != None)
+ elif name == svn.core.SVN_PROP_EXTERNALS:
+ mutter('%r property on file!' % name)
elif name == svn.core.SVN_PROP_ENTRY_COMMITTED_REV:
self.last_file_rev = int(value)
elif name in (svn.core.SVN_PROP_ENTRY_COMMITTED_DATE,
More information about the bazaar-commits
mailing list