Rev 6250: (jelmer) Allow commit builders to update the branch as part of a commit. in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

Patch Queue Manager pqm at pqm.ubuntu.com
Tue Nov 8 20:00:31 UTC 2011


At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 6250 [merge]
revision-id: pqm at pqm.ubuntu.com-20111108200030-7muon3zmq1pxfy4f
parent: pqm at pqm.ubuntu.com-20111108193523-3pn06vmmw2508tsj
parent: jelmer at samba.org-20111107110219-ywbvifd666p1j9u5
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2011-11-08 20:00:30 +0000
message:
  (jelmer) Allow commit builders to update the branch as part of a commit.
   (Jelmer Vernooij)
modified:
  bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
=== modified file 'bzrlib/commit.py'
--- a/bzrlib/commit.py	2011-09-16 10:08:09 +0000
+++ b/bzrlib/commit.py	2011-11-07 11:02:19 +0000
@@ -363,7 +363,7 @@
         self._check_bound_branch(operation, possible_master_transports)
 
         # Check that the working tree is up to date
-        old_revno, new_revno = self._check_out_of_date_tree()
+        old_revno, old_revid, new_revno = self._check_out_of_date_tree()
 
         # Complete configuration setup
         if reporter is not None:
@@ -411,6 +411,12 @@
             self.builder.abort()
             raise errors.ExcludesUnsupported(self.branch.repository)
 
+        if self.builder.updates_branch and self.bound_branch:
+            self.builder.abort()
+            raise AssertionError(
+                "bound branches not supported for commit builders "
+                "that update the branch")
+
         try:
             self.builder.will_record_deletes()
             # find the location being committed to
@@ -445,31 +451,7 @@
             self.builder.abort()
             raise
 
-        self._process_pre_hooks(old_revno, new_revno)
-
-        # Upload revision data to the master.
-        # this will propagate merged revisions too if needed.
-        if self.bound_branch:
-            self._set_progress_stage("Uploading data to master branch")
-            # 'commit' to the master first so a timeout here causes the
-            # local branch to be out of date
-            (new_revno, self.rev_id) = self.master_branch.import_last_revision_info_and_tags(
-                self.branch, new_revno, self.rev_id, lossy=lossy)
-            if lossy:
-                self.branch.fetch(self.master_branch, self.rev_id)
-
-        # and now do the commit locally.
-        self.branch.set_last_revision_info(new_revno, self.rev_id)
-
-        # Merge local tags to remote
-        if self.bound_branch:
-            self._set_progress_stage("Merging tags to master branch")
-            tag_updates, tag_conflicts = self.branch.tags.merge_to(
-                self.master_branch.tags)
-            if tag_conflicts:
-                warning_lines = ['    ' + name for name, _, _ in tag_conflicts]
-                note( gettext("Conflicting tags in bound branch:\n{0}".format(
-                    "\n".join(warning_lines))) )
+        self._update_branches(old_revno, old_revid, new_revno)
 
         # Make the working tree be up to date with the branch. This
         # includes automatic changes scheduled to be made to the tree, such
@@ -482,6 +464,52 @@
         self._process_post_hooks(old_revno, new_revno)
         return self.rev_id
 
+    def _update_branches(self, old_revno, old_revid, new_revno):
+        """Update the master and local branch to the new revision.
+
+        This will try to make sure that the master branch is updated
+        before the local branch.
+
+        :param old_revno: Revision number of master branch before the
+            commit
+        :param old_revid: Tip of master branch before the commit
+        :param new_revno: Revision number of the new commit
+        """
+        if not self.builder.updates_branch:
+            self._process_pre_hooks(old_revno, new_revno)
+
+            # Upload revision data to the master.
+            # this will propagate merged revisions too if needed.
+            if self.bound_branch:
+                self._set_progress_stage("Uploading data to master branch")
+                # 'commit' to the master first so a timeout here causes the
+                # local branch to be out of date
+                (new_revno, self.rev_id) = self.master_branch.import_last_revision_info_and_tags(
+                    self.branch, new_revno, self.rev_id, lossy=self._lossy)
+                if self._lossy:
+                    self.branch.fetch(self.master_branch, self.rev_id)
+
+            # and now do the commit locally.
+            self.branch.set_last_revision_info(new_revno, self.rev_id)
+        else:
+            try:
+                self._process_pre_hooks(old_revno, new_revno)
+            except:
+                # The commit builder will already have updated the branch,
+                # revert it.
+                self.branch.set_last_revision_info(old_revno, old_revid)
+                raise
+
+        # Merge local tags to remote
+        if self.bound_branch:
+            self._set_progress_stage("Merging tags to master branch")
+            tag_updates, tag_conflicts = self.branch.tags.merge_to(
+                self.master_branch.tags)
+            if tag_conflicts:
+                warning_lines = ['    ' + name for name, _, _ in tag_conflicts]
+                note( gettext("Conflicting tags in bound branch:\n{0}".format(
+                    "\n".join(warning_lines))) )
+
     def _select_reporter(self):
         """Select the CommitReporter to use."""
         if is_quiet():
@@ -544,7 +572,8 @@
     def _check_out_of_date_tree(self):
         """Check that the working tree is up to date.
 
-        :return: old_revision_number,new_revision_number tuple
+        :return: old_revision_number, old_revision_id, new_revision_number
+            tuple
         """
         try:
             first_tree_parent = self.work_tree.get_parent_ids()[0]
@@ -563,7 +592,7 @@
         else:
             # ghost parents never appear in revision history.
             new_revno = 1
-        return old_revno,new_revno
+        return old_revno, master_last, new_revno
 
     def _process_pre_hooks(self, old_revno, new_revno):
         """Process any registered pre commit hooks."""

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2011-10-17 08:45:09 +0000
+++ b/bzrlib/repository.py	2011-11-08 20:00:30 +0000
@@ -74,6 +74,9 @@
     record_root_entry = True
     # whether this commit builder supports the record_entry_contents interface
     supports_record_entry_contents = False
+    # whether this commit builder will automatically update the branch that is
+    # being committed to
+    updates_branch = False
 
     def __init__(self, repository, parents, config, timestamp=None,
                  timezone=None, committer=None, revprops=None,

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2011-10-16 17:34:17 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2011-11-08 20:00:30 +0000
@@ -148,6 +148,21 @@
         rev = tree.branch.repository.get_revision(rev_id)
         self.assertEqual('foo bar blah', rev.message)
 
+    def test_updates_branch(self):
+        tree = self.make_branch_and_tree(".")
+        tree.lock_write()
+        try:
+            builder = tree.branch.get_commit_builder([])
+            list(builder.record_iter_changes(tree, tree.last_revision(),
+                tree.iter_changes(tree.basis_tree())))
+            builder.finish_inventory()
+            will_update_branch = builder.updates_branch
+            rev_id = builder.commit('might update the branch')
+        finally:
+            tree.unlock()
+        actually_updated_branch = (tree.branch.last_revision() == rev_id)
+        self.assertEquals(actually_updated_branch, will_update_branch)
+
     def test_commit_with_revision_id_record_entry_contents(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()




More information about the bazaar-commits mailing list