Rev 440: True push works, with some limits. in file:///home/jelmer/bzr-svn/customrevids/
Jelmer Vernooij
jelmer at samba.org
Fri May 18 13:22:58 BST 2007
At file:///home/jelmer/bzr-svn/customrevids/
------------------------------------------------------------
revno: 440
revision-id: jelmer at samba.org-20070518122257-v826cvviwuo5xq8b
parent: jelmer at samba.org-20070518110606-ghip0jetjq210xdg
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: customrevids
timestamp: Fri 2007-05-18 13:22:57 +0100
message:
True push works, with some limits.
modified:
BRANCH.TODO branch.todo-20070516183134-f9xjfbsv6x6u6x2t-1
branch.py svnbranch.py-20051017135706-11c749eb0dab04a7
commit.py commit.py-20060607190346-qvq128wgfubhhgm2-1
repository.py repository.py-20060306123302-1f8c5069b3fe0265
tests/test_commit.py test_commit.py-20060624213521-l5kcufywkh9mnilk-1
tests/test_push.py test_push.py-20070201165715-g2ievcdfqi33wqsy-1
tests/test_repos.py test_repos.py-20060508151940-ddc49a59257ca712
tree.py tree.py-20060624222557-dudlwqcmkf22lt2s-1
=== modified file 'BRANCH.TODO'
--- a/BRANCH.TODO 2007-05-18 02:01:15 +0000
+++ b/BRANCH.TODO 2007-05-18 12:22:57 +0000
@@ -1,3 +1,6 @@
-- keep revision ids when doing true pushes
- add tests to make sure a revision is still 100% the same after being pushed
to subversion
+ still not kept:
+ - timestamp
+ - timezone
+ - committer
=== modified file 'branch.py'
--- a/branch.py 2007-05-17 19:04:30 +0000
+++ b/branch.py 2007-05-18 12:22:57 +0000
@@ -24,7 +24,7 @@
import svn.client, svn.core
-from commit import push_as_merged
+from commit import push
from repository import SvnRepository
from transport import bzr_to_svn_url, svn_config
@@ -226,7 +226,7 @@
else:
for rev_id in self.missing_revisions(other, stop_revision):
mutter('pushing %r to Svn branch' % rev_id)
- push_as_merged(self, other, rev_id)
+ push(self, other, rev_id)
# The remote server handles all this for us
def lock_write(self):
=== modified file 'commit.py'
--- a/commit.py 2007-05-18 11:06:06 +0000
+++ b/commit.py 2007-05-18 12:22:57 +0000
@@ -84,10 +84,15 @@
self._svnprops[SVN_PROP_SVK_MERGE] = old + new
if revision_id is not None:
- extra = "%s\n" % revision_id
- if not self._svnprops.has_key(SVN_PROP_BZR_REVISION_ID):
- self._svnprops[SVN_PROP_BZR_REVISION_ID] = ""
- self._svnprops[SVN_PROP_BZR_REVISION_ID] += extra
+ if branch.last_revision():
+ (bp, revnum) = repository.lookup_revision_id(branch.last_revision())
+ old = repository.branchprop_list.get_property(bp, revnum,
+ SVN_PROP_BZR_REVISION_ID, "")
+ else:
+ old = ""
+
+ self._svnprops[SVN_PROP_BZR_REVISION_ID] = old + \
+ "%s\n" % revision_id
# At least one of the parents has to be the last revision on the
# mainline in # Subversion.
@@ -384,6 +389,28 @@
ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
+def replay_delta(builder, delta, old_tree):
+ for (_, ie) in builder.new_inventory.entries():
+ if not delta.touches_file_id(ie.file_id):
+ continue
+
+ id = ie.file_id
+ while builder.new_inventory[id].parent_id is not None:
+ if builder.new_inventory[id].revision is None:
+ break
+ builder.new_inventory[id].revision = None
+ if builder.new_inventory[id].kind == 'directory':
+ builder.modified_directory(id, [])
+ id = builder.new_inventory[id].parent_id
+
+ if ie.kind == 'link':
+ builder.modified_link(ie.file_id, [], ie.symlink_target)
+ elif ie.kind == 'file':
+ def get_text():
+ return old_tree.get_file_text(ie.file_id)
+ builder.modified_file_text(ie.file_id, [], get_text)
+
+
def push_as_merged(target, source, revision_id):
"""Push a revision as merged revision.
@@ -422,27 +449,46 @@
delta = new_tree.changes_from(old_tree)
builder.new_inventory = inv
-
- for (_, ie) in inv.entries():
- if not delta.touches_file_id(ie.file_id):
- continue
-
- id = ie.file_id
- while inv[id].parent_id is not None:
- if inv[id].revision is None:
- break
- inv[id].revision = None
- if inv[id].kind == 'directory':
- builder.modified_directory(id, [])
- id = inv[id].parent_id
-
- if ie.kind == 'link':
- builder.modified_link(ie.file_id, [], ie.symlink_target)
- elif ie.kind == 'file':
- def get_text():
- return old_tree.get_file_text(ie.file_id)
- builder.modified_file_text(ie.file_id, [], get_text)
-
+ replay_delta(builder, delta, old_tree)
+
+ try:
+ return builder.commit(rev.message)
+ except SubversionException, (_, num):
+ if num == svn.core.SVN_ERR_FS_TXN_OUT_OF_DATE:
+ raise DivergedBranches(source, target)
+ raise
+
+def push(target, source, revision_id):
+ """Push a revision into Subversion.
+
+ This will do a new commit in the target branch.
+
+ :param target: Repository to push to
+ :param source: Repository to pull the revision from
+ :param revision_id: Revision id of the revision to push
+ """
+ assert isinstance(source, Branch)
+ rev = source.repository.get_revision(revision_id)
+ inv = source.repository.get_inventory(revision_id)
+
+ # revision on top of which to commit
+ assert target.last_revision() in rev.parent_ids
+
+ mutter('pushing %r' % (revision_id))
+
+ old_tree = source.repository.revision_tree(revision_id)
+ new_tree = source.repository.revision_tree(target.last_revision())
+
+ builder = SvnCommitBuilder(target.repository, target,
+ rev.parent_ids,
+ target.get_config(),
+ rev.properties,
+ revision_id,
+ new_tree.inventory)
+
+ delta = new_tree.changes_from(old_tree)
+ builder.new_inventory = inv
+ replay_delta(builder, delta, old_tree)
try:
return builder.commit(rev.message)
except SubversionException, (_, num):
=== modified file 'repository.py'
--- a/repository.py 2007-05-18 02:01:15 +0000
+++ b/repository.py 2007-05-18 12:22:57 +0000
@@ -205,7 +205,7 @@
(path, revnum) = self.lookup_revision_id(revision_id)
- ancestry = []
+ ancestry = [revision_id]
for l in self.branchprop_list.get_property(path, revnum,
SVN_PROP_BZR_MERGE, "").splitlines():
=== modified file 'tests/test_commit.py'
--- a/tests/test_commit.py 2007-05-18 01:46:26 +0000
+++ b/tests/test_commit.py 2007-05-18 12:22:57 +0000
@@ -224,11 +224,13 @@
repos = self.olddir.find_repository()
inv = repos.get_inventory(repos.generate_revision_id(2, ""))
+ import pdb
+ pdb.set_trace()
self.assertEqual(repos.generate_revision_id(2, ""),
inv[inv.path2id('foo/bla')].revision)
self.assertTrue(wt.branch.last_revision() in
repos.revision_parents(repos.generate_revision_id(2, "")))
- self.assertEqual(repos.generate_revision_id(2, ""),
+ self.assertEqual(wt.branch.last_revision(),
self.olddir.open_branch().last_revision())
self.assertEqual("other data",
repos.revision_tree(repos.generate_revision_id(2, "")).get_file_text( inv.path2id("foo/bla")))
@@ -244,9 +246,8 @@
repos = self.olddir.find_repository()
inv = repos.get_inventory(repos.generate_revision_id(2, ""))
self.assertTrue(inv.has_filename('file'))
- self.assertTrue(wt.branch.last_revision() in
- repos.revision_parents(
- repos.generate_revision_id(2, "")))
+ self.assertEqual(wt.branch.last_revision(),
+ repos.generate_revision_id(2, ""))
self.assertEqual(repos.generate_revision_id(2, ""),
self.olddir.open_branch().last_revision())
@@ -261,8 +262,9 @@
repos = self.olddir.find_repository()
inv = repos.get_inventory(repos.generate_revision_id(2, ""))
self.assertTrue(inv.has_filename('file'))
- self.assertTrue(wt.branch.last_revision() in
- repos.revision_parents(repos.generate_revision_id(2, "")))
+ self.assertEquals(wt.branch.last_revision(),
+ repos.generate_revision_id(2, ""))
+
self.assertEqual(repos.generate_revision_id(2, ""),
self.olddir.open_branch().last_revision())
@@ -296,34 +298,6 @@
repos.get_revision(repos.generate_revision_id(2, "")).message.decode("utf-8"))
- def test_multiple(self):
- self.build_tree({'dc/file': 'data'})
- wt = self.newdir.open_workingtree()
- wt.add('file')
- wt.commit(message="Commit from Bzr")
-
- self.build_tree({'dc/file': 'data2', 'dc/adir': None})
- wt.add('adir')
- wt.commit(message="Another commit from Bzr")
-
- self.olddir.open_branch().pull(self.newdir.open_branch())
-
- repos = self.olddir.find_repository()
-
- self.assertEqual(repos.generate_revision_id(3, ""),
- self.olddir.open_branch().last_revision())
-
- inv = repos.get_inventory(repos.generate_revision_id(2, ""))
- self.assertTrue(inv.has_filename('file'))
- self.assertFalse(inv.has_filename('adir'))
-
- inv = repos.get_inventory(repos.generate_revision_id(3, ""))
- self.assertTrue(inv.has_filename('file'))
- self.assertTrue(inv.has_filename('adir'))
-
- self.assertTrue(wt.branch.last_revision() in
- repos.get_ancestry(repos.generate_revision_id(3, "")))
-
class TestPushNested(TestCaseWithSubversionRepository):
def setUp(self):
super(TestPushNested, self).setUp()
=== modified file 'tests/test_push.py'
--- a/tests/test_push.py 2007-05-18 11:06:06 +0000
+++ b/tests/test_push.py 2007-05-18 12:22:57 +0000
@@ -211,6 +211,10 @@
self.assertEqual(self.svndir.open_branch().revision_history(),
self.bzrdir.open_branch().revision_history())
- self.assertTrue(wt.branch.last_revision() in
- repos.get_ancestry(repos.generate_revision_id(3, "")))
+
+ self.assertEqual(wt.branch.last_revision(),
+ repos.generate_revision_id(3, ""))
+ self.assertEqual(
+ wt.branch.repository.get_ancestry(wt.branch.last_revision()),
+ repos.get_ancestry(wt.branch.last_revision()))
=== modified file 'tests/test_repos.py'
--- a/tests/test_repos.py 2007-05-18 01:46:26 +0000
+++ b/tests/test_repos.py 2007-05-18 12:22:57 +0000
@@ -456,19 +456,22 @@
self.assertEqual([None,
repository.generate_revision_id(0, ""),
repository.generate_revision_id(1, ""),
+ repository.generate_revision_id(2, ""),
+ repository.generate_revision_id(3, "")],
+ repository.get_ancestry(
+ repository.generate_revision_id(3, "")))
+ self.assertEqual([None,
+ repository.generate_revision_id(0, ""),
+ repository.generate_revision_id(1, ""),
repository.generate_revision_id(2, "")],
repository.get_ancestry(
- repository.generate_revision_id(3, "")))
- self.assertEqual([None,
- repository.generate_revision_id(0, ""),
- repository.generate_revision_id(1, "")],
- repository.get_ancestry(
repository.generate_revision_id(2, "")))
self.assertEqual([None,
- repository.generate_revision_id(0, "")],
+ repository.generate_revision_id(0, ""),
+ repository.generate_revision_id(1, "")],
repository.get_ancestry(
repository.generate_revision_id(1, "")))
- self.assertEqual([None],
+ self.assertEqual([None, repository.generate_revision_id(0, "")],
repository.get_ancestry(
repository.generate_revision_id(0, "")))
self.assertEqual([None], repository.get_ancestry(None))
@@ -558,15 +561,17 @@
self.build_tree({'dc/foo': "data2"})
self.client_commit("dc", "Second Message")
repository = Repository.open("svn+%s" % repos_url)
- self.assertEqual([None],
+ self.assertEqual([None, repository.generate_revision_id(0, "")],
repository.get_ancestry(
repository.generate_revision_id(0, "")))
- self.assertEqual([None, repository.generate_revision_id(0, "")],
+ self.assertEqual([None, repository.generate_revision_id(0, ""),
+ repository.generate_revision_id(1, "")],
repository.get_ancestry(
repository.generate_revision_id(1, "")))
self.assertEqual([None,
repository.generate_revision_id(0, ""),
- repository.generate_revision_id(1, "")],
+ repository.generate_revision_id(1, ""),
+ repository.generate_revision_id(2, "")],
repository.get_ancestry(
repository.generate_revision_id(2, "")))
@@ -579,16 +584,17 @@
self.build_tree({'dc/foo': "data2"})
self.client_commit("dc", "Second Message")
repository = Repository.open("svn+%s" % repos_url)
- self.assertEqual([None],
+ self.assertEqual([None, repository.generate_revision_id(0, "")],
repository.get_ancestry(
repository.generate_revision_id(0, "")))
- self.assertEqual([None, repository.generate_revision_id(0, "")],
+ self.assertEqual([None, repository.generate_revision_id(0, ""),
+ repository.generate_revision_id(1, "")],
repository.get_ancestry(
repository.generate_revision_id(1, "")))
self.assertEqual([None,
repository.generate_revision_id(0, ""),
repository.generate_revision_id(1, ""),
- "a-parent"],
+ "a-parent", repository.generate_revision_id(2, "")],
repository.get_ancestry(
repository.generate_revision_id(2, "")))
=== modified file 'tree.py'
--- a/tree.py 2007-05-17 19:04:30 +0000
+++ b/tree.py 2007-05-18 12:22:57 +0000
@@ -98,7 +98,7 @@
def change_dir_prop(self, id, name, value, pool):
from repository import (SVN_PROP_BZR_MERGE, SVN_PROP_SVK_MERGE,
SVN_PROP_BZR_PREFIX, SVN_PROP_BZR_REVPROP_PREFIX,
- SVN_PROP_BZR_FILEIDS)
+ SVN_PROP_BZR_FILEIDS, SVN_PROP_BZR_REVISION_ID)
if name == svn.core.SVN_PROP_ENTRY_COMMITTED_REV:
self.dir_revnum[id] = int(value)
@@ -122,6 +122,8 @@
pass
elif name.startswith(SVN_PROP_BZR_REVPROP_PREFIX):
pass
+ elif name == SVN_PROP_BZR_REVISION_ID:
+ pass
elif (name.startswith(svn.core.SVN_PROP_PREFIX) or
name.startswith(SVN_PROP_BZR_PREFIX)):
mutter('unsupported dir property %r' % name)
More information about the bazaar-commits
mailing list