Rev 357: Store file id maps when committing to Subversion. Fixes #54738. in http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev
Jelmer Vernooij
jelmer at samba.org
Mon Jan 1 22:19:50 GMT 2007
------------------------------------------------------------
revno: 357
revision-id: jelmer at samba.org-20070101221853-z74gmy058bm6z1j0
parent: jelmer at samba.org-20070101214906-cw23w5x9ytcf1ia0
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: main
timestamp: Mon 2007-01-01 23:18:53 +0100
message:
Store file id maps when committing to Subversion. Fixes #54738.
modified:
NEWS news-20061231030336-h9fhq245ie0de8bs-1
commit.py commit.py-20060607190346-qvq128wgfubhhgm2-1
fetch.py fetch.py-20060625004942-x2lfaib8ra707a8p-1
fileids.py fileids.py-20060714013623-u5iiyqqnko11grcf-1
repository.py repository.py-20060306123302-1f8c5069b3fe0265
tests/test_commit.py test_commit.py-20060624213521-l5kcufywkh9mnilk-1
tests/test_fileids.py test_fileids.py-20060622131341-19gyrlgqy8yl2od5-1
=== modified file 'NEWS'
--- a/NEWS 2007-01-01 17:36:22 +0000
+++ b/NEWS 2007-01-01 22:18:53 +0000
@@ -32,6 +32,8 @@
* Don't try to import files as branches.
+ * Store file id map when committing to Subversion. (#54738)
+
IMPROVEMENTS
* Implemented SvnRepository.all_revision_ids().
=== modified file 'commit.py'
--- a/commit.py 2007-01-01 21:49:06 +0000
+++ b/commit.py 2007-01-01 22:18:53 +0000
@@ -21,19 +21,18 @@
DivergedBranches)
from bzrlib.inventory import Inventory, ROOT_ID
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.
@@ -332,6 +331,44 @@
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)
=== modified file 'fetch.py'
--- a/fetch.py 2007-01-01 21:49:06 +0000
+++ b/fetch.py 2007-01-01 22:18:53 +0000
@@ -346,8 +346,9 @@
parent_inv = prev_inv
changes = self.source._log.get_revision_paths(revnum, branch)
+ renames = self.source.revision_fileid_renames(revid)
id_map = self.source.transform_fileid_map(self.source.uuid,
- revnum, branch, changes)
+ revnum, branch, changes, renames)
editor = RevisionBuildEditor(self.source, self.target, branch,
parent_inv, revid,
=== modified file 'fileids.py'
--- a/fileids.py 2006-12-30 17:43:09 +0000
+++ b/fileids.py 2007-01-01 22:18:53 +0000
@@ -118,7 +118,7 @@
return map
def apply_changes(self, uuid, revnum, branch, global_changes,
- find_children=None):
+ renames, find_children=None):
"""Change file id map to incorporate specified changes.
:param uuid: UUID of repository changes happen in
@@ -141,8 +141,10 @@
return self._apply_changes(lambda x: generate_file_id(revid, x),
changes, get_children)
- def get_map(self, uuid, revnum, branch):
+ def get_map(self, uuid, revnum, branch, renames_cb=None):
"""Make sure the map is up to date until revnum."""
+ if renames_cb is None:
+ renames_cb = lambda x: {}
# First, find the last cached map
todo = []
next_parent_revs = []
@@ -178,9 +180,15 @@
yield self.repos.scheme.unprefix(p)[1]
parent_revs = next_parent_revs
+
+ renames = renames_cb(revid)
+
+ def new_file_id(x):
+ if renames.has_key(x):
+ return renames[x]
+ return generate_file_id(revid, x)
- revmap = self._apply_changes(lambda x: generate_file_id(revid, x),
- changes, find_children)
+ revmap = self._apply_changes(new_file_id, changes, find_children)
for p in changes:
if changes[p][0] == 'M':
revmap[p] = map[p][0]
=== modified file 'repository.py'
--- a/repository.py 2007-01-01 21:49:06 +0000
+++ b/repository.py 2007-01-01 22:18:53 +0000
@@ -21,10 +21,11 @@
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.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
@@ -55,9 +56,9 @@
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)
@@ -255,10 +256,12 @@
return self.revision_tree(revision_id).inventory
def get_fileid_map(self, revnum, path):
- return self.fileid_map.get_map(self.uuid, revnum, path)
+ return self.fileid_map.get_map(self.uuid, revnum, path,
+ self.revision_fileid_renames)
- def transform_fileid_map(self, uuid, revnum, branch, changes):
- return self.fileid_map.apply_changes(uuid, revnum, branch, changes)
+ def transform_fileid_map(self, uuid, revnum, branch, changes, renames):
+ return self.fileid_map.apply_changes(uuid, revnum, branch, changes,
+ renames)
def path_to_file_id(self, revnum, path):
"""Generate a bzr file id from a Subversion file name.
@@ -270,6 +273,10 @@
assert isinstance(revnum, int) and revnum >= 0
assert isinstance(path, basestring)
+ 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)
try:
@@ -341,10 +348,18 @@
revision_id = NULL_REVISION
if revision_id == NULL_REVISION:
- inventory = Inventory(ROOT_ID)
+ inventory = Inventory()
+ 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.branchprop_list.get_property_diff(path, revnum,
+ SVN_PROP_BZR_FILEIDS).splitlines()
+ return dict(map(lambda x: x.split("\t"), items))
+
def _mainline_revision_parent(self, path, revnum):
assert isinstance(path, basestring)
assert isinstance(revnum, int)
=== modified file 'tests/test_commit.py'
--- a/tests/test_commit.py 2007-01-01 21:49:06 +0000
+++ b/tests/test_commit.py 2007-01-01 22:18:53 +0000
@@ -159,7 +159,7 @@
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.assertEqual("file\t%s\n" % wt.inventory.path2id("file"),
self.client_get_prop(self.repos_url, "bzr:file-ids", 1))
def test_commit_fileids_added(self):
=== modified file 'tests/test_fileids.py'
--- a/tests/test_fileids.py 2007-01-01 21:49:06 +0000
+++ b/tests/test_fileids.py 2007-01-01 22:18:53 +0000
@@ -214,7 +214,8 @@
("svn-v%d:2 at uuid-" % MAPPING_VERSION): {
"foo/bla": ('M', None, None)}
})
- self.assertEqual("svn-v%d:2 at uuid-" % MAPPING_VERSION, map["foo"][1])
+ self.assertEqual("svn-v%d:1 at uuid-" % MAPPING_VERSION, map["foo"][1])
+ self.assertEqual("svn-v%d:1 at uuid-" % MAPPING_VERSION, map["foo/bla"][1])
def test_usemap(self):
map = self.apply_mappings(
More information about the bazaar-commits
mailing list