Rev 422: Initial work on push and support for setting revision id during commit. in http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev

Jelmer Vernooij jelmer at samba.org
Thu Feb 1 17:36:39 GMT 2007


At http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev

------------------------------------------------------------
revno: 422
revision-id: jelmer at samba.org-20070201173614-9rzjpk5puez5rj11
parent: jelmer at samba.org-20070201103709-z4xm1j5cwaezzxt0
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: main
timestamp: Thu 2007-02-01 18:36:14 +0100
message:
  Initial work on push and support for setting revision id during commit.
added:
  tests/test_push.py             test_push.py-20070201165715-g2ievcdfqi33wqsy-1
modified:
  commit.py                      commit.py-20060607190346-qvq128wgfubhhgm2-1
  mapping.txt                    mapping.txt-20060625151311-9ghaqrm71ajq593n-1
  repository.py                  repository.py-20060306123302-1f8c5069b3fe0265
  tests/__init__.py              __init__.py-20060508151940-e9f4d914801a2535
  tests/test_commit.py           test_commit.py-20060624213521-l5kcufywkh9mnilk-1
=== added file 'tests/test_push.py'
--- a/tests/test_push.py	1970-01-01 00:00:00 +0000
+++ b/tests/test_push.py	2007-02-01 17:36:14 +0000
@@ -0,0 +1,172 @@
+# Copyright (C) 2006-2007 Jelmer Vernooij <jelmer at samba.org>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# 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
+
+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
+
+class TestPush(TestCaseWithSubversionRepository):
+    def setUp(self):
+        super(TestPush, self).setUp()
+        self.repos_url = self.make_client('d', 'sc')
+
+        self.build_tree({'sc/foo/bla': "data"})
+        self.client_add("sc/foo")
+        self.client_commit("sc", "foo")
+
+        self.svndir = BzrDir.open("sc")
+        os.mkdir("dc")
+        self.bzrdir = self.svndir.sprout("dc")
+
+    def test_empty(self):
+        svnbranch = self.svndir.open_branch()
+        bzrbranch = self.bzrdir.open_branch()
+        self.assertEqual(0, svnbranch.pull(bzrbranch))
+        self.assertEqual(svnbranch.revision_history(),
+                         bzrbranch.revision_history())
+
+    def test_child(self):
+        self.build_tree({'sc/foo/bar': "data"})
+        self.client_add("sc/foo/bar")
+        self.client_commit("sc", "second message")
+
+        svnbranch = self.svndir.open_branch()
+        bzrbranch = self.bzrdir.open_branch()
+        self.assertEqual(0, svnbranch.pull(bzrbranch))
+
+    def test_diverged(self):
+        self.build_tree({'sc/foo/bar': "data"})
+        self.client_add("sc/foo/bar")
+        self.client_commit("sc", "second message")
+
+        svndir = BzrDir.open("sc")
+
+        self.build_tree({'dc/file': 'data'})
+        wt = self.bzrdir.open_workingtree()
+        wt.add('file')
+        wt.commit(message="Commit from Bzr")
+
+        self.assertRaises(DivergedBranches, 
+                          svndir.open_branch().pull,
+                          self.bzrdir.open_branch())
+
+    def test_change(self):
+        self.build_tree({'dc/foo/bla': 'other data'})
+        wt = self.bzrdir.open_workingtree()
+        wt.commit(message="Commit from Bzr")
+
+        self.svndir.open_branch().pull(self.bzrdir.open_branch())
+
+        repos = self.svndir.find_repository()
+        inv = repos.get_inventory(repos.generate_revision_id(2, ""))
+        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.svndir.open_branch().last_revision())
+        self.assertEqual("other data", 
+            repos.revision_tree(repos.generate_revision_id(2, "")).get_file_text( inv.path2id("foo/bla")))
+
+    def test_simple(self):
+        self.build_tree({'dc/file': 'data'})
+        wt = self.bzrdir.open_workingtree()
+        wt.add('file')
+        wt.commit(message="Commit from Bzr")
+
+        self.svndir.open_branch().pull(self.bzrdir.open_branch())
+
+        repos = self.svndir.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(repos.generate_revision_id(2, ""),
+                        self.svndir.open_branch().last_revision())
+
+    def test_pull_after_push(self):
+        self.build_tree({'dc/file': 'data'})
+        wt = self.bzrdir.open_workingtree()
+        wt.add('file')
+        wt.commit(message="Commit from Bzr")
+
+        self.svndir.open_branch().pull(self.bzrdir.open_branch())
+
+        repos = self.svndir.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(repos.generate_revision_id(2, ""),
+                        self.svndir.open_branch().last_revision())
+
+        self.bzrdir.open_branch().pull(self.svndir.open_branch())
+
+        self.assertEqual(repos.generate_revision_id(2, ""),
+                        self.bzrdir.open_branch().last_revision())
+
+    def test_message(self):
+        self.build_tree({'dc/file': 'data'})
+        wt = self.bzrdir.open_workingtree()
+        wt.add('file')
+        wt.commit(message="Commit from Bzr")
+
+        self.svndir.open_branch().pull(self.bzrdir.open_branch())
+
+        repos = self.svndir.find_repository()
+        self.assertEqual("Commit from Bzr",
+            repos.get_revision(repos.generate_revision_id(2, "")).message)
+
+    def test_multiple(self):
+        self.build_tree({'dc/file': 'data'})
+        wt = self.bzrdir.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.svndir.open_branch().pull(self.bzrdir.open_branch())
+
+        repos = self.svndir.find_repository()
+
+        self.assertEqual(repos.generate_revision_id(3, ""), 
+                        self.svndir.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.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, "")))
+

=== modified file 'commit.py'
--- a/commit.py	2007-01-15 17:28:15 +0000
+++ b/commit.py	2007-02-01 17:36:14 +0000
@@ -26,14 +26,16 @@
 
 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)
+                        SVN_PROP_BZR_REVISION_ID, revision_id_to_svk_feature, 
+                        escape_svn_path)
 
 import os
 
 class SvnCommitBuilder(RootCommitBuilder):
     """Commit Builder implementation wrapped around svn_delta_editor. """
 
-    def __init__(self, repository, branch, parents, config, revprops):
+    def __init__(self, repository, branch, parents, config, revprops, 
+                 revision_id):
         """Instantiate a new SvnCommitBuilder.
 
         :param repository: SvnRepository to commit to.
@@ -41,6 +43,7 @@
         :param parents: List of parent revision ids.
         :param config: Branch configuration to use.
         :param revprops: Revision properties to set.
+        :param revision_id: Revision id for the new revision.
         """
         super(SvnCommitBuilder, self).__init__(repository, parents, 
             config, None, None, None, revprops, None)
@@ -80,6 +83,9 @@
             if new != "":
                 self._svnprops[SVN_PROP_SVK_MERGE] = old + new
 
+        if revision_id is not None:
+            self._svnprops[SVN_PROP_BZR_REVISION_ID] = revision_id
+
         # At least one of the parents has to be the last revision on the 
         # mainline in # Subversion.
         assert (self.branch.last_revision() is None or 

=== modified file 'mapping.txt'
--- a/mapping.txt	2007-01-14 01:56:13 +0000
+++ b/mapping.txt	2007-02-01 17:36:14 +0000
@@ -4,6 +4,7 @@
 Jelmer Vernooij <jelmer at samba.org>, June 2006.
 Updated October 2006.
 Updated January 2007.
+Updated February 2007.
 
 == Branch paths ==
 
@@ -65,6 +66,19 @@
 svn-v3-trunk-1:0c0555d6-39d7-0310-84fc-f1cc0bd64818:branches%2Ffoobranch:14323
 }}}
 
+It is also possible that the revision id for a particular revision is 
+stored in a revision property. To guarantee that the meaning of a revision id 
+does not change, this revision id is only valid within a specific version 
+of the mappings.
+
+To override the revision id this way, set the revision property:
+
+bzr:revision-id-v%d (where %d is the current mapping version) 
+
+to the revision id. This property should only be honored for the revision 
+in which it was set, as subversion will not erase the property 
+for subsequent commits.
+
 == File ids ==
 
 Subversion does not use file ids. It is not possible to know whether a file in 
@@ -173,4 +187,5 @@
 
 Revision 3 changed the file id format, changed the urlencoding to be 
 uppercased, changed the separator between uuids and branch paths in the 
-revision id from "-" to ":" and added the branching scheme to the revision id.
+revision id from "-" to ":", added the branching scheme to the revision id 
+and added the bzr:revision-id-vX property.

=== modified file 'repository.py'
--- a/repository.py	2007-01-20 23:11:09 +0000
+++ b/repository.py	2007-02-01 17:36:14 +0000
@@ -54,6 +54,7 @@
 SVN_PROP_BZR_FILEIDS = 'bzr:file-ids'
 SVN_PROP_BZR_REVPROP_PREFIX = 'bzr:revprop:'
 SVN_REVPROP_BZR_SIGNATURE = 'bzr:gpg-signature'
+SVN_PROP_BZR_REVISION_ID = 'svn:revision-id-v%d' % MAPPING_VERSION
 
 import urllib
 
@@ -629,11 +630,8 @@
             raise NotImplementedError(self.get_commit_builder, 
                 "committer can not be user-specified for Subversion repositories")
 
-        if revision_id != None:
-            raise NotImplementedError(self.get_commit_builder, 
-                "revision_id can not be user-specified for Subversion repositories")
-
         from commit import SvnCommitBuilder
-        return SvnCommitBuilder(self, branch, parents, config, revprops)
+        return SvnCommitBuilder(self, branch, parents, config, revprops,
+                                revision_id)
 
 

=== modified file 'tests/__init__.py'
--- a/tests/__init__.py	2007-01-29 15:19:34 +0000
+++ b/tests/__init__.py	2007-02-01 17:36:14 +0000
@@ -237,6 +237,7 @@
             'test_errors',
             'test_fileids', 
             'test_logwalker',
+            'test_push',
             'test_radir',
             'test_repos', 
             'test_scheme', 

=== modified file 'tests/test_commit.py'
--- a/tests/test_commit.py	2007-01-09 04:25:01 +0000
+++ b/tests/test_commit.py	2007-02-01 17:36:14 +0000
@@ -20,6 +20,7 @@
 from bzrlib.inventory import Inventory
 from bzrlib.workingtree import WorkingTree
 
+from copy import copy
 import os
 import format
 import checkout
@@ -190,140 +191,22 @@
         self.assertEqual("mybranch", 
                 self.client_get_prop(self.repos_url, "bzr:revprop:branch-nick", 2))
 
-class TestPush(TestCaseWithSubversionRepository):
-    def setUp(self):
-        super(TestPush, self).setUp()
-        self.repos_url = self.make_client('d', 'sc')
-
-        self.build_tree({'sc/foo/bla': "data"})
-        self.client_add("sc/foo")
-        self.client_commit("sc", "foo")
-
-        self.olddir = BzrDir.open("sc")
-        os.mkdir("dc")
-        self.newdir = self.olddir.sprout("dc")
-
-    def test_empty(self):
-        self.assertEqual(0, self.olddir.open_branch().pull(
-                                self.newdir.open_branch()))
-
-    def test_child(self):
-        self.build_tree({'sc/foo/bar': "data"})
-        self.client_add("sc/foo/bar")
-        self.client_commit("sc", "second message")
-
-        self.assertEqual(0, self.olddir.open_branch().pull(
-                                self.newdir.open_branch()))
-
-    def test_diverged(self):
-        self.build_tree({'sc/foo/bar': "data"})
-        self.client_add("sc/foo/bar")
-        self.client_commit("sc", "second message")
-
-        olddir = BzrDir.open("sc")
-
-        self.build_tree({'dc/file': 'data'})
-        wt = self.newdir.open_workingtree()
-        wt.add('file')
-        wt.commit(message="Commit from Bzr")
-
-        self.assertRaises(DivergedBranches, 
-                          olddir.open_branch().pull,
-                          self.newdir.open_branch())
-
-    def test_change(self):
-        self.build_tree({'dc/foo/bla': 'other data'})
-        wt = self.newdir.open_workingtree()
-        wt.commit(message="Commit from Bzr")
-
-        self.olddir.open_branch().pull(self.newdir.open_branch())
-
-        repos = self.olddir.find_repository()
-        inv = repos.get_inventory(repos.generate_revision_id(2, ""))
-        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.olddir.open_branch().last_revision())
-        self.assertEqual("other data", 
-            repos.revision_tree(repos.generate_revision_id(2, "")).get_file_text( inv.path2id("foo/bla")))
-
-    def test_simple(self):
-        self.build_tree({'dc/file': 'data'})
-        wt = self.newdir.open_workingtree()
-        wt.add('file')
-        wt.commit(message="Commit from Bzr")
-
-        self.olddir.open_branch().pull(self.newdir.open_branch())
-
-        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(repos.generate_revision_id(2, ""),
-                        self.olddir.open_branch().last_revision())
-
-    def test_pull_after_push(self):
-        self.build_tree({'dc/file': 'data'})
-        wt = self.newdir.open_workingtree()
-        wt.add('file')
-        wt.commit(message="Commit from Bzr")
-
-        self.olddir.open_branch().pull(self.newdir.open_branch())
-
-        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(repos.generate_revision_id(2, ""),
-                        self.olddir.open_branch().last_revision())
-
-        self.newdir.open_branch().pull(self.olddir.open_branch())
-
-        self.assertEqual(repos.generate_revision_id(2, ""),
-                        self.newdir.open_branch().last_revision())
-
-    def test_message(self):
-        self.build_tree({'dc/file': 'data'})
-        wt = self.newdir.open_workingtree()
-        wt.add('file')
-        wt.commit(message="Commit from Bzr")
-
-        self.olddir.open_branch().pull(self.newdir.open_branch())
-
-        repos = self.olddir.find_repository()
-        self.assertEqual("Commit from Bzr",
-            repos.get_revision(repos.generate_revision_id(2, "")).message)
-
-    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, "")))
+    def test_commit_revision_id(self):
+        wt = self.checkout.create_workingtree()
+        self.build_tree({'dc/foo/bla': "data", 'dc/bla': "otherdata"})
+        wt.add('bla')
+        wt.commit(message="data")
+
+        branch = Branch.open(self.repos_url)
+        builder = branch.get_commit_builder([branch.last_revision()], revision_id="my-revision-id")
+        tree = branch.repository.revision_tree(branch.last_revision())
+        new_tree = copy(tree)
+        ie = new_tree.inventory.root
+        ie.revision = None
+        builder.record_entry_contents(ie, [tree.inventory], '', new_tree)
+        builder.finish_inventory()
+        builder.commit("foo")
+
+        self.assertEqual("my-revision-id", 
+                self.client_get_prop(self.repos_url, "bzr:revision-id-%d" % MAPPING_VERSION, 2))
 




More information about the bazaar-commits mailing list