build
*.pyc
test????.tmp
+tags
raise Exception, 'Version mismatch'
check_bzrlib_version(required_bzr_version)
+try:
+ from bzrlib.workingtree import WorkingTreeFormat4
+except ImportError:
+ warning('this version of bzr-svn requires WorkingTreeFormat4 to be available to work properly')
import branch
import convert
from binascii import hexlify
from bzrlib.bzrdir import BzrDirFormat, BzrDir
from bzrlib.errors import NotBranchError, NoSuchFile, InvalidRevisionId
-from bzrlib.inventory import (Inventory, InventoryDirectory, InventoryFile,
- ROOT_ID)
+from bzrlib.inventory import (Inventory, InventoryDirectory, InventoryFile)
from bzrlib.lockable_files import TransportLock, LockableFiles
from bzrlib.lockdir import LockDir
from bzrlib.osutils import rand_bytes, fingerprint_file
self.client_ctx.log_msg_baton2 = self.log_message_func
self._set_inventory(self.read_working_inventory(), dirty=False)
- mutter('working inv: %r' % self.read_working_inventory().entries())
self.base_revid = branch.repository.generate_revision_id(
self.base_revnum, branch.branch_path)
- mutter('basis inv: %r' % self.basis_tree().inventory.entries())
self.controldir = os.path.join(self.basedir, svn.wc.get_adm_dir(), 'bzr')
try:
os.makedirs(self.controldir)
svn.wc.adm_close(to_wc)
def read_working_inventory(self):
- inv = Inventory(ROOT_ID)
+ inv = Inventory()
def add_file_to_inv(relpath, id, revid, parent_id):
"""Add a file to the inventory."""
self.base_revnum = max(self.base_revnum, entry.revision)
# First handle directory itself
- if relpath == "":
- inv.add_path("", 'directory', ROOT_ID)
- inv.revision_id = revid
- else:
- inventry = InventoryDirectory(id, os.path.basename(relpath), parent_id)
- inventry.revision = revid
- inv.add(inventry)
+ inv.add_path(relpath, 'directory', id, parent_id).revision = revid
for name in entries:
if name == "":
commit_info = svn.client.commit3(specific_files, True, False, self.client_ctx)
- revid = self.branch.repository.generate_revision_id(commit_info.revision, self.branch.branch_path)
+ revid = self.branch.repository.generate_revision_id(
+ commit_info.revision, self.branch.branch_path)
self.base_revid = revid
self.branch._revision_history.append(revid)
from bzrlib.errors import (UnsupportedOperation, BzrError, InvalidRevisionId,
DivergedBranches)
-from bzrlib.inventory import Inventory, ROOT_ID
+from bzrlib.inventory import Inventory
import bzrlib.osutils as osutils
-from bzrlib.repository import CommitBuilder
+from bzrlib.repository import RootCommitBuilder
from bzrlib.trace import mutter, warning
-from repository import (SvnRepository, SVN_PROP_BZR_MERGE, SVN_PROP_SVK_MERGE,
- SVN_PROP_BZR_REVPROP_PREFIX, revision_id_to_svk_feature)
+from repository import (SvnRepository, SVN_PROP_BZR_MERGE, SVN_PROP_BZR_FILEIDS,
+ SVN_PROP_SVK_MERGE, SVN_PROP_BZR_REVPROP_PREFIX,
+ revision_id_to_svk_feature, escape_svn_path)
import os
-class SvnCommitBuilder(CommitBuilder):
+class SvnCommitBuilder(RootCommitBuilder):
"""Commit Builder implementation wrapped around svn_delta_editor. """
- record_root_entry = True
-
def __init__(self, repository, branch, parents, config, revprops):
"""Instantiate a new SvnCommitBuilder.
self.branch.last_revision() in parents)
if self.branch.last_revision() is None:
- self.old_inv = Inventory(ROOT_ID)
+ self.old_inv = Inventory(root_id=None)
else:
- self.old_inv = self.repository.get_inventory(
- self.branch.last_revision())
+ self.old_inv = self.repository.get_inventory(self.branch.last_revision())
self.modified_files = {}
self.modified_dirs = []
-
+
def _generate_revision_if_needed(self):
pass
svn.delta.svn_txdelta_send_string(contents, txdelta, txbaton, self.pool)
- def _dir_process(self, path, file_id, baton):
- mutter('processing %r' % path)
+ def _dir_process(self, file_id, baton):
+ path = self.new_inventory.id2path(file_id)
+ mutter('processing %r (%r)' % (path, file_id))
if path == "":
# Set all the revprops
for prop, value in self._svnprops.items():
# Handle this directory
if child_ie.file_id in self.modified_dirs:
- self._dir_process(self.new_inventory.id2path(child_ie.file_id),
- child_ie.file_id, child_baton)
+ self._dir_process(child_ie.file_id, child_baton)
svn.delta.editor_invoke_close_directory(self.editor, child_baton,
self.pool)
branch_batons = self.open_branch_batons(root,
self.branch.branch_path.split("/"))
- self._dir_process("", self.new_inventory.root.file_id, branch_batons[-1])
+ self._dir_process(self.new_inventory.root.file_id, branch_batons[-1])
branch_batons.reverse()
for baton in branch_batons:
return revid
+ def record_entry_contents(self, ie, parent_invs, path, tree):
+ """Record the content of ie from tree into the commit if needed.
+
+ Side effect: sets ie.revision when unchanged
+
+ :param ie: An inventory entry present in the commit.
+ :param parent_invs: The inventories of the parent revisions of the
+ commit.
+ :param path: The path the entry is at in the tree.
+ :param tree: The tree which contains this entry and should be used to
+ obtain content.
+ """
+ assert self.new_inventory.root is not None or ie.parent_id is None
+ self.new_inventory.add(ie)
+
+ # ie.revision is always None if the InventoryEntry is considered
+ # for committing. ie.snapshot will record the correct revision
+ # which may be the sole parent if it is untouched.
+ mutter('recording %s' % ie.file_id)
+ if ie.revision is not None:
+ return
+
+ # Make sure that ie.file_id exists in the map
+ if not ie.file_id in self.old_inv:
+ if not self._svnprops.has_key(SVN_PROP_BZR_FILEIDS):
+ self._svnprops[SVN_PROP_BZR_FILEIDS] = ""
+ mutter('adding fileid mapping %s -> %s' % (path, ie.file_id))
+ self._svnprops[SVN_PROP_BZR_FILEIDS] += "%s\t%s\n" % (escape_svn_path(path, "%\t\n"), ie.file_id)
+
+ previous_entries = ie.find_previous_heads(
+ parent_invs,
+ self.repository.weave_store,
+ self.repository.get_transaction())
+
+ # we are creating a new revision for ie in the history store
+ # and inventory.
+ ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
+
def push_as_merged(target, source, revision_id):
rev = source.repository.get_revision(revision_id)
continue
id = ie.file_id
- while id != ROOT_ID:
+ while inv[id].parent_id is not None:
if inv[id].revision is None:
break
inv[id].revision = None
import bzrlib
from bzrlib.decorators import needs_write_lock
-from bzrlib.inventory import Inventory, ROOT_ID
+from bzrlib.inventory import Inventory
import bzrlib.osutils as osutils
from bzrlib.progress import ProgressBar
from bzrlib.revision import Revision
return s.hexdigest()
class RevisionBuildEditor(svn.delta.Editor):
- def __init__(self, source, target, branch_path, revnum, prev_inventory, revid, svn_revprops, id_map, parent_branch, parent_id_map):
+ def __init__(self, source, target, branch_path, revnum, prev_inventory,
+ revid, svn_revprops, id_map, parent_branch, parent_id_map):
self.branch_path = branch_path
self.inventory = copy(prev_inventory)
+ assert self.inventory.root is None or revnum > 0
self.revid = revid
self.revnum = revnum
+ mutter('idmap for %r %r' % (revid, id_map))
self.id_map = id_map
self.parent_branch = parent_branch
self.parent_id_map = parent_id_map
return rev
def open_root(self, base_revnum, baton):
- if self.inventory.revision_id is None:
- self.dir_baserev[ROOT_ID] = []
+ file_id, revision_id = self.id_map[""]
+ if self.inventory.root is None:
+ self.dir_baserev[file_id] = []
+ ie = self.inventory.add_path("", 'directory', file_id)
else:
- self.dir_baserev[ROOT_ID] = [self.inventory.revision_id]
- self.inventory.revision_id = self.revid
- return ROOT_ID
+ self.dir_baserev[file_id] = [self.inventory.revision_id]
+ ie = self.inventory[file_id]
+
+ if ie is not None:
+ ie.revision = revision_id
+ return file_id
def relpath(self, path):
return path.strip("/")
def close_directory(self, id):
revid = self.revid
- if id != ROOT_ID:
+ if id != self.id_map[""][0]:
self.inventory[id].revision = revid
file_weave = self.weave_store.get_weave_or_empty(id, self.transact)
self.dir_baserev[file_id] = []
ie = self.inventory.add_path(path, 'directory', file_id)
- if ie:
- ie.revision = revision_id
+ ie.revision = revision_id
return file_id
def change_dir_prop(self, id, name, value, pool):
if name == SVN_PROP_BZR_MERGE:
- if id != ROOT_ID:
+ if id != self.id_map[""][0]:
mutter('rogue %r on non-root directory' % SVN_PROP_BZR_MERGE)
return
repos_root = self.source.transport.get_repos_root()
+ # first, figure out what revisions need to be fetched
needed = []
parents = {}
prev_revid = None
parent_branch = None
if parent_revid is None:
- parent_id_map = {"": (ROOT_ID, None)}
+ # if there is no parent id, that means this is the
+ # first revision on this branch
id_map = self.source.get_fileid_map(revnum, branch)
- parent_inv = Inventory(ROOT_ID)
+ parent_id_map = None
+ parent_inv = Inventory(root_id=None)
elif prev_revid != parent_revid:
parent_id_map = self.source.get_fileid_map(parent_revnum, parent_branch)
id_map = self.source.get_fileid_map(revnum, branch)
changes, id_map)
parent_inv = prev_inv
-
editor = RevisionBuildEditor(self.source, self.target, branch,
revnum, parent_inv, revid,
self.source._log.get_revision_info(revnum),
def is_compatible(source, target):
"""Be compatible with SvnRepository."""
# FIXME: Also check target uses VersionedFile
- mutter('test %r' % source)
return isinstance(source, SvnRepository)
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-from bzrlib.errors import RevisionNotPresent
-from bzrlib.inventory import ROOT_ID
+from bzrlib.errors import RevisionNotPresent, NotBranchError
from bzrlib.progress import ProgressBar
+from bzrlib.revision import NULL_REVISION
from bzrlib.trace import mutter
from bzrlib.transport import get_transport
from bzrlib.knit import KnitVersionedFile
:param branch: Branch path of the branch in which the file was introduced.
:param path: Original path of the file.
"""
- if path == "":
- return ROOT_ID
- introduced_revision_id = generate_svn_revision_id(uuid, revnum, branch)
- return "%s-%s" % (introduced_revision_id, escape_svn_path(path))
+ # FIXME: is the branch path required here?
+ return "svn-v%d:%d@%s-%s-%s" % (MAPPING_VERSION, revnum,
+ uuid, escape_svn_path(branch), escape_svn_path(path))
def generate_file_id(revid, path):
return map
- def apply_changes(self, uuid, revnum, branch, global_changes, map):
+ def apply_changes(self, uuid, revnum, branch, global_changes, map,
+ renames={}):
"""Change file id map to incorporate specified changes.
:param uuid: UUID of repository changes happen in
revid = generate_svn_revision_id(uuid, revnum, branch)
- return self._apply_changes(map, revid, changes, find_children)
+ return self._apply_changes(map, revid, changes, find_children, renames)
def get_map(self, uuid, revnum, branch, pb=None):
"""Make sure the map is up to date until revnum."""
# First, find the last cached map
todo = []
next_parent_revs = []
- map = {"": (ROOT_ID, None)} # No history -> empty map
+
+ if revnum == 0:
+ return {}
+
+ # No history -> empty map
for (bp, paths, rev) in self._log.follow_history(branch, revnum):
revid = generate_svn_revision_id(uuid, rev, bp)
map = self.load(revid)
else:
todo.append((revid, paths))
continue
+
+ if len(next_parent_revs) == 0:
+ if self._log.scheme.is_branch(""):
+ map = {"": (generate_svn_file_id(uuid, 0, "", ""), NULL_REVISION)}
+ else:
+ map = {}
# target revision was present
if len(todo) == 0:
class SimpleFileIdMap(FileIdMap):
@staticmethod
- def _apply_changes(map, revid, changes, find_children=None):
- map[""] = (ROOT_ID, revid)
-
+ def _apply_changes(map, revid, changes, find_children=None, renames={}):
+ def new_file_id(path):
+ mutter('new file id for %r. renames: %r' % (path, renames))
+ if renames.has_key(path):
+ return renames[path]
+ return generate_file_id(revid, path)
sorted_paths = changes.keys()
sorted_paths.sort()
for p in sorted_paths:
del map[c]
if data[0] in ('A', 'R'):
- map[p] = generate_file_id(revid, p), revid
+ map[p] = new_file_id(p), revid
if not data[1] is None:
mutter('%r:%s copied from %r:%s' % (p, revid, data[1], data[2]))
warn('incomplete data for %r' % p)
else:
for c in find_children(data[1], data[2]):
- map[c.replace(data[1], p, 1)] = generate_file_id(revid, c), revid
+ map[c.replace(data[1], p, 1)] = new_file_id(c), revid
elif data[0] == 'M':
- if p == "":
- map[p] = (ROOT_ID, "")
assert map.has_key(p), "Map has no item %s to modify" % p
map[p] = map[p][0], revid
class NotSvnBranchPath(BzrError):
- _fmt = """{%(branch_path)s} is not a valid Svn branch path"""
+ _fmt = """{%(branch_path)s}:%(revnum)s is not a valid Svn branch path"""
- def __init__(self, branch_path):
+ def __init__(self, branch_path, revnum=None):
BzrError.__init__(self)
self.branch_path = branch_path
+ self.revnum = revnum
class LogWalker(object):
return
if not branch_path is None and not self.scheme.is_branch(branch_path):
- raise NotSvnBranchPath(branch_path)
+ raise NotSvnBranchPath(branch_path, revnum)
if branch_path:
branch_path = branch_path.strip("/")
This document specifies mapping between Subversion and Bazaar semantics.
-Revision: 2
+Revision: 3
Jelmer Vernooij <jelmer@samba.org>, June 2006.
Updated October 2006.
+Updated December 2006.
== Branch paths ==
revision X and a file in revision Y are the same without traversing over all
the revisions between X and Y.
-Fileids are generated by concatenating a revision id and the path of the file
-from the revision it was added or was copied from another file.
+File ids use the following syntax:
-Since / is forbidden in revision ids, the '/', '-', '%' and all whitespace
+svn-v<MAPPING_VERSION>:<REVNO>@<UUID>-<BRANCHPATH>-<PATH>
+
+Since / is forbidden in file ids, the '/', '-', '%' and all whitespace
characters are urlencoded.
+The same rules apply to the roots of branches. This means there is no
+predefined file id for tree roots.
+
+Alternatively, these file ids can be mapped to more specific file ids. Such
+a map should be stored in the `bzr:file-ids' property that is set on the
+branch path.
+
+The bzr:file-ids property should contain a list of mappings. Entries are
+separated by newlines. The path in the branch and new file-id are separated
+by a tab.
+
+Given, the path, the revision the mapping was added, the repository uuid
+and the path the property is set on the (the branch path), the original
+file id can be determined.
+
+Tabs, newlines and percent signs in path will be urlencoded.
+
+Neither the original nor the target file id may occur more than once.
+
+The entries are sorted by revnum (highest revnum last). Within a specific
+revnum, the order is not specified.
+
NEXT VERSION: Special rules are applied to make sure that renames are tracked.
== Properties ==
Revision 1 was the original version of this document.
-Revision 2 uses real file ids for the tree root rather than the hardcoded
-"TREE_ROOT" and enforces UTF-8-valid characters for everything except file
+Revision 2 enforces UTF-8-valid characters for everything except file
contents.
+
+Revision 3 uses real file ids for the tree root rather than the hardcoded
+"TREE_ROOT" and adds the file id map.
NoSuchRevision, NotBranchError,
UninitializableFormat)
from bzrlib.graph import Graph
-from bzrlib.inventory import Inventory, ROOT_ID
+from bzrlib.inventory import Inventory
from bzrlib.lockable_files import LockableFiles, TransportLock
import bzrlib.osutils as osutils
from bzrlib.progress import ProgressBar
from bzrlib.repository import Repository, RepositoryFormat
+from bzrlib.revisiontree import RevisionTree
from bzrlib.revision import Revision, NULL_REVISION
from bzrlib.transport import Transport
from bzrlib.trace import mutter
MAPPING_VERSION = 2
REVISION_ID_PREFIX = "svn-v%d:" % MAPPING_VERSION
SVN_PROP_BZR_MERGE = 'bzr:merge'
+SVN_PROP_BZR_FILEIDS = 'bzr:file-ids'
SVN_PROP_SVK_MERGE = 'svk:merge'
SVN_PROP_BZR_REVPROP_PREFIX = 'bzr:revprop:'
SVN_REVPROP_BZR_SIGNATURE = 'bzr:gpg-signature'
-_unsafe = "%/-\t "
-def escape_svn_path(id):
- r = [((c in _unsafe) and ('%%%02x' % ord(c)) or c)
+def escape_svn_path(id, unsafe="%/-\t \n"):
+ assert "%" in unsafe
+ r = [((c in unsafe) and ('%%%02x' % ord(c)) or c)
for c in id]
return ''.join(r)
def get_fileid_map(self, revnum, path, pb=None):
return self.fileid_map.get_map(self.uuid, revnum, path, pb)
- def transform_fileid_map(self, uuid, revnum, branch, changes, map):
- return self.fileid_map.apply_changes(uuid, revnum, branch, changes, map)
+ def transform_fileid_map(self, uuid, revnum, branch, changes, map, renames):
+ return self.fileid_map.apply_changes(uuid, revnum, branch, changes, map, renames)
def path_to_file_id(self, revnum, path):
"""Generate a bzr file id from a Subversion file name.
This implementation DOES NOT track renames.
+ Use get_fileid_map() directly instead of calling this function
+ multiple times if possible.
+
:param revnum: Revision number.
:param path: Absolute path.
:return: Tuple with file id and revision id.
path = path.strip("/")
+ if revnum == 0:
+ from fileids import generate_svn_file_id
+ return (generate_svn_file_id(self.uuid, 0, "", ""), NULL_REVISION)
+
(bp, rp) = self.scheme.unprefix(path)
revid = self.generate_revision_id(revnum, bp)
revision_id = NULL_REVISION
if revision_id == NULL_REVISION:
- inventory = Inventory(ROOT_ID)
+ inventory = Inventory(root_id=None)
+ inventory.revision_id = revision_id
+ return RevisionTree(self, inventory, revision_id)
return SvnRevisionTree(self, revision_id, inventory)
+ def revision_fileid_renames(self, revid):
+ (path, revnum) = self.parse_revision_id(revid)
+ items = self._get_branch_prop(path, revnum,
+ SVN_PROP_BZR_FILEIDS, "").splitlines()
+ return dict(map(lambda x: x.split("\t"), items))
+
def revision_parents(self, revision_id, merged_data=None):
(path, revnum) = self.parse_revision_id(revision_id)
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-from bzrlib.branch import BranchReferenceFormat
-from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
+from bzrlib.branch import Branch, BranchReferenceFormat
+from bzrlib.bzrdir import BzrDir, BzrDirFormat
from bzrlib.errors import DivergedBranches
from bzrlib.inventory import Inventory
from bzrlib.workingtree import WorkingTree
import os
import format
import checkout
+import svn.core
from repository import MAPPING_VERSION
from tests import TestCaseWithSubversionRepository
self.repos_url = self.make_repository('d')
source = BzrDir.open("svn+"+self.repos_url)
os.mkdir('dc')
- self.checkout = BzrDirMetaFormat1().initialize('dc')
+ self.checkout = BzrDirFormat.get_default_format().initialize('dc')
BranchReferenceFormat().initialize(self.checkout, source.open_branch())
def test_simple_commit(self):
wt.commit(message="data")
wt.add('foo')
wt.add('foo/bla')
+ self.assertTrue(wt.inventory.has_filename("bla"))
+ self.assertTrue(wt.inventory.has_filename("foo/bla"))
wt.set_pending_merges(["some-ghost-revision"])
wt.commit(message="data")
self.assertEqual([
self.assertEqual("some-ghost-revision\n",
self.client_get_prop(self.repos_url, "bzr:merge", 2))
+ def test_commit_fileids(self):
+ wt = self.checkout.create_workingtree()
+ self.build_tree({'dc/file': 'data'})
+ wt.add('file')
+ wt.commit(message="Commit from Bzr")
+ self.assertEqual("\t%s\nfile\t%s\n" % (wt.inventory.root.file_id, wt.inventory.path2id("file")),
+ self.client_get_prop(self.repos_url, "bzr:file-ids", 1))
+
+ def test_commit_fileids_added(self):
+
+ rev = svn.core.svn_opt_revision_t()
+ rev.kind = svn.core.svn_opt_revision_head
+
+ svn.client.checkout2(self.repos_url, "db",
+ rev, rev, True, False, self.client_ctx)
+
+ self.build_tree({'dc/file1': 'data', 'db/file2': "otherdata"})
+ self.client_add("db/file2")
+ self.client_commit("db", "amesg")
+ branch = Branch.open(self.repos_url)
+ inv = branch.repository.get_inventory(branch.last_revision())
+ wt = self.checkout.create_workingtree()
+ self.assertEqual(wt.inventory.root.file_id, inv.root.file_id)
+ wt.add('file1')
+ wt.commit(message="Commit from Bzr")
+ self.assertEqual("file1\t%s\n" % wt.inventory.path2id("file1"),
+ self.client_get_prop(self.repos_url, "bzr:file-ids", 2))
+
def test_commit_branchnick(self):
wt = self.checkout.create_workingtree()
self.build_tree({'dc/foo/bla': "data", 'dc/bla': "otherdata"})
self.assertTrue(wt.branch.last_revision() in
repos.get_ancestry("svn-v%d:3@%s-" % (MAPPING_VERSION, repos.uuid)))
+
revid)
class TestFileMapping(TestCase):
- def apply_mappings(self, mappings, find_children=None):
- map = {}
+ def apply_mappings(self, mappings, find_children=None, renames={}):
+ map = {"": ("ROOT", "first-revision") }
revids = mappings.keys()
revids.sort()
for r in revids:
+ if not renames.has_key(r):
+ renames[r] = {}
map = SimpleFileIdMap._apply_changes(map, r, mappings[r],
- find_children)
+ find_children, renames=renames[r])
return map
def test_simple(self):
map = self.apply_mappings({"svn-v%d:1@uuid-" % MAPPING_VERSION: {"foo": ('A', None, None)}})
- self.assertEqual({'': ('TREE_ROOT', "svn-v%d:1@uuid-" % MAPPING_VERSION),
+ self.assertEqual({'': ('ROOT', "first-revision"),
'foo': ("svn-v%d:1@uuid--foo" % MAPPING_VERSION,
"svn-v%d:1@uuid-" % MAPPING_VERSION)
}, map)
"foo/bla": ('M', None, None)}
})
self.assertEqual("svn-v%d:2@uuid-" % MAPPING_VERSION, map["foo"][1])
+
+ def test_usemap(self):
+ map = self.apply_mappings(
+ {("svn-v%d:1@uuid-" % MAPPING_VERSION): {
+ "foo": ('A', None, None),
+ "foo/bla": ('A', None, None)},
+ ("svn-v%d:2@uuid-" % MAPPING_VERSION): {
+ "foo/bla": ('M', None, None)}
+ },
+ renames={("svn-v%d:1@uuid-" % MAPPING_VERSION): {"foo": "myid"}})
+ self.assertEqual("myid", map["foo"][0])
+
+ def test_usemap_later(self):
+ map = self.apply_mappings(
+ {("svn-v%d:1@uuid-" % MAPPING_VERSION): {
+ "foo": ('A', None, None),
+ "foo/bla": ('A', None, None)},
+ ("svn-v%d:2@uuid-" % MAPPING_VERSION): {
+ "foo/bla": ('M', None, None)}
+ },
+ renames={("svn-v%d:2@uuid-" % MAPPING_VERSION): {"foo": "myid"}})
+ self.assertEqual("svn-v%d:1@uuid--foo" % MAPPING_VERSION, map["foo"][0])
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+from bzrlib.branch import Branch
from bzrlib.bzrdir import BzrDir
from bzrlib.errors import NoSuchRevision
from bzrlib.inventory import Inventory
repository.revision_parents(
"svn-v%d:2@%s-" % (MAPPING_VERSION, repository.uuid)))
+ def test_revision_fileidmap(self):
+ repos_url = self.make_client('d', 'dc')
+ self.build_tree({'dc/foo': "data"})
+ self.client_add("dc/foo")
+ self.client_set_prop("dc", "bzr:file-ids", "foo\tsomeid\n")
+ self.client_commit("dc", "My Message")
+ repository = Repository.open("svn+%s" % repos_url)
+ tree = repository.revision_tree(Branch.open(repos_url).last_revision())
+ self.assertEqual("someid", tree.inventory.path2id("foo"))
+ self.assertFalse("svn-v2:1@%s--foo" % repository.uuid in tree.inventory)
+
def test_revision_ghost_parents(self):
repos_url = self.make_client('d', 'dc')
self.build_tree({'dc/foo': "data"})
repository = Repository.open("svn+%s" % repos_url)
self.assertTrue(repository.is_shared())
+ def test_revision_fileid_renames(self):
+ repos_url = self.make_client('d', 'dc')
+ self.build_tree({'dc/test': "data"})
+ self.client_add("dc/test")
+ self.client_set_prop("dc", "bzr:file-ids", "test\tbla\n")
+ self.client_commit("dc", "Msg")
+
+ repos = Repository.open(repos_url)
+ renames = repos.revision_fileid_renames("svn-v%d:1@%s-" % (MAPPING_VERSION, repos.uuid))
+ self.assertEqual({"test": "bla"}, renames)
+
def test_fetch_local(self):
repos_url = self.make_client('d', 'dc')
self.build_tree({'dc/foo/bla': "data"})
self.assertTrue(inventory[inventory.path2id("foo/bla")].executable)
+
def test_symlink(self):
os.symlink('foo/bla', 'dc/bar')
self.client_add('dc/bar')
t = SvnRaTransport(repos_url)
self.assertEqual("%s/dir" % repos_url, t.clone('dir').base)
-
+
def test_get_root(self):
repos_url = self.make_client('d', 'dc')
self.build_tree({"dc/dir": None, "dc/bl": "data"})
from bzrlib.branch import Branch
from bzrlib.bzrdir import BzrDir
from bzrlib.errors import NoSuchRevision, NoSuchFile
-from bzrlib.inventory import Inventory, ROOT_ID
+from bzrlib.inventory import Inventory
from bzrlib.revision import NULL_REVISION
from bzrlib.trace import mutter
from bzrlib.workingtree import WorkingTree
self.make_client('a', 'dc')
wt = WorkingTree.open("dc")
self.assertEqual(NULL_REVISION, wt.basis_tree().inventory.revision_id)
- self.assertEqual(Inventory(), wt.basis_tree().inventory)
+ self.assertEqual(Inventory(root_id=None), wt.basis_tree().inventory)
def test_basis_tree(self):
self.make_client('a', 'dc')
self.client_add("dc/test")
tree = WorkingTree.open("dc")
inv = tree.read_working_inventory()
- self.assertEqual(ROOT_ID, inv.path2id(""))
+ self.assertEqual(inv.path2id(""), inv.root.file_id)
self.assertTrue(inv.path2id("foo") != "")
self.assertTrue(inv.has_filename("bl"))
self.assertTrue(inv.has_filename("foo"))
from binascii import hexlify
from bzrlib.bzrdir import BzrDirFormat
from bzrlib.errors import NotBranchError, NoSuchFile
-from bzrlib.inventory import (Inventory, InventoryDirectory, InventoryFile,
- ROOT_ID)
+from bzrlib.inventory import (Inventory, InventoryDirectory, InventoryFile)
from bzrlib.lockable_files import TransportLock, LockableFiles
from bzrlib.lockdir import LockDir
import bzrlib.osutils as osutils
def __init__(self, repository, revision_id, inventory=None):
self._repository = repository
self._revision_id = revision_id
- if revision_id == NULL_REVISION:
- self._inventory = Inventory(ROOT_ID)
- self._inventory.revision_id = NULL_REVISION
- else:
- (self.branch_path, self.revnum) = repository.parse_revision_id(revision_id)
- self._inventory = Inventory(ROOT_ID)
- self._inventory.revision_id = revision_id
- self.id_map = repository.get_fileid_map(self.revnum, self.branch_path)
- self.editor = TreeBuildEditor(self)
- self.file_data = {}
+ (self.branch_path, self.revnum) = repository.parse_revision_id(revision_id)
+ self.id_map = repository.get_fileid_map(self.revnum, self.branch_path)
+ self._inventory = Inventory(root_id=self.id_map[""][0])
+ self._inventory.revision_id = revision_id
+ self.editor = TreeBuildEditor(self)
+ self.file_data = {}
- editor, baton = svn.delta.make_editor(self.editor)
+ editor, baton = svn.delta.make_editor(self.editor)
- root_repos = repository.transport.get_repos_root()
- mutter('svn checkout -r %r %r' % (self.revnum, self.branch_path))
- reporter, reporter_baton = repository.transport.do_switch(
- self.revnum, "", True,
- os.path.join(root_repos, self.branch_path), editor, baton)
+ root_repos = repository.transport.get_repos_root()
+ mutter('svn checkout -r %r %r' % (self.revnum, self.branch_path))
+ reporter, reporter_baton = repository.transport.do_switch(
+ self.revnum, "", True,
+ os.path.join(root_repos, self.branch_path), editor, baton)
- svn.ra.reporter2_invoke_set_path(reporter, reporter_baton, "", 0, True, None)
+ svn.ra.reporter2_invoke_set_path(reporter, reporter_baton, "", 0, True, None)
- svn.ra.reporter2_invoke_finish_report(reporter, reporter_baton)
+ svn.ra.reporter2_invoke_finish_report(reporter, reporter_baton)
def get_file_lines(self, file_id):
return osutils.split_lines(self.file_data[file_id])
self.revnum = revnum
def open_root(self, revnum, baton):
- return ROOT_ID
+ return self.tree.id_map[""][0]
def relpath(self, path):
bp, rp = self.tree._repository.scheme.unprefix(path)
elif name == svn.core.SVN_PROP_IGNORE:
self.dir_ignores[id] = value
elif name == SVN_PROP_BZR_MERGE or name == SVN_PROP_SVK_MERGE:
- if id != ROOT_ID:
+ if id != self.tree.id_map[""][0]:
mutter('%r set on non-root dir!' % SVN_PROP_BZR_MERGE)
return
elif name in (svn.core.SVN_PROP_ENTRY_COMMITTED_DATE,