Rev 3328: Faster Branch and revspec operations (jam, abentley) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Apr 3 03:23:10 BST 2008


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

------------------------------------------------------------
revno: 3328
revision-id:pqm at pqm.ubuntu.com-20080403022255-5l0yelvi9m74mq24
parent: pqm at pqm.ubuntu.com-20080402090835-uq4ef5jnwo7opd9t
parent: aaron at aaronbentley.com-20080403003718-fmjr2u6dacofcbkw
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2008-04-03 03:22:55 +0100
message:
  Faster Branch and revspec operations (jam, abentley)
renamed:
  bzrlib/tests/test_revisionnamespaces.py => bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
  bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.18
    revision-id:aaron at aaronbentley.com-20080403003718-fmjr2u6dacofcbkw
    parent: aaron at aaronbentley.com-20080403002341-4b8qdu57v6amp85n
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Wed 2008-04-02 20:37:18 -0400
    message:
      Restore original diff revision spec handling
    modified:
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
    ------------------------------------------------------------
    revno: 3298.2.17
    revision-id:aaron at aaronbentley.com-20080403002341-4b8qdu57v6amp85n
    parent: aaron at aaronbentley.com-20080403002050-own1uh1l6xqavu3p
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Wed 2008-04-02 20:23:41 -0400
    message:
      Update from review
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3298.2.16
    revision-id:aaron at aaronbentley.com-20080403002050-own1uh1l6xqavu3p
    parent: aaron at aaronbentley.com-20080403001905-vp1z7zjd9o27zfce
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Wed 2008-04-02 20:20:50 -0400
    message:
      Update NEWS
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3298.2.15
    revision-id:aaron at aaronbentley.com-20080403001905-vp1z7zjd9o27zfce
    parent: aaron at aaronbentley.com-20080331063750-6cjuhtymwlsfflzl
    parent: aaron at aaronbentley.com-20080403001839-c28y89efowzygc5h
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Wed 2008-04-02 20:19:05 -0400
    message:
      Merge from as_revision_id
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
      bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
      bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
      bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/smart/server.py         server.py-20061110062051-chzu10y32vx8gvur-1
      bzrlib/smart/vfs.py            vfs.py-20061108095550-gunadhxmzkdjfeek-2
      bzrlib/tests/TestUtil.py       TestUtil.py-20050824080200-5f70140a2d938694
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
      bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
      bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
      bzrlib/tests/repository_implementations/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_lazy_import.py test_lazy_import.py-20060910203832-f77c54gf3n232za0-2
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/tests/test_wsgi.py      test_wsgi.py-20061005091552-rz8pva0olkxv0sd8-1
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/chroot.py     chroot.py-20061011104729-0us9mgm97z378vnt-1
      bzrlib/transport/ftp.py        ftp.py-20051116161804-58dc9506548c2a53
      bzrlib/transport/http/wsgi.py  wsgi.py-20061005091552-rz8pva0olkxv0sd8-2
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      doc/developers/repository.txt  repository.txt-20070709152006-xkhlek456eclha4u-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/http_smart_server.txt fastcgi.txt-20061005091552-rz8pva0olkxv0sd8-3
      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
        ------------------------------------------------------------
        revno: 3298.2.11.1.4
        revision-id:aaron at aaronbentley.com-20080403001839-c28y89efowzygc5h
        parent: aaron at aaronbentley.com-20080403001751-mkl9uxvmzybz2ztx
        parent: pqm at pqm.ubuntu.com-20080401091848-6y4f104r061ad8bk
        committer: Aaron Bentley <aaron at aaronbentley.com>
        branch nick: as_revision_id
        timestamp: Wed 2008-04-02 20:18:39 -0400
        message:
          Merge from bzr.dev
        modified:
          NEWS                           NEWS-20050323055033-4e00b5db738777ff
          bzr                            bzr.py-20050313053754-5485f144c7006fa6
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
          bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
          bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
          bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
          bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
          bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
          bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
          bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
          bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
          bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
          bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
          bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
          bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
          bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
          bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
          bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
          bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
          bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
          bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
          bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
          bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
          bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
          bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
          bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
          bzrlib/smart/server.py         server.py-20061110062051-chzu10y32vx8gvur-1
          bzrlib/smart/vfs.py            vfs.py-20061108095550-gunadhxmzkdjfeek-2
          bzrlib/tests/TestUtil.py       TestUtil.py-20050824080200-5f70140a2d938694
          bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
          bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
          bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
          bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
          bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
          bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
          bzrlib/tests/repository_implementations/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
          bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
          bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
          bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
          bzrlib/tests/test_lazy_import.py test_lazy_import.py-20060910203832-f77c54gf3n232za0-2
          bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
          bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
          bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
          bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
          bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
          bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
          bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
          bzrlib/tests/test_wsgi.py      test_wsgi.py-20061005091552-rz8pva0olkxv0sd8-1
          bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
          bzrlib/transport/chroot.py     chroot.py-20061011104729-0us9mgm97z378vnt-1
          bzrlib/transport/ftp.py        ftp.py-20051116161804-58dc9506548c2a53
          bzrlib/transport/http/wsgi.py  wsgi.py-20061005091552-rz8pva0olkxv0sd8-2
          bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
          bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
          bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
          doc/developers/repository.txt  repository.txt-20070709152006-xkhlek456eclha4u-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/http_smart_server.txt fastcgi.txt-20061005091552-rz8pva0olkxv0sd8-3
          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
        ------------------------------------------------------------
        revno: 3298.2.11.1.3
        revision-id:aaron at aaronbentley.com-20080403001751-mkl9uxvmzybz2ztx
        parent: aaron at aaronbentley.com-20080330172819-46dbczkez78c3658
        committer: Aaron Bentley <aaron at aaronbentley.com>
        branch nick: as_revision_id
        timestamp: Wed 2008-04-02 20:17:51 -0400
        message:
          Update from review
        modified:
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3298.2.14
    revision-id:aaron at aaronbentley.com-20080331063750-6cjuhtymwlsfflzl
    parent: aaron at aaronbentley.com-20080331034532-6glc71s5vnleai8p
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Mon 2008-03-31 02:37:50 -0400
    message:
      Optimize revision-info and cat-revision
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
    ------------------------------------------------------------
    revno: 3298.2.13
    revision-id:aaron at aaronbentley.com-20080331034532-6glc71s5vnleai8p
    parent: aaron at aaronbentley.com-20080329214109-onk1ut1azqq8hgrm
    parent: aaron at aaronbentley.com-20080330172819-46dbczkez78c3658
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Sun 2008-03-30 23:45:32 -0400
    message:
      merge from as_revision_id
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
        ------------------------------------------------------------
        revno: 3298.2.11.1.2
        revision-id:aaron at aaronbentley.com-20080330172819-46dbczkez78c3658
        parent: aaron at aaronbentley.com-20080330165354-pohfm2fd3v953u9b
        committer: Aaron Bentley <aaron at aaronbentley.com>
        branch nick: as_revision_id
        timestamp: Sun 2008-03-30 13:28:19 -0400
        message:
          Catch history mismatch, cleanup
        modified:
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
        ------------------------------------------------------------
        revno: 3298.2.11.1.1
        revision-id:aaron at aaronbentley.com-20080330165354-pohfm2fd3v953u9b
        parent: aaron at aaronbentley.com-20080329211620-1a91xrjinusqxudy
        committer: Aaron Bentley <aaron at aaronbentley.com>
        branch nick: as_revision_id
        timestamp: Sun 2008-03-30 12:53:54 -0400
        message:
          Make stop_revision optional for extend_partial_history
        modified:
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3298.2.12
    revision-id:aaron at aaronbentley.com-20080329214109-onk1ut1azqq8hgrm
    parent: aaron at aaronbentley.com-20080329211620-1a91xrjinusqxudy
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: revision_id_to_revno
    timestamp: Sat 2008-03-29 17:41:09 -0400
    message:
      Add Branch6.revision_id_to_revno
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3298.2.11
    revision-id:aaron at aaronbentley.com-20080329211620-1a91xrjinusqxudy
    parent: aaron at aaronbentley.com-20080329193343-ovqohqn5bd7r4hyq
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: as_revision_id
    timestamp: Sat 2008-03-29 17:16:20 -0400
    message:
      Update tests for null:, clea up slightly
    modified:
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.10
    revision-id:aaron at aaronbentley.com-20080329193343-ovqohqn5bd7r4hyq
    parent: aaron at aaronbentley.com-20080329173406-vm8zfzt7z5lbmho7
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: as_revision_id
    timestamp: Sat 2008-03-29 15:33:43 -0400
    message:
      Refactor partial history code
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
    ------------------------------------------------------------
    revno: 3298.2.9
    revision-id:aaron at aaronbentley.com-20080329173406-vm8zfzt7z5lbmho7
    parent: john at arbash-meinel.com-20080320224535-l3h1k92yaa6sr910
    parent: pqm at pqm.ubuntu.com-20080327163915-wtpepv5kq5hm42zv
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: as_revision_id
    timestamp: Sat 2008-03-29 13:34:06 -0400
    message:
      Merge bzr.dev
    added:
      bzrlib/tests/test_uncommit.py  test_uncommit.py-20080316104338-y3gxu67g5m2qih10-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/_knit_load_data_c.pyx   knit_c.pyx-20070509143944-u42gy8w387a10m0j-1
      bzrlib/_knit_load_data_py.py   _knit_load_data_py.p-20070629000948-9a0nh4s118bi5y8n-1
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/__init__.py      changeset.py-20050513021216-b02ab57fb9738913
      bzrlib/bundle/serializer/v4.py v10.py-20070611062757-5ggj7k18s9dej0fr-1
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/debug.py                debug.py-20061102062349-vdhrw9qdpck8cl35-1
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/multiparent.py          __init__.py-20070410133617-n1jdhcc1n1mibarp-1
      bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/symbol_versioning.py    symbol_versioning.py-20060105104851-9ecf8af605d15a80
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
      bzrlib/tests/blackbox/test_uncommit.py test_uncommit.py-20051027212835-84944b63adae51be
      bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
      bzrlib/tests/repository_implementations/test_check_reconcile.py test_broken.py-20070928125406-62236394w0jpbpd6-2
      bzrlib/tests/repository_implementations/test_iter_reverse_revision_history.py test_iter_reverse_re-20070217015036-spu7j5ggch7pbpyd-1
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_bundle.py    test.py-20050630184834-092aa401ab9f039c
      bzrlib/tests/test_diff.py      testdiff.py-20050727164403-d1a3496ebb12e339
      bzrlib/tests/test_fetch.py     testfetch.py-20050825090644-f73e07e7dfb1765a
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_read_bundle.py test_read_bundle.py-20060615211421-ud8cwr1ulgd914zf-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/uncommit.py             uncommit.py-20050626215513-5ec509fa425b305c
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
      doc/en/user-guide/partner_intro.txt partner_workflow.txt-20071122141511-0knao2lklsdsvb1q-4
      doc/en/user-guide/undoing_mistakes.txt undoing_mistakes.txt-20071121092300-8fyacngt1w98e5mp-1
    ------------------------------------------------------------
    revno: 3298.2.8
    revision-id:john at arbash-meinel.com-20080320224535-l3h1k92yaa6sr910
    parent: john at arbash-meinel.com-20080320223558-c51frzshaj11bw29
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 17:45:35 -0500
    message:
      Get rid of .in_branch(need_revno=False) in favor of simpler .as_revision_id()
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
      bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.7
    revision-id:john at arbash-meinel.com-20080320223558-c51frzshaj11bw29
    parent: john at arbash-meinel.com-20080320223038-rv9bnn65p2co2j0u
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 17:35:58 -0500
    message:
      Rename test_revisionnamespaces => test_revisionspec
    renamed:
      bzrlib/tests/test_revisionnamespaces.py => bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
    ------------------------------------------------------------
    revno: 3298.2.6
    revision-id:john at arbash-meinel.com-20080320223038-rv9bnn65p2co2j0u
    parent: john at arbash-meinel.com-20080320221449-ng18p9ecynrau3es
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 17:30:38 -0500
    message:
      Don't abstract through RevisionInfo for RevisionSpec_revno.as_revision_id()
    modified:
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
    ------------------------------------------------------------
    revno: 3298.2.5
    revision-id:john at arbash-meinel.com-20080320221449-ng18p9ecynrau3es
    parent: john at arbash-meinel.com-20080320211426-5c3jff1u4fnfemtj
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 17:14:49 -0500
    message:
      Start implementing everything in terms of cheaper _as_revision_id lookups.
    modified:
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/test_revisionnamespaces.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.4
    revision-id:john at arbash-meinel.com-20080320211426-5c3jff1u4fnfemtj
    parent: john at arbash-meinel.com-20080320192535-1cqd3rnulm3hh36l
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 16:14:26 -0500
    message:
      Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
    modified:
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/test_revisionnamespaces.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.3
    revision-id:john at arbash-meinel.com-20080320192535-1cqd3rnulm3hh36l
    parent: john at arbash-meinel.com-20080320172810-qqk69q0vc3lmop02
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 14:25:35 -0500
    message:
      Add tests that all RevisionSpecs implement in_branch(b, needs_revno)
    modified:
      bzrlib/tests/test_revisionnamespaces.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
    ------------------------------------------------------------
    revno: 3298.2.2
    revision-id:john at arbash-meinel.com-20080320172810-qqk69q0vc3lmop02
    parent: john at arbash-meinel.com-20080320171926-0eyc8dohs0on591o
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 12:28:10 -0500
    message:
      some small cleanups.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3298.2.1
    revision-id:john at arbash-meinel.com-20080320171926-0eyc8dohs0on591o
    parent: pqm at pqm.ubuntu.com-20080320074642-46bf1vcpyubnaptz
    parent: lalinsky at gmail.com-20071203230359-lhcqc1peusply2cc
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: get_rev_id
    timestamp: Thu 2008-03-20 12:19:26 -0500
    message:
      Merge in Lukáš's work to only access partial history for most revision specs.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
    ------------------------------------------------------------
    revno: 3060.3.6
    revision-id:lalinsky at gmail.com-20071203230359-lhcqc1peusply2cc
    parent: lalinsky at gmail.com-20071203213554-8x1dsmlqdtm79ala
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Tue 2007-12-04 00:03:59 +0100
    message:
      Implement partial history cache in BzrBranch6.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
    ------------------------------------------------------------
    revno: 3060.3.5
    revision-id:lalinsky at gmail.com-20071203213554-8x1dsmlqdtm79ala
    parent: lalinsky at gmail.com-20071203212805-ehlgkz9aielhi8gb
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Mon 2007-12-03 22:35:54 +0100
    message:
      Add support for in_branch for the remaining RevisionSpec subclasses.
    modified:
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
    ------------------------------------------------------------
    revno: 3060.3.4
    revision-id:lalinsky at gmail.com-20071203212805-ehlgkz9aielhi8gb
    parent: lalinsky at gmail.com-20071203211103-40soo8ldds0lyu2l
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Mon 2007-12-03 22:28:05 +0100
    message:
      Replace all RevisionSpec.in_history(...).rev_id calls to RevisionSpec.in_branch(..., need_revno=False).rev_id.
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
    ------------------------------------------------------------
    revno: 3060.3.3
    revision-id:lalinsky at gmail.com-20071203211103-40soo8ldds0lyu2l
    parent: lalinsky at gmail.com-20071203204808-gv1m751xdb8m9ltc
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Mon 2007-12-03 22:11:03 +0100
    message:
      Make RevisionSpec_revid and RevisionSpec_revno not load the whole revision history.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
    ------------------------------------------------------------
    revno: 3060.3.2
    revision-id:lalinsky at gmail.com-20071203204808-gv1m751xdb8m9ltc
    parent: lalinsky at gmail.com-20071203200431-qwd9ju3y4ha12n6r
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Mon 2007-12-03 21:48:08 +0100
    message:
      Make RevisionSpec_last not load the whole history.
      
      Implement BzrBranch6.get_rev_id, that uses last_revision_info and repository.iter_reverse_revision_history to find out the revision_id incrementally without loading the whole history.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
    ------------------------------------------------------------
    revno: 3060.3.1
    revision-id:lalinsky at gmail.com-20071203200431-qwd9ju3y4ha12n6r
    parent: pqm at pqm.ubuntu.com-20071130182102-i0t564k01anm7uk2
    committer: Lukáš Lalinský <lalinsky at gmail.com>
    branch nick: pack-revno
    timestamp: Mon 2007-12-03 21:04:31 +0100
    message:
      Cache last_revision_info in BzrBranch6, since this is often called multiple times within one lock and we don't want to read the file over and over again.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
=== renamed file 'bzrlib/tests/test_revisionnamespaces.py' => 'bzrlib/tests/test_revisionspec.py'
--- a/bzrlib/tests/test_revisionnamespaces.py	2007-11-27 00:44:20 +0000
+++ b/bzrlib/tests/test_revisionspec.py	2008-03-29 21:16:20 +0000
@@ -49,15 +49,15 @@
 
         self.tree = self.make_branch_and_tree('tree')
         self.build_tree(['tree/a'])
+        self.tree.lock_write()
+        self.addCleanup(self.tree.unlock)
         self.tree.add(['a'])
         self.tree.commit('a', rev_id='r1')
 
         self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
         self.tree2.commit('alt', rev_id='alt_r2')
 
-        self.tree.branch.repository.fetch(self.tree2.branch.repository,
-                                          revision_id='alt_r2')
-        self.tree.set_pending_merges(['alt_r2'])
+        self.tree.merge_from_branch(self.tree2.branch)
         self.tree.commit('second', rev_id='r2')
 
     def get_in_history(self, revision_spec):
@@ -83,12 +83,18 @@
             self.fail('Expected InvalidRevisionSpec to be raised for %s'
                       % (revision_spec,))
 
+    def assertAsRevisionId(self, revision_id, revision_spec):
+        """Calling as_revision_id() should return the specified id."""
+        spec = RevisionSpec.from_string(revision_spec)
+        self.assertEqual(revision_id,
+                         spec.as_revision_id(self.tree.branch))
+
 
 class TestOddRevisionSpec(TestRevisionSpec):
     """Test things that aren't normally thought of as revision specs"""
 
     def test_none(self):
-        self.assertInHistoryIs(0, None, None)
+        self.assertInHistoryIs(None, None, None)
 
     def test_object(self):
         self.assertRaises(TypeError, RevisionSpec.from_string, object())
@@ -246,6 +252,13 @@
         self.assertEqual((2, 'b at r-0-2'),
                          spec_in_history('revno:2:b/', None))
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('null:', '0')
+        self.assertAsRevisionId('r1', '1')
+        self.assertAsRevisionId('r2', '2')
+        self.assertAsRevisionId('r1', '-2')
+        self.assertAsRevisionId('r2', '-1')
+        self.assertAsRevisionId('alt_r2', '1.1.1')
 
 
 class TestRevisionSpec_revid(TestRevisionSpec):
@@ -283,6 +296,11 @@
         self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
         self.assertInHistoryIs(3, revision_id, 'revid:' + revision_id)
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('r1', 'revid:r1')
+        self.assertAsRevisionId('r2', 'revid:r2')
+        self.assertAsRevisionId('alt_r2', 'revid:alt_r2')
+
 
 class TestRevisionSpec_last(TestRevisionSpec):
 
@@ -314,6 +332,10 @@
             pass
         self.assertInvalid('last:Y', extra='\n' + str(e))
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('r2', 'last:1')
+        self.assertAsRevisionId('r1', 'last:2')
+
 
 class TestRevisionSpec_before(TestRevisionSpec):
 
@@ -345,6 +367,12 @@
                                           revision_id='new_r1')
         self.assertInHistoryIs(0, 'null:', 'before:revid:new_r1')
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('r1', 'before:revid:r2')
+        self.assertAsRevisionId('r1', 'before:2')
+        self.assertAsRevisionId('r1', 'before:1.1.1')
+        self.assertAsRevisionId('r1', 'before:revid:alt_r2')
+
 
 class TestRevisionSpec_tag(TestRevisionSpec):
     
@@ -361,6 +389,8 @@
     def test_lookup_tag(self):
         self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
         self.assertInHistoryIs(1, 'r1', 'tag:bzr-0.14')
+        self.tree.branch.tags.set_tag('null_rev', 'null:')
+        self.assertInHistoryIs(0, 'null:', 'tag:null_rev')
 
     def test_failed_lookup(self):
         # tags that don't exist give a specific message: arguably we should
@@ -369,6 +399,13 @@
             self.get_in_history,
             'tag:some-random-tag')
 
+    def test_as_revision_id(self):
+        self.tree.branch.tags.set_tag('my-tag', 'r2')
+        self.tree.branch.tags.set_tag('null_rev', 'null:')
+        self.assertAsRevisionId('r2', 'tag:my-tag')
+        self.assertAsRevisionId('null:', 'tag:null_rev')
+        self.assertAsRevisionId('r1', 'before:tag:my-tag')
+
 
 class TestRevisionSpec_date(TestRevisionSpec):
 
@@ -405,6 +442,9 @@
         self.assertInHistoryIs(2, 'new_r2',
             'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('new_r2', 'date:today')
+
 
 class TestRevisionSpec_ancestor(TestRevisionSpec):
     
@@ -448,6 +488,9 @@
                           spec_in_history, 'ancestor:tree',
                                            new_tree.branch)
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
+
 
 class TestRevisionSpec_branch(TestRevisionSpec):
     
@@ -482,6 +525,9 @@
         self.assertRaises(errors.NoCommits,
                           self.get_in_history, 'branch:new_tree')
 
+    def test_as_revision_id(self):
+        self.assertAsRevisionId('alt_r2', 'branch:tree2')
+
 
 class TestRevisionSpec_submit(TestRevisionSpec):
 
@@ -497,3 +543,7 @@
         # submit branch overrides parent branch
         self.tree.branch.set_submit_branch('tree2')
         self.assertInHistoryIs(None, 'alt_r2', 'submit:')
+
+    def test_as_revision_id(self):
+        self.tree.branch.set_submit_branch('tree2')
+        self.assertAsRevisionId('alt_r2', 'branch:tree2')

=== modified file 'NEWS'
--- a/NEWS	2008-04-02 07:32:09 +0000
+++ b/NEWS	2008-04-03 02:22:55 +0000
@@ -54,6 +54,9 @@
       transport will now automatically use a smart server if one is present.
       (Andrew Bennetts)
 
+     * Various operations with revision specs and commands that calculate
+       revnos and revision ids are faster.  (John A. Meinel, Aaron Bentley)
+
   BUGFIXES:
 
     * Add ``root_client_path`` parameter to SmartWSGIApp and

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2008-03-28 03:54:40 +0000
+++ b/bzrlib/branch.py	2008-04-03 00:23:41 +0000
@@ -1377,8 +1377,8 @@
         """See Branch.set_revision_history."""
         if 'evil' in debug.debug_flags:
             mutter_callsite(3, "set_revision_history scales with history.")
-        self._clear_cached_state()
         self._write_revision_history(rev_history)
+        self._clear_cached_state()
         self._cache_revision_history(rev_history)
         for hook in Branch.hooks['set_rh']:
             hook(self, rev_history)
@@ -1811,8 +1811,27 @@
 
 class BzrBranch6(BzrBranch5):
 
+    def __init__(self, *args, **kwargs):
+        super(BzrBranch6, self).__init__(*args, **kwargs)
+        self._last_revision_info_cache = None
+        self._partial_revision_history_cache = []
+
+    def _clear_cached_state(self):
+        super(BzrBranch6, self)._clear_cached_state()
+        self._last_revision_info_cache = None
+        self._partial_revision_history_cache = []
+
     @needs_read_lock
     def last_revision_info(self):
+        """Return information about the last revision.
+
+        :return: A tuple (revno, revision_id).
+        """
+        if self._last_revision_info_cache is None:
+            self._last_revision_info_cache = self._last_revision_info()
+        return self._last_revision_info_cache
+
+    def _last_revision_info(self):
         revision_string = self.control_files.get('last-revision').read()
         revno, revision_id = revision_string.rstrip('\n').split(' ', 1)
         revision_id = cache_utf8.get_cached_utf8(revision_id)
@@ -1839,6 +1858,7 @@
             self._check_history_violation(revision_id)
         self._write_last_revision_info(revno, revision_id)
         self._clear_cached_state()
+        self._last_revision_info_cache = revno, revision_id
 
     def _check_history_violation(self, revision_id):
         last_revision = _mod_revision.ensure_null(self.last_revision())
@@ -1850,10 +1870,38 @@
     def _gen_revision_history(self):
         """Generate the revision history from last revision
         """
-        history = list(self.repository.iter_reverse_revision_history(
-            self.last_revision()))
-        history.reverse()
-        return history
+        self._extend_partial_history()
+        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()
+            assert next_revision == start_revision
+        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.
@@ -1971,6 +2019,42 @@
         revno = len(history)
         self.set_last_revision_info(revno, 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
+
+        last_revno, last_revision_id = self.last_revision_info()
+        if revno <= 0 or revno > last_revno:
+            raise errors.NoSuchRevision(self, revno)
+
+        if history is not None:
+            assert len(history) == last_revno, 'revno/history mismatch'
+            return history[revno - 1]
+
+        index = last_revno - revno
+        if len(self._partial_revision_history_cache) <= index:
+            self._extend_partial_history(stop_index=index)
+        if len(self._partial_revision_history_cache) > index:
+            return self._partial_revision_history_cache[index]
+        else:
+            raise errors.NoSuchRevision(self, revno)
+
+    @needs_read_lock
+    def revision_id_to_revno(self, revision_id):
+        """Given a revision id, return its revno"""
+        if _mod_revision.is_null(revision_id):
+            return 0
+        try:
+            index = self._partial_revision_history_cache.index(revision_id)
+        except ValueError:
+            self._extend_partial_history(stop_revision=revision_id)
+            index = len(self._partial_revision_history_cache) - 1
+            if self._partial_revision_history_cache[index] != revision_id:
+                raise errors.NoSuchRevision(self, revision_id)
+        return self.revno() - index
+
 
 ######################################################################
 # results of operations

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2008-03-28 07:24:55 +0000
+++ b/bzrlib/builtins.py	2008-04-03 00:19:05 +0000
@@ -221,7 +221,7 @@
                 if rev is None:
                     raise errors.BzrCommandError('You cannot specify a NULL'
                                                  ' revision.')
-                revno, rev_id = rev.in_history(b)
+                rev_id = rev.as_revision_id(b)
                 self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
     
 
@@ -295,13 +295,13 @@
             revs.append(RevisionSpec.from_string('-1'))
 
         for rev in revs:
-            revinfo = rev.in_history(b)
-            if revinfo.revno is None:
+            revision_id = rev.as_revision_id(b)
+            try:
+                revno = '%4d' % (b.revision_id_to_revno(revision_id))
+            except errors.NoSuchRevision:
                 dotted_map = b.get_revision_id_to_revno_map()
-                revno = '.'.join(str(i) for i in dotted_map[revinfo.rev_id])
-                print '%s %s' % (revno, revinfo.rev_id)
-            else:
-                print '%4d %s' % (revinfo.revno, revinfo.rev_id)
+                revno = '.'.join(str(i) for i in dotted_map[revision_id])
+            print '%s %s' % (revno, revision_id)
 
     
 class cmd_add(Command):
@@ -466,7 +466,7 @@
                     raise errors.BzrCommandError(
                         'bzr inventory --revision takes exactly one revision'
                         ' identifier')
-                revision_id = revision[0].in_history(work_tree.branch).rev_id
+                revision_id = revision[0].as_revision_id(work_tree.branch)
                 tree = work_tree.branch.repository.revision_tree(revision_id)
 
                 extra_trees = [work_tree]
@@ -661,7 +661,7 @@
 
         if revision is not None:
             if len(revision) == 1:
-                revision_id = revision[0].in_history(branch_from).rev_id
+                revision_id = revision[0].as_revision_id(branch_from)
             else:
                 raise errors.BzrCommandError(
                     'bzr pull --revision takes one value.')
@@ -922,7 +922,7 @@
         br_from.lock_read()
         try:
             if len(revision) == 1 and revision[0] is not None:
-                revision_id = revision[0].in_history(br_from)[1]
+                revision_id = revision[0].as_revision_id(br_from)
             else:
                 # FIXME - wt.last_revision, fallback to branch, fall back to
                 # None or perhaps NULL_REVISION to mean copy nothing
@@ -1016,8 +1016,7 @@
         if files_from is not None:
             accelerator_tree = WorkingTree.open(files_from)
         if len(revision) == 1 and revision[0] is not None:
-            revision_id = _mod_revision.ensure_null(
-                revision[0].in_history(source)[1])
+            revision_id = revision[0].as_revision_id(source)
         else:
             revision_id = None
         if to_location is None:
@@ -1877,7 +1876,7 @@
             relpath += '/'
         if revision is not None:
             tree = branch.repository.revision_tree(
-                revision[0].in_history(branch).rev_id)
+                revision[0].as_revision_id(branch))
         elif tree is None:
             tree = branch.basis_tree()
 
@@ -2142,7 +2141,7 @@
         else:
             if len(revision) != 1:
                 raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
-            rev_id = revision[0].in_history(b).rev_id
+            rev_id = revision[0].as_revision_id(b)
         t = b.repository.revision_tree(rev_id)
         try:
             export(t, dest, format, root)
@@ -2187,7 +2186,7 @@
         if revision is None:
             revision_id = b.last_revision()
         else:
-            revision_id = revision[0].in_history(b).rev_id
+            revision_id = revision[0].as_revision_id(b)
 
         cur_file_id = tree.path2id(relpath)
         rev_tree = b.repository.revision_tree(revision_id)
@@ -2992,14 +2991,10 @@
             other_revision_id = _mod_revision.ensure_null(
                 other_branch.last_revision())
         else:
-            other_revision_id = \
-                _mod_revision.ensure_null(
-                    revision[-1].in_history(other_branch).rev_id)
+            other_revision_id = revision[-1].as_revision_id(other_branch)
         if (revision is not None and len(revision) == 2
             and revision[0] is not None):
-            base_revision_id = \
-                _mod_revision.ensure_null(
-                    revision[0].in_history(base_branch).rev_id)
+            base_revision_id = revision[0].as_revision_id(base_branch)
         else:
             base_revision_id = None
         # Remember where we merge from
@@ -3218,7 +3213,7 @@
         elif len(revision) != 1:
             raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
         else:
-            rev_id = revision[0].in_history(tree.branch).rev_id
+            rev_id = revision[0].as_revision_id(tree.branch)
         pb = ui.ui_factory.nested_progress_bar()
         try:
             tree.revert(file_list,
@@ -3469,7 +3464,7 @@
             if revision is None:
                 rev_id = b.last_revision()
             else:
-                rev_id = revision[0].in_history(b).rev_id
+                rev_id = revision[0].as_revision_id(b)
             t = testament_class.from_revision(b.repository, rev_id)
             if long:
                 sys.stdout.writelines(t.as_text_lines())
@@ -3516,7 +3511,7 @@
             elif len(revision) != 1:
                 raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
             else:
-                revision_id = revision[0].in_history(branch).rev_id
+                revision_id = revision[0].as_revision_id(branch)
             tree = branch.repository.revision_tree(revision_id)
             if wt is not None:
                 file_id = wt.path2id(relpath)
@@ -4017,10 +4012,9 @@
             if len(revision) > 2:
                 raise errors.BzrCommandError('bzr merge-directive takes '
                     'at most two one revision identifiers')
-            revision_id = revision[-1].in_history(branch).rev_id
+            revision_id = revision[-1].as_revision_id(branch)
             if len(revision) == 2:
-                base_revision_id = revision[0].in_history(branch).rev_id
-                base_revision_id = ensure_null(base_revision_id)
+                base_revision_id = revision[0].as_revision_id(branch)
         else:
             revision_id = branch.last_revision()
         revision_id = ensure_null(revision_id)
@@ -4186,9 +4180,9 @@
                 if len(revision) > 2:
                     raise errors.BzrCommandError('bzr send takes '
                         'at most two one revision identifiers')
-                revision_id = revision[-1].in_history(branch).rev_id
+                revision_id = revision[-1].as_revision_id(branch)
                 if len(revision) == 2:
-                    base_revision_id = revision[0].in_history(branch).rev_id
+                    base_revision_id = revision[0].as_revision_id(branch)
             if revision_id is None:
                 revision_id = branch.last_revision()
             if revision_id == NULL_REVISION:
@@ -4354,7 +4348,7 @@
                         raise errors.BzrCommandError(
                             "Tags can only be placed on a single revision, "
                             "not on a range")
-                    revision_id = revision[0].in_history(branch).rev_id
+                    revision_id = revision[0].as_revision_id(branch)
                 else:
                     revision_id = branch.last_revision()
                 if (not force) and branch.tags.has_tag(tag_name):

=== modified file 'bzrlib/revisionspec.py'
--- a/bzrlib/revisionspec.py	2008-03-10 15:39:56 +0000
+++ b/bzrlib/revisionspec.py	2008-03-29 21:16:20 +0000
@@ -100,6 +100,8 @@
 
         Use this if you don't know or care what the revno is.
         """
+        if revision_id == revision.NULL_REVISION:
+            return RevisionInfo(branch, 0, revision_id)
         try:
             revno = revs.index(revision_id) + 1
         except ValueError:
@@ -201,14 +203,14 @@
 
     def _match_on(self, branch, revs):
         trace.mutter('Returning RevisionSpec._match_on: None')
-        return RevisionInfo(branch, 0, None)
+        return RevisionInfo(branch, None, None)
 
     def _match_on_and_check(self, branch, revs):
         info = self._match_on(branch, revs)
         if info:
             return info
-        elif info == (0, None):
-            # special case - the empty tree
+        elif info == (None, None):
+            # special case - nothing supplied
             return info
         elif self.prefix:
             raise errors.InvalidRevisionSpec(self.user_spec, branch)
@@ -233,7 +235,23 @@
     # will do what you expect.
     in_store = in_history
     in_branch = in_store
-        
+
+    def as_revision_id(self, context_branch):
+        """Return just the revision_id for this revisions spec.
+
+        Some revision specs require a context_branch to be able to determine
+        their value. Not all specs will make use of it.
+        """
+        return self._as_revision_id(context_branch)
+
+    def _as_revision_id(self, context_branch):
+        """Implementation of as_revision_id()
+
+        Classes should override this function to provide appropriate
+        functionality. The default is to just call '.in_history().rev_id'
+        """
+        return self.in_history(context_branch).rev_id
+
     def __repr__(self):
         # this is mostly for helping with testing
         return '<%s %s>' % (self.__class__.__name__,
@@ -281,6 +299,10 @@
 
     def _match_on(self, branch, revs):
         """Lookup a revision by revision number"""
+        branch, revno, revision_id = self._lookup(branch, revs)
+        return RevisionInfo(branch, revno, revision_id)
+
+    def _lookup(self, branch, revs_or_none):
         loc = self.spec.find(':')
         if loc == -1:
             revno_spec = self.spec
@@ -315,9 +337,7 @@
             # the branch object.
             from bzrlib.branch import Branch
             branch = Branch.open(branch_spec)
-            # Need to use a new revision history
-            # because we are using a specific branch
-            revs = branch.revision_history()
+            revs_or_none = None
 
         if dotted:
             branch.lock_read()
@@ -329,25 +349,31 @@
             finally:
                 branch.unlock()
             if len(revisions) != 1:
-                return RevisionInfo(branch, None, None)
+                return branch, None, None
             else:
                 # there is no traditional 'revno' for dotted-decimal revnos.
                 # so for  API compatability we return None.
-                return RevisionInfo(branch, None, revisions[0])
+                return branch, None, revisions[0]
         else:
+            last_revno, last_revision_id = branch.last_revision_info()
             if revno < 0:
                 # if get_rev_id supported negative revnos, there would not be a
                 # need for this special case.
-                if (-revno) >= len(revs):
+                if (-revno) >= last_revno:
                     revno = 1
                 else:
-                    revno = len(revs) + revno + 1
+                    revno = last_revno + revno + 1
             try:
-                revision_id = branch.get_rev_id(revno, revs)
+                revision_id = branch.get_rev_id(revno, revs_or_none)
             except errors.NoSuchRevision:
                 raise errors.InvalidRevisionSpec(self.user_spec, branch)
-        return RevisionInfo(branch, revno, revision_id)
-        
+        return branch, revno, revision_id
+
+    def _as_revision_id(self, context_branch):
+        # We would have the revno here, but we don't really care
+        branch, revno, revision_id = self._lookup(context_branch, None)
+        return revision_id
+
     def needs_branch(self):
         return self.spec.find(':') == -1
 
@@ -374,7 +400,8 @@
     Examples::
 
       revid:aaaa at bbbb-123456789 -> Select revision 'aaaa at bbbb-123456789'
-    """    
+    """
+
     prefix = 'revid:'
 
     def _match_on(self, branch, revs):
@@ -384,6 +411,9 @@
         revision_id = osutils.safe_revision_id(self.spec, warn=False)
         return RevisionInfo.from_revision_id(branch, revision_id, revs)
 
+    def _as_revision_id(self, context_branch):
+        return osutils.safe_revision_id(self.spec, warn=False)
+
 SPEC_TYPES.append(RevisionSpec_revid)
 
 
@@ -398,30 +428,43 @@
 
       last:1        -> return the last revision
       last:3        -> return the revision 2 before the end.
-    """    
+    """
 
     prefix = 'last:'
 
     def _match_on(self, branch, revs):
+        revno, revision_id = self._revno_and_revision_id(branch, revs)
+        return RevisionInfo(branch, revno, revision_id)
+
+    def _revno_and_revision_id(self, context_branch, revs_or_none):
+        last_revno, last_revision_id = context_branch.last_revision_info()
+
         if self.spec == '':
-            if not revs:
-                raise errors.NoCommits(branch)
-            return RevisionInfo(branch, len(revs), revs[-1])
+            if not last_revno:
+                raise errors.NoCommits(context_branch)
+            return last_revno, last_revision_id
 
         try:
             offset = int(self.spec)
         except ValueError, e:
-            raise errors.InvalidRevisionSpec(self.user_spec, branch, e)
+            raise errors.InvalidRevisionSpec(self.user_spec, context_branch, e)
 
         if offset <= 0:
-            raise errors.InvalidRevisionSpec(self.user_spec, branch,
+            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
                                              'you must supply a positive value')
-        revno = len(revs) - offset + 1
+
+        revno = last_revno - offset + 1
         try:
-            revision_id = branch.get_rev_id(revno, revs)
+            revision_id = context_branch.get_rev_id(revno, revs_or_none)
         except errors.NoSuchRevision:
-            raise errors.InvalidRevisionSpec(self.user_spec, branch)
-        return RevisionInfo(branch, revno, revision_id)
+            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
+        return revno, revision_id
+
+    def _as_revision_id(self, context_branch):
+        # We compute the revno as part of the process, but we don't really care
+        # about it.
+        revno, revision_id = self._revno_and_revision_id(context_branch, None)
+        return revision_id
 
 SPEC_TYPES.append(RevisionSpec_last)
 
@@ -474,6 +517,28 @@
                                                  branch)
         return RevisionInfo(branch, revno, revision_id)
 
+    def _as_revision_id(self, context_branch):
+        base_revspec = RevisionSpec.from_string(self.spec)
+        base_revision_id = base_revspec.as_revision_id(context_branch)
+        if base_revision_id == revision.NULL_REVISION:
+            raise errors.InvalidRevisionSpec(self.user_spec, branch,
+                                         'cannot go before the null: revision')
+        context_repo = context_branch.repository
+        context_repo.lock_read()
+        try:
+            parent_map = context_repo.get_parent_map([base_revision_id])
+        finally:
+            context_repo.unlock()
+        if base_revision_id not in parent_map:
+            # Ghost, or unknown revision id
+            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
+                'cannot find the matching revision')
+        parents = parent_map[base_revision_id]
+        if len(parents) < 1:
+            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
+                'No parents for revision.')
+        return parents[0]
+
 SPEC_TYPES.append(RevisionSpec_before)
 
 
@@ -493,6 +558,9 @@
             branch.tags.lookup_tag(self.spec),
             revs)
 
+    def _as_revision_id(self, context_branch):
+        return context_branch.tags.lookup_tag(self.spec)
+
 SPEC_TYPES.append(RevisionSpec_tag)
 
 
@@ -596,7 +664,7 @@
         finally:
             branch.unlock()
         if rev == len(revs):
-            return RevisionInfo(branch, None)
+            raise errors.InvalidRevisionSpec(self.user_spec, branch)
         else:
             return RevisionInfo(branch, rev + 1)
 
@@ -629,36 +697,43 @@
         trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
         return self._find_revision_info(branch, self.spec)
 
+    def _as_revision_id(self, context_branch):
+        return self._find_revision_id(context_branch, self.spec)
+
     @staticmethod
     def _find_revision_info(branch, other_location):
+        revision_id = RevisionSpec_ancestor._find_revision_id(branch,
+                                                              other_location)
+        try:
+            revno = branch.revision_id_to_revno(revision_id)
+        except errors.NoSuchRevision:
+            revno = None
+        return RevisionInfo(branch, revno, revision_id)
+
+    @staticmethod
+    def _find_revision_id(branch, other_location):
         from bzrlib.branch import Branch
 
-        other_branch = Branch.open(other_location)
-        revision_a = branch.last_revision()
-        revision_b = other_branch.last_revision()
-        for r, b in ((revision_a, branch), (revision_b, other_branch)):
-            if r in (None, revision.NULL_REVISION):
-                raise errors.NoCommits(b)
         branch.lock_read()
-        other_branch.lock_read()
         try:
-            graph = branch.repository.get_graph(other_branch.repository)
-            revision_a = revision.ensure_null(revision_a)
-            revision_b = revision.ensure_null(revision_b)
-            if revision.NULL_REVISION in (revision_a, revision_b):
-                rev_id = revision.NULL_REVISION
-            else:
+            revision_a = revision.ensure_null(branch.last_revision())
+            if revision_a == revision.NULL_REVISION:
+                raise errors.NoCommits(branch)
+            other_branch = Branch.open(other_location)
+            other_branch.lock_read()
+            try:
+                revision_b = revision.ensure_null(other_branch.last_revision())
+                if revision_b == revision.NULL_REVISION:
+                    raise errors.NoCommits(other_branch)
+                graph = branch.repository.get_graph(other_branch.repository)
                 rev_id = graph.find_unique_lca(revision_a, revision_b)
-                if rev_id == revision.NULL_REVISION:
-                    raise errors.NoCommonAncestor(revision_a, revision_b)
-            try:
-                revno = branch.revision_id_to_revno(rev_id)
-            except errors.NoSuchRevision:
-                revno = None
-            return RevisionInfo(branch, revno, rev_id)
+            finally:
+                other_branch.unlock()
+            if rev_id == revision.NULL_REVISION:
+                raise errors.NoCommonAncestor(revision_a, revision_b)
+            return rev_id
         finally:
             branch.unlock()
-            other_branch.unlock()
 
 
 SPEC_TYPES.append(RevisionSpec_ancestor)
@@ -690,7 +765,16 @@
         except errors.NoSuchRevision:
             revno = None
         return RevisionInfo(branch, revno, revision_b)
-        
+
+    def _as_revision_id(self, context_branch):
+        from bzrlib.branch import Branch
+        other_branch = Branch.open(self.spec)
+        last_revision = other_branch.last_revision()
+        last_revision = revision.ensure_null(last_revision)
+        if last_revision == revision.NULL_REVISION:
+            raise errors.NoCommits(other_branch)
+        return last_revision
+
 SPEC_TYPES.append(RevisionSpec_branch)
 
 
@@ -715,8 +799,7 @@
 
     prefix = 'submit:'
 
-    def _match_on(self, branch, revs):
-        trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
+    def _get_submit_location(self, branch):
         submit_location = branch.get_submit_branch()
         location_type = 'submit branch'
         if submit_location is None:
@@ -725,7 +808,16 @@
         if submit_location is None:
             raise errors.NoSubmitBranch(branch)
         trace.note('Using %s %s', location_type, submit_location)
-        return self._find_revision_info(branch, submit_location)
+        return submit_location
+
+    def _match_on(self, branch, revs):
+        trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
+        return self._find_revision_info(branch,
+            self._get_submit_location(branch))
+
+    def _as_revision_id(self, context_branch):
+        return self._find_revision_id(context_branch,
+            self._get_submit_location(context_branch))
 
 
 SPEC_TYPES.append(RevisionSpec_submit)

=== modified file 'bzrlib/status.py'
--- a/bzrlib/status.py	2008-03-20 17:14:01 +0000
+++ b/bzrlib/status.py	2008-04-03 02:22:55 +0000
@@ -84,13 +84,13 @@
             old = new.basis_tree()
         elif len(revision) > 0:
             try:
-                rev_id = revision[0].in_history(wt.branch).rev_id
+                rev_id = revision[0].as_revision_id(wt.branch)
                 old = wt.branch.repository.revision_tree(rev_id)
             except errors.NoSuchRevision, e:
                 raise errors.BzrCommandError(str(e))
             if (len(revision) > 1) and (revision[1].spec is not None):
                 try:
-                    rev_id = revision[1].in_history(wt.branch).rev_id
+                    rev_id = revision[1].as_revision_id(wt.branch)
                     new = wt.branch.repository.revision_tree(rev_id)
                     new_is_working_tree = False
                 except errors.NoSuchRevision, e:

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2008-03-31 17:20:08 +0000
+++ b/bzrlib/tests/__init__.py	2008-04-03 00:18:39 +0000
@@ -2759,7 +2759,7 @@
                    'bzrlib.tests.test_repository',
                    'bzrlib.tests.test_revert',
                    'bzrlib.tests.test_revision',
-                   'bzrlib.tests.test_revisionnamespaces',
+                   'bzrlib.tests.test_revisionspec',
                    'bzrlib.tests.test_revisiontree',
                    'bzrlib.tests.test_rio',
                    'bzrlib.tests.test_sampler',




More information about the bazaar-commits mailing list