Rev 4331: (Jelmer) Add InterBranch.push. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue May 5 15:19:53 BST 2009


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

------------------------------------------------------------
revno: 4331
revision-id: pqm at pqm.ubuntu.com-20090505141949-is3fyloox546i797
parent: pqm at pqm.ubuntu.com-20090505133047-y224knqp4sy23gso
parent: jelmer at samba.org-20090505125537-xza7ywtqxrihvb7a
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2009-05-05 15:19:49 +0100
message:
  (Jelmer) Add InterBranch.push.
added:
  bzrlib/tests/per_interbranch/test_push.py test_push.py-20090330192649-pca31sb2ubbtcs15-1
modified:
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
  bzrlib/tests/per_interbranch/test_update_revisions.py test_update_revision-20090225011043-7u1jnapdeuj07rre-1
    ------------------------------------------------------------
    revno: 4211.1.7
    revision-id: jelmer at samba.org-20090505125537-xza7ywtqxrihvb7a
    parent: jelmer at samba.org-20090505125451-f09g3ly9eb3qtylw
    parent: jelmer at samba.org-20090502120537-iu0aulscqmwizkz4
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Tue 2009-05-05 14:55:37 +0200
    message:
      Merge bzr.dev.
    removed:
      bzrlib/tests/blackbox/test_guess_renames.py test_guess_renames.p-20090312063936-bqdtxr0r3md3jc00-1
      bzrlib/util/configobj/docs/    docs-20051018184548-5eb1575f28e645ab
      bzrlib/util/configobj/docs/BSD-LICENSE.txt BSDLICENSE.txt-20051018184548-29b89ff3102657f5
      bzrlib/util/configobj/docs/configobj.txt configobj.txt-20051018184548-4949b5f17e6a19c7
      bzrlib/util/configobj/docs/validate.txt validate.txt-20051018184548-9e0e5ad913e258f5
    added:
      bzrlib/_chk_map_py.py          _chk_map_py.py-20090309114220-1kurz7oez2gwqtcf-1
      bzrlib/_chk_map_pyx.pyx        _chk_map_pyx.pyx-20090309111231-peyz7p2azr0dzdrb-1
      bzrlib/_groupcompress_py.py    _groupcompress_py.py-20090324110021-j63s399f4icrgw4p-1
      bzrlib/_groupcompress_pyx.pyx  _groupcompress_c.pyx-20080724041824-yelg6ii7c7zxt4z0-1
      bzrlib/chk_map.py              chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
      bzrlib/chk_serializer.py       chk_serializer.py-20081002064345-2tofdfj2eqq01h4b-1
      bzrlib/delta.h                 delta.h-20090227173129-qsu3u43vowf1q3ay-1
      bzrlib/diff-delta.c            diffdelta.c-20090226042143-l9wzxynyuxnb5hus-1
      bzrlib/filters/eol.py          eol.py-20090327060429-todzdjmqt3bpv5r8-1
      bzrlib/groupcompress.py        groupcompress.py-20080705181503-ccbxd6xuy1bdnrpu-8
      bzrlib/help_topics/en/eol.txt  eol.txt-20090327060429-todzdjmqt3bpv5r8-3
      bzrlib/inventory_delta.py      journalled_inventory-20080103020931-0ht5n40kwc0p7fy1-1
      bzrlib/repofmt/groupcompress_repo.py repofmt.py-20080715094215-wp1qfvoo7093c8qr-1
      bzrlib/serializer.py           serializer.py-20090402143702-wmkh9cfjhwpju0qi-1
      bzrlib/tests/blackbox/test_dpush.py test_dpush.py-20090108125928-st1td6le59g0vyv2-1
      bzrlib/tests/blackbox/test_reference.py test_reference.py-20090428205614-7lo1hc2etrwd73x3-1
      bzrlib/tests/bzrdir_implementations/test_push.py test_push.py-20090403142358-xnn0wtsk3gx238ot-1
      bzrlib/tests/per_repository_chk/ per_repository_chk-20080925061730-e4g24t5xstp2n2vp-1
      bzrlib/tests/per_repository_chk/__init__.py __init__.py-20080925061730-e4g24t5xstp2n2vp-2
      bzrlib/tests/per_repository_chk/test_supported.py test_supported.py-20080925063728-k65ry0n2rhta6t34-1
      bzrlib/tests/per_repository_chk/test_unsupported.py test_unsupported.py-20080925063728-k65ry0n2rhta6t34-2
      bzrlib/tests/test__chk_map.py  test__chk_map.py-20090309114220-1kurz7oez2gwqtcf-2
      bzrlib/tests/test__groupcompress.py test__groupcompress_-20080724145854-koifwb7749cfzrvj-1
      bzrlib/tests/test_chk_map.py   test_chk_map.py-20081001014447-ue6kkuhofvdecvxa-2
      bzrlib/tests/test_eol_filters.py test_eol_filters.py-20090327060429-todzdjmqt3bpv5r8-2
      bzrlib/tests/test_groupcompress.py test_groupcompress.p-20080705181503-ccbxd6xuy1bdnrpu-13
      bzrlib/tests/test_inventory_delta.py test_journalled_inv.-20080103012121-ny2w9slze5jgty8i-1
      bzrlib/tests/test_serializer.py test_serializer.py-20090403213933-q6x117y8t9fbeyoz-1
      bzrlib/tests/workingtree_implementations/test_eol_conversion.py test_eol_conversion.-20090327060429-todzdjmqt3bpv5r8-4
      doc/developers/groupcompress-design.txt design-20080705181503-ccbxd6xuy1bdnrpu-2
    modified:
      .bzrignore                     bzrignore-20050311232317-81f7b71efa2db11a
      Makefile                       Makefile-20050805140406-d96e3498bb61c5bb
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_btree_serializer_c.pyx _parse_btree_c.pyx-20080703034413-3q25bklkenti3p8p-2
      bzrlib/add.py                  add.py-20050323030017-3a77d63feda58e33
      bzrlib/annotate.py             annotate.py-20050922133147-7c60541d2614f022
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/branchbuilder.py        branchbuilder.py-20070427022007-zlxpqz2lannhk6y8-1
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/serializer/v4.py v10.py-20070611062757-5ggj7k18s9dej0fr-1
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/filters/__init__.py     __init__.py-20080416080515-mkxl29amuwrf6uir-2
      bzrlib/foreign.py              foreign.py-20081112170002-olsxmandkk8qyfuq-1
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/hashcache.py            hashcache.py-20050706091756-fe3a8cc1143ff24f
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/help_topics/en/rules.txt rules.txt-20080516063844-ghr5l6pvvrhiycun-1
      bzrlib/hooks.py                hooks.py-20070325015548-ix4np2q0kd8452au-1
      bzrlib/info.py                 info.py-20050323235939-6bbfe7d9700b0b9b
      bzrlib/inventory.py            inventory.py-20050309040759-6648b84ca2005b37
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/lru_cache.py            lru_cache.py-20070119165515-tlw203kuwh0id5gv-1
      bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
      bzrlib/memorytree.py           memorytree.py-20060906023413-4wlkalbdpsxi2r4y-1
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/merge_directive.py      merge_directive.py-20070228184838-ja62280spt1g7f4x-1
      bzrlib/multiparent.py          __init__.py-20070410133617-n1jdhcc1n1mibarp-1
      bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
      bzrlib/option.py               option.py-20051014052914-661fb36e76e7362f
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/pack.py                 container.py-20070607160755-tr8zc26q18rn0jnb-1
      bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
      bzrlib/plugins/launchpad/account.py account.py-20071011033320-50y6vfftywf4yllw-1
      bzrlib/plugins/netrc_credential_store/__init__.py __init__.py-20081006090402-hd75m8kcrrm0vlz1-1
      bzrlib/push.py                 push.py-20080606021927-5fe39050e8xne9un-1
      bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
      bzrlib/reconfigure.py          reconfigure.py-20070908040425-6ykgo7escxhyrg9p-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/rename_map.py           rename_map.py-20090312140439-xexkkmjlg2enbohc-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/revisiontree.py         revisiontree.py-20060724012533-bg8xyryhxd0o0i0h-1
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
      bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/smart/server.py         server.py-20061110062051-chzu10y32vx8gvur-1
      bzrlib/smtp_connection.py      smtp_connection.py-20070618204456-nu6wag1ste4biuk2-1
      bzrlib/symbol_versioning.py    symbol_versioning.py-20060105104851-9ecf8af605d15a80
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tests/blackbox/test_add.py test_add.py-20060518072250-857e4f86f54a30b2
      bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
      bzrlib/tests/blackbox/test_export.py test_export.py-20051229024010-e6c26658e460fb1c
      bzrlib/tests/blackbox/test_filesystem_cicp.py test_filesystem_cicp-20081028010456-vclkg401m81keaxc-1
      bzrlib/tests/blackbox/test_filtered_view_ops.py test_filtered_view_o-20081110012645-5t7ogtola0l33lkg-1
      bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_ls.py test_ls.py-20060712232047-0jraqpecwngee12y-1
      bzrlib/tests/blackbox/test_mv.py test_mv.py-20060705114902-33tkxz0o9cdshemo-1
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
      bzrlib/tests/blackbox/test_uncommit.py test_uncommit.py-20051027212835-84944b63adae51be
      bzrlib/tests/blackbox/test_view.py test_view.py-20080731135100-66o8o32heop7augi-1
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/branch_implementations/test_break_lock.py test_break_lock.py-20060504111902-9aae411dbe9aadd2
      bzrlib/tests/branch_implementations/test_create_clone.py test_create_clone.py-20090225031440-8ybpkzojo7cvourv-1
      bzrlib/tests/branch_implementations/test_locking.py test_locking.py-20060707151933-tav3o2hpibwi53u4-4
      bzrlib/tests/branch_implementations/test_parent.py test_parent.py-20050830052751-5e62766623c32222
      bzrlib/tests/bzrdir_implementations/__init__.py __init__.py-20060131065642-34c39b54f42dd048
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
      bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
      bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
      bzrlib/tests/intertree_implementations/__init__.py __init__.py-20060724101752-09ysswo1a92uqyoz-3
      bzrlib/tests/intertree_implementations/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
      bzrlib/tests/inventory_implementations/basics.py basics.py-20070903044446-kdjwbiu1p1zi9phs-1
      bzrlib/tests/lock_helpers.py   LockHelpers.py-20060707151933-tav3o2hpibwi53u4-1
      bzrlib/tests/per_repository/test_add_inventory_by_delta.py test_add_inventory_d-20081013002626-rut81igtlqb4590z-1
      bzrlib/tests/per_repository/test_check.py test_check.py-20070824124512-38g4d135gcqxo4zb-1
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/per_repository/test_write_group.py test_write_group.py-20070716105516-89n34xtogq5frn0m-1
      bzrlib/tests/per_repository_reference/test_add_inventory.py test_add_inventory.p-20080220025549-nnm2s80it1lvcwnc-3
      bzrlib/tests/per_repository_reference/test_add_revision.py test_add_revision.py-20080220034108-ao1u8qgakqbo5a08-1
      bzrlib/tests/per_repository_reference/test_add_signature_text.py test_add_signature_t-20080220041905-1j2g4lyz3c6h34v4-1
      bzrlib/tests/test_branch.py    test_branch.py-20060116013032-97819aa07b8ab3b5
      bzrlib/tests/test_bundle.py    test.py-20050630184834-092aa401ab9f039c
      bzrlib/tests/test_commands.py  test_command.py-20051019190109-3b17be0f52eaa7a8
      bzrlib/tests/test_config.py    testconfig.py-20051011041908-742d0c15d8d8c8eb
      bzrlib/tests/test_diff.py      testdiff.py-20050727164403-d1a3496ebb12e339
      bzrlib/tests/test_dirstate.py  test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
      bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
      bzrlib/tests/test_export.py    test_export.py-20090220201010-tpbxssdnezsvu9pk-1
      bzrlib/tests/test_fetch.py     testfetch.py-20050825090644-f73e07e7dfb1765a
      bzrlib/tests/test_filters.py   test_filters.py-20080417120614-tc3zok0vvvprsc99-1
      bzrlib/tests/test_foreign.py   test_foreign.py-20081125004048-ywb901edgp9lluxo-1
      bzrlib/tests/test_ftp_transport.py test_aftp_transport.-20060823221619-98mwjzxtwtkt527k-1
      bzrlib/tests/test_hooks.py     test_hooks.py-20070628030849-89rtsbe5dmer5npz-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_info.py      test_info.py-20070320150933-m0xxm1g7xi9v6noe-1
      bzrlib/tests/test_inv.py       testinv.py-20050722220913-1dc326138d1a5892
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_lockable_files.py test_lockable_files.py-20051225183927-365c7fd99591caf1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_lru_cache.py test_lru_cache.py-20070119165535-hph6rk4h9rzy4180-1
      bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
      bzrlib/tests/test_options.py   testoptions.py-20051014093702-96457cfc86319a8f
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
      bzrlib/tests/test_reconfigure.py test_reconfigure.py-20070908040425-6ykgo7escxhyrg9p-2
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_rename_map.py test_rename_map.py-20090312140439-xexkkmjlg2enbohc-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
      bzrlib/tests/test_shelf.py     test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/test_smart_request.py test_smart_request.p-20090211070731-o38wayv3asm25d6a-1
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/tests/test_source.py    test_source.py-20051207061333-a58dea6abecc030d
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
      bzrlib/tests/test_ui.py        test_ui.py-20051130162854-458e667a7414af09
      bzrlib/tests/test_upgrade.py   test_upgrade.py-20051004040251-555fe1d2bae1bc71
      bzrlib/tests/test_urlutils.py  test_urlutils.py-20060502192900-46b1f9579987cf9c
      bzrlib/tests/test_version_info.py test_version_info.py-20051228204928-2c364e30b702b41b
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/tests/test_workingtree_4.py test_workingtree_4.p-20070223025758-531n3tznl3zacv2o-1
      bzrlib/tests/test_xml.py       test_xml.py-20050905091053-80b45588931a9b35
      bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
      bzrlib/tests/tree_implementations/test_get_symlink_target.py test_get_symlink_tar-20070225165554-ickod3w3t7u0zzqh-1
      bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
      bzrlib/tests/tree_implementations/test_path_content_summary.py test_path_content_su-20070904100855-3vrwedz6akn34kl5-1
      bzrlib/tests/tree_implementations/test_test_trees.py test_tree_trees.py-20060720091921-3nwi5h21lf06vf5p-1
      bzrlib/tests/tree_implementations/test_walkdirs.py test_walkdirs.py-20060729160421-gmjnkotqgxdh98ce-1
      bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
      bzrlib/tests/workingtree_implementations/test_read_working_inventory.py test_read_working_in-20061005073432-585uyj0sua6r7i9v-2
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
      bzrlib/transport/ftp/_gssapi.py _gssapi.py-20080611190840-7ejrtp884bk5eu72-2
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/transport/ssh.py        ssh.py-20060824042150-0s9787kng6zv1nwq-1
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
      bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
      bzrlib/urlutils.py             urlutils.py-20060502195429-e8a161ecf8fac004
      bzrlib/util/configobj/configobj.py configobj.py-20051018184548-06992a2246425e3e
      bzrlib/version_info_formats/format_custom.py format_custom.py-20071029100350-ajovqhbpb5khf6gu-1
      bzrlib/version_info_formats/format_python.py format_python.py-20060809202444-ike7i9ub03gb432p-1
      bzrlib/version_info_formats/format_rio.py format_rio.py-20060809202444-ike7i9ub03gb432p-2
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
      bzrlib/win32utils.py           win32console.py-20051021033308-123c6c929d04973d
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      bzrlib/xml4.py                 xml4.py-20050916091259-db5ab55e7e6ca324
      bzrlib/xml5.py                 xml5.py-20080328030717-t9guwinq8hom0ar3-1
      bzrlib/xml8.py                 xml5.py-20050907032657-aac8f960815b66b1
      bzrlib/xml_serializer.py       xml.py-20050309040759-57d51586fdec365d
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
      doc/developers/container-format.txt containerformat.txt-20070601074309-7n7w1jiyayud6xdn-1
      doc/developers/development-repo.txt developmentrepo.txt-20080102200205-raj42k61dch8pjmj-1
      doc/developers/incremental-push-pull.txt incrementalpushpull.-20070508045640-zneiu1yzbci574c6-1
      doc/developers/index.txt       index.txt-20070508041241-qznziunkg0nffhiw-1
      doc/developers/inventory.txt   inventory.txt-20080103013957-opkrhxy6lmywmx4i-1
      doc/developers/lca-merge.txt   lcamerge.txt-20080103061803-9isydn4ivgwrvorw-1
      doc/developers/merge-scaling.txt mergescaling.rst-20070527173558-rqaqxn1al7vzgcto-2
      doc/developers/network-protocol.txt networkprotocol.txt-20070903044232-woustorrjbmg5zol-1
      doc/developers/planned-performance-changes.txt plannedperformancech-20070604053752-bnjdhako613xfufb-1
      doc/en/user-guide/filtered_views.txt filtered_views.txt-20090226100856-a16ba1v97v91ru58-1
      doc/en/user-guide/installing_bazaar.txt installing_bazaar.tx-20071114035000-q36a9h57ps06uvnl-4
      doc/en/user-guide/releasing_a_project.txt releasing_a_project.-20071121073725-0corxykv5irjal00-5
      doc/en/user-guide/server.txt   server.txt-20060913044801-h939fvbwzz39gf7g-1
      doc/en/user-guide/specifying_revisions.txt specifying_revisions.txt-20060314161707-19deb139101bea33
      doc/en/user-guide/svn_plugin.txt svn_plugin.txt-20080509065016-cjc90f46407vi9a0-2
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
      tools/win32/build_release.py   build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
    ------------------------------------------------------------
    revno: 4211.1.6
    revision-id: jelmer at samba.org-20090505125451-f09g3ly9eb3qtylw
    parent: jelmer at samba.org-20090330194844-xn4mk8gihdd5bt1s
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Tue 2009-05-05 14:54:51 +0200
    message:
      Review from Ian.
    modified:
      bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
      bzrlib/tests/per_interbranch/test_push.py test_push.py-20090330192649-pca31sb2ubbtcs15-1
    ------------------------------------------------------------
    revno: 4211.1.5
    revision-id: jelmer at samba.org-20090330194844-xn4mk8gihdd5bt1s
    parent: jelmer at samba.org-20090330194207-pis56ela8is1fac7
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Mon 2009-03-30 21:48:44 +0200
    message:
      Fix copyright year, number of columns used.
    modified:
      bzrlib/tests/per_interbranch/test_push.py test_push.py-20090330192649-pca31sb2ubbtcs15-1
    ------------------------------------------------------------
    revno: 4211.1.4
    revision-id: jelmer at samba.org-20090330194207-pis56ela8is1fac7
    parent: jelmer at samba.org-20090330184812-38iwrya88aqep614
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Mon 2009-03-30 21:42:07 +0200
    message:
      add InterBranch.push() tests.
    added:
      bzrlib/tests/per_interbranch/test_push.py test_push.py-20090330192649-pca31sb2ubbtcs15-1
    modified:
      bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
    ------------------------------------------------------------
    revno: 4211.1.3
    revision-id: jelmer at samba.org-20090330184812-38iwrya88aqep614
    parent: jelmer at samba.org-20090330184212-bkhtulkho5fzdvhj
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Mon 2009-03-30 20:48:12 +0200
    message:
      Fix trailing whitespace, add prototype for InterBranch.push().
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 4211.1.2
    revision-id: jelmer at samba.org-20090330184212-bkhtulkho5fzdvhj
    parent: jelmer at samba.org-20090328155134-vp9yokawyq2g4oe1
    parent: jelmer at samba.org-20090330164141-10ti3dtu3z0l7l84
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Mon 2009-03-30 20:42:12 +0200
    message:
      Merge interbranch test class improvements.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/filters/__init__.py     __init__.py-20080416080515-mkxl29amuwrf6uir-2
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
      bzrlib/tests/per_interbranch/test_update_revisions.py test_update_revision-20090225011043-7u1jnapdeuj07rre-1
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/test_commit.py    test_commit.py-20050914060732-279f057f8c295434
      bzrlib/tests/test_filters.py   test_filters.py-20080417120614-tc3zok0vvvprsc99-1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_upgrade.py   test_upgrade.py-20051004040251-555fe1d2bae1bc71
      bzrlib/tests/workingtree_implementations/test_commit.py test_commit.py-20060421013633-1610ec2331c8190f
      bzrlib/upgrade.py              history2weaves.py-20050818063535-e7d319791c19a8b2
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      doc/en/user-guide/browsing_history.txt browsing_history.txt-20071121073725-0corxykv5irjal00-2
        ------------------------------------------------------------
        revno: 4216.7.1
        revision-id: jelmer at samba.org-20090330164141-10ti3dtu3z0l7l84
        parent: pqm at pqm.ubuntu.com-20090330055028-lhmncpzf7ebkd2yc
        committer: Jelmer Vernooij <jelmer at samba.org>
        branch nick: interbranch
        timestamp: Mon 2009-03-30 18:41:41 +0200
        message:
          Simplify interbranch test base class.
        modified:
          bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
          bzrlib/tests/per_interbranch/test_update_revisions.py test_update_revision-20090225011043-7u1jnapdeuj07rre-1
    ------------------------------------------------------------
    revno: 4211.1.1
    revision-id: jelmer at samba.org-20090328155134-vp9yokawyq2g4oe1
    parent: pqm at pqm.ubuntu.com-20090328053724-souztdxo868gjo3q
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: interbranch-push
    timestamp: Sat 2009-03-28 16:51:34 +0100
    message:
      Move Branch.push to InterBranch.push.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2009-04-28 03:55:56 +0000
+++ b/bzrlib/branch.py	2009-05-05 12:55:37 +0000
@@ -855,12 +855,14 @@
         """
         raise NotImplementedError(self.pull)
 
-    def push(self, target, overwrite=False, stop_revision=None):
+    def push(self, target, overwrite=False, stop_revision=None, *args,
+        **kwargs):
         """Mirror this branch into target.
 
         This branch is considered to be 'local', having low latency.
         """
-        raise NotImplementedError(self.push)
+        return InterBranch.get(self, target).push(overwrite, stop_revision,
+            *args, **kwargs)
 
     def basis_tree(self):
         """Return `Tree` object for last revision."""
@@ -2228,75 +2230,10 @@
                 pass
         return None
 
-    @needs_read_lock
-    def push(self, target, overwrite=False, stop_revision=None,
-             _override_hook_source_branch=None):
-        """See Branch.push.
-
-        This is the basic concrete implementation of push()
-
-        :param _override_hook_source_branch: If specified, run
-        the hooks passing this Branch as the source, rather than self.
-        This is for use of RemoteBranch, where push is delegated to the
-        underlying vfs-based Branch.
-        """
-        # TODO: Public option to disable running hooks - should be trivial but
-        # needs tests.
-        return _run_with_write_locked_target(
-            target, self._push_with_bound_branches, target, overwrite,
-            stop_revision,
-            _override_hook_source_branch=_override_hook_source_branch)
-
-    def _push_with_bound_branches(self, target, overwrite,
-            stop_revision,
-            _override_hook_source_branch=None):
-        """Push from self into target, and into target's master if any.
-
-        This is on the base BzrBranch class even though it doesn't support
-        bound branches because the *target* might be bound.
-        """
-        def _run_hooks():
-            if _override_hook_source_branch:
-                result.source_branch = _override_hook_source_branch
-            for hook in Branch.hooks['post_push']:
-                hook(result)
-
-        bound_location = target.get_bound_location()
-        if bound_location and target.base != bound_location:
-            # there is a master branch.
-            #
-            # XXX: Why the second check?  Is it even supported for a branch to
-            # be bound to itself? -- mbp 20070507
-            master_branch = target.get_master_branch()
-            master_branch.lock_write()
-            try:
-                # push into the master from this branch.
-                self._basic_push(master_branch, overwrite, stop_revision)
-                # and push into the target branch from this. Note that we push from
-                # this branch again, because its considered the highest bandwidth
-                # repository.
-                result = self._basic_push(target, overwrite, stop_revision)
-                result.master_branch = master_branch
-                result.local_branch = target
-                _run_hooks()
-                return result
-            finally:
-                master_branch.unlock()
-        else:
-            # no master branch
-            result = self._basic_push(target, overwrite, stop_revision)
-            # TODO: Why set master_branch and local_branch if there's no
-            # binding?  Maybe cleaner to just leave them unset? -- mbp
-            # 20070504
-            result.master_branch = target
-            result.local_branch = None
-            _run_hooks()
-            return result
-
     def _basic_push(self, target, overwrite, stop_revision):
         """Basic implementation of push without bound branches or hooks.
 
-        Must be called with self read locked and target write locked.
+        Must be called with source read locked and target write locked.
         """
         result = BranchPushResult()
         result.source_branch = self
@@ -2307,10 +2244,11 @@
             # We assume that during 'push' this repository is closer than
             # the target.
             graph = self.repository.get_graph(target.repository)
-            target.update_revisions(self, stop_revision, overwrite=overwrite,
-                                    graph=graph)
+            target.update_revisions(self, stop_revision,
+                overwrite=overwrite, graph=graph)
         if self._push_should_merge_tags():
-            result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
+            result.tag_conflicts = self.tags.merge_to(target.tags,
+                overwrite)
         result.new_revno, result.new_revid = target.last_revision_info()
         return result
 
@@ -3016,6 +2954,14 @@
         """
         raise NotImplementedError(self.update_revisions)
 
+    def push(self, overwrite=False, stop_revision=None,
+             _override_hook_source_branch=None):
+        """Mirror the source branch into the target branch.
+
+        The source branch is considered to be 'local', having low latency.
+        """
+        raise NotImplementedError(self.push)
+
 
 class GenericInterBranch(InterBranch):
     """InterBranch implementation that uses public Branch functions.
@@ -3068,6 +3014,72 @@
         finally:
             self.source.unlock()
 
+    def push(self, overwrite=False, stop_revision=None,
+             _override_hook_source_branch=None):
+        """See InterBranch.push.
+
+        This is the basic concrete implementation of push()
+
+        :param _override_hook_source_branch: If specified, run
+        the hooks passing this Branch as the source, rather than self.
+        This is for use of RemoteBranch, where push is delegated to the
+        underlying vfs-based Branch.
+        """
+        # TODO: Public option to disable running hooks - should be trivial but
+        # needs tests.
+        self.source.lock_read()
+        try:
+            return _run_with_write_locked_target(
+                self.target, self._push_with_bound_branches, overwrite,
+                stop_revision,
+                _override_hook_source_branch=_override_hook_source_branch)
+        finally:
+            self.source.unlock()
+
+    def _push_with_bound_branches(self, overwrite, stop_revision,
+            _override_hook_source_branch=None):
+        """Push from source into target, and into target's master if any.
+        """
+        def _run_hooks():
+            if _override_hook_source_branch:
+                result.source_branch = _override_hook_source_branch
+            for hook in Branch.hooks['post_push']:
+                hook(result)
+
+        bound_location = self.target.get_bound_location()
+        if bound_location and self.target.base != bound_location:
+            # there is a master branch.
+            #
+            # XXX: Why the second check?  Is it even supported for a branch to
+            # be bound to itself? -- mbp 20070507
+            master_branch = self.target.get_master_branch()
+            master_branch.lock_write()
+            try:
+                # push into the master from the source branch.
+                self.source._basic_push(master_branch, overwrite, stop_revision)
+                # and push into the target branch from the source. Note that we
+                # push from the source branch again, because its considered the
+                # highest bandwidth repository.
+                result = self.source._basic_push(self.target, overwrite,
+                    stop_revision)
+                result.master_branch = master_branch
+                result.local_branch = self.target
+                _run_hooks()
+                return result
+            finally:
+                master_branch.unlock()
+        else:
+            # no master branch
+            result = self.source._basic_push(self.target, overwrite,
+                stop_revision)
+            # TODO: Why set master_branch and local_branch if there's no
+            # binding?  Maybe cleaner to just leave them unset? -- mbp
+            # 20070504
+            result.master_branch = self.target
+            result.local_branch = None
+            _run_hooks()
+            return result
+
     @classmethod
     def is_compatible(self, source, target):
         # GenericBranch uses the public API, so always compatible

=== modified file 'bzrlib/tests/per_interbranch/__init__.py'
--- a/bzrlib/tests/per_interbranch/__init__.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_interbranch/__init__.py	2009-05-05 12:54:51 +0000
@@ -25,16 +25,27 @@
 """
 
 
+from bzrlib import (
+    branchbuilder,
+    memorytree,
+    )
 from bzrlib.branch import (
                            GenericInterBranch,
                            InterBranch,
                            )
+from bzrlib.bzrdir import (
+    BzrDirFormat,
+    BzrDirMetaFormat1,
+    )
 from bzrlib.errors import (
     FileExists,
+    NotBranchError,
     UninitializableFormat,
     )
-from bzrlib.tests import multiply_tests
-from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
+from bzrlib.tests import (
+    TestCaseWithTransport,
+    multiply_tests,
+    )
 from bzrlib.transport import get_transport
 
 
@@ -75,47 +86,69 @@
     return result
 
 
-class TestCaseWithInterBranch(TestCaseWithBzrDir):
-
-    def setUp(self):
-        super(TestCaseWithInterBranch, self).setUp()
-
-    def make_branch(self, relpath, format=None):
-        repo = self.make_repository(relpath, format=format)
-        return repo.bzrdir.create_branch()
-
-    def make_bzrdir(self, relpath, format=None):
-        try:
-            url = self.get_url(relpath)
-            segments = url.split('/')
-            if segments and segments[-1] not in ('', '.'):
-                parent = '/'.join(segments[:-1])
-                t = get_transport(parent)
-                try:
-                    t.mkdir(segments[-1])
-                except FileExists:
-                    pass
-            if format is None:
-                format = self.branch_format_from._matchingbzrdir
-            return format.initialize(url)
-        except UninitializableFormat:
-            raise TestSkipped("Format %s is not initializable." % format)
-
-    def make_repository(self, relpath, format=None):
-        made_control = self.make_bzrdir(relpath, format=format)
-        return made_control.create_repository()
-
-    def make_to_bzrdir(self, relpath):
-        return self.make_bzrdir(relpath,
-            self.branch_format_to._matchingbzrdir)
+class TestCaseWithInterBranch(TestCaseWithTransport):
+
+    def make_from_branch(self, relpath):
+        repo = self.make_repository(relpath)
+        return self.branch_format_from.initialize(repo.bzrdir)
+
+    def make_from_branch_and_memory_tree(self, relpath):
+        """Create a branch on the default transport and a MemoryTree for it."""
+        b = self.make_from_branch(relpath)
+        return memorytree.MemoryTree.create_on_branch(b)
+
+    def make_from_branch_and_tree(self, relpath):
+        """Create a branch on the default transport and a working tree for it."""
+        b = self.make_from_branch(relpath)
+        return b.bzrdir.create_workingtree()
+
+    def make_from_branch_builder(self, relpath):
+        default_format = BzrDirFormat.get_default_format()
+        format = BzrDirMetaFormat1()
+        format.set_branch_format(self.branch_format_from)
+        format.repository_format = default_format.repository_format
+        format.workingtree_format = default_format.workingtree_format
+        return branchbuilder.BranchBuilder(self.get_transport(relpath),
+            format=format)
 
     def make_to_branch(self, relpath):
-        made_control = self.make_to_bzrdir(relpath)
-        return self.branch_format_to.initialize(made_control)
+        repo = self.make_repository(relpath)
+        return self.branch_format_to.initialize(repo.bzrdir)
+
+    def make_to_branch_and_memory_tree(self, relpath):
+        """Create a branch on the default transport and a MemoryTree for it."""
+        b = self.make_to_branch(relpath)
+        return memorytree.MemoryTree.create_on_branch(b)
+
+    def make_to_branch_and_tree(self, relpath):
+        """Create a branch on the default transport and a working tree for it."""
+        b = self.make_to_branch(relpath)
+        return b.bzrdir.create_workingtree()
+
+    def sprout_to(self, origdir, to_url):
+        """Sprout a bzrdir, using to_format for the new branch."""
+        newbranch = self.make_to_branch(to_url)
+        origbranch = origdir.open_branch()
+        newbranch.repository.fetch(origbranch.repository)
+        origbranch.copy_content_into(newbranch)
+        newbranch.bzrdir.create_workingtree()
+        return newbranch.bzrdir
+
+    def sprout_from(self, origdir, to_url):
+        """Sprout a bzrdir, using from_format for the new bzrdir."""
+        newbranch = self.make_from_branch(to_url)
+        origbranch = origdir.open_branch()
+        newbranch.repository.fetch(origbranch.repository)
+        origbranch.copy_content_into(newbranch)
+        newbranch.bzrdir.create_workingtree()
+        return newbranch.bzrdir
+
+
 
 
 def load_tests(standard_tests, module, loader):
     submod_tests = loader.loadTestsFromModuleNames([
+        'bzrlib.tests.per_interbranch.test_push',
         'bzrlib.tests.per_interbranch.test_update_revisions',
         ])
     scenarios = make_scenarios(default_test_list())

=== added file 'bzrlib/tests/per_interbranch/test_push.py'
--- a/bzrlib/tests/per_interbranch/test_push.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_interbranch/test_push.py	2009-05-05 12:54:51 +0000
@@ -0,0 +1,379 @@
+# Copyright (C) 2004, 2005, 2007, 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 branch.push behaviour."""
+
+from cStringIO import StringIO
+import os
+
+from bzrlib import (
+    branch,
+    builtins,
+    bzrdir,
+    debug,
+    errors,
+    push,
+    repository,
+    tests,
+    )
+from bzrlib.branch import Branch
+from bzrlib.bzrdir import BzrDir
+from bzrlib.memorytree import MemoryTree
+from bzrlib.revision import NULL_REVISION
+from bzrlib.smart import client, server
+from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
+from bzrlib.tests.per_interbranch import (
+    TestCaseWithInterBranch,
+    )
+from bzrlib.transport import get_transport
+from bzrlib.transport.local import LocalURLServer
+
+
+# These tests are based on similar tests in 
+# bzrlib.tests.branch_implementations.test_push.
+
+
+class TestPush(TestCaseWithInterBranch):
+
+    def test_push_convergence_simple(self):
+        # when revisions are pushed, the left-most accessible parents must
+        # become the revision-history.
+        mine = self.make_from_branch_and_tree('mine')
+        mine.commit('1st post', rev_id='P1', allow_pointless=True)
+        other = self.sprout_to(mine.bzrdir, 'other').open_workingtree()
+        other.commit('my change', rev_id='M1', allow_pointless=True)
+        mine.merge_from_branch(other.branch)
+        mine.commit('merge my change', rev_id='P2')
+        result = mine.branch.push(other.branch)
+        self.assertEqual(['P1', 'P2'], other.branch.revision_history())
+        # result object contains some structured data
+        self.assertEqual(result.old_revid, 'M1')
+        self.assertEqual(result.new_revid, 'P2')
+        # and it can be treated as an integer for compatibility
+        self.assertEqual(int(result), 0)
+
+    def test_push_merged_indirect(self):
+        # it should be possible to do a push from one branch into another
+        # when the tip of the target was merged into the source branch
+        # via a third branch - so its buried in the ancestry and is not
+        # directly accessible.
+        mine = self.make_from_branch_and_tree('mine')
+        mine.commit('1st post', rev_id='P1', allow_pointless=True)
+        target = self.sprout_to(mine.bzrdir, 'target').open_workingtree()
+        target.commit('my change', rev_id='M1', allow_pointless=True)
+        other = self.sprout_to(mine.bzrdir, 'other').open_workingtree()
+        other.merge_from_branch(target.branch)
+        other.commit('merge my change', rev_id='O2')
+        mine.merge_from_branch(other.branch)
+        mine.commit('merge other', rev_id='P2')
+        mine.branch.push(target.branch)
+        self.assertEqual(['P1', 'P2'], target.branch.revision_history())
+
+    def test_push_to_checkout_updates_master(self):
+        """Pushing into a checkout updates the checkout and the master branch"""
+        master_tree = self.make_to_branch_and_tree('master')
+        checkout = self.make_to_branch_and_tree('checkout')
+        try:
+            checkout.branch.bind(master_tree.branch)
+        except errors.UpgradeRequired:
+            # cant bind this format, the test is irrelevant.
+            return
+        rev1 = checkout.commit('master')
+
+        other_bzrdir = self.sprout_from(master_tree.branch.bzrdir, 'other')
+        other = other_bzrdir.open_workingtree()
+        rev2 = other.commit('other commit')
+        # now push, which should update both checkout and master.
+        other.branch.push(checkout.branch)
+        self.assertEqual([rev1, rev2], checkout.branch.revision_history())
+        self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
+
+    def test_push_raises_specific_error_on_master_connection_error(self):
+        master_tree = self.make_to_branch_and_tree('master')
+        checkout = self.make_to_branch_and_tree('checkout')
+        try:
+            checkout.branch.bind(master_tree.branch)
+        except errors.UpgradeRequired:
+            # cant bind this format, the test is irrelevant.
+            return
+        other_bzrdir = self.sprout_from(master_tree.branch.bzrdir, 'other')
+        other = other_bzrdir.open_workingtree()
+        # move the branch out of the way on disk to cause a connection
+        # error.
+        os.rename('master', 'master_gone')
+        # try to push, which should raise a BoundBranchConnectionFailure.
+        self.assertRaises(errors.BoundBranchConnectionFailure,
+                other.branch.push, checkout.branch)
+
+    def test_push_uses_read_lock(self):
+        """Push should only need a read lock on the source side."""
+        source = self.make_from_branch_and_tree('source')
+        target = self.make_to_branch('target')
+
+        self.build_tree(['source/a'])
+        source.add(['a'])
+        source.commit('a')
+
+        source.branch.lock_read()
+        try:
+            target.lock_write()
+            try:
+                source.branch.push(target, stop_revision=source.last_revision())
+            finally:
+                target.unlock()
+        finally:
+            source.branch.unlock()
+
+    def test_push_within_repository(self):
+        """Push from one branch to another inside the same repository."""
+        try:
+            repo = self.make_repository('repo', shared=True)
+        except (errors.IncompatibleFormat, errors.UninitializableFormat):
+            # This Branch format cannot create shared repositories
+            return
+        # This is a little bit trickier because make_branch_and_tree will not
+        # re-use a shared repository.
+        try:
+            a_branch = self.make_from_branch('repo/tree')
+        except (errors.UninitializableFormat):
+            # Cannot create these branches
+            return
+        try:
+            tree = a_branch.bzrdir.create_workingtree()
+        except errors.NotLocalUrl:
+            if self.vfs_transport_factory is LocalURLServer:
+                # the branch is colocated on disk, we cannot create a checkout.
+                # hopefully callers will expect this.
+                local_controldir = bzrdir.BzrDir.open(self.get_vfs_only_url('repo/tree'))
+                tree = local_controldir.create_workingtree()
+            else:
+                tree = a_branch.create_checkout('repo/tree', lightweight=True)
+        self.build_tree(['repo/tree/a'])
+        tree.add(['a'])
+        tree.commit('a')
+
+        to_branch = self.make_to_branch('repo/branch')
+        tree.branch.push(to_branch)
+
+        self.assertEqual(tree.branch.last_revision(),
+                         to_branch.last_revision())
+
+    def test_push_overwrite_of_non_tip_with_stop_revision(self):
+        """Combining the stop_revision and overwrite options works.
+
+        This was <https://bugs.launchpad.net/bzr/+bug/234229>.
+        """
+        source = self.make_from_branch_and_tree('source')
+        target = self.make_to_branch('target')
+
+        source.commit('1st commit')
+        source.branch.push(target)
+        source.commit('2nd commit', rev_id='rev-2')
+        source.commit('3rd commit')
+
+        source.branch.push(target, stop_revision='rev-2', overwrite=True)
+        self.assertEqual('rev-2', target.last_revision())
+
+    def test_push_with_default_stacking_does_not_create_broken_branch(self):
+        """Pushing a new standalone branch works even when there's a default
+        stacking policy at the destination.
+
+        The new branch will preserve the repo format (even if it isn't the
+        default for the branch), and will be stacked when the repo format
+        allows (which means that the branch format isn't necessarly preserved).
+        """
+        if isinstance(self.branch_format_from, branch.BzrBranchFormat4):
+            raise tests.TestNotApplicable('Not a metadir format.')
+        if isinstance(self.branch_format_from, branch.BranchReferenceFormat):
+            # This test could in principle apply to BranchReferenceFormat, but
+            # make_branch_builder doesn't support it.
+            raise tests.TestSkipped(
+                "BranchBuilder can't make reference branches.")
+        # Make a branch called "local" in a stackable repository
+        # The branch has 3 revisions:
+        #   - rev-1, adds a file
+        #   - rev-2, no changes
+        #   - rev-3, modifies the file.
+        repo = self.make_repository('repo', shared=True, format='1.6')
+        builder = self.make_from_branch_builder('repo/local')
+        builder.start_series()
+        builder.build_snapshot('rev-1', None, [
+            ('add', ('', 'root-id', 'directory', '')),
+            ('add', ('filename', 'f-id', 'file', 'content\n'))])
+        builder.build_snapshot('rev-2', ['rev-1'], [])
+        builder.build_snapshot('rev-3', ['rev-2'],
+            [('modify', ('f-id', 'new-content\n'))])
+        builder.finish_series()
+        trunk = builder.get_branch()
+        # Sprout rev-1 to "trunk", so that we can stack on it.
+        trunk.bzrdir.sprout(self.get_url('trunk'), revision_id='rev-1')
+        # Set a default stacking policy so that new branches will automatically
+        # stack on trunk.
+        self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
+        # Push rev-2 to a new branch "remote".  It will be stacked on "trunk".
+        output = StringIO()
+        push._show_push_branch(trunk, 'rev-2', self.get_url('remote'), output)
+        # Push rev-3 onto "remote".  If "remote" not stacked and is missing the
+        # fulltext record for f-id @ rev-1, then this will fail.
+        remote_branch = Branch.open(self.get_url('remote'))
+        trunk.push(remote_branch)
+        remote_branch.check()
+
+    def test_no_get_parent_map_after_insert_stream(self):
+        # Effort test for bug 331823
+        self.setup_smart_server_with_call_log()
+        # Make a local branch with four revisions.  Four revisions because:
+        # one to push, one there for _walk_to_common_revisions to find, one we
+        # don't want to access, one for luck :)
+        if isinstance(self.branch_format_from, branch.BranchReferenceFormat):
+            # This test could in principle apply to BranchReferenceFormat, but
+            # make_branch_builder doesn't support it.
+            raise tests.TestSkipped(
+                "BranchBuilder can't make reference branches.")
+        try:
+            builder = self.make_from_branch_builder('local')
+        except (errors.TransportNotPossible, errors.UninitializableFormat):
+            raise tests.TestNotApplicable('format not directly constructable')
+        builder.start_series()
+        builder.build_snapshot('first', None, [
+            ('add', ('', 'root-id', 'directory', ''))])
+        builder.build_snapshot('second', ['first'], [])
+        builder.build_snapshot('third', ['second'], [])
+        builder.build_snapshot('fourth', ['third'], [])
+        builder.finish_series()
+        local = builder.get_branch()
+        local = branch.Branch.open(self.get_vfs_only_url('local'))
+        # Initial push of three revisions
+        remote_bzrdir = local.bzrdir.sprout(
+            self.get_url('remote'), revision_id='third')
+        remote = remote_bzrdir.open_branch()
+        # Push fourth revision
+        self.reset_smart_call_log()
+        self.disableOptimisticGetParentMap()
+        self.assertFalse(local.is_locked())
+        local.push(remote)
+        hpss_call_names = [item.call.method for item in self.hpss_calls]
+        self.assertTrue('Repository.insert_stream' in hpss_call_names)
+        insert_stream_idx = hpss_call_names.index('Repository.insert_stream')
+        calls_after_insert_stream = hpss_call_names[insert_stream_idx:]
+        # After inserting the stream the client has no reason to query the
+        # remote graph any further.
+        self.assertEqual(
+            ['Repository.insert_stream', 'Repository.insert_stream', 'get',
+             'Branch.set_last_revision_info', 'Branch.unlock'],
+            calls_after_insert_stream)
+
+    def disableOptimisticGetParentMap(self):
+        # Tweak some class variables to stop remote get_parent_map calls asking
+        # for or receiving more data than the caller asked for.
+        old_flag = SmartServerRepositoryGetParentMap.no_extra_results
+        inter_class = repository.InterRepository
+        old_batch_size = inter_class._walk_to_common_revisions_batch_size
+        inter_class._walk_to_common_revisions_batch_size = 1
+        SmartServerRepositoryGetParentMap.no_extra_results = True
+        def reset_values():
+            SmartServerRepositoryGetParentMap.no_extra_results = old_flag
+            inter_class._walk_to_common_revisions_batch_size = old_batch_size
+        self.addCleanup(reset_values)
+
+
+class TestPushHook(TestCaseWithInterBranch):
+
+    def setUp(self):
+        self.hook_calls = []
+        TestCaseWithInterBranch.setUp(self)
+
+    def capture_post_push_hook(self, result):
+        """Capture post push hook calls to self.hook_calls.
+
+        The call is logged, as is some state of the two branches.
+        """
+        if result.local_branch:
+            local_locked = result.local_branch.is_locked()
+            local_base = result.local_branch.base
+        else:
+            local_locked = None
+            local_base = None
+        self.hook_calls.append(
+            ('post_push', result.source_branch, local_base,
+             result.master_branch.base,
+             result.old_revno, result.old_revid,
+             result.new_revno, result.new_revid,
+             result.source_branch.is_locked(), local_locked,
+             result.master_branch.is_locked()))
+
+    def test_post_push_empty_history(self):
+        target = self.make_to_branch('target')
+        source = self.make_from_branch('source')
+        Branch.hooks.install_named_hook('post_push',
+                                        self.capture_post_push_hook, None)
+        source.push(target)
+        # with nothing there we should still get a notification, and
+        # have both branches locked at the notification time.
+        self.assertEqual([
+            ('post_push', source, None, target.base, 0, NULL_REVISION,
+             0, NULL_REVISION, True, None, True)
+            ],
+            self.hook_calls)
+
+    def test_post_push_bound_branch(self):
+        # pushing to a bound branch should pass in the master branch to the
+        # hook, allowing the correct number of emails to be sent, while still
+        # allowing hooks that want to modify the target to do so to both
+        # instances.
+        target = self.make_to_branch('target')
+        local = self.make_from_branch('local')
+        try:
+            local.bind(target)
+        except errors.UpgradeRequired:
+            # We can't bind this format to itself- typically it is the local
+            # branch that doesn't support binding.  As of May 2007
+            # remotebranches can't be bound.  Let's instead make a new local
+            # branch of the default type, which does allow binding.
+            # See https://bugs.launchpad.net/bzr/+bug/112020
+            local = BzrDir.create_branch_convenience('local2')
+            local.bind(target)
+        source = self.make_from_branch('source')
+        Branch.hooks.install_named_hook('post_push',
+                                        self.capture_post_push_hook, None)
+        source.push(local)
+        # with nothing there we should still get a notification, and
+        # have both branches locked at the notification time.
+        self.assertEqual([
+            ('post_push', source, local.base, target.base, 0, NULL_REVISION,
+             0, NULL_REVISION, True, True, True)
+            ],
+            self.hook_calls)
+
+    def test_post_push_nonempty_history(self):
+        target = self.make_to_branch_and_tree('target')
+        target.lock_write()
+        target.add('')
+        rev1 = target.commit('rev 1')
+        target.unlock()
+        sourcedir = target.bzrdir.clone(self.get_url('source'))
+        source = MemoryTree.create_on_branch(sourcedir.open_branch())
+        rev2 = source.commit('rev 2')
+        Branch.hooks.install_named_hook('post_push',
+                                        self.capture_post_push_hook, None)
+        source.branch.push(target.branch)
+        # with nothing there we should still get a notification, and
+        # have both branches locked at the notification time.
+        self.assertEqual([
+            ('post_push', source.branch, None, target.branch.base, 1, rev1,
+             2, rev2, True, None, True)
+            ],
+            self.hook_calls)

=== modified file 'bzrlib/tests/per_interbranch/test_update_revisions.py'
--- a/bzrlib/tests/per_interbranch/test_update_revisions.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_interbranch/test_update_revisions.py	2009-03-30 16:41:41 +0000
@@ -28,10 +28,10 @@
         super(TestUpdateRevisions, self).setUp()
         self.tree1 = self.make_branch_and_tree('tree1')
         rev1 = self.tree1.commit('one')
-        dir2 = self.make_to_bzrdir('tree2')
-        dir2.create_repository().fetch(self.tree1.branch.repository)
-        branch2 = self.tree1.branch.sprout(dir2)
-        self.tree2 = dir2.create_workingtree()
+        branch2 = self.make_to_branch('tree2')
+        branch2.repository.fetch(self.tree1.branch.repository)
+        self.tree1.branch.copy_content_into(branch2)
+        self.tree2 = branch2.bzrdir.create_workingtree()
 
     def test_accepts_graph(self):
         # An implementation may not use it, but it should allow a 'graph' to be




More information about the bazaar-commits mailing list