Rev 3072: (John Arbash Meinel) Change Branch.pull() so it doesn't have to in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Dec 3 22:21:42 GMT 2007


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3072
revision-id:pqm at pqm.ubuntu.com-20071203222135-gjk2xshgdfgxje6m
parent: pqm at pqm.ubuntu.com-20071203214310-467u6waddal0ucuw
parent: john at arbash-meinel.com-20071201011228-3aqhvy1wtc305nn4
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-12-03 22:21:35 +0000
message:
  (John Arbash Meinel) Change Branch.pull() so it doesn't have to
  	search all history all the time.
modified:
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/tests/branch_implementations/test_pull.py test_pull.py-20060410103942-83c35b26657414fc
  bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
    ------------------------------------------------------------
    revno: 3052.5.5
    revision-id:john at arbash-meinel.com-20071201011228-3aqhvy1wtc305nn4
    parent: john at arbash-meinel.com-20071130232718-9e3thvmobvj799br
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: pull_set_last_revision_info_172970
    timestamp: Fri 2007-11-30 19:12:28 -0600
    message:
      Special case Graph.heads() for NULL_REVISION rather than is_ancestor.
    modified:
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
    ------------------------------------------------------------
    revno: 3052.5.4
    revision-id:john at arbash-meinel.com-20071130232718-9e3thvmobvj799br
    parent: john at arbash-meinel.com-20071130232100-dwv5q1y86svbcts2
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: pull_set_last_revision_info_172970
    timestamp: Fri 2007-11-30 17:27:18 -0600
    message:
      If we are going to overwrite the target, we don't have to do
      any ancestry checks. Just nuke it right away.
      This makes 'bzr pull --overwrite' a bit faster.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
    ------------------------------------------------------------
    revno: 3052.5.3
    revision-id:john at arbash-meinel.com-20071130232100-dwv5q1y86svbcts2
    parent: john at arbash-meinel.com-20071130231815-0r6ce70307kmv28r
    parent: pqm at pqm.ubuntu.com-20071130225629-sovkf7a4lksj1z4g
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: pull_set_last_revision_info_172970
    timestamp: Fri 2007-11-30 17:21:00 -0600
    message:
      [merge] bzr.dev 3061
    added:
      doc/en/tutorials/              docentutorials-20071127235845-bm2lu60bvau1ptmh-1
      doc/en/user-guide/annotating_changes.txt annotating_changes.t-20071122141511-0knao2lklsdsvb1q-1
      doc/en/user-guide/bazaar_workflows.txt bazaar_workflows.txt-20071114035000-q36a9h57ps06uvnl-1
      doc/en/user-guide/best_practice_intro.txt best_practice_intro.-20071123154453-dk2mjhrg1vpjm5w2-1
      doc/en/user-guide/branching_a_project.txt branching_a_project.-20071122141511-0knao2lklsdsvb1q-2
      doc/en/user-guide/browsing_history.txt browsing_history.txt-20071121073725-0corxykv5irjal00-2
      doc/en/user-guide/central_intro.txt central_intro.txt-20071123055134-k5x4ekduci2lbn36-1
      doc/en/user-guide/configuring_bazaar.txt configuring_bazaar.t-20071128000722-ncxiua259xwbdbg7-1
      doc/en/user-guide/controlling_registration.txt controlling_registra-20071121073725-0corxykv5irjal00-3
      doc/en/user-guide/core_concepts.txt core_concepts.txt-20071114035000-q36a9h57ps06uvnl-2
      doc/en/user-guide/distributed_intro.txt distributed_intro.tx-20071123154453-dk2mjhrg1vpjm5w2-2
      doc/en/user-guide/entering_commands.txt using_bazaar.txt-20071114035000-q36a9h57ps06uvnl-6
      doc/en/user-guide/getting_help.txt getting_help.txt-20071128000722-ncxiua259xwbdbg7-2
      doc/en/user-guide/images/      images-20071114035000-q36a9h57ps06uvnl-3
      doc/en/user-guide/images/workflows_centralized.png workflows_centralize-20071114035000-q36a9h57ps06uvnl-8
      doc/en/user-guide/images/workflows_centralized.svg workflows_centralize-20071130043324-bhms0cgyphhq1b2x-1
      doc/en/user-guide/images/workflows_gatekeeper.png workflows_gatekeeper-20071114035000-q36a9h57ps06uvnl-9
      doc/en/user-guide/images/workflows_gatekeeper.svg workflows_gatekeeper-20071130043324-bhms0cgyphhq1b2x-2
      doc/en/user-guide/images/workflows_localcommit.png workflows_localcommi-20071114035000-q36a9h57ps06uvnl-10
      doc/en/user-guide/images/workflows_localcommit.svg workflows_localcommi-20071130043324-bhms0cgyphhq1b2x-3
      doc/en/user-guide/images/workflows_peer.png workflows_peer.png-20071114035000-q36a9h57ps06uvnl-11
      doc/en/user-guide/images/workflows_peer.svg workflows_peer.svg-20071130043324-bhms0cgyphhq1b2x-4
      doc/en/user-guide/images/workflows_pqm.png workflows_pqm.png-20071114035000-q36a9h57ps06uvnl-12
      doc/en/user-guide/images/workflows_pqm.svg workflows_pqm.svg-20071130043324-bhms0cgyphhq1b2x-5
      doc/en/user-guide/images/workflows_shared.png workflows_shared.png-20071114035000-q36a9h57ps06uvnl-13
      doc/en/user-guide/images/workflows_shared.svg workflows_shared.svg-20071130043324-bhms0cgyphhq1b2x-6
      doc/en/user-guide/images/workflows_single.png workflows_single.png-20071114035000-q36a9h57ps06uvnl-14
      doc/en/user-guide/images/workflows_single.svg workflows_single.svg-20071130043324-bhms0cgyphhq1b2x-7
      doc/en/user-guide/installing_bazaar.txt installing_bazaar.tx-20071114035000-q36a9h57ps06uvnl-4
      doc/en/user-guide/introducing_bazaar.txt introducing_bazaar.t-20071114035000-q36a9h57ps06uvnl-5
      doc/en/user-guide/merging_changes.txt merging_changes.txt-20071122141511-0knao2lklsdsvb1q-3
      doc/en/user-guide/organizing_branches.txt organizing_branches.-20071123154453-dk2mjhrg1vpjm5w2-3
      doc/en/user-guide/partner_intro.txt partner_workflow.txt-20071122141511-0knao2lklsdsvb1q-4
      doc/en/user-guide/publishing_a_branch.txt publishing_a_branch.-20071123055134-k5x4ekduci2lbn36-2
      doc/en/user-guide/recording_changes.txt recording_changes.tx-20071121073725-0corxykv5irjal00-4
      doc/en/user-guide/releasing_a_project.txt releasing_a_project.-20071121073725-0corxykv5irjal00-5
      doc/en/user-guide/resolving_conflicts.txt resolving_conflicts.-20071122141511-0knao2lklsdsvb1q-5
      doc/en/user-guide/reusing_a_checkout.txt reusing_a_checkout.t-20071123055134-k5x4ekduci2lbn36-3
      doc/en/user-guide/reviewing_changes.txt reviewing_changes.tx-20071121073725-0corxykv5irjal00-6
      doc/en/user-guide/sending_changes.txt sending_changes.txt-20071123154453-dk2mjhrg1vpjm5w2-4
      doc/en/user-guide/solo_intro.txt solo_workflow.txt-20071121073725-0corxykv5irjal00-7
      doc/en/user-guide/starting_a_project.txt starting_a_project.t-20071121073725-0corxykv5irjal00-8
      doc/en/user-guide/undoing_mistakes.txt undoing_mistakes.txt-20071121092300-8fyacngt1w98e5mp-1
      doc/en/user-guide/using_checkouts.txt using_checkouts.txt-20071123055134-k5x4ekduci2lbn36-4
      doc/en/user-guide/using_gatekeepers.txt using_gatekeepers.tx-20071123154453-dk2mjhrg1vpjm5w2-5
      doc/en/user-guide/working_offline_central.txt working_offline_cent-20071123055134-k5x4ekduci2lbn36-5
      doc/en/user-guide/writing_a_plugin.txt writing_a_plugin.txt-20071114035000-q36a9h57ps06uvnl-7
      index.txt                      index.txt-20071121073725-0corxykv5irjal00-1
    renamed:
      doc/en/user-guide/centralized_workflow.txt => doc/en/tutorials/centralized_workflow.txt centralized_workflow-20060830194948-kspf52565xvgrlil-1
      doc/en/user-guide/tutorial.txt => doc/en/tutorials/tutorial.txt tutorial.txt-20050804190939-9dcbba2ef053bc84
    modified:
      Makefile                       Makefile-20050805140406-d96e3498bb61c5bb
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/debug.py                debug.py-20061102062349-vdhrw9qdpck8cl35-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/tests/HTTPTestUtil.py   HTTPTestUtil.py-20050914180604-247d3aafb7a43343
      bzrlib/tests/HttpServer.py     httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_ancestry.py  test_ancestry.py-20050913023709-69768e94848312c6
      bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
      bzrlib/tests/test_switch.py    test_switch.py-20071116011000-v5lnw7d2wkng9eux-2
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
      bzrlib/transport/http/_urllib.py _urlgrabber.py-20060113083826-0bbf7d992fbf090c
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
      doc/en/user-guide/authentication_conf.txt authentication_conf.-20071104135035-glfv0ri355tyg1nf-1
      doc/en/user-guide/bug_trackers.txt bug_trackers.txt-20070713223459-khxdlcudraii95uv-1
      doc/en/user-guide/configuration.txt configuration.txt-20060314161707-868350809502af01
      doc/en/user-guide/conflicts.txt conflicts.txt-20070723221841-ns3jvwxdb4okn6fk-1
      doc/en/user-guide/hooks.txt    hooks.txt-20070829200551-7nr6e5a1io6x78uf-1
      doc/en/user-guide/http_smart_server.txt fastcgi.txt-20061005091552-rz8pva0olkxv0sd8-3
      doc/en/user-guide/index.txt    index.txt-20060622101119-tgwtdci8z769bjb9-2
      doc/en/user-guide/plugins.txt  plugins.txt-20060314145616-525099a747f3ffdd
      doc/en/user-guide/server.txt   server.txt-20060913044801-h939fvbwzz39gf7g-1
      doc/en/user-guide/setting_up_email.txt setting_up_email.txt-20060314161707-fd242c8944346173
      doc/en/user-guide/shared_repository_layouts.txt shared_repository_la-20070502152030-bagewuqs18ns24o7-1
      doc/en/user-guide/specifying_revisions.txt specifying_revisions.txt-20060314161707-19deb139101bea33
      doc/en/user-guide/using_aliases.txt using_aliases.txt-20060314161707-c21d27fa2939e039
      doc/en/user-guide/version_info.txt version_info.txt-20060921215543-gju6o5xdic8w25np-1
      doc/index.txt                  index.txt-20070813101924-07gd9i9d2jt124bf-1
      tools/win32/bzr.iss.cog        bzr.iss.cog-20060622100836-b3yup582rt3y0nvm-5
      doc/en/tutorials/tutorial.txt  tutorial.txt-20050804190939-9dcbba2ef053bc84
    ------------------------------------------------------------
    revno: 3052.5.2
    revision-id:john at arbash-meinel.com-20071130231815-0r6ce70307kmv28r
    parent: john at arbash-meinel.com-20071130045443-11kpm1ka40aix3mh
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: pull_set_last_revision_info_172970
    timestamp: Fri 2007-11-30 17:18:15 -0600
    message:
      Use a Graph.heads() check to determine if the ancestries are compatible.
      Whether we should do nothing because source is already ahead,
      raise an exception because we have diverged,
      or move forward because the new revision is a tip revision.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/tests/branch_implementations/test_pull.py test_pull.py-20060410103942-83c35b26657414fc
    ------------------------------------------------------------
    revno: 3052.5.1
    revision-id:john at arbash-meinel.com-20071130045443-11kpm1ka40aix3mh
    parent: pqm at pqm.ubuntu.com-20071129184101-u9506rihe4zbzyyz
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: pull_set_last_revision_info_172970
    timestamp: Thu 2007-11-29 22:54:43 -0600
    message:
      (bug #172970) Change Branch.pull to need to generate_history less often.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2007-12-03 18:38:51 +0000
+++ b/bzrlib/branch.py	2007-12-03 22:21:35 +0000
@@ -1439,13 +1439,14 @@
             last_rev, other_branch))
 
     @needs_write_lock
-    def update_revisions(self, other, stop_revision=None):
+    def update_revisions(self, other, stop_revision=None, overwrite=False):
         """See Branch.update_revisions."""
         other.lock_read()
         try:
+            other_last_revno, other_last_revision = other.last_revision_info()
             if stop_revision is None:
-                stop_revision = other.last_revision()
-                if stop_revision is None:
+                stop_revision = other_last_revision
+                if _mod_revision.is_null(stop_revision):
                     # if there are no commits, we're done.
                     return
             # whats the current last revision, before we fetch [and change it
@@ -1456,11 +1457,29 @@
             # already merged can operate on the just fetched graph, which will
             # be cached in memory.
             self.fetch(other, stop_revision)
-            if self.repository.get_graph().is_ancestor(stop_revision,
-                                                       last_rev):
-                return
-            self.generate_revision_history(stop_revision, last_rev=last_rev,
-                other_branch=other)
+            # Check to see if one is an ancestor of the other
+            if not overwrite:
+                heads = self.repository.get_graph().heads([stop_revision,
+                                                           last_rev])
+                if heads == set([last_rev]):
+                    # The current revision is a decendent of the target,
+                    # nothing to do
+                    return
+                elif heads == set([stop_revision, last_rev]):
+                    # These branches have diverged
+                    raise errors.DivergedBranches(self, other)
+                assert heads == set([stop_revision])
+            if other_last_revision == stop_revision:
+                self.set_last_revision_info(other_last_revno,
+                                            other_last_revision)
+            else:
+                # TODO: jam 2007-11-29 Is there a way to determine the
+                #       revno without searching all of history??
+                if overwrite:
+                    self.generate_revision_history(stop_revision)
+                else:
+                    self.generate_revision_history(stop_revision,
+                        last_rev=last_rev, other_branch=other)
         finally:
             other.unlock()
 
@@ -1485,15 +1504,7 @@
         source.lock_read()
         try:
             result.old_revno, result.old_revid = self.last_revision_info()
-            try:
-                self.update_revisions(source, stop_revision)
-            except DivergedBranches:
-                if not overwrite:
-                    raise
-            if overwrite:
-                if stop_revision is None:
-                    stop_revision = source.last_revision()
-                self.generate_revision_history(stop_revision)
+            self.update_revisions(source, stop_revision, overwrite=overwrite)
             result.tag_conflicts = source.tags.merge_to(self.tags, overwrite)
             result.new_revno, result.new_revid = self.last_revision_info()
             if _hook_master:

=== modified file 'bzrlib/graph.py'
--- a/bzrlib/graph.py	2007-11-30 15:20:15 +0000
+++ b/bzrlib/graph.py	2007-12-01 01:12:28 +0000
@@ -242,6 +242,11 @@
             order if they need it.
         """
         candidate_heads = set(keys)
+        if revision.NULL_REVISION in candidate_heads:
+            # NULL_REVISION is only a head if it is the only entry
+            candidate_heads.remove(revision.NULL_REVISION)
+            if not candidate_heads:
+                return set([revision.NULL_REVISION])
         if len(candidate_heads) < 2:
             return candidate_heads
         searchers = dict((c, self._make_breadth_first_searcher([c]))
@@ -348,13 +353,6 @@
         smallest number of parent looksup to determine the ancestral
         relationship between N revisions.
         """
-        if revision.is_null(candidate_ancestor):
-            return True
-        if revision.is_null(candidate_descendant):
-            # if candidate_descendant is NULL_REVISION, then only
-            # candidate_ancestor == NULL_REVISION is an ancestor, but we've
-            # already handled that case.
-            return False
         return set([candidate_descendant]) == self.heads(
             [candidate_ancestor, candidate_descendant])
 

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2007-11-30 06:04:54 +0000
+++ b/bzrlib/remote.py	2007-11-30 23:27:18 +0000
@@ -1283,10 +1283,10 @@
         self._ensure_real()
         return self._real_branch.set_push_location(location)
 
-    def update_revisions(self, other, stop_revision=None):
+    def update_revisions(self, other, stop_revision=None, overwrite=False):
         self._ensure_real()
         return self._real_branch.update_revisions(
-            other, stop_revision=stop_revision)
+            other, stop_revision=stop_revision, overwrite=overwrite)
 
 
 class RemoteBranchConfig(BranchConfig):

=== modified file 'bzrlib/tests/branch_implementations/test_pull.py'
--- a/bzrlib/tests/branch_implementations/test_pull.py	2007-11-08 23:36:39 +0000
+++ b/bzrlib/tests/branch_implementations/test_pull.py	2007-11-30 23:18:15 +0000
@@ -88,6 +88,13 @@
         tree_a.commit('message 2', rev_id='rev2a')
         tree_b.commit('message 2', rev_id='rev2b')
         self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
+        self.assertRaises(errors.DivergedBranches,
+                          tree_a.branch.pull, tree_b.branch,
+                          overwrite=False, stop_revision='rev2b')
+        # It should not have updated the branch tip, but it should have fetched
+        # the revision
+        self.assertEqual('rev2a', tree_a.branch.last_revision())
+        self.assertTrue(tree_a.branch.repository.has_revision('rev2b'))
         tree_a.branch.pull(tree_b.branch, overwrite=True,
                            stop_revision='rev2b')
         self.assertEqual('rev2b', tree_a.branch.last_revision())

=== modified file 'bzrlib/tests/test_graph.py'
--- a/bzrlib/tests/test_graph.py	2007-11-22 22:33:27 +0000
+++ b/bzrlib/tests/test_graph.py	2007-12-01 01:12:28 +0000
@@ -373,7 +373,7 @@
         self.assertEqual(set(['rev1']), graph.heads(('rev1', 'null:')))
 
     def test_heads_one(self):
-        # A single node will alwaya be a head
+        # A single node will always be a head
         graph = self.make_graph(ancestry_1)
         self.assertEqual(set(['null:']), graph.heads(['null:']))
         self.assertEqual(set(['rev1']), graph.heads(['rev1']))




More information about the bazaar-commits mailing list