Rev 4446: (andrew) Add Repository.get_rev_id_for_revno HPSS verb (and API). in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Jun 16 10:05:41 BST 2009


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

------------------------------------------------------------
revno: 4446
revision-id: pqm at pqm.ubuntu.com-20090616090534-gl7ghksxrhuse5z4
parent: pqm at pqm.ubuntu.com-20090616025031-veox1vdgpt769fsk
parent: andrew.bennetts at canonical.com-20090616080658-ej18m1u773k55tsc
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2009-06-16 10:05:34 +0100
message:
  (andrew) Add Repository.get_rev_id_for_revno HPSS verb (and API).
added:
  bzrlib/tests/per_repository_reference/test_get_rev_id_for_revno.py test_get_rev_id_for_-20090615064050-b6mq6co557towrxh-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
  bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
  bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
  bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
  bzrlib/tests/per_repository_reference/__init__.py __init__.py-20080220025549-nnm2s80it1lvcwnc-2
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 4419.2.17
    revision-id: andrew.bennetts at canonical.com-20090616080658-ej18m1u773k55tsc
    parent: andrew.bennetts at canonical.com-20090616064632-t03ugkxmq57owe35
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Tue 2009-06-16 18:06:58 +1000
    message:
      Fix test failures in test_lookup_revision_id_by_dotted.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
    ------------------------------------------------------------
    revno: 4419.2.16
    revision-id: andrew.bennetts at canonical.com-20090616064632-t03ugkxmq57owe35
    parent: andrew.bennetts at canonical.com-20090615080147-6umr0sjxley7bq3n
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Tue 2009-06-16 16:46:32 +1000
    message:
      New in 1.17, not 1.16.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
    ------------------------------------------------------------
    revno: 4419.2.15
    revision-id: andrew.bennetts at canonical.com-20090615080147-6umr0sjxley7bq3n
    parent: andrew.bennetts at canonical.com-20090615080121-ef0m1mj83qjv6gc6
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 18:01:47 +1000
    message:
      Simplify RemoteBranch.get_rev_id a little; get_rev_id_for_revno handles stacking for us.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
    ------------------------------------------------------------
    revno: 4419.2.14
    revision-id: andrew.bennetts at canonical.com-20090615080121-ef0m1mj83qjv6gc6
    parent: andrew.bennetts at canonical.com-20090615065904-elg399nnihcb7683
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 18:01:21 +1000
    message:
      Fix bug when partial_history == [stop_revision]
    modified:
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
    ------------------------------------------------------------
    revno: 4419.2.13
    revision-id: andrew.bennetts at canonical.com-20090615065904-elg399nnihcb7683
    parent: andrew.bennetts at canonical.com-20090615065610-sfbp7exs7s51da7w
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 16:59:04 +1000
    message:
      Remove obsolete XXX.
    modified:
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
    ------------------------------------------------------------
    revno: 4419.2.12
    revision-id: andrew.bennetts at canonical.com-20090615065610-sfbp7exs7s51da7w
    parent: andrew.bennetts at canonical.com-20090615064832-eustj8mn0q2rs4bh
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 16:56:10 +1000
    message:
      Add NEWS entry.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 4419.2.11
    revision-id: andrew.bennetts at canonical.com-20090615064832-eustj8mn0q2rs4bh
    parent: andrew.bennetts at canonical.com-20090615064714-j04tkbgfz6bis3la
    parent: pqm at pqm.ubuntu.com-20090612094207-jk5dodjd19e9h2hk
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 16:48:32 +1000
    message:
      Merge bzr.dev.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
    ------------------------------------------------------------
    revno: 4419.2.10
    revision-id: andrew.bennetts at canonical.com-20090615064714-j04tkbgfz6bis3la
    parent: andrew.bennetts at canonical.com-20090615064149-f3vxn27mi3ak8akp
    parent: pqm at pqm.ubuntu.com-20090612034412-oi5ll5wrbarb2w7s
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 16:47:14 +1000
    message:
      Merge bzr.dev.
    removed:
      doc/developers/performance-contributing.txt performancecontribut-20070621063612-ac4zhhagjzkr21qp-1
    added:
      bzrlib/util/bencode.py         bencode.py-20090609141817-jtvhqq6vyryjoeky-1
      doc/index.ru.txt               index.ru.txt-20080819091426-kfq61l02dhm9pplk-1
      doc/ru/                        ru-20080818031309-t3nyctvfbvfh4h2u-1
      doc/ru/mini-tutorial/          minitutorial-20080818031309-t3nyctvfbvfh4h2u-2
      doc/ru/mini-tutorial/index.txt index.txt-20080818031309-t3nyctvfbvfh4h2u-4
      doc/ru/quick-reference/        quickreference-20080818031309-t3nyctvfbvfh4h2u-3
      doc/ru/quick-reference/Makefile makefile-20080818031309-t3nyctvfbvfh4h2u-5
      doc/ru/quick-reference/quick-start-summary.pdf quickstartsummary.pd-20080818031309-t3nyctvfbvfh4h2u-6
      doc/ru/quick-reference/quick-start-summary.png quickstartsummary.pn-20080818031309-t3nyctvfbvfh4h2u-7
      doc/ru/quick-reference/quick-start-summary.svg quickstartsummary.sv-20080818031309-t3nyctvfbvfh4h2u-8
      doc/ru/tutorials/              docrututorials-20090427084615-toum0jo7qohd807p-1
      doc/ru/tutorials/centralized_workflow.txt centralized_workflow-20090531190825-ex3ums4bcuaf2r6k-1
      doc/ru/tutorials/tutorial.txt  tutorial.txt-20090602180629-wkp7wr27jl4i2zep-1
      doc/ru/tutorials/using_bazaar_with_launchpad.txt using_bazaar_with_la-20090427084917-b22ppqtdx7q4hapw-1
      doc/ru/user-guide/             docruuserguide-20090601191403-rcoy6nsre0vjiozm-1
      doc/ru/user-guide/branching_a_project.txt branching_a_project.-20090602104644-pjpwfx7xh2k5l0ba-1
      doc/ru/user-guide/core_concepts.txt core_concepts.txt-20090602104644-pjpwfx7xh2k5l0ba-2
      doc/ru/user-guide/images/      images-20090601201124-cruf3mmq5cfxeb1w-1
      doc/ru/user-guide/images/workflows_centralized.png workflows_centralize-20090601201124-cruf3mmq5cfxeb1w-3
      doc/ru/user-guide/images/workflows_centralized.svg workflows_centralize-20090601201124-cruf3mmq5cfxeb1w-4
      doc/ru/user-guide/images/workflows_gatekeeper.png workflows_gatekeeper-20090601201124-cruf3mmq5cfxeb1w-5
      doc/ru/user-guide/images/workflows_gatekeeper.svg workflows_gatekeeper-20090601201124-cruf3mmq5cfxeb1w-6
      doc/ru/user-guide/images/workflows_localcommit.png workflows_localcommi-20090601201124-cruf3mmq5cfxeb1w-7
      doc/ru/user-guide/images/workflows_localcommit.svg workflows_localcommi-20090601201124-cruf3mmq5cfxeb1w-8
      doc/ru/user-guide/images/workflows_peer.png workflows_peer.png-20090601201124-cruf3mmq5cfxeb1w-9
      doc/ru/user-guide/images/workflows_peer.svg workflows_peer.svg-20090601201124-cruf3mmq5cfxeb1w-10
      doc/ru/user-guide/images/workflows_pqm.png workflows_pqm.png-20090601201124-cruf3mmq5cfxeb1w-11
      doc/ru/user-guide/images/workflows_pqm.svg workflows_pqm.svg-20090601201124-cruf3mmq5cfxeb1w-12
      doc/ru/user-guide/images/workflows_shared.png workflows_shared.png-20090601201124-cruf3mmq5cfxeb1w-13
      doc/ru/user-guide/images/workflows_shared.svg workflows_shared.svg-20090601201124-cruf3mmq5cfxeb1w-14
      doc/ru/user-guide/images/workflows_single.png workflows_single.png-20090601201124-cruf3mmq5cfxeb1w-15
      doc/ru/user-guide/images/workflows_single.svg workflows_single.svg-20090601201124-cruf3mmq5cfxeb1w-16
      doc/ru/user-guide/index.txt    index.txt-20090601201124-cruf3mmq5cfxeb1w-2
      doc/ru/user-guide/introducing_bazaar.txt introducing_bazaar.t-20090601221109-6ehwbt2pvzgpftlu-1
      doc/ru/user-guide/specifying_revisions.txt specifying_revisions-20090602104644-pjpwfx7xh2k5l0ba-3
      doc/ru/user-guide/stacked.txt  stacked.txt-20090602104644-pjpwfx7xh2k5l0ba-4
      doc/ru/user-guide/using_checkouts.txt using_checkouts.txt-20090602104644-pjpwfx7xh2k5l0ba-5
      doc/ru/user-guide/zen.txt      zen.txt-20090602104644-pjpwfx7xh2k5l0ba-6
    modified:
      Makefile                       Makefile-20050805140406-d96e3498bb61c5bb
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_dirstate_helpers_c.pyx dirstate_helpers.pyx-20070503201057-u425eni465q4idwn-3
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
      bzrlib/filters/__init__.py     __init__.py-20080416080515-mkxl29amuwrf6uir-2
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/lock.py                 lock.py-20050527050856-ec090bb51bc03349
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/groupcompress_repo.py repofmt.py-20080715094215-wp1qfvoo7093c8qr-1
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/blackbox/test_init.py test_init.py-20060309032856-a292116204d86eb7
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/blackbox/test_status.py teststatus.py-20050712014354-508855eb9f29f7dc
      bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
      bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
      bzrlib/tests/test_eol_filters.py test_eol_filters.py-20090327060429-todzdjmqt3bpv5r8-2
      bzrlib/tests/test_filters.py   test_filters.py-20080417120614-tc3zok0vvvprsc99-1
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/workingtree_implementations/test_content_filters.py test_content_filters-20080424071441-8navsrmrfdxpn90a-1
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/win32utils.py           win32console.py-20051021033308-123c6c929d04973d
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      doc/developers/performance-roadmap.txt performanceroadmap.t-20070507174912-mwv3xv517cs4sisd-2
      doc/developers/planned-change-integration.txt plannedchangeintegra-20070619004702-i1b3ccamjtfaoq6w-1
      doc/en/developer-guide/HACKING.txt HACKING-20050805200004-2a5dc975d870f78c
      doc/en/quick-reference/Makefile makefile-20070813143223-5i7bgw7w8s7l3ae2-2
      doc/en/quick-reference/quick-start-summary.png quickstartsummary.pn-20071203142852-hsiybkmh37q5owwe-1
      doc/en/tutorials/using_bazaar_with_launchpad.txt using_bazaar_with_lp-20071211073140-7msh8uf9a9h4y9hb-1
      doc/en/user-guide/images/workflows_centralized.png workflows_centralize-20071114035000-q36a9h57ps06uvnl-8
      doc/en/user-guide/images/workflows_gatekeeper.png workflows_gatekeeper-20071114035000-q36a9h57ps06uvnl-9
      doc/en/user-guide/images/workflows_localcommit.png workflows_localcommi-20071114035000-q36a9h57ps06uvnl-10
      doc/en/user-guide/images/workflows_peer.png workflows_peer.png-20071114035000-q36a9h57ps06uvnl-11
      doc/en/user-guide/images/workflows_pqm.png workflows_pqm.png-20071114035000-q36a9h57ps06uvnl-12
      doc/en/user-guide/images/workflows_shared.png workflows_shared.png-20071114035000-q36a9h57ps06uvnl-13
      doc/en/user-guide/images/workflows_single.png workflows_single.png-20071114035000-q36a9h57ps06uvnl-14
      doc/en/user-guide/introducing_bazaar.txt introducing_bazaar.t-20071114035000-q36a9h57ps06uvnl-5
      doc/index.txt                  index.txt-20070813101924-07gd9i9d2jt124bf-1
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
    ------------------------------------------------------------
    revno: 4419.2.9
    revision-id: andrew.bennetts at canonical.com-20090615064149-f3vxn27mi3ak8akp
    parent: andrew.bennetts at canonical.com-20090615032304-szn017g7t4w4pwgl
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 16:41:49 +1000
    message:
      Add per_repository_reference test for get_rev_id_for_revno, fix the bugs it revealed.
    added:
      bzrlib/tests/per_repository_reference/test_get_rev_id_for_revno.py test_get_rev_id_for_-20090615064050-b6mq6co557towrxh-1
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/per_repository_reference/__init__.py __init__.py-20080220025549-nnm2s80it1lvcwnc-2
    ------------------------------------------------------------
    revno: 4419.2.8
    revision-id: andrew.bennetts at canonical.com-20090615032304-szn017g7t4w4pwgl
    parent: andrew.bennetts at canonical.com-20090615030447-mn24he9pyqaxnz3v
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 13:23:04 +1000
    message:
      Add unit test for RemoteRepository.get_rev_id_for_revno using fallbacks if it gets a history-incomplete response.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 4419.2.7
    revision-id: andrew.bennetts at canonical.com-20090615030447-mn24he9pyqaxnz3v
    parent: andrew.bennetts at canonical.com-20090611072139-yp9tbd5sfjaynb57
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Mon 2009-06-15 13:04:47 +1000
    message:
      Add unit tests for RemoteRepository.get_rev_id_for_revno.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 4419.2.6
    revision-id: andrew.bennetts at canonical.com-20090611072139-yp9tbd5sfjaynb57
    parent: andrew.bennetts at canonical.com-20090611053729-o45rt297wg7dezan
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Thu 2009-06-11 17:21:39 +1000
    message:
      Add tests for server-side logic, and fix the bugs exposed by those tests.
    modified:
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 4419.2.5
    revision-id: andrew.bennetts at canonical.com-20090611053729-o45rt297wg7dezan
    parent: andrew.bennetts at canonical.com-20090610104545-idppwhjfv7iiz1f4
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Thu 2009-06-11 15:37:29 +1000
    message:
      Add Repository.get_rev_id_for_revno, and use it both as the _ensure_real fallback and as the server-side implementation.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
    ------------------------------------------------------------
    revno: 4419.2.4
    revision-id: andrew.bennetts at canonical.com-20090610104545-idppwhjfv7iiz1f4
    parent: andrew.bennetts at canonical.com-20090610075248-1sniwsietj9f1f83
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Wed 2009-06-10 20:45:45 +1000
    message:
      Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
    ------------------------------------------------------------
    revno: 4419.2.3
    revision-id: andrew.bennetts at canonical.com-20090610075248-1sniwsietj9f1f83
    parent: andrew.bennetts at canonical.com-20090610054525-7m4y16qdrlb7q10x
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Wed 2009-06-10 17:52:48 +1000
    message:
      Refactor _extend_partial_history into a standalone function that can be used without a branch.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
    ------------------------------------------------------------
    revno: 4419.2.2
    revision-id: andrew.bennetts at canonical.com-20090610054525-7m4y16qdrlb7q10x
    parent: andrew.bennetts at canonical.com-20090610053252-38q6noygu4nvef8p
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Wed 2009-06-10 15:45:25 +1000
    message:
      Read lock branch_from in cmd_pull, avoids refetching last_revision_info and so reduces test_pull acceptance ratchet.
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
    ------------------------------------------------------------
    revno: 4419.2.1
    revision-id: andrew.bennetts at canonical.com-20090610053252-38q6noygu4nvef8p
    parent: andrew.bennetts at canonical.com-20090610052951-g3lf1k53ux6vzfix
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: stacking-friendly-revision-history-verb
    timestamp: Wed 2009-06-10 15:32:52 +1000
    message:
      Move _extend_partial_history into Branch base class, and use it in get_rev_id rather than self.revision_history().
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
=== modified file 'NEWS'
--- a/NEWS	2009-06-15 15:20:24 +0000
+++ b/NEWS	2009-06-16 09:05:34 +0000
@@ -26,6 +26,14 @@
   rather than requiring all command names be known a-priori.
   (Robert Collins)
 
+Improvements
+************
+
+* Resolving a revno to a revision id on a branch accessed via ``bzr://``
+  or ``bzr+ssh://`` is now much faster and involves no VFS operations.
+  This speeds up commands like ``bzr pull -r 123``.  (Andrew Bennetts)
+
+
 bzr 1.16rc1 "It's yesterday in California" 2009-06-11
 #####################################################
 :Codename: yesterday-in-california

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2009-06-10 03:56:49 +0000
+++ b/bzrlib/branch.py	2009-06-16 08:06:58 +0000
@@ -91,6 +91,7 @@
         self._revision_history_cache = None
         self._revision_id_to_revno_cache = None
         self._partial_revision_id_to_revno_cache = {}
+        self._partial_revision_history_cache = []
         self._last_revision_info_cache = None
         self._merge_sorted_revisions_cache = None
         self._open_hook()
@@ -125,6 +126,27 @@
             raise errors.UnstackableRepositoryFormat(self.repository._format,
                 self.repository.base)
 
+    def _extend_partial_history(self, stop_index=None, stop_revision=None):
+        """Extend the partial history to include a given index
+
+        If a stop_index is supplied, stop when that index has been reached.
+        If a stop_revision is supplied, stop when that revision is
+        encountered.  Otherwise, stop when the beginning of history is
+        reached.
+
+        :param stop_index: The index which should be present.  When it is
+            present, history extension will stop.
+        :param stop_revision: The revision id which should be present.  When
+            it is encountered, history extension will stop.
+        """
+        if len(self._partial_revision_history_cache) == 0:
+            self._partial_revision_history_cache = [self.last_revision()]
+        repository._iter_for_revno(
+            self.repository, self._partial_revision_history_cache,
+            stop_index=stop_index, stop_revision=stop_revision)
+        if self._partial_revision_history_cache[-1] == _mod_revision.NULL_REVISION:
+            self._partial_revision_history_cache.pop()
+
     @staticmethod
     def open(base, _unsupported=False, possible_transports=None):
         """Open the branch rooted at base.
@@ -698,6 +720,8 @@
         self._revision_id_to_revno_cache = None
         self._last_revision_info_cache = None
         self._merge_sorted_revisions_cache = None
+        self._partial_revision_history_cache = []
+        self._partial_revision_id_to_revno_cache = {}
 
     def _gen_revision_history(self):
         """Return sequence of revision hashes on to this branch.
@@ -831,15 +855,20 @@
         except ValueError:
             raise errors.NoSuchRevision(self, revision_id)
 
+    @needs_read_lock
     def get_rev_id(self, revno, history=None):
         """Find the revision id of the specified revno."""
         if revno == 0:
             return _mod_revision.NULL_REVISION
-        if history is None:
-            history = self.revision_history()
-        if revno <= 0 or revno > len(history):
+        last_revno, last_revid = self.last_revision_info()
+        if revno == last_revno:
+            return last_revid
+        if revno <= 0 or revno > last_revno:
             raise errors.NoSuchRevision(self, revno)
-        return history[revno - 1]
+        distance_from_last = last_revno - revno
+        if len(self._partial_revision_history_cache) <= distance_from_last:
+            self._extend_partial_history(distance_from_last)
+        return self._partial_revision_history_cache[distance_from_last]
 
     @needs_write_lock
     def pull(self, source, overwrite=False, stop_revision=None,
@@ -2376,13 +2405,11 @@
         self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)
         super(BzrBranch8, self).__init__(*args, **kwargs)
         self._last_revision_info_cache = None
-        self._partial_revision_history_cache = []
         self._reference_info = None
 
     def _clear_cached_state(self):
         super(BzrBranch8, self)._clear_cached_state()
         self._last_revision_info_cache = None
-        self._partial_revision_history_cache = []
         self._reference_info = None
 
     def _last_revision_info(self):
@@ -2444,35 +2471,6 @@
         self._extend_partial_history(stop_index=last_revno-1)
         return list(reversed(self._partial_revision_history_cache))
 
-    def _extend_partial_history(self, stop_index=None, stop_revision=None):
-        """Extend the partial history to include a given index
-
-        If a stop_index is supplied, stop when that index has been reached.
-        If a stop_revision is supplied, stop when that revision is
-        encountered.  Otherwise, stop when the beginning of history is
-        reached.
-
-        :param stop_index: The index which should be present.  When it is
-            present, history extension will stop.
-        :param revision_id: The revision id which should be present.  When
-            it is encountered, history extension will stop.
-        """
-        repo = self.repository
-        if len(self._partial_revision_history_cache) == 0:
-            iterator = repo.iter_reverse_revision_history(self.last_revision())
-        else:
-            start_revision = self._partial_revision_history_cache[-1]
-            iterator = repo.iter_reverse_revision_history(start_revision)
-            #skip the last revision in the list
-            next_revision = iterator.next()
-        for revision_id in iterator:
-            self._partial_revision_history_cache.append(revision_id)
-            if (stop_index is not None and
-                len(self._partial_revision_history_cache) > stop_index):
-                break
-            if revision_id == stop_revision:
-                break
-
     def _write_revision_history(self, history):
         """Factored out of set_revision_history.
 

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2009-06-11 06:54:33 +0000
+++ b/bzrlib/builtins.py	2009-06-15 06:47:14 +0000
@@ -946,29 +946,36 @@
             if branch_to.get_parent() is None or remember:
                 branch_to.set_parent(branch_from.base)
 
-        if revision is not None:
-            revision_id = revision.as_revision_id(branch_from)
-
-        branch_to.lock_write()
+        if branch_from is not branch_to:
+            branch_from.lock_read()
         try:
-            if tree_to is not None:
-                view_info = _get_view_info_for_change_reporter(tree_to)
-                change_reporter = delta._ChangeReporter(
-                    unversioned_filter=tree_to.is_ignored, view_info=view_info)
-                result = tree_to.pull(branch_from, overwrite, revision_id,
-                                      change_reporter,
-                                      possible_transports=possible_transports,
-                                      local=local)
-            else:
-                result = branch_to.pull(branch_from, overwrite, revision_id,
-                                      local=local)
-
-            result.report(self.outf)
-            if verbose and result.old_revid != result.new_revid:
-                log.show_branch_change(branch_to, self.outf, result.old_revno,
-                                       result.old_revid)
+            if revision is not None:
+                revision_id = revision.as_revision_id(branch_from)
+
+            branch_to.lock_write()
+            try:
+                if tree_to is not None:
+                    view_info = _get_view_info_for_change_reporter(tree_to)
+                    change_reporter = delta._ChangeReporter(
+                        unversioned_filter=tree_to.is_ignored,
+                        view_info=view_info)
+                    result = tree_to.pull(
+                        branch_from, overwrite, revision_id, change_reporter,
+                        possible_transports=possible_transports, local=local)
+                else:
+                    result = branch_to.pull(
+                        branch_from, overwrite, revision_id, local=local)
+
+                result.report(self.outf)
+                if verbose and result.old_revid != result.new_revid:
+                    log.show_branch_change(
+                        branch_to, self.outf, result.old_revno,
+                        result.old_revid)
+            finally:
+                branch_to.unlock()
         finally:
-            branch_to.unlock()
+            if branch_from is not branch_to:
+                branch_from.unlock()
 
 
 class cmd_push(Command):

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-06-11 09:11:21 +0000
+++ b/bzrlib/remote.py	2009-06-16 08:06:58 +0000
@@ -28,12 +28,10 @@
     errors,
     graph,
     lockdir,
-    pack,
     repository,
     revision,
     revision as _mod_revision,
     symbol_versioning,
-    urlutils,
 )
 from bzrlib.branch import BranchReferenceFormat
 from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
@@ -675,6 +673,37 @@
         return self._real_repository.get_missing_parent_inventories(
             check_for_missing_texts=check_for_missing_texts)
 
+    def _get_rev_id_for_revno_vfs(self, revno, known_pair):
+        self._ensure_real()
+        return self._real_repository.get_rev_id_for_revno(
+            revno, known_pair)
+
+    def get_rev_id_for_revno(self, revno, known_pair):
+        """See Repository.get_rev_id_for_revno."""
+        path = self.bzrdir._path_for_remote_call(self._client)
+        try:
+            if self._client._medium._is_remote_before((1, 17)):
+                return self._get_rev_id_for_revno_vfs(revno, known_pair)
+            response = self._call(
+                'Repository.get_rev_id_for_revno', path, revno, known_pair)
+        except errors.UnknownSmartMethod:
+            self._client._medium._remember_remote_is_before((1, 17))
+            return self._get_rev_id_for_revno_vfs(revno, known_pair)
+        if response[0] == 'ok':
+            return True, response[1]
+        elif response[0] == 'history-incomplete':
+            known_pair = response[1:3]
+            for fallback in self._fallback_repositories:
+                found, result = fallback.get_rev_id_for_revno(revno, known_pair)
+                if found:
+                    return True, result
+                else:
+                    known_pair = result
+            # Not found in any fallbacks
+            return False, known_pair
+        else:
+            raise errors.UnexpectedSmartServerResponse(response)
+
     def _ensure_real(self):
         """Ensure that there is a _real_repository set.
 
@@ -1919,11 +1948,6 @@
         # We intentionally don't call the parent class's __init__, because it
         # will try to assign to self.tags, which is a property in this subclass.
         # And the parent's __init__ doesn't do much anyway.
-        self._revision_id_to_revno_cache = None
-        self._partial_revision_id_to_revno_cache = {}
-        self._revision_history_cache = None
-        self._last_revision_info_cache = None
-        self._merge_sorted_revisions_cache = None
         self.bzrdir = remote_bzrdir
         if _client is not None:
             self._client = _client
@@ -1943,6 +1967,7 @@
         else:
             self._real_branch = None
         # Fill out expected attributes of branch for bzrlib API users.
+        self._clear_cached_state()
         self.base = self.bzrdir.root_transport.base
         self._control_files = None
         self._lock_mode = None
@@ -2229,6 +2254,23 @@
             raise NotImplementedError(self.dont_leave_lock_in_place)
         self._leave_lock = False
 
+    def get_rev_id(self, revno, history=None):
+        if revno == 0:
+            return _mod_revision.NULL_REVISION
+        last_revision_info = self.last_revision_info()
+        ok, result = self.repository.get_rev_id_for_revno(
+            revno, last_revision_info)
+        if ok:
+            return result
+        missing_parent = result[1]
+        # Either the revision named by the server is missing, or its parent
+        # is.  Call get_parent_map to determine which, so that we report a
+        # useful error.
+        parent_map = self.repository.get_parent_map([missing_parent])
+        if missing_parent in parent_map:
+            missing_parent = parent_map[missing_parent]
+        raise errors.RevisionNotPresent(missing_parent, self.repository)
+
     def _last_revision_info(self):
         response = self._call('Branch.last_revision_info', self._remote_path())
         if response[0] != 'ok':

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2009-06-12 01:11:00 +0000
+++ b/bzrlib/repository.py	2009-06-15 08:01:21 +0000
@@ -2234,6 +2234,41 @@
         """
         return self.get_revision(revision_id).inventory_sha1
 
+    def get_rev_id_for_revno(self, revno, known_pair):
+        """Return the revision id of a revno, given a later (revno, revid)
+        pair in the same history.
+
+        :return: if found (True, revid).  If the available history ran out
+            before reaching the revno, then this returns
+            (False, (closest_revno, closest_revid)).
+        """
+        known_revno, known_revid = known_pair
+        partial_history = [known_revid]
+        distance_from_known = known_revno - revno
+        if distance_from_known < 0:
+            raise ValueError(
+                'requested revno (%d) is later than given known revno (%d)'
+                % (revno, known_revno))
+        try:
+            _iter_for_revno(
+                self, partial_history, stop_index=distance_from_known)
+        except errors.RevisionNotPresent, err:
+            if err.revision_id == known_revid:
+                # The start revision (known_revid) wasn't found.
+                raise
+            # This is a stacked repository with no fallbacks, or a there's a
+            # left-hand ghost.  Either way, even though the revision named in
+            # the error isn't in this repo, we know it's the next step in this
+            # left-hand history.
+            partial_history.append(err.revision_id)
+        if len(partial_history) <= distance_from_known:
+            # Didn't find enough history to get a revid for the revno.
+            earliest_revno = known_revno - len(partial_history) + 1
+            return (False, (earliest_revno, partial_history[-1]))
+        if len(partial_history) - 1 > distance_from_known:
+            raise AssertionError('_iter_for_revno returned too much history')
+        return (True, partial_history[-1])
+
     def iter_reverse_revision_history(self, revision_id):
         """Iterate backwards through revision ids in the lefthand history
 
@@ -4417,3 +4452,35 @@
             yield versionedfile.FulltextContentFactory(
                 key, parent_keys, None, as_bytes)
 
+
+def _iter_for_revno(repo, partial_history_cache, stop_index=None,
+                    stop_revision=None):
+    """Extend the partial history to include a given index
+
+    If a stop_index is supplied, stop when that index has been reached.
+    If a stop_revision is supplied, stop when that revision is
+    encountered.  Otherwise, stop when the beginning of history is
+    reached.
+
+    :param stop_index: The index which should be present.  When it is
+        present, history extension will stop.
+    :param stop_revision: The revision id which should be present.  When
+        it is encountered, history extension will stop.
+    """
+    start_revision = partial_history_cache[-1]
+    iterator = repo.iter_reverse_revision_history(start_revision)
+    try:
+        #skip the last revision in the list
+        iterator.next()
+        while True:
+            if (stop_index is not None and
+                len(partial_history_cache) > stop_index):
+                break
+            if partial_history_cache[-1] == stop_revision:
+                break
+            revision_id = iterator.next()
+            partial_history_cache.append(revision_id)
+    except StopIteration:
+        # No more history
+        return
+

=== modified file 'bzrlib/smart/repository.py'
--- a/bzrlib/smart/repository.py	2009-06-10 03:56:49 +0000
+++ b/bzrlib/smart/repository.py	2009-06-16 06:46:32 +0000
@@ -19,7 +19,6 @@
 import bz2
 import os
 import Queue
-import struct
 import sys
 import tarfile
 import tempfile
@@ -284,6 +283,31 @@
         return SuccessfulSmartServerResponse(('ok', ), '\n'.join(lines))
 
 
+class SmartServerRepositoryGetRevIdForRevno(SmartServerRepositoryReadLocked):
+
+    def do_readlocked_repository_request(self, repository, revno,
+            known_pair):
+        """Find the revid for a given revno, given a known revno/revid pair.
+        
+        New in 1.17.
+        """
+        try:
+            found_flag, result = repository.get_rev_id_for_revno(revno, known_pair)
+        except errors.RevisionNotPresent, err:
+            if err.revision_id != known_pair[1]:
+                raise AssertionError(
+                    'get_rev_id_for_revno raised RevisionNotPresent for '
+                    'non-initial revision: ' + err.revision_id)
+            return FailedSmartServerResponse(
+                ('nosuchrevision', err.revision_id))
+        if found_flag:
+            return SuccessfulSmartServerResponse(('ok', result))
+        else:
+            earliest_revno, earliest_revid = result
+            return SuccessfulSmartServerResponse(
+                ('history-incomplete', earliest_revno, earliest_revid))
+
+
 class SmartServerRequestHasRevision(SmartServerRepositoryRequest):
 
     def do_repository_request(self, repository, revision_id):

=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py	2009-06-12 01:48:43 +0000
+++ b/bzrlib/smart/request.py	2009-06-15 06:47:14 +0000
@@ -555,6 +555,9 @@
 request_handlers.register_lazy(
     'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
 request_handlers.register_lazy(
+    'Repository.get_rev_id_for_revno', 'bzrlib.smart.repository',
+    'SmartServerRepositoryGetRevIdForRevno')
+request_handlers.register_lazy(
     'Repository.get_stream', 'bzrlib.smart.repository',
     'SmartServerRepositoryGetStream')
 request_handlers.register_lazy(

=== modified file 'bzrlib/tests/blackbox/test_pull.py'
--- a/bzrlib/tests/blackbox/test_pull.py	2009-06-11 07:43:56 +0000
+++ b/bzrlib/tests/blackbox/test_pull.py	2009-06-15 06:47:14 +0000
@@ -368,8 +368,12 @@
         See <https://launchpad.net/bugs/380314>
         """
         self.setup_smart_server_with_call_log()
+        # Make a stacked-on branch with two commits so that the
+        # revision-history can't be determined just by looking at the parent
+        # field in the revision in the stacked repo.
         parent = self.make_branch_and_tree('parent', format='1.9')
         parent.commit(message='first commit')
+        parent.commit(message='second commit')
         local = parent.bzrdir.sprout('local').open_workingtree()
         local.commit(message='local commit')
         local.branch.create_clone_on_transport(
@@ -383,7 +387,7 @@
         # being too low. If rpc_count increases, more network roundtrips have
         # become necessary for this use case. Please do not adjust this number
         # upwards without agreement from bzr's network support maintainers.
-        self.assertLength(43, self.hpss_calls)
+        self.assertLength(18, self.hpss_calls)
         remote = Branch.open('stacked')
         self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
 

=== modified file 'bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py'
--- a/bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py	2009-06-16 08:06:58 +0000
@@ -26,6 +26,8 @@
     def test_lookup_revision_id_by_dotted(self):
         tree = self.create_tree_with_merge()
         the_branch = tree.branch
+        the_branch.lock_read()
+        self.addCleanup(the_branch.unlock)
         self.assertEqual('null:', the_branch.dotted_revno_to_revision_id((0,)))
         self.assertEqual('rev-1', the_branch.dotted_revno_to_revision_id((1,)))
         self.assertEqual('rev-2', the_branch.dotted_revno_to_revision_id((2,)))

=== modified file 'bzrlib/tests/per_repository_reference/__init__.py'
--- a/bzrlib/tests/per_repository_reference/__init__.py	2009-06-10 03:56:49 +0000
+++ b/bzrlib/tests/per_repository_reference/__init__.py	2009-06-15 06:47:14 +0000
@@ -98,6 +98,7 @@
         'bzrlib.tests.per_repository_reference.test_check',
         'bzrlib.tests.per_repository_reference.test_default_stacking',
         'bzrlib.tests.per_repository_reference.test_fetch',
+        'bzrlib.tests.per_repository_reference.test_get_rev_id_for_revno',
         'bzrlib.tests.per_repository_reference.test_initialize',
         'bzrlib.tests.per_repository_reference.test_unlock',
         ]

=== added file 'bzrlib/tests/per_repository_reference/test_get_rev_id_for_revno.py'
--- a/bzrlib/tests/per_repository_reference/test_get_rev_id_for_revno.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_repository_reference/test_get_rev_id_for_revno.py	2009-06-15 06:41:49 +0000
@@ -0,0 +1,46 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for get_rev_id_for_revno on a repository with external references."""
+
+from bzrlib import errors
+from bzrlib.tests.per_repository_reference import (
+    TestCaseWithExternalReferenceRepository,
+    )
+
+class TestGetRevIdForRevno(TestCaseWithExternalReferenceRepository):
+
+    def test_uses_fallback(self):
+        tree = self.make_branch_and_tree('base')
+        base = tree.branch.repository
+        revid = tree.commit('one')
+        revid2 = tree.commit('two')
+        spare_tree = tree.bzrdir.sprout('spare').open_workingtree()
+        revid3 = spare_tree.commit('three')
+        branch = spare_tree.branch.create_clone_on_transport(
+            self.get_transport('referring'), stacked_on=self.get_url('base'))
+        repo = branch.repository
+        # Sanity check: now repo has 'revid3', and base has 'revid' + 'revid2'
+        self.assertEqual(set([revid3]),
+                set(repo.bzrdir.open_repository().all_revision_ids()))
+        self.assertEqual(set([revid2, revid]),
+                set(base.bzrdir.open_repository().all_revision_ids()))
+        # get_rev_id_for_revno will find revno 1 == 'revid', even though
+        # that revision can only be found in the fallback.
+        repo.lock_read()
+        self.addCleanup(repo.unlock)
+        self.assertEqual(
+            (True, revid), repo.get_rev_id_for_revno(1, (3, revid3)))

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-06-12 01:48:43 +0000
+++ b/bzrlib/tests/test_remote.py	2009-06-15 06:47:14 +0000
@@ -2018,6 +2018,65 @@
         self.assertEqual(('AnUnexpectedError',), e.error_tuple)
 
 
+class TestRepositoryGetRevIdForRevno(TestRemoteRepository):
+
+    def test_ok(self):
+        repo, client = self.setup_fake_client_and_repository('quack')
+        client.add_expected_call(
+            'Repository.get_rev_id_for_revno', ('quack/', 5, (42, 'rev-foo')),
+            'success', ('ok', 'rev-five'))
+        result = repo.get_rev_id_for_revno(5, (42, 'rev-foo'))
+        self.assertEqual((True, 'rev-five'), result)
+        client.finished_test()
+
+    def test_history_incomplete(self):
+        repo, client = self.setup_fake_client_and_repository('quack')
+        client.add_expected_call(
+            'Repository.get_rev_id_for_revno', ('quack/', 5, (42, 'rev-foo')),
+            'success', ('history-incomplete', 10, 'rev-ten'))
+        result = repo.get_rev_id_for_revno(5, (42, 'rev-foo'))
+        self.assertEqual((False, (10, 'rev-ten')), result)
+        client.finished_test()
+
+    def test_history_incomplete_with_fallback(self):
+        """A 'history-incomplete' response causes the fallback repository to be
+        queried too, if one is set.
+        """
+        # Make a repo with a fallback repo, both using a FakeClient.
+        format = remote.response_tuple_to_repo_format(
+            ('yes', 'no', 'yes', 'fake-network-name'))
+        repo, client = self.setup_fake_client_and_repository('quack')
+        repo._format = format
+        fallback_repo, ignored = self.setup_fake_client_and_repository(
+            'fallback')
+        fallback_repo._client = client
+        repo.add_fallback_repository(fallback_repo)
+        # First the client should ask the primary repo
+        client.add_expected_call(
+            'Repository.get_rev_id_for_revno', ('quack/', 1, (42, 'rev-foo')),
+            'success', ('history-incomplete', 2, 'rev-two'))
+        # Then it should ask the fallback, using revno/revid from the
+        # history-incomplete response as the known revno/revid.
+        client.add_expected_call(
+            'Repository.get_rev_id_for_revno',('fallback/', 1, (2, 'rev-two')),
+            'success', ('ok', 'rev-one'))
+        result = repo.get_rev_id_for_revno(1, (42, 'rev-foo'))
+        self.assertEqual((True, 'rev-one'), result)
+        client.finished_test()
+
+    def test_nosuchrevision(self):
+        # 'nosuchrevision' is returned when the known-revid is not found in the
+        # remote repo.  The client translates that response to NoSuchRevision.
+        repo, client = self.setup_fake_client_and_repository('quack')
+        client.add_expected_call(
+            'Repository.get_rev_id_for_revno', ('quack/', 5, (42, 'rev-foo')),
+            'error', ('nosuchrevision', 'rev-foo'))
+        self.assertRaises(
+            errors.NoSuchRevision,
+            repo.get_rev_id_for_revno, 5, (42, 'rev-foo'))
+        client.finished_test()
+
+
 class TestRepositoryIsShared(TestRemoteRepository):
 
     def test_is_shared(self):

=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py	2009-06-12 01:48:43 +0000
+++ b/bzrlib/tests/test_smart.py	2009-06-15 06:47:14 +0000
@@ -1161,6 +1161,47 @@
             request.execute('', 'missingrevision'))
 
 
+class TestSmartServerRepositoryGetRevIdForRevno(tests.TestCaseWithMemoryTransport):
+
+    def test_revno_found(self):
+        backing = self.get_transport()
+        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
+        tree = self.make_branch_and_memory_tree('.')
+        tree.lock_write()
+        tree.add('')
+        rev1_id_utf8 = u'\xc8'.encode('utf-8')
+        rev2_id_utf8 = u'\xc9'.encode('utf-8')
+        tree.commit('1st commit', rev_id=rev1_id_utf8)
+        tree.commit('2nd commit', rev_id=rev2_id_utf8)
+        tree.unlock()
+
+        self.assertEqual(SmartServerResponse(('ok', rev1_id_utf8)),
+            request.execute('', 1, (2, rev2_id_utf8)))
+
+    def test_known_revid_missing(self):
+        backing = self.get_transport()
+        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
+        repo = self.make_repository('.')
+        self.assertEqual(
+            FailedSmartServerResponse(('nosuchrevision', 'ghost')),
+            request.execute('', 1, (2, 'ghost')))
+
+    def test_history_incomplete(self):
+        backing = self.get_transport()
+        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
+        parent = self.make_branch_and_memory_tree('parent', format='1.9')
+        r1 = parent.commit(message='first commit')
+        r2 = parent.commit(message='second commit')
+        local = self.make_branch_and_memory_tree('local', format='1.9')
+        local.branch.pull(parent.branch)
+        local.set_parent_ids([r2])
+        r3 = local.commit(message='local commit')
+        local.branch.create_clone_on_transport(
+            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
+        self.assertEqual(
+            SmartServerResponse(('history-incomplete', 2, r2)),
+            request.execute('stacked', 1, (3, r3)))
+
 class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
     def make_two_commit_repo(self):
@@ -1576,6 +1617,8 @@
             smart.repository.SmartServerRepositoryGatherStats)
         self.assertHandlerEqual('Repository.get_parent_map',
             smart.repository.SmartServerRepositoryGetParentMap)
+        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
+            smart.repository.SmartServerRepositoryGetRevIdForRevno)
         self.assertHandlerEqual('Repository.get_revision_graph',
             smart.repository.SmartServerRepositoryGetRevisionGraph)
         self.assertHandlerEqual('Repository.get_stream',




More information about the bazaar-commits mailing list