Merge lp:~vila/bzr/552922-plugins-at into lp:bzr/2.2

Proposed by Vincent Ladeuil
Status: Merged
Merged at revision: not available
Proposed branch: lp:~vila/bzr/552922-plugins-at
Merge into: lp:bzr/2.2
Diff against target: 8039 lines (+2585/-1104)
269 files modified
.testr.conf (+3/-0)
NEWS (+207/-41)
NEWS-template.txt (+31/-0)
bzrlib/_annotator_pyx.pyx (+1/-1)
bzrlib/_bencode_pyx.pyx (+1/-1)
bzrlib/_btree_serializer_py.py (+1/-1)
bzrlib/_btree_serializer_pyx.pyx (+1/-1)
bzrlib/_chk_map_py.py (+1/-1)
bzrlib/_chk_map_pyx.pyx (+1/-1)
bzrlib/_groupcompress_pyx.pyx (+1/-1)
bzrlib/_knit_load_data_pyx.pyx (+1/-1)
bzrlib/_known_graph_py.py (+1/-1)
bzrlib/_known_graph_pyx.pyx (+1/-1)
bzrlib/_readdir_pyx.pyx (+1/-1)
bzrlib/_rio_pyx.pyx (+1/-1)
bzrlib/_simple_set_pyx.pxd (+1/-1)
bzrlib/_simple_set_pyx.pyx (+1/-1)
bzrlib/_static_tuple_c.c (+1/-1)
bzrlib/_static_tuple_c.pxd (+1/-1)
bzrlib/_static_tuple_py.py (+1/-1)
bzrlib/_walkdirs_win32.pyx (+1/-1)
bzrlib/atomicfile.py (+1/-1)
bzrlib/benchmarks/bench_dirstate.py (+1/-1)
bzrlib/benchmarks/tree_creator/kernel_like.py (+2/-1)
bzrlib/branch.py (+47/-37)
bzrlib/branchbuilder.py (+8/-5)
bzrlib/btree_index.py (+1/-1)
bzrlib/bugtracker.py (+1/-1)
bzrlib/builtins.py (+46/-35)
bzrlib/bundle/__init__.py (+1/-1)
bzrlib/bzrdir.py (+44/-23)
bzrlib/chk_serializer.py (+1/-1)
bzrlib/cleanup.py (+1/-1)
bzrlib/cmd_version_info.py (+1/-1)
bzrlib/cmdline.py (+8/-8)
bzrlib/commands.py (+33/-23)
bzrlib/commit.py (+1/-1)
bzrlib/conflicts.py (+35/-7)
bzrlib/decorators.py (+1/-1)
bzrlib/delta.py (+1/-1)
bzrlib/diff.py (+1/-1)
bzrlib/doc_generate/autodoc_rstx.py (+1/-1)
bzrlib/errors.py (+12/-2)
bzrlib/export/__init__.py (+10/-5)
bzrlib/export/dir_exporter.py (+7/-3)
bzrlib/export/tar_exporter.py (+17/-10)
bzrlib/export/zip_exporter.py (+10/-5)
bzrlib/globbing.py (+1/-1)
bzrlib/graph.py (+1/-1)
bzrlib/groupcompress.py (+1/-1)
bzrlib/help.py (+1/-1)
bzrlib/help_topics/en/authentication.txt (+4/-4)
bzrlib/help_topics/en/configuration.txt (+43/-1)
bzrlib/hooks.py (+1/-1)
bzrlib/index.py (+1/-1)
bzrlib/info.py (+1/-1)
bzrlib/inventory.py (+1/-1)
bzrlib/lockdir.py (+19/-8)
bzrlib/merge.py (+2/-1)
bzrlib/merge_directive.py (+1/-1)
bzrlib/msgeditor.py (+1/-1)
bzrlib/osutils.py (+85/-9)
bzrlib/patches.py (+54/-9)
bzrlib/plugin.py (+181/-69)
bzrlib/plugins/launchpad/__init__.py (+2/-2)
bzrlib/plugins/launchpad/lp_api.py (+1/-1)
bzrlib/plugins/launchpad/lp_directory.py (+1/-1)
bzrlib/plugins/launchpad/test_lp_api.py (+1/-1)
bzrlib/plugins/launchpad/test_lp_directory.py (+1/-1)
bzrlib/plugins/launchpad/test_lp_open.py (+1/-1)
bzrlib/progress.py (+0/-5)
bzrlib/reconcile.py (+1/-1)
bzrlib/reconfigure.py (+1/-1)
bzrlib/remote.py (+39/-27)
bzrlib/revisionspec.py (+1/-1)
bzrlib/revisiontree.py (+1/-1)
bzrlib/serializer.py (+1/-1)
bzrlib/shellcomplete.py (+1/-1)
bzrlib/smart/bzrdir.py (+1/-1)
bzrlib/smart/client.py (+1/-1)
bzrlib/smart/medium.py (+1/-1)
bzrlib/smart/protocol.py (+1/-1)
bzrlib/smart/repository.py (+1/-1)
bzrlib/smart/request.py (+1/-1)
bzrlib/smart/server.py (+1/-1)
bzrlib/smart/vfs.py (+1/-1)
bzrlib/static_tuple.py (+1/-1)
bzrlib/status.py (+1/-1)
bzrlib/switch.py (+1/-1)
bzrlib/tests/TestUtil.py (+1/-1)
bzrlib/tests/__init__.py (+29/-1)
bzrlib/tests/blackbox/test_annotate.py (+1/-1)
bzrlib/tests/blackbox/test_branch.py (+1/-1)
bzrlib/tests/blackbox/test_break_lock.py (+1/-1)
bzrlib/tests/blackbox/test_cat.py (+1/-1)
bzrlib/tests/blackbox/test_checkout.py (+1/-1)
bzrlib/tests/blackbox/test_debug.py (+1/-1)
bzrlib/tests/blackbox/test_exceptions.py (+1/-1)
bzrlib/tests/blackbox/test_export.py (+11/-1)
bzrlib/tests/blackbox/test_filtered_view_ops.py (+1/-1)
bzrlib/tests/blackbox/test_help.py (+1/-1)
bzrlib/tests/blackbox/test_ignore.py (+1/-1)
bzrlib/tests/blackbox/test_info.py (+2/-1)
bzrlib/tests/blackbox/test_init.py (+1/-1)
bzrlib/tests/blackbox/test_ls.py (+1/-1)
bzrlib/tests/blackbox/test_merge.py (+1/-1)
bzrlib/tests/blackbox/test_mv.py (+1/-1)
bzrlib/tests/blackbox/test_nick.py (+19/-19)
bzrlib/tests/blackbox/test_non_ascii.py (+1/-1)
bzrlib/tests/blackbox/test_pull.py (+1/-1)
bzrlib/tests/blackbox/test_push.py (+1/-1)
bzrlib/tests/blackbox/test_remerge.py (+1/-1)
bzrlib/tests/blackbox/test_send.py (+1/-1)
bzrlib/tests/blackbox/test_serve.py (+1/-1)
bzrlib/tests/blackbox/test_shared_repository.py (+1/-1)
bzrlib/tests/blackbox/test_shelve.py (+1/-1)
bzrlib/tests/blackbox/test_status.py (+2/-1)
bzrlib/tests/blackbox/test_switch.py (+1/-1)
bzrlib/tests/blackbox/test_too_much.py (+1/-1)
bzrlib/tests/blackbox/test_uncommit.py (+1/-1)
bzrlib/tests/blackbox/test_update.py (+4/-3)
bzrlib/tests/blackbox/test_versioning.py (+19/-6)
bzrlib/tests/commands/test_branch.py (+1/-1)
bzrlib/tests/commands/test_cat.py (+1/-1)
bzrlib/tests/commands/test_checkout.py (+1/-1)
bzrlib/tests/commands/test_commit.py (+2/-3)
bzrlib/tests/commands/test_init.py (+1/-1)
bzrlib/tests/commands/test_init_repository.py (+1/-1)
bzrlib/tests/commands/test_merge.py (+1/-1)
bzrlib/tests/commands/test_missing.py (+1/-1)
bzrlib/tests/commands/test_pull.py (+1/-1)
bzrlib/tests/commands/test_push.py (+1/-1)
bzrlib/tests/commands/test_update.py (+1/-1)
bzrlib/tests/ftp_server/__init__.py (+1/-1)
bzrlib/tests/ftp_server/medusa_based.py (+1/-1)
bzrlib/tests/ftp_server/pyftpdlib_based.py (+1/-1)
bzrlib/tests/http_server.py (+1/-1)
bzrlib/tests/http_utils.py (+1/-1)
bzrlib/tests/per_branch/test_branch.py (+17/-0)
bzrlib/tests/per_branch/test_iter_merge_sorted_revisions.py (+1/-1)
bzrlib/tests/per_branch/test_parent.py (+1/-1)
bzrlib/tests/per_bzrdir/test_bzrdir.py (+39/-11)
bzrlib/tests/per_foreign_vcs/__init__.py (+1/-1)
bzrlib/tests/per_foreign_vcs/test_repository.py (+1/-1)
bzrlib/tests/per_interbranch/test_push.py (+1/-1)
bzrlib/tests/per_intertree/__init__.py (+1/-1)
bzrlib/tests/per_pack_repository.py (+1/-1)
bzrlib/tests/per_repository/test_check.py (+1/-1)
bzrlib/tests/per_repository/test_check_reconcile.py (+1/-1)
bzrlib/tests/per_repository_reference/test_check.py (+1/-1)
bzrlib/tests/per_transport.py (+47/-1)
bzrlib/tests/per_tree/test_get_file_with_stat.py (+1/-1)
bzrlib/tests/per_tree/test_iter_search_rules.py (+1/-1)
bzrlib/tests/per_tree/test_path_content_summary.py (+1/-1)
bzrlib/tests/per_tree/test_revision_tree.py (+9/-6)
bzrlib/tests/per_workingtree/test_content_filters.py (+1/-1)
bzrlib/tests/per_workingtree/test_is_ignored.py (+1/-1)
bzrlib/tests/per_workingtree/test_revision_tree.py (+57/-6)
bzrlib/tests/per_workingtree/test_workingtree.py (+6/-3)
bzrlib/tests/script.py (+1/-1)
bzrlib/tests/stub_sftp.py (+9/-7)
bzrlib/tests/test__annotator.py (+1/-1)
bzrlib/tests/test__bencode.py (+1/-1)
bzrlib/tests/test__chk_map.py (+1/-1)
bzrlib/tests/test__chunks_to_lines.py (+1/-1)
bzrlib/tests/test__dirstate_helpers.py (+1/-1)
bzrlib/tests/test__groupcompress.py (+1/-1)
bzrlib/tests/test__known_graph.py (+1/-1)
bzrlib/tests/test__rio.py (+1/-1)
bzrlib/tests/test__simple_set.py (+1/-1)
bzrlib/tests/test__static_tuple.py (+1/-1)
bzrlib/tests/test__walkdirs_win32.py (+1/-1)
bzrlib/tests/test_branch.py (+4/-4)
bzrlib/tests/test_branchbuilder.py (+9/-0)
bzrlib/tests/test_btree_index.py (+1/-1)
bzrlib/tests/test_bzrdir.py (+7/-3)
bzrlib/tests/test_cleanup.py (+1/-1)
bzrlib/tests/test_cmdline.py (+1/-1)
bzrlib/tests/test_commands.py (+32/-11)
bzrlib/tests/test_commit.py (+1/-1)
bzrlib/tests/test_config.py (+1/-1)
bzrlib/tests/test_conflicts.py (+115/-52)
bzrlib/tests/test_diff.py (+1/-1)
bzrlib/tests/test_directory_service.py (+1/-1)
bzrlib/tests/test_errors.py (+1/-1)
bzrlib/tests/test_export.py (+22/-1)
bzrlib/tests/test_fetch.py (+1/-84)
bzrlib/tests/test_foreign.py (+6/-4)
bzrlib/tests/test_ftp_transport.py (+19/-1)
bzrlib/tests/test_globbing.py (+1/-1)
bzrlib/tests/test_graph.py (+1/-1)
bzrlib/tests/test_groupcompress.py (+1/-1)
bzrlib/tests/test_hooks.py (+1/-1)
bzrlib/tests/test_http_response.py (+1/-1)
bzrlib/tests/test_ignores.py (+1/-1)
bzrlib/tests/test_index.py (+1/-1)
bzrlib/tests/test_info.py (+1/-1)
bzrlib/tests/test_knit.py (+1/-1)
bzrlib/tests/test_lockable_files.py (+1/-1)
bzrlib/tests/test_lockdir.py (+20/-1)
bzrlib/tests/test_log.py (+1/-1)
bzrlib/tests/test_merge.py (+5/-0)
bzrlib/tests/test_merge_core.py (+19/-3)
bzrlib/tests/test_msgeditor.py (+1/-1)
bzrlib/tests/test_patches.py (+9/-2)
bzrlib/tests/test_plugins.py (+270/-96)
bzrlib/tests/test_progress.py (+1/-1)
bzrlib/tests/test_remote.py (+1/-1)
bzrlib/tests/test_revisionspec.py (+1/-1)
bzrlib/tests/test_revisiontree.py (+1/-1)
bzrlib/tests/test_script.py (+1/-1)
bzrlib/tests/test_shelf_ui.py (+1/-1)
bzrlib/tests/test_smart.py (+1/-1)
bzrlib/tests/test_source.py (+1/-1)
bzrlib/tests/test_ssh_transport.py (+1/-1)
bzrlib/tests/test_trace.py (+22/-1)
bzrlib/tests/test_transport_log.py (+1/-1)
bzrlib/tests/test_urlutils.py (+1/-1)
bzrlib/tests/test_version.py (+1/-1)
bzrlib/tests/test_win32utils.py (+1/-1)
bzrlib/tests/test_xml.py (+1/-1)
bzrlib/tests/transport_util.py (+1/-1)
bzrlib/trace.py (+1/-1)
bzrlib/transport/__init__.py (+14/-2)
bzrlib/transport/chroot.py (+1/-1)
bzrlib/transport/decorator.py (+1/-1)
bzrlib/transport/ftp/__init__.py (+21/-15)
bzrlib/transport/http/__init__.py (+1/-1)
bzrlib/transport/http/_urllib.py (+1/-1)
bzrlib/transport/http/_urllib2_wrappers.py (+1/-1)
bzrlib/transport/http/wsgi.py (+1/-1)
bzrlib/transport/local.py (+33/-6)
bzrlib/transport/memory.py (+1/-1)
bzrlib/transport/pathfilter.py (+1/-1)
bzrlib/transport/sftp.py (+24/-2)
bzrlib/transport/ssh.py (+6/-3)
bzrlib/ui/text.py (+5/-1)
bzrlib/urlutils.py (+1/-1)
bzrlib/version_info_formats/format_rio.py (+1/-1)
bzrlib/versionedfile.py (+1/-1)
bzrlib/workingtree.py (+2/-1)
bzrlib/workingtree_4.py (+4/-2)
bzrlib/xml4.py (+1/-1)
bzrlib/xml5.py (+1/-1)
bzrlib/xml7.py (+1/-1)
bzrlib/xml8.py (+1/-1)
bzrlib/xml_serializer.py (+1/-1)
doc/developers/_templates/layout.html (+0/-19)
doc/developers/bug-handling.txt (+2/-0)
doc/developers/contribution-quickstart.txt (+117/-56)
doc/developers/index-plain.txt (+2/-2)
doc/developers/index.txt (+18/-5)
doc/developers/plugin-api.txt (+5/-5)
doc/developers/process.txt (+0/-39)
doc/developers/testing.txt (+36/-3)
doc/en/_templates/index.html (+16/-4)
doc/en/_templates/layout.html (+0/-19)
doc/en/admin-guide/hooks-plugins.txt (+1/-1)
doc/en/conf.py (+6/-0)
doc/en/index.txt (+1/-0)
doc/en/user-guide/http_smart_server.txt (+79/-15)
doc/en/whats-new/whats-new-in-2.1.txt (+202/-0)
doc/es/_templates/layout.html (+0/-19)
doc/index.es.txt (+1/-1)
doc/index.ja.txt (+1/-1)
doc/index.ru.txt (+1/-1)
doc/index.txt (+1/-1)
doc/ru/_templates/layout.html (+0/-19)
setup.py (+23/-7)
To merge this branch: bzr merge lp:~vila/bzr/552922-plugins-at
Reviewer Review Type Date Requested Status
Vincent Ladeuil Needs Resubmitting
Review via email: mp+22694@code.launchpad.net

Description of the change

@Reviewers: this is targeted at lp:bzr/2.2 but I'm afraid the branch (2.2)
is not up-to-date, so if the diff looks awfully wrong, you'll know why.

This patch fixes the BZR_PLUGINS_AT handling to not depend on os.listdir() order.
The automated tests couldn't catch the problem and I was lucky enough to not encounter
it before (and neither was Gary).

Unlike _find_module_plugin() which scan the 'plugins' directories and deduce the plugin
names from the loadable files, BZR_PLUGINS_AT *knows* the plugin names and can (and should)
try some file names explicitly.

Tests added.

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

Bah. It's even worse than I thought, I'll resubmit against bzr.dev.

review: Needs Resubmitting

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.testr.conf'
--- .testr.conf 1970-01-01 00:00:00 +0000
+++ .testr.conf 2010-04-06 07:24:41 +0000
@@ -0,0 +1,3 @@
1[DEFAULT]
2test_command=./bzr selftest --subunit $IDOPTION
3test_id_option=--load-list $IDFILE
04
=== modified file 'NEWS'
--- NEWS 2010-02-18 04:59:30 +0000
+++ NEWS 2010-04-06 07:24:41 +0000
@@ -8,7 +8,6 @@
8bzr 2.2.0b18bzr 2.2.0b1
9###########9###########
1010
11:Codename: ???
12:2.2.0b1: Not released yet11:2.2.0b1: Not released yet
1312
14Compatibility Breaks13Compatibility Breaks
@@ -31,9 +30,17 @@
31 ``bzrlib.tests.test_server``.30 ``bzrlib.tests.test_server``.
32 (Vincent Ladeuil)31 (Vincent Ladeuil)
3332
33* ``BranchReferenceFormat.initialize()`` now takes an optional name argument
34 as its second parameter, for consistency with the initialize() method of
35 other formats. (Jelmer Vernooij)
36
34New Features37New Features
35************38************
3639
40* ``bzr export`` now takes an optional argument ``--per-file-timestamps``
41 to set file mtimes to the last timestamp of the last revision in which
42 they were changed rather than the current time. (Jelmer Vernooij)
43
37* If the Apport crash-reporting tool is available, bzr crashes are now44* If the Apport crash-reporting tool is available, bzr crashes are now
38 stored into the ``/var/crash`` apport spool directory, and the user is45 stored into the ``/var/crash`` apport spool directory, and the user is
39 invited to report them to the developers from there, either46 invited to report them to the developers from there, either
@@ -44,6 +51,17 @@
44 treats backslash as an escape character on Windows. (Gordon Tyler,51 treats backslash as an escape character on Windows. (Gordon Tyler,
45 #392248)52 #392248)
4653
54* Plugins can be disabled by defining ``BZR_DISABLE_PLUGINS`` as
55 a list of plugin names separated by ':' (';' on windows).
56 (Vincent Ladeuil, #411413)
57
58* Plugins can be loaded from arbitrary locations by defining
59 ``BZR_PLUGINS_AT`` as a list of name@path separated by ':' (';' on
60 windows). This takes precedence over ``BZR_PLUGIN_PATH`` for the
61 specified plugins. This is targeted at plugin developers for punctual
62 needs and *not* intended to replace ``BZR_PLUGIN_PATH``.
63 (Vincent Ladeuil, #82693)
64
47* Tree-shape conflicts can be resolved by providing ``--take-this`` and65* Tree-shape conflicts can be resolved by providing ``--take-this`` and
48 ``--take-other`` to the ``bzr resolve`` command. Just marking the conflict66 ``--take-other`` to the ``bzr resolve`` command. Just marking the conflict
49 as resolved is still accessible via the ``--done`` default action.67 as resolved is still accessible via the ``--done`` default action.
@@ -61,6 +79,11 @@
61* Allow exporting a single file using ``bzr export``.79* Allow exporting a single file using ``bzr export``.
62 (Michal Junák, #511987)80 (Michal Junák, #511987)
6381
82* Allow syscalls to automatically restart when ``TextUIFactory``'s
83 SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
84 IO, which are often poorly handled by Python's libraries and parts of
85 bzrlib. (Andrew Bennetts, #496813)
86
64* Avoid infinite recursion when probing for apport.87* Avoid infinite recursion when probing for apport.
65 (Vincent Ladeuil, #516934)88 (Vincent Ladeuil, #516934)
6689
@@ -70,9 +93,39 @@
70* ``bzr add`` will not add conflict related files unless explicitly required.93* ``bzr add`` will not add conflict related files unless explicitly required.
71 (Vincent Ladeuil, #322767, #414589)94 (Vincent Ladeuil, #322767, #414589)
7295
96* ``bzr help`` will no longer trigger the get_missing_command hook when
97 doing a topic lookup. This avoids prompting (like 'no command plugins/loom,
98 did you mean log?') when getting help. In future we may trigger the hook
99 deliberately when no help topics match from any help index.
100 (Robert Collins, #396261)
101
73* ``bzr remove-tree`` can now remove multiple working trees.102* ``bzr remove-tree`` can now remove multiple working trees.
74 (Jared Hance, Andrew Bennetts, #253137)103 (Jared Hance, Andrew Bennetts, #253137)
75104
105* ``bzr resolve --take-this`` and ``--take-other`` now correctly renames
106 the kept file on content conflicts where one side deleted the file.
107 (Vincent Ladeuil, #529968)
108
109* ``bzr upgrade`` now names backup directory as ``backup.bzr.~N~`` instead
110 of ``backup.bzr``. This directory is ignored by bzr commands such as
111 ``add``.
112 (Parth Malwankar, #335033, #300001)
113
114* Correctly interpret "451 Rename/move failure: Directory not empty" from
115 ftp servers while trying to take a lock.
116 (Martin Pool, #528722)
117
118* DirStateRevisionTree.kind() was returning wrong result when 'kind'
119 changes occured between the workingtree and one of its parents.
120 (Vincent Ladeuil, #533437)
121
122* Fix stub sftp test server to call os.getcwdu().
123 (Vincent Ladeuil, #526211, #526353)
124
125* Loading a plugin from a given path with ``BZR_PLUGINS_AT`` doesn't depend
126 on os.lisdir() order and is now reliable.
127 (Vincent Ladeuil, #552922).
128
76* Network transfer amounts and rates are now displayed in SI units according129* Network transfer amounts and rates are now displayed in SI units according
77 to the Ubuntu Units Policy <https://wiki.ubuntu.com/UnitsPolicy>.130 to the Ubuntu Units Policy <https://wiki.ubuntu.com/UnitsPolicy>.
78 (Gordon Tyler, #514399)131 (Gordon Tyler, #514399)
@@ -81,26 +134,85 @@
81 prevents ``bzr status --short`` from crashing when those files are134 prevents ``bzr status --short`` from crashing when those files are
82 present. (John Arbash Meinel, #303275)135 present. (John Arbash Meinel, #303275)
83136
84* ``bzr upgrade`` now names backup directory as ``backup.bzr.~N~`` instead137* ``bzr mkdir DIR`` will not create DIR unless DIR's parent is a versioned
85 of ``backup.bzr``. This directory is ignored by bzr commands such as138 directory. (Parth Malwankar, #138600)
86 ``add``.139
87 (Parth Malwankar, #335033, #300001)140* SSH child processes will now ignore SIGQUIT on nix systems so breaking into
141 the debugger won't kill the session.
142 (Martin <gzlist@googlemail.com>, #162502)
143
144* Allow additional arguments to
145 ``RemoteRepository.add_inventory_by_delta()``. (Jelmer Vernooij, #532631)
146
147* Tolerate patches with leading noise in ``bzr-handle-patch``.
148 (Toshio Kuratomi, Martin Pool, #502076)
88149
89API Changes150API Changes
90***********151***********
91152
153* ``BranchFormat.initialize`` now takes an optional ``name`` of the colocated
154 branch to create. (Jelmer Vernooij)
155
156* ``BzrDir.get_branch_transport`` now takes an optional ``name`` of the
157 colocated branch to open. (Jelmer Vernooij)
158
159* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
160 can set a signal handler and call ``signal.siginterrupt(signum,
161 False)`` for it, if the platform and Python version supports it.
162 (Andrew Bennetts, #496813)
163
92* New ``bzrlib.initialize`` is recommended for programs using bzrlib to 164* New ``bzrlib.initialize`` is recommended for programs using bzrlib to
93 run when starting up; it sets up several things that previously needed165 run when starting up; it sets up several things that previously needed
94 to be done separately.166 to be done separately.
95 (Martin Pool, #507710)167 (Martin Pool, #507710)
96168
169* Exporters now support a ``per_file_timestamps`` argument to write out the
170 timestamp of the commit in which a file revision was introduced.
171 (Jelmer Vernooij)
172
173* New method ``BzrDir.list_branches()`` that returns a sequence of branches
174 present in a control directory. (Jelmer Vernooij)
175
176* New transport methods ``readlink``, ``symlink`` and ``hardlink``.
177 (Neil Santos)
178
97* Remove unused ``CommandFailed`` exception.179* Remove unused ``CommandFailed`` exception.
98 (Martin Pool)180 (Martin Pool)
99181
182Internals
183*********
184
185* ``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
186 ``message_callback`` in the same way that commit does. (Robert Collins)
187
188* ``bzrlib.builtins.Commit.run`` raises ``bzrlib.errors.BoundBranchOutOfDate``
189 rather than ``bzrlib.errors.BzrCommandError`` when the bound branch is out
190 of date. (Gary van der Merwe)
191
192* ``bzrlib.commands.run_bzr`` is more extensible: callers can supply the
193 functions to load or disable plugins if they wish to use a different
194 plugin mechanism; the --help, --version and no-command name code paths
195 now use the generic pluggable command lookup infrastructure.
196 (Robert Collins)
197
198* ``bzrlib.errors.BoundBranchOutOfDate`` has a new field ``extra_help``
199 which can be set to add extra help to the error. (Gary van der Merwe)
200
201* The methods ``BzrDir.create_branch()``, ``BzrDir.destroy_branch()`` and
202 ``BzrDir.open_branch()`` now take an optional ``name`` argument.
203 (Jelmer Vernooij)
204
100Testing205Testing
101*******206*******
102207
103* New `bzrlib.tests.test_import_tariff` can make assertions about what208* bzr now has a ``.testr.conf`` file in its source tree configured
209 appropriately for running tests with Testrepository
210 (``https://launchpad.net/testrepository``). (Robert Collins)
211
212* Documentation about testing with ``subunit`` has been tweaked.
213 (Robert Collins)
214
215* New ``bzrlib.tests.test_import_tariff`` can make assertions about what
104 Python modules are loaded, to guard against startup time or library216 Python modules are loaded, to guard against startup time or library
105 dependency regressions.217 dependency regressions.
106 (Martin Pool)218 (Martin Pool)
@@ -108,6 +220,70 @@
108* Stop sending apport crash files to ``.cache`` in the directory from220* Stop sending apport crash files to ``.cache`` in the directory from
109 which ``bzr selftest`` was run. (Martin Pool, #422350)221 which ``bzr selftest`` was run. (Martin Pool, #422350)
110222
223* Tests no longer fail if "close() called during concurrent
224 operation on the same file object" occurs when closing the log file
225 (which can happen if a thread tries to write to the log file at the
226 wrong moment). An warning will be written to ``stderr`` when this
227 happens, and another warning will be written if the log file could not
228 be closed after retrying 100 times. (Andrew Bennetts, #531746)
229
230bzr 2.1.1
231#########
232
233:2.1.1: not released yet
234
235Bug Fixes
236*********
237
238* Allow syscalls to automatically restart when ``TextUIFactory``'s
239 SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
240 IO, which are often poorly handled by Python's libraries and parts of
241 bzrlib. (Andrew Bennetts, #496813)
242
243* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
244 (Martin Pool, #331095)
245
246* Fix plugin packaging on Windows. (Ian Clatworthy, #524162)
247
248* Fix stub sftp test server to call os.getcwdu().
249 (Vincent Ladeuil, #526211, #526353)
250
251* Fixed CHM generation by moving the NEWS section template into
252 a separate file. (Ian Clatworthy, #524184)
253
254* Merge correctly when this_tree is not a WorkingTree. (Aaron Bentley)
255
256* Register SIGWINCH handler only when creating a ``TextUIFactory``; avoids
257 problems importing bzrlib from a non-main thread.
258 (Elliot Murphy, #521989)
259
260* Standardize the error handling when creating a new ``StaticTuple``
261 (problems will raise TypeError). (Matt Nordhoff, #457979)
262
263* Warn if pyrex is too old to compile the new ``SimpleSet`` and
264 ``StaticTuple`` extensions, rather than having the build fail randomly.
265 (John Arbash Meinel, #449776)
266
267
268Documentation
269*************
270
271* Added a link to the Desktop Guide. (Ian Clatworthy)
272
273* Added What's New in Bazaar 2.1 document. (Ian Clatworthy)
274
275* Drop Google Analytics from the core docs as they caused problems
276 in the CHM files. (Ian Clatworthy, #502010)
277
278API Changes
279***********
280
281* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
282 can set a signal handler and call ``signal.siginterrupt(signum,
283 False)`` for it, if the platform and Python version supports it.
284 (Andrew Bennetts, #496813)
285
286
111bzr 2.1.0287bzr 2.1.0
112#########288#########
113289
@@ -465,18 +641,36 @@
465 (Martin Pool)641 (Martin Pool)
466642
467643
468bzr 2.0.5 (not released yet)644bzr 2.0.5
469############################645#########
470646
471:Codename:647:Codename:
472:2.0.5:648:2.0.5: NOT RELEASED YET
473649
474Bug Fixes650Bug Fixes
475*********651*********
476652
653* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
654 (Martin Pool, #331095)
655
656* Concurrent autopacking is more resilient to already-renamed pack files.
657 If we find that a file we are about to obsolete is already obsoleted, we
658 do not try to rename it, and we leave the file in ``obsolete_packs``.
659 The code is also fault tolerant if a file goes missing, assuming that
660 another process already removed the file.
661 (John Arbash Meinel, Gareth White, #507557)
662
663* Cope with the lockdir ``held/info`` file being empty, which seems to
664 happen fairly often if the process is suddenly interrupted while taking
665 a lock.
666 (Martin Pool, #185103)
667
477* Handle renames correctly when there are files or directories that 668* Handle renames correctly when there are files or directories that
478 differ only in case. (Chris Jones, Martin Pool, #368931)669 differ only in case. (Chris Jones, Martin Pool, #368931)
479670
671* Fixed CHM generation by moving the NEWS section template into
672 a separate file. (Ian Clatworthy, #524184)
673
480* If ``bzr push --create-prefix`` triggers an unexpected ``NoSuchFile``674* If ``bzr push --create-prefix`` triggers an unexpected ``NoSuchFile``
481 error, report that error rather than failing with an unhelpful675 error, report that error rather than failing with an unhelpful
482 ``UnboundLocalError``.676 ``UnboundLocalError``.
@@ -486,6 +680,10 @@
486 version number along with rest of the help text.680 version number along with rest of the help text.
487 (Parth Malwankar, #369501)681 (Parth Malwankar, #369501)
488682
683* Use osutils.O_NOINHERIT for some files on win32 to avoid PermissionDenied
684 errors.
685 (Inada Naoki, #524560)
686
489Documentation687Documentation
490*************688*************
491689
@@ -11972,37 +12170,5 @@
11972 diff, status, etc.12170 diff, status, etc.
1197312171
1197412172
11975bzr ?.?.? (not released yet)
11976############################
11977
11978:Codename: template
11979:2.0.2: ???
11980
11981Compatibility Breaks
11982********************
11983
11984New Features
11985************
11986
11987Bug Fixes
11988*********
11989
11990Improvements
11991************
11992
11993Documentation
11994*************
11995
11996API Changes
11997***********
11998
11999Internals
12000*********
12001
12002Testing
12003*******
12004
12005
12006
12007..12173..
12008 vim: tw=74 ft=rst ff=unix encoding=utf-812174 vim: tw=74 ft=rst ff=unix encoding=utf-8
1200912175
=== added file 'NEWS-template.txt'
--- NEWS-template.txt 1970-01-01 00:00:00 +0000
+++ NEWS-template.txt 2010-04-06 07:24:41 +0000
@@ -0,0 +1,31 @@
1bzr ?.?.?
2#########
3
4:Codename: Nirvana
5:2.x.y: NOT RELEASED YET
6
7Compatibility Breaks
8********************
9
10New Features
11************
12
13Bug Fixes
14*********
15
16Improvements
17************
18
19Documentation
20*************
21
22API Changes
23***********
24
25Internals
26*********
27
28Testing
29*******
30
31
032
=== modified file 'bzrlib/_annotator_pyx.pyx'
--- bzrlib/_annotator_pyx.pyx 2010-01-05 04:59:57 +0000
+++ bzrlib/_annotator_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_bencode_pyx.pyx'
--- bzrlib/_bencode_pyx.pyx 2010-01-04 02:25:11 +0000
+++ bzrlib/_bencode_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007,2009 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_btree_serializer_py.py'
--- bzrlib/_btree_serializer_py.py 2009-11-07 00:28:26 +0000
+++ bzrlib/_btree_serializer_py.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_btree_serializer_pyx.pyx'
--- bzrlib/_btree_serializer_pyx.pyx 2010-01-05 05:09:45 +0000
+++ bzrlib/_btree_serializer_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_chk_map_py.py'
--- bzrlib/_chk_map_py.py 2009-10-21 21:27:19 +0000
+++ bzrlib/_chk_map_py.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_chk_map_pyx.pyx'
--- bzrlib/_chk_map_pyx.pyx 2010-01-05 05:09:45 +0000
+++ bzrlib/_chk_map_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_groupcompress_pyx.pyx'
--- bzrlib/_groupcompress_pyx.pyx 2010-01-05 05:09:45 +0000
+++ bzrlib/_groupcompress_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_knit_load_data_pyx.pyx'
--- bzrlib/_knit_load_data_pyx.pyx 2010-01-04 23:13:20 +0000
+++ bzrlib/_knit_load_data_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_known_graph_py.py'
--- bzrlib/_known_graph_py.py 2009-11-30 17:25:22 +0000
+++ bzrlib/_known_graph_py.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_known_graph_pyx.pyx'
--- bzrlib/_known_graph_pyx.pyx 2010-01-05 05:09:45 +0000
+++ bzrlib/_known_graph_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_readdir_pyx.pyx'
--- bzrlib/_readdir_pyx.pyx 2010-01-06 22:17:10 +0000
+++ bzrlib/_readdir_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2008, 2009 Canonical Ltd1# Copyright (C) 2006, 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_rio_pyx.pyx'
--- bzrlib/_rio_pyx.pyx 2010-01-05 04:59:57 +0000
+++ bzrlib/_rio_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_simple_set_pyx.pxd'
--- bzrlib/_simple_set_pyx.pxd 2010-01-05 05:28:42 +0000
+++ bzrlib/_simple_set_pyx.pxd 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_simple_set_pyx.pyx'
--- bzrlib/_simple_set_pyx.pyx 2010-01-05 05:28:42 +0000
+++ bzrlib/_simple_set_pyx.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_static_tuple_c.c'
--- bzrlib/_static_tuple_c.c 2010-02-18 01:10:16 +0000
+++ bzrlib/_static_tuple_c.c 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1/* Copyright (C) 2009 Canonical Ltd1/* Copyright (C) 2009, 2010 Canonical Ltd
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by4 * it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_static_tuple_c.pxd'
--- bzrlib/_static_tuple_c.pxd 2009-10-21 21:27:19 +0000
+++ bzrlib/_static_tuple_c.pxd 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_static_tuple_py.py'
--- bzrlib/_static_tuple_py.py 2010-02-18 01:10:16 +0000
+++ bzrlib/_static_tuple_py.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/_walkdirs_win32.pyx'
--- bzrlib/_walkdirs_win32.pyx 2010-01-07 17:02:44 +0000
+++ bzrlib/_walkdirs_win32.pyx 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/atomicfile.py'
--- bzrlib/atomicfile.py 2009-03-23 14:59:43 +0000
+++ bzrlib/atomicfile.py 2010-04-06 07:24:41 +0000
@@ -60,7 +60,7 @@
6060
61 self.realfilename = filename61 self.realfilename = filename
6262
63 flags = os.O_EXCL | os.O_CREAT | os.O_WRONLY63 flags = os.O_EXCL | os.O_CREAT | os.O_WRONLY | osutils.O_NOINHERIT
64 if mode == 'wb':64 if mode == 'wb':
65 flags |= osutils.O_BINARY65 flags |= osutils.O_BINARY
66 elif mode != 'wt':66 elif mode != 'wt':
6767
=== modified file 'bzrlib/benchmarks/bench_dirstate.py'
--- bzrlib/benchmarks/bench_dirstate.py 2009-12-22 17:05:47 +0000
+++ bzrlib/benchmarks/bench_dirstate.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2009 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/benchmarks/tree_creator/kernel_like.py'
--- bzrlib/benchmarks/tree_creator/kernel_like.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/tree_creator/kernel_like.py 2010-04-06 07:24:41 +0000
@@ -48,7 +48,8 @@
48 if self._url is not None:48 if self._url is not None:
49 b = bzrdir.BzrDir.create_branch_convenience(self._url)49 b = bzrdir.BzrDir.create_branch_convenience(self._url)
50 d = bzrdir.BzrDir.create(root)50 d = bzrdir.BzrDir.create(root)
51 bzrlib.branch.BranchReferenceFormat().initialize(d, b)51 bzrlib.branch.BranchReferenceFormat().initialize(d,
52 target_branch=b)
52 tree = d.create_workingtree()53 tree = d.create_workingtree()
53 else:54 else:
54 tree = bzrdir.BzrDir.create_standalone_workingtree(root)55 tree = bzrdir.BzrDir.create_standalone_workingtree(root)
5556
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py 2010-01-12 02:48:41 +0000
+++ bzrlib/branch.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -167,13 +167,13 @@
167 """167 """
168 control = bzrdir.BzrDir.open(base, _unsupported,168 control = bzrdir.BzrDir.open(base, _unsupported,
169 possible_transports=possible_transports)169 possible_transports=possible_transports)
170 return control.open_branch(_unsupported)170 return control.open_branch(unsupported=_unsupported)
171171
172 @staticmethod172 @staticmethod
173 def open_from_transport(transport, _unsupported=False):173 def open_from_transport(transport, name=None, _unsupported=False):
174 """Open the branch rooted at transport"""174 """Open the branch rooted at transport"""
175 control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)175 control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
176 return control.open_branch(_unsupported)176 return control.open_branch(name=name, unsupported=_unsupported)
177177
178 @staticmethod178 @staticmethod
179 def open_containing(url, possible_transports=None):179 def open_containing(url, possible_transports=None):
@@ -217,9 +217,9 @@
217 def _get_fallback_repository(self, url):217 def _get_fallback_repository(self, url):
218 """Get the repository we fallback to at url."""218 """Get the repository we fallback to at url."""
219 url = urlutils.join(self.base, url)219 url = urlutils.join(self.base, url)
220 a_bzrdir = bzrdir.BzrDir.open(url,220 a_branch = Branch.open(url,
221 possible_transports=[self.bzrdir.root_transport])221 possible_transports=[self.bzrdir.root_transport])
222 return a_bzrdir.open_branch().repository222 return a_branch.repository
223223
224 def _get_tags_bytes(self):224 def _get_tags_bytes(self):
225 """Get the bytes of a serialised tags dict.225 """Get the bytes of a serialised tags dict.
@@ -1317,7 +1317,8 @@
1317 if lightweight:1317 if lightweight:
1318 format = self._get_checkout_format()1318 format = self._get_checkout_format()
1319 checkout = format.initialize_on_transport(t)1319 checkout = format.initialize_on_transport(t)
1320 from_branch = BranchReferenceFormat().initialize(checkout, self)1320 from_branch = BranchReferenceFormat().initialize(checkout,
1321 target_branch=self)
1321 else:1322 else:
1322 format = self._get_checkout_format()1323 format = self._get_checkout_format()
1323 checkout_branch = bzrdir.BzrDir.create_branch_convenience(1324 checkout_branch = bzrdir.BzrDir.create_branch_convenience(
@@ -1434,10 +1435,10 @@
1434 return not (self == other)1435 return not (self == other)
14351436
1436 @classmethod1437 @classmethod
1437 def find_format(klass, a_bzrdir):1438 def find_format(klass, a_bzrdir, name=None):
1438 """Return the format for the branch object in a_bzrdir."""1439 """Return the format for the branch object in a_bzrdir."""
1439 try:1440 try:
1440 transport = a_bzrdir.get_branch_transport(None)1441 transport = a_bzrdir.get_branch_transport(None, name=name)
1441 format_string = transport.get_bytes("format")1442 format_string = transport.get_bytes("format")
1442 return klass._formats[format_string]1443 return klass._formats[format_string]
1443 except errors.NoSuchFile:1444 except errors.NoSuchFile:
@@ -1483,20 +1484,21 @@
1483 """Return the short format description for this format."""1484 """Return the short format description for this format."""
1484 raise NotImplementedError(self.get_format_description)1485 raise NotImplementedError(self.get_format_description)
14851486
1486 def _initialize_helper(self, a_bzrdir, utf8_files, lock_type='metadir',1487 def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1487 set_format=True):1488 lock_type='metadir', set_format=True):
1488 """Initialize a branch in a bzrdir, with specified files1489 """Initialize a branch in a bzrdir, with specified files
14891490
1490 :param a_bzrdir: The bzrdir to initialize the branch in1491 :param a_bzrdir: The bzrdir to initialize the branch in
1491 :param utf8_files: The files to create as a list of1492 :param utf8_files: The files to create as a list of
1492 (filename, content) tuples1493 (filename, content) tuples
1494 :param name: Name of colocated branch to create, if any
1493 :param set_format: If True, set the format with1495 :param set_format: If True, set the format with
1494 self.get_format_string. (BzrBranch4 has its format set1496 self.get_format_string. (BzrBranch4 has its format set
1495 elsewhere)1497 elsewhere)
1496 :return: a branch in this format1498 :return: a branch in this format
1497 """1499 """
1498 mutter('creating branch %r in %s', self, a_bzrdir.transport.base)1500 mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
1499 branch_transport = a_bzrdir.get_branch_transport(self)1501 branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1500 lock_map = {1502 lock_map = {
1501 'metadir': ('lock', lockdir.LockDir),1503 'metadir': ('lock', lockdir.LockDir),
1502 'branch4': ('branch-lock', lockable_files.TransportLock),1504 'branch4': ('branch-lock', lockable_files.TransportLock),
@@ -1523,10 +1525,13 @@
1523 finally:1525 finally:
1524 if lock_taken:1526 if lock_taken:
1525 control_files.unlock()1527 control_files.unlock()
1526 return self.open(a_bzrdir, _found=True)1528 return self.open(a_bzrdir, name, _found=True)
15271529
1528 def initialize(self, a_bzrdir):1530 def initialize(self, a_bzrdir, name=None):
1529 """Create a branch of this format in a_bzrdir."""1531 """Create a branch of this format in a_bzrdir.
1532
1533 :param name: Name of the colocated branch to create.
1534 """
1530 raise NotImplementedError(self.initialize)1535 raise NotImplementedError(self.initialize)
15311536
1532 def is_supported(self):1537 def is_supported(self):
@@ -1562,10 +1567,11 @@
1562 """1567 """
1563 raise NotImplementedError(self.network_name)1568 raise NotImplementedError(self.network_name)
15641569
1565 def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):1570 def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1566 """Return the branch object for a_bzrdir1571 """Return the branch object for a_bzrdir
15671572
1568 :param a_bzrdir: A BzrDir that contains a branch.1573 :param a_bzrdir: A BzrDir that contains a branch.
1574 :param name: Name of colocated branch to open
1569 :param _found: a private parameter, do not use it. It is used to1575 :param _found: a private parameter, do not use it. It is used to
1570 indicate if format probing has already be done.1576 indicate if format probing has already be done.
1571 :param ignore_fallbacks: when set, no fallback branches will be opened1577 :param ignore_fallbacks: when set, no fallback branches will be opened
@@ -1735,12 +1741,12 @@
1735 """See BranchFormat.get_format_description()."""1741 """See BranchFormat.get_format_description()."""
1736 return "Branch format 4"1742 return "Branch format 4"
17371743
1738 def initialize(self, a_bzrdir):1744 def initialize(self, a_bzrdir, name=None):
1739 """Create a branch of this format in a_bzrdir."""1745 """Create a branch of this format in a_bzrdir."""
1740 utf8_files = [('revision-history', ''),1746 utf8_files = [('revision-history', ''),
1741 ('branch-name', ''),1747 ('branch-name', ''),
1742 ]1748 ]
1743 return self._initialize_helper(a_bzrdir, utf8_files,1749 return self._initialize_helper(a_bzrdir, utf8_files, name=name,
1744 lock_type='branch4', set_format=False)1750 lock_type='branch4', set_format=False)
17451751
1746 def __init__(self):1752 def __init__(self):
@@ -1751,8 +1757,10 @@
1751 """The network name for this format is the control dirs disk label."""1757 """The network name for this format is the control dirs disk label."""
1752 return self._matchingbzrdir.get_format_string()1758 return self._matchingbzrdir.get_format_string()
17531759
1754 def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):1760 def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1755 """See BranchFormat.open()."""1761 """See BranchFormat.open()."""
1762 if name is not None:
1763 raise errors.NoColocatedBranchSupport(a_bzrdir)
1756 if not _found:1764 if not _found:
1757 # we are being called directly and must probe.1765 # we are being called directly and must probe.
1758 raise NotImplementedError1766 raise NotImplementedError
@@ -1779,15 +1787,15 @@
1779 """1787 """
1780 return self.get_format_string()1788 return self.get_format_string()
17811789
1782 def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):1790 def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1783 """See BranchFormat.open()."""1791 """See BranchFormat.open()."""
1784 if not _found:1792 if not _found:
1785 format = BranchFormat.find_format(a_bzrdir)1793 format = BranchFormat.find_format(a_bzrdir, name=name)
1786 if format.__class__ != self.__class__:1794 if format.__class__ != self.__class__:
1787 raise AssertionError("wrong format %r found for %r" %1795 raise AssertionError("wrong format %r found for %r" %
1788 (format, self))1796 (format, self))
1789 try:1797 try:
1790 transport = a_bzrdir.get_branch_transport(None)1798 transport = a_bzrdir.get_branch_transport(None, name=name)
1791 control_files = lockable_files.LockableFiles(transport, 'lock',1799 control_files = lockable_files.LockableFiles(transport, 'lock',
1792 lockdir.LockDir)1800 lockdir.LockDir)
1793 return self._branch_class()(_format=self,1801 return self._branch_class()(_format=self,
@@ -1831,12 +1839,12 @@
1831 """See BranchFormat.get_format_description()."""1839 """See BranchFormat.get_format_description()."""
1832 return "Branch format 5"1840 return "Branch format 5"
18331841
1834 def initialize(self, a_bzrdir):1842 def initialize(self, a_bzrdir, name=None):
1835 """Create a branch of this format in a_bzrdir."""1843 """Create a branch of this format in a_bzrdir."""
1836 utf8_files = [('revision-history', ''),1844 utf8_files = [('revision-history', ''),
1837 ('branch-name', ''),1845 ('branch-name', ''),
1838 ]1846 ]
1839 return self._initialize_helper(a_bzrdir, utf8_files)1847 return self._initialize_helper(a_bzrdir, utf8_files, name)
18401848
1841 def supports_tags(self):1849 def supports_tags(self):
1842 return False1850 return False
@@ -1864,13 +1872,13 @@
1864 """See BranchFormat.get_format_description()."""1872 """See BranchFormat.get_format_description()."""
1865 return "Branch format 6"1873 return "Branch format 6"
18661874
1867 def initialize(self, a_bzrdir):1875 def initialize(self, a_bzrdir, name=None):
1868 """Create a branch of this format in a_bzrdir."""1876 """Create a branch of this format in a_bzrdir."""
1869 utf8_files = [('last-revision', '0 null:\n'),1877 utf8_files = [('last-revision', '0 null:\n'),
1870 ('branch.conf', ''),1878 ('branch.conf', ''),
1871 ('tags', ''),1879 ('tags', ''),
1872 ]1880 ]
1873 return self._initialize_helper(a_bzrdir, utf8_files)1881 return self._initialize_helper(a_bzrdir, utf8_files, name)
18741882
1875 def make_tags(self, branch):1883 def make_tags(self, branch):
1876 """See bzrlib.branch.BranchFormat.make_tags()."""1884 """See bzrlib.branch.BranchFormat.make_tags()."""
@@ -1894,14 +1902,14 @@
1894 """See BranchFormat.get_format_description()."""1902 """See BranchFormat.get_format_description()."""
1895 return "Branch format 8"1903 return "Branch format 8"
18961904
1897 def initialize(self, a_bzrdir):1905 def initialize(self, a_bzrdir, name=None):
1898 """Create a branch of this format in a_bzrdir."""1906 """Create a branch of this format in a_bzrdir."""
1899 utf8_files = [('last-revision', '0 null:\n'),1907 utf8_files = [('last-revision', '0 null:\n'),
1900 ('branch.conf', ''),1908 ('branch.conf', ''),
1901 ('tags', ''),1909 ('tags', ''),
1902 ('references', '')1910 ('references', '')
1903 ]1911 ]
1904 return self._initialize_helper(a_bzrdir, utf8_files)1912 return self._initialize_helper(a_bzrdir, utf8_files, name)
19051913
1906 def __init__(self):1914 def __init__(self):
1907 super(BzrBranchFormat8, self).__init__()1915 super(BzrBranchFormat8, self).__init__()
@@ -1930,13 +1938,13 @@
1930 This format was introduced in bzr 1.6.1938 This format was introduced in bzr 1.6.
1931 """1939 """
19321940
1933 def initialize(self, a_bzrdir):1941 def initialize(self, a_bzrdir, name=None):
1934 """Create a branch of this format in a_bzrdir."""1942 """Create a branch of this format in a_bzrdir."""
1935 utf8_files = [('last-revision', '0 null:\n'),1943 utf8_files = [('last-revision', '0 null:\n'),
1936 ('branch.conf', ''),1944 ('branch.conf', ''),
1937 ('tags', ''),1945 ('tags', ''),
1938 ]1946 ]
1939 return self._initialize_helper(a_bzrdir, utf8_files)1947 return self._initialize_helper(a_bzrdir, utf8_files, name)
19401948
1941 def _branch_class(self):1949 def _branch_class(self):
1942 return BzrBranch71950 return BzrBranch7
@@ -1984,19 +1992,19 @@
1984 transport = a_bzrdir.get_branch_transport(None)1992 transport = a_bzrdir.get_branch_transport(None)
1985 location = transport.put_bytes('location', to_branch.base)1993 location = transport.put_bytes('location', to_branch.base)
19861994
1987 def initialize(self, a_bzrdir, target_branch=None):1995 def initialize(self, a_bzrdir, name=None, target_branch=None):
1988 """Create a branch of this format in a_bzrdir."""1996 """Create a branch of this format in a_bzrdir."""
1989 if target_branch is None:1997 if target_branch is None:
1990 # this format does not implement branch itself, thus the implicit1998 # this format does not implement branch itself, thus the implicit
1991 # creation contract must see it as uninitializable1999 # creation contract must see it as uninitializable
1992 raise errors.UninitializableFormat(self)2000 raise errors.UninitializableFormat(self)
1993 mutter('creating branch reference in %s', a_bzrdir.transport.base)2001 mutter('creating branch reference in %s', a_bzrdir.transport.base)
1994 branch_transport = a_bzrdir.get_branch_transport(self)2002 branch_transport = a_bzrdir.get_branch_transport(self, name=name)
1995 branch_transport.put_bytes('location',2003 branch_transport.put_bytes('location',
1996 target_branch.bzrdir.root_transport.base)2004 target_branch.bzrdir.root_transport.base)
1997 branch_transport.put_bytes('format', self.get_format_string())2005 branch_transport.put_bytes('format', self.get_format_string())
1998 return self.open(2006 return self.open(
1999 a_bzrdir, _found=True,2007 a_bzrdir, name, _found=True,
2000 possible_transports=[target_branch.bzrdir.root_transport])2008 possible_transports=[target_branch.bzrdir.root_transport])
20012009
2002 def __init__(self):2010 def __init__(self):
@@ -2009,17 +2017,18 @@
2009 def clone(to_bzrdir, revision_id=None,2017 def clone(to_bzrdir, revision_id=None,
2010 repository_policy=None):2018 repository_policy=None):
2011 """See Branch.clone()."""2019 """See Branch.clone()."""
2012 return format.initialize(to_bzrdir, a_branch)2020 return format.initialize(to_bzrdir, target_branch=a_branch)
2013 # cannot obey revision_id limits when cloning a reference ...2021 # cannot obey revision_id limits when cloning a reference ...
2014 # FIXME RBC 20060210 either nuke revision_id for clone, or2022 # FIXME RBC 20060210 either nuke revision_id for clone, or
2015 # emit some sort of warning/error to the caller ?!2023 # emit some sort of warning/error to the caller ?!
2016 return clone2024 return clone
20172025
2018 def open(self, a_bzrdir, _found=False, location=None,2026 def open(self, a_bzrdir, name=None, _found=False, location=None,
2019 possible_transports=None, ignore_fallbacks=False):2027 possible_transports=None, ignore_fallbacks=False):
2020 """Return the branch that the branch reference in a_bzrdir points at.2028 """Return the branch that the branch reference in a_bzrdir points at.
20212029
2022 :param a_bzrdir: A BzrDir that contains a branch.2030 :param a_bzrdir: A BzrDir that contains a branch.
2031 :param name: Name of colocated branch to open, if any
2023 :param _found: a private parameter, do not use it. It is used to2032 :param _found: a private parameter, do not use it. It is used to
2024 indicate if format probing has already be done.2033 indicate if format probing has already be done.
2025 :param ignore_fallbacks: when set, no fallback branches will be opened2034 :param ignore_fallbacks: when set, no fallback branches will be opened
@@ -2030,7 +2039,7 @@
2030 :param possible_transports: An optional reusable transports list.2039 :param possible_transports: An optional reusable transports list.
2031 """2040 """
2032 if not _found:2041 if not _found:
2033 format = BranchFormat.find_format(a_bzrdir)2042 format = BranchFormat.find_format(a_bzrdir, name=name)
2034 if format.__class__ != self.__class__:2043 if format.__class__ != self.__class__:
2035 raise AssertionError("wrong format %r found for %r" %2044 raise AssertionError("wrong format %r found for %r" %
2036 (format, self))2045 (format, self))
@@ -2038,7 +2047,8 @@
2038 location = self.get_reference(a_bzrdir)2047 location = self.get_reference(a_bzrdir)
2039 real_bzrdir = bzrdir.BzrDir.open(2048 real_bzrdir = bzrdir.BzrDir.open(
2040 location, possible_transports=possible_transports)2049 location, possible_transports=possible_transports)
2041 result = real_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)2050 result = real_bzrdir.open_branch(name=name,
2051 ignore_fallbacks=ignore_fallbacks)
2042 # this changes the behaviour of result.clone to create a new reference2052 # this changes the behaviour of result.clone to create a new reference
2043 # rather than a copy of the content of the branch.2053 # rather than a copy of the content of the branch.
2044 # I did not use a proxy object because that needs much more extensive2054 # I did not use a proxy object because that needs much more extensive
20452055
=== modified file 'bzrlib/branchbuilder.py'
--- bzrlib/branchbuilder.py 2009-08-05 02:12:22 +0000
+++ bzrlib/branchbuilder.py 2010-04-06 07:24:41 +0000
@@ -103,11 +103,11 @@
103 finally:103 finally:
104 tree.unlock()104 tree.unlock()
105105
106 def _do_commit(self, tree, message=None, **kwargs):106 def _do_commit(self, tree, message=None, message_callback=None, **kwargs):
107 reporter = commit.NullCommitReporter()107 reporter = commit.NullCommitReporter()
108 if message is None:108 if message is None and message_callback is None:
109 message = u'commit %d' % (self._branch.revno() + 1,)109 message = u'commit %d' % (self._branch.revno() + 1,)
110 return tree.commit(message,110 return tree.commit(message, message_callback=message_callback,
111 reporter=reporter,111 reporter=reporter,
112 **kwargs)112 **kwargs)
113113
@@ -162,7 +162,7 @@
162162
163 def build_snapshot(self, revision_id, parent_ids, actions,163 def build_snapshot(self, revision_id, parent_ids, actions,
164 message=None, timestamp=None, allow_leftmost_as_ghost=False,164 message=None, timestamp=None, allow_leftmost_as_ghost=False,
165 committer=None, timezone=None):165 committer=None, timezone=None, message_callback=None):
166 """Build a commit, shaped in a specific way.166 """Build a commit, shaped in a specific way.
167167
168 :param revision_id: The handle for the new commit, can be None168 :param revision_id: The handle for the new commit, can be None
@@ -175,6 +175,8 @@
175 ('rename', ('orig-path', 'new-path'))175 ('rename', ('orig-path', 'new-path'))
176 :param message: An optional commit message, if not supplied, a default176 :param message: An optional commit message, if not supplied, a default
177 commit message will be written.177 commit message will be written.
178 :param message_callback: A message callback to use for the commit, as
179 per mutabletree.commit.
178 :param timestamp: If non-None, set the timestamp of the commit to this180 :param timestamp: If non-None, set the timestamp of the commit to this
179 value.181 value.
180 :param timezone: An optional timezone for timestamp.182 :param timezone: An optional timezone for timestamp.
@@ -244,7 +246,8 @@
244 for file_id, content in new_contents.iteritems():246 for file_id, content in new_contents.iteritems():
245 tree.put_file_bytes_non_atomic(file_id, content)247 tree.put_file_bytes_non_atomic(file_id, content)
246 return self._do_commit(tree, message=message, rev_id=revision_id,248 return self._do_commit(tree, message=message, rev_id=revision_id,
247 timestamp=timestamp, timezone=timezone, committer=committer)249 timestamp=timestamp, timezone=timezone, committer=committer,
250 message_callback=message_callback)
248 finally:251 finally:
249 tree.unlock()252 tree.unlock()
250253
251254
=== modified file 'bzrlib/btree_index.py'
--- bzrlib/btree_index.py 2009-11-07 01:58:11 +0000
+++ bzrlib/btree_index.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/bugtracker.py'
--- bzrlib/bugtracker.py 2010-01-08 07:37:25 +0000
+++ bzrlib/bugtracker.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py 2010-02-15 20:23:34 +0000
+++ bzrlib/builtins.py 2010-04-06 07:24:41 +0000
@@ -699,10 +699,15 @@
699699
700 def run(self, dir_list):700 def run(self, dir_list):
701 for d in dir_list:701 for d in dir_list:
702 os.mkdir(d)
703 wt, dd = WorkingTree.open_containing(d)702 wt, dd = WorkingTree.open_containing(d)
704 wt.add([dd])703 base = os.path.dirname(dd)
705 self.outf.write('added %s\n' % d)704 id = wt.path2id(base)
705 if id != None:
706 os.mkdir(d)
707 wt.add([dd])
708 self.outf.write('added %s\n' % d)
709 else:
710 raise errors.NotVersionedError(path=base)
706711
707712
708class cmd_relpath(Command):713class cmd_relpath(Command):
@@ -2684,7 +2689,7 @@
2684 if old_default_rules is not None:2689 if old_default_rules is not None:
2685 # dump the rules and exit2690 # dump the rules and exit
2686 for pattern in ignores.OLD_DEFAULTS:2691 for pattern in ignores.OLD_DEFAULTS:
2687 print pattern2692 self.outf.write("%s\n" % pattern)
2688 return2693 return
2689 if not name_pattern_list:2694 if not name_pattern_list:
2690 raise errors.BzrCommandError("ignore requires at least one "2695 raise errors.BzrCommandError("ignore requires at least one "
@@ -2706,13 +2711,13 @@
2706 if id is not None:2711 if id is not None:
2707 filename = entry[0]2712 filename = entry[0]
2708 if ignored.match(filename):2713 if ignored.match(filename):
2709 matches.append(filename.encode('utf-8'))2714 matches.append(filename)
2710 tree.unlock()2715 tree.unlock()
2711 if len(matches) > 0:2716 if len(matches) > 0:
2712 print "Warning: the following files are version controlled and" \2717 self.outf.write("Warning: the following files are version controlled and"
2713 " match your ignore pattern:\n%s" \2718 " match your ignore pattern:\n%s"
2714 "\nThese files will continue to be version controlled" \2719 "\nThese files will continue to be version controlled"
2715 " unless you 'bzr remove' them." % ("\n".join(matches),)2720 " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
27162721
27172722
2718class cmd_ignored(Command):2723class cmd_ignored(Command):
@@ -2756,9 +2761,10 @@
2756 try:2761 try:
2757 revno = int(revno)2762 revno = int(revno)
2758 except ValueError:2763 except ValueError:
2759 raise errors.BzrCommandError("not a valid revision-number: %r" % revno)2764 raise errors.BzrCommandError("not a valid revision-number: %r"
27602765 % revno)
2761 print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)2766 revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2767 self.outf.write("%s\n" % revid)
27622768
27632769
2764class cmd_export(Command):2770class cmd_export(Command):
@@ -2800,9 +2806,12 @@
2800 Option('root',2806 Option('root',
2801 type=str,2807 type=str,
2802 help="Name of the root directory inside the exported file."),2808 help="Name of the root directory inside the exported file."),
2809 Option('per-file-timestamps',
2810 help='Set modification time of files to that of the last '
2811 'revision in which it was changed.'),
2803 ]2812 ]
2804 def run(self, dest, branch_or_subdir=None, revision=None, format=None,2813 def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2805 root=None, filters=False):2814 root=None, filters=False, per_file_timestamps=False):
2806 from bzrlib.export import export2815 from bzrlib.export import export
28072816
2808 if branch_or_subdir is None:2817 if branch_or_subdir is None:
@@ -2815,7 +2824,8 @@
28152824
2816 rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)2825 rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2817 try:2826 try:
2818 export(rev_tree, dest, format, root, subdir, filtered=filters)2827 export(rev_tree, dest, format, root, subdir, filtered=filters,
2828 per_file_timestamps=per_file_timestamps)
2819 except errors.NoSuchExportFormat, e:2829 except errors.NoSuchExportFormat, e:
2820 raise errors.BzrCommandError('Unsupported export format: %s' % e.format)2830 raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
28212831
@@ -2911,7 +2921,7 @@
2911 hidden = True2921 hidden = True
2912 @display_command2922 @display_command
2913 def run(self):2923 def run(self):
2914 print osutils.local_time_offset()2924 self.outf.write("%s\n" % osutils.local_time_offset())
29152925
29162926
29172927
@@ -3168,10 +3178,11 @@
3168 raise errors.BzrCommandError("Commit refused because there are"3178 raise errors.BzrCommandError("Commit refused because there are"
3169 " unknown files in the working tree.")3179 " unknown files in the working tree.")
3170 except errors.BoundBranchOutOfDate, e:3180 except errors.BoundBranchOutOfDate, e:
3171 raise errors.BzrCommandError(str(e) + "\n"3181 e.extra_help = ("\n"
3172 'To commit to master branch, run update and then commit.\n'3182 'To commit to master branch, run update and then commit.\n'
3173 'You can also pass --local to commit to continue working '3183 'You can also pass --local to commit to continue working '
3174 'disconnected.')3184 'disconnected.')
3185 raise
31753186
31763187
3177class cmd_check(Command):3188class cmd_check(Command):
@@ -3339,7 +3350,7 @@
33393350
3340 @display_command3351 @display_command
3341 def printme(self, branch):3352 def printme(self, branch):
3342 print branch.nick3353 self.outf.write('%s\n' % branch.nick)
33433354
33443355
3345class cmd_alias(Command):3356class cmd_alias(Command):
@@ -3619,7 +3630,7 @@
36193630
3620 @display_command3631 @display_command
3621 def run(self):3632 def run(self):
3622 print "It sure does!"3633 self.outf.write("It sure does!\n")
36233634
36243635
3625class cmd_find_merge_base(Command):3636class cmd_find_merge_base(Command):
@@ -3645,7 +3656,7 @@
3645 graph = branch1.repository.get_graph(branch2.repository)3656 graph = branch1.repository.get_graph(branch2.repository)
3646 base_rev_id = graph.find_unique_lca(last1, last2)3657 base_rev_id = graph.find_unique_lca(last1, last2)
36473658
3648 print 'merge base is revision %s' % base_rev_id3659 self.outf.write('merge base is revision %s\n' % base_rev_id)
36493660
36503661
3651class cmd_merge(Command):3662class cmd_merge(Command):
@@ -4444,11 +4455,11 @@
4444 doc = '(no description)'4455 doc = '(no description)'
4445 result.append((name_ver, doc, plugin.path()))4456 result.append((name_ver, doc, plugin.path()))
4446 for name_ver, doc, path in sorted(result):4457 for name_ver, doc, path in sorted(result):
4447 print name_ver4458 self.outf.write("%s\n" % name_ver)
4448 print ' ', doc4459 self.outf.write(" %s\n" % doc)
4449 if verbose:4460 if verbose:
4450 print ' ', path4461 self.outf.write(" %s\n" % path)
4451 print4462 self.outf.write("\n")
44524463
44534464
4454class cmd_testament(Command):4465class cmd_testament(Command):
@@ -4734,12 +4745,11 @@
4734 rev_id = b.get_rev_id(revno)4745 rev_id = b.get_rev_id(revno)
47354746
4736 if rev_id is None or _mod_revision.is_null(rev_id):4747 if rev_id is None or _mod_revision.is_null(rev_id):
4737 ui.ui_factory.note('No revisions to uncommit.')4748 self.outf.write('No revisions to uncommit.\n')
4738 return 14749 return 1
47394750
4740 log_collector = ui.ui_factory.make_output_stream()
4741 lf = log_formatter('short',4751 lf = log_formatter('short',
4742 to_file=log_collector,4752 to_file=self.outf,
4743 show_timezone='original')4753 show_timezone='original')
47444754
4745 show_log(b,4755 show_log(b,
@@ -4750,21 +4760,22 @@
4750 end_revision=last_revno)4760 end_revision=last_revno)
47514761
4752 if dry_run:4762 if dry_run:
4753 ui.ui_factory.note('Dry-run, pretending to remove the above revisions.')4763 self.outf.write('Dry-run, pretending to remove'
4764 ' the above revisions.\n')
4754 else:4765 else:
4755 ui.ui_factory.note('The above revision(s) will be removed.')4766 self.outf.write('The above revision(s) will be removed.\n')
47564767
4757 if not force:4768 if not force:
4758 if not ui.ui_factory.get_boolean('Are you sure [y/N]? '):4769 if not ui.ui_factory.get_boolean('Are you sure'):
4759 ui.ui_factory.note('Canceled')4770 self.outf.write('Canceled')
4760 return 04771 return 0
47614772
4762 mutter('Uncommitting from {%s} to {%s}',4773 mutter('Uncommitting from {%s} to {%s}',
4763 last_rev_id, rev_id)4774 last_rev_id, rev_id)
4764 uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,4775 uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4765 revno=revno, local=local)4776 revno=revno, local=local)
4766 ui.ui_factory.note('You can restore the old tip by running:\n'4777 self.outf.write('You can restore the old tip by running:\n'
4767 ' bzr pull . -r revid:%s' % last_rev_id)4778 ' bzr pull . -r revid:%s\n' % last_rev_id)
47684779
47694780
4770class cmd_break_lock(Command):4781class cmd_break_lock(Command):
47714782
=== modified file 'bzrlib/bundle/__init__.py'
--- bzrlib/bundle/__init__.py 2009-11-28 00:48:03 +0000
+++ bzrlib/bundle/__init__.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/bzrdir.py'
--- bzrlib/bzrdir.py 2010-02-18 04:04:19 +0000
+++ bzrlib/bzrdir.py 2010-04-06 07:24:41 +0000
@@ -396,16 +396,23 @@
396 """Destroy the repository in this BzrDir"""396 """Destroy the repository in this BzrDir"""
397 raise NotImplementedError(self.destroy_repository)397 raise NotImplementedError(self.destroy_repository)
398398
399 def create_branch(self):399 def create_branch(self, name=None):
400 """Create a branch in this BzrDir.400 """Create a branch in this BzrDir.
401401
402 :param name: Name of the colocated branch to create, None for
403 the default branch.
404
402 The bzrdir's format will control what branch format is created.405 The bzrdir's format will control what branch format is created.
403 For more control see BranchFormatXX.create(a_bzrdir).406 For more control see BranchFormatXX.create(a_bzrdir).
404 """407 """
405 raise NotImplementedError(self.create_branch)408 raise NotImplementedError(self.create_branch)
406409
407 def destroy_branch(self):410 def destroy_branch(self, name=None):
408 """Destroy the branch in this BzrDir"""411 """Destroy a branch in this BzrDir.
412
413 :param name: Name of the branch to destroy, None for the default
414 branch.
415 """
409 raise NotImplementedError(self.destroy_branch)416 raise NotImplementedError(self.destroy_branch)
410417
411 @staticmethod418 @staticmethod
@@ -708,7 +715,7 @@
708 """715 """
709 return None716 return None
710717
711 def get_branch_transport(self, branch_format):718 def get_branch_transport(self, branch_format, name=None):
712 """Get the transport for use by branch format in this BzrDir.719 """Get the transport for use by branch format in this BzrDir.
713720
714 Note that bzr dirs that do not support format strings will raise721 Note that bzr dirs that do not support format strings will raise
@@ -892,7 +899,8 @@
892 BzrDir._check_supported(format, _unsupported)899 BzrDir._check_supported(format, _unsupported)
893 return format.open(transport, _found=True)900 return format.open(transport, _found=True)
894901
895 def open_branch(self, unsupported=False, ignore_fallbacks=False):902 def open_branch(self, name=None, unsupported=False,
903 ignore_fallbacks=False):
896 """Open the branch object at this BzrDir if one is present.904 """Open the branch object at this BzrDir if one is present.
897905
898 If unsupported is True, then no longer supported branch formats can906 If unsupported is True, then no longer supported branch formats can
@@ -1036,7 +1044,7 @@
1036 """1044 """
1037 raise NotImplementedError(self.open_workingtree)1045 raise NotImplementedError(self.open_workingtree)
10381046
1039 def has_branch(self):1047 def has_branch(self, name=None):
1040 """Tell if this bzrdir contains a branch.1048 """Tell if this bzrdir contains a branch.
10411049
1042 Note: if you're going to open the branch, you should just go ahead1050 Note: if you're going to open the branch, you should just go ahead
@@ -1044,7 +1052,7 @@
1044 branch and discards it, and that's somewhat expensive.)1052 branch and discards it, and that's somewhat expensive.)
1045 """1053 """
1046 try:1054 try:
1047 self.open_branch()1055 self.open_branch(name)
1048 return True1056 return True
1049 except errors.NotBranchError:1057 except errors.NotBranchError:
1050 return False1058 return False
@@ -1373,11 +1381,11 @@
1373 tree.clone(result)1381 tree.clone(result)
1374 return result1382 return result
13751383
1376 def create_branch(self):1384 def create_branch(self, name=None):
1377 """See BzrDir.create_branch."""1385 """See BzrDir.create_branch."""
1378 return self._format.get_branch_format().initialize(self)1386 return self._format.get_branch_format().initialize(self, name=name)
13791387
1380 def destroy_branch(self):1388 def destroy_branch(self, name=None):
1381 """See BzrDir.destroy_branch."""1389 """See BzrDir.destroy_branch."""
1382 raise errors.UnsupportedOperation(self.destroy_branch, self)1390 raise errors.UnsupportedOperation(self.destroy_branch, self)
13831391
@@ -1439,8 +1447,10 @@
1439 raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,1447 raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1440 self)1448 self)
14411449
1442 def get_branch_transport(self, branch_format):1450 def get_branch_transport(self, branch_format, name=None):
1443 """See BzrDir.get_branch_transport()."""1451 """See BzrDir.get_branch_transport()."""
1452 if name is not None:
1453 raise errors.NoColocatedBranchSupport(self)
1444 if branch_format is None:1454 if branch_format is None:
1445 return self.transport1455 return self.transport
1446 try:1456 try:
@@ -1479,12 +1489,13 @@
1479 format = BzrDirFormat.get_default_format()1489 format = BzrDirFormat.get_default_format()
1480 return not isinstance(self._format, format.__class__)1490 return not isinstance(self._format, format.__class__)
14811491
1482 def open_branch(self, unsupported=False, ignore_fallbacks=False):1492 def open_branch(self, name=None, unsupported=False,
1493 ignore_fallbacks=False):
1483 """See BzrDir.open_branch."""1494 """See BzrDir.open_branch."""
1484 from bzrlib.branch import BzrBranchFormat41495 from bzrlib.branch import BzrBranchFormat4
1485 format = BzrBranchFormat4()1496 format = BzrBranchFormat4()
1486 self._check_supported(format, unsupported)1497 self._check_supported(format, unsupported)
1487 return format.open(self, _found=True)1498 return format.open(self, name, _found=True)
14881499
1489 def sprout(self, url, revision_id=None, force_new_repo=False,1500 def sprout(self, url, revision_id=None, force_new_repo=False,
1490 possible_transports=None, accelerator_tree=None,1501 possible_transports=None, accelerator_tree=None,
@@ -1607,12 +1618,14 @@
1607 """See BzrDir.can_convert_format()."""1618 """See BzrDir.can_convert_format()."""
1608 return True1619 return True
16091620
1610 def create_branch(self):1621 def create_branch(self, name=None):
1611 """See BzrDir.create_branch."""1622 """See BzrDir.create_branch."""
1612 return self._format.get_branch_format().initialize(self)1623 return self._format.get_branch_format().initialize(self, name=name)
16131624
1614 def destroy_branch(self):1625 def destroy_branch(self, name=None):
1615 """See BzrDir.create_branch."""1626 """See BzrDir.create_branch."""
1627 if name is not None:
1628 raise errors.NoColocatedBranchSupport(self)
1616 self.transport.delete_tree('branch')1629 self.transport.delete_tree('branch')
16171630
1618 def create_repository(self, shared=False):1631 def create_repository(self, shared=False):
@@ -1661,8 +1674,10 @@
1661 format = BranchFormat.find_format(self)1674 format = BranchFormat.find_format(self)
1662 return format.get_reference(self)1675 return format.get_reference(self)
16631676
1664 def get_branch_transport(self, branch_format):1677 def get_branch_transport(self, branch_format, name=None):
1665 """See BzrDir.get_branch_transport()."""1678 """See BzrDir.get_branch_transport()."""
1679 if name is not None:
1680 raise errors.NoColocatedBranchSupport(self)
1666 # XXX: this shouldn't implicitly create the directory if it's just1681 # XXX: this shouldn't implicitly create the directory if it's just
1667 # promising to get a transport -- mbp 200907271682 # promising to get a transport -- mbp 20090727
1668 if branch_format is None:1683 if branch_format is None:
@@ -1739,13 +1754,11 @@
1739 return True1754 return True
1740 except errors.NoRepositoryPresent:1755 except errors.NoRepositoryPresent:
1741 pass1756 pass
1742 try:1757 for branch in self.list_branches():
1743 if not isinstance(self.open_branch()._format,1758 if not isinstance(branch._format,
1744 format.get_branch_format().__class__):1759 format.get_branch_format().__class__):
1745 # the branch needs an upgrade.1760 # the branch needs an upgrade.
1746 return True1761 return True
1747 except errors.NotBranchError:
1748 pass
1749 try:1762 try:
1750 my_wt = self.open_workingtree(recommend_upgrade=False)1763 my_wt = self.open_workingtree(recommend_upgrade=False)
1751 if not isinstance(my_wt._format,1764 if not isinstance(my_wt._format,
@@ -1756,11 +1769,13 @@
1756 pass1769 pass
1757 return False1770 return False
17581771
1759 def open_branch(self, unsupported=False, ignore_fallbacks=False):1772 def open_branch(self, name=None, unsupported=False,
1773 ignore_fallbacks=False):
1760 """See BzrDir.open_branch."""1774 """See BzrDir.open_branch."""
1761 format = self.find_branch_format()1775 format = self.find_branch_format()
1762 self._check_supported(format, unsupported)1776 self._check_supported(format, unsupported)
1763 return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)1777 return format.open(self, name=name,
1778 _found=True, ignore_fallbacks=ignore_fallbacks)
17641779
1765 def open_repository(self, unsupported=False):1780 def open_repository(self, unsupported=False):
1766 """See BzrDir.open_repository."""1781 """See BzrDir.open_repository."""
@@ -1798,6 +1813,8 @@
1798 Once a format is deprecated, just deprecate the initialize and open1813 Once a format is deprecated, just deprecate the initialize and open
1799 methods on the format class. Do not deprecate the object, as the1814 methods on the format class. Do not deprecate the object, as the
1800 object will be created every system load.1815 object will be created every system load.
1816
1817 :cvar colocated_branches: Whether this formats supports colocated branches.
1801 """1818 """
18021819
1803 _default_format = None1820 _default_format = None
@@ -1820,6 +1837,10 @@
18201837
1821 _lock_file_name = 'branch-lock'1838 _lock_file_name = 'branch-lock'
18221839
1840 colocated_branches = False
1841 """Whether co-located branches are supported for this control dir format.
1842 """
1843
1823 # _lock_class must be set in subclasses to the lock type, typ.1844 # _lock_class must be set in subclasses to the lock type, typ.
1824 # TransportLock or LockDir1845 # TransportLock or LockDir
18251846
18261847
=== modified file 'bzrlib/chk_serializer.py'
--- bzrlib/chk_serializer.py 2009-12-03 04:55:02 +0000
+++ bzrlib/chk_serializer.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/cleanup.py'
--- bzrlib/cleanup.py 2010-02-05 03:37:52 +0000
+++ bzrlib/cleanup.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/cmd_version_info.py'
--- bzrlib/cmd_version_info.py 2009-11-16 02:26:32 +0000
+++ bzrlib/cmd_version_info.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2009 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/cmdline.py'
--- bzrlib/cmdline.py 2010-02-12 05:40:17 +0000
+++ bzrlib/cmdline.py 2010-04-06 07:24:41 +0000
@@ -26,16 +26,16 @@
26 def __init__(self, orig):26 def __init__(self, orig):
27 self._iter = iter(orig)27 self._iter = iter(orig)
28 self._pushback_buffer = []28 self._pushback_buffer = []
29 29
30 def next(self):30 def next(self):
31 if len(self._pushback_buffer) > 0:31 if len(self._pushback_buffer) > 0:
32 return self._pushback_buffer.pop()32 return self._pushback_buffer.pop()
33 else:33 else:
34 return self._iter.next()34 return self._iter.next()
35 35
36 def pushback(self, char):36 def pushback(self, char):
37 self._pushback_buffer.append(char)37 self._pushback_buffer.append(char)
38 38
39 def __iter__(self):39 def __iter__(self):
40 return self40 return self
4141
@@ -77,7 +77,7 @@
77 def __init__(self, exit_state):77 def __init__(self, exit_state):
78 self.exit_state = exit_state78 self.exit_state = exit_state
79 self.count = 179 self.count = 1
80 80
81 def process(self, next_char, context):81 def process(self, next_char, context):
82 if next_char == u'\\':82 if next_char == u'\\':
83 self.count += 183 self.count += 1
@@ -104,7 +104,7 @@
104 # let exit_state handle next_char104 # let exit_state handle next_char
105 context.seq.pushback(next_char)105 context.seq.pushback(next_char)
106 return self.exit_state106 return self.exit_state
107 107
108 def finish(self, context):108 def finish(self, context):
109 if self.count > 0:109 if self.count > 0:
110 context.token.append(u'\\' * self.count)110 context.token.append(u'\\' * self.count)
@@ -129,16 +129,16 @@
129 self.allowed_quote_chars = u'"'129 self.allowed_quote_chars = u'"'
130 if single_quotes_allowed:130 if single_quotes_allowed:
131 self.allowed_quote_chars += u"'"131 self.allowed_quote_chars += u"'"
132 132
133 def __iter__(self):133 def __iter__(self):
134 return self134 return self
135 135
136 def next(self):136 def next(self):
137 quoted, token = self._get_token()137 quoted, token = self._get_token()
138 if token is None:138 if token is None:
139 raise StopIteration139 raise StopIteration
140 return quoted, token140 return quoted, token
141 141
142 def _get_token(self):142 def _get_token(self):
143 self.quoted = False143 self.quoted = False
144 self.token = []144 self.token = []
145145
=== modified file 'bzrlib/commands.py'
--- bzrlib/commands.py 2010-02-12 04:02:50 +0000
+++ bzrlib/commands.py 2010-04-06 07:24:41 +0000
@@ -55,6 +55,7 @@
55from bzrlib.hooks import HookPoint, Hooks55from bzrlib.hooks import HookPoint, Hooks
56# Compatibility - Option used to be in commands.56# Compatibility - Option used to be in commands.
57from bzrlib.option import Option57from bzrlib.option import Option
58from bzrlib.plugin import disable_plugins, load_plugins
58from bzrlib import registry59from bzrlib import registry
59from bzrlib.symbol_versioning import (60from bzrlib.symbol_versioning import (
60 deprecated_function,61 deprecated_function,
@@ -198,11 +199,13 @@
198 raise errors.BzrCommandError('unknown command "%s"' % cmd_name)199 raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
199200
200201
201def _get_cmd_object(cmd_name, plugins_override=True):202def _get_cmd_object(cmd_name, plugins_override=True, check_missing=True):
202 """Get a command object.203 """Get a command object.
203204
204 :param cmd_name: The name of the command.205 :param cmd_name: The name of the command.
205 :param plugins_override: Allow plugins to override builtins.206 :param plugins_override: Allow plugins to override builtins.
207 :param check_missing: Look up commands not found in the regular index via
208 the get_missing_command hook.
206 :return: A Command object instance209 :return: A Command object instance
207 :raises KeyError: If no command is found.210 :raises KeyError: If no command is found.
208 """211 """
@@ -218,7 +221,7 @@
218 # We've found a non-plugin command, don't permit it to be221 # We've found a non-plugin command, don't permit it to be
219 # overridden.222 # overridden.
220 break223 break
221 if cmd is None:224 if cmd is None and check_missing:
222 for hook in Command.hooks['get_missing_command']:225 for hook in Command.hooks['get_missing_command']:
223 cmd = hook(cmd_name)226 cmd = hook(cmd_name)
224 if cmd is not None:227 if cmd is not None:
@@ -369,7 +372,7 @@
369 # List of standard options directly supported372 # List of standard options directly supported
370 self.supported_std_options = []373 self.supported_std_options = []
371 self._operation = cleanup.OperationWithCleanups(self.run)374 self._operation = cleanup.OperationWithCleanups(self.run)
372 375
373 def add_cleanup(self, cleanup_func, *args, **kwargs):376 def add_cleanup(self, cleanup_func, *args, **kwargs):
374 """Register a function to call after self.run returns or raises.377 """Register a function to call after self.run returns or raises.
375378
@@ -389,7 +392,7 @@
389 resources (such as writing results to self.outf).392 resources (such as writing results to self.outf).
390 """393 """
391 self._operation.cleanup_now()394 self._operation.cleanup_now()
392 395
393 @deprecated_method(deprecated_in((2, 1, 0)))396 @deprecated_method(deprecated_in((2, 1, 0)))
394 def _maybe_expand_globs(self, file_list):397 def _maybe_expand_globs(self, file_list):
395 """Glob expand file_list if the platform does not do that itself.398 """Glob expand file_list if the platform does not do that itself.
@@ -874,6 +877,11 @@
874 return ret877 return ret
875878
876879
880@deprecated_function(deprecated_in((2, 2, 0)))
881def shlex_split_unicode(unsplit):
882 return cmdline.split(unsplit)
883
884
877def get_alias(cmd, config=None):885def get_alias(cmd, config=None):
878 """Return an expanded alias, or None if no alias exists.886 """Return an expanded alias, or None if no alias exists.
879887
@@ -893,15 +901,21 @@
893 return None901 return None
894902
895903
896def run_bzr(argv):904def run_bzr(argv, load_plugins=load_plugins, disable_plugins=disable_plugins):
897 """Execute a command.905 """Execute a command.
898906
899 argv907 :param argv: The command-line arguments, without the program name from
900 The command-line arguments, without the program name from argv[0]908 argv[0] These should already be decoded. All library/test code calling
901 These should already be decoded. All library/test code calling909 run_bzr should be passing valid strings (don't need decoding).
902 run_bzr should be passing valid strings (don't need decoding).910 :param load_plugins: What function to call when triggering plugin loading.
903911 This function should take no arguments and cause all plugins to be
904 Returns a command status or raises an exception.912 loaded.
913 :param disable_plugins: What function to call when disabling plugin
914 loading. This function should take no arguments and cause all plugin
915 loading to be prohibited (so that code paths in your application that
916 know about some plugins possibly being present will fail to import
917 those plugins even if they are installed.)
918 :return: Returns a command exit code or raises an exception.
905919
906 Special master options: these must come before the command because920 Special master options: these must come before the command because
907 they control how the command is interpreted.921 they control how the command is interpreted.
@@ -972,24 +986,20 @@
972986
973 debug.set_debug_flags_from_config()987 debug.set_debug_flags_from_config()
974988
989 if not opt_no_plugins:
990 load_plugins()
991 else:
992 disable_plugins()
993
975 argv = argv_copy994 argv = argv_copy
976 if (not argv):995 if (not argv):
977 from bzrlib.builtins import cmd_help996 get_cmd_object('help').run_argv_aliases([])
978 cmd_help().run_argv_aliases([])
979 return 0997 return 0
980998
981 if argv[0] == '--version':999 if argv[0] == '--version':
982 from bzrlib.builtins import cmd_version1000 get_cmd_object('version').run_argv_aliases([])
983 cmd_version().run_argv_aliases([])
984 return 01001 return 0
9851002
986 if not opt_no_plugins:
987 from bzrlib.plugin import load_plugins
988 load_plugins()
989 else:
990 from bzrlib.plugin import disable_plugins
991 disable_plugins()
992
993 alias_argv = None1003 alias_argv = None
9941004
995 if not opt_no_aliases:1005 if not opt_no_aliases:
@@ -1159,7 +1169,7 @@
1159 if topic and topic.startswith(self.prefix):1169 if topic and topic.startswith(self.prefix):
1160 topic = topic[len(self.prefix):]1170 topic = topic[len(self.prefix):]
1161 try:1171 try:
1162 cmd = _get_cmd_object(topic)1172 cmd = _get_cmd_object(topic, check_missing=False)
1163 except KeyError:1173 except KeyError:
1164 return []1174 return []
1165 else:1175 else:
11661176
=== modified file 'bzrlib/commit.py'
--- bzrlib/commit.py 2009-10-15 02:53:30 +0000
+++ bzrlib/commit.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/conflicts.py'
--- bzrlib/conflicts.py 2010-02-11 09:51:03 +0000
+++ bzrlib/conflicts.py 2010-04-06 07:24:41 +0000
@@ -26,6 +26,7 @@
2626
27from bzrlib import (27from bzrlib import (
28 builtins,28 builtins,
29 cleanup,
29 commands,30 commands,
30 errors,31 errors,
31 osutils,32 osutils,
@@ -479,16 +480,43 @@
479 def associated_filenames(self):480 def associated_filenames(self):
480 return [self.path + suffix for suffix in ('.BASE', '.OTHER')]481 return [self.path + suffix for suffix in ('.BASE', '.OTHER')]
481482
482 # FIXME: I smell something weird here and it seems we should be able to be483 def _take_it(self, tt, suffix_to_remove):
483 # more coherent with some other conflict ? bzr *did* a choice there but484 """Resolve the conflict.
484 # neither action_take_this nor action_take_other reflect that...485
485 # -- vila 20091224486 :param tt: The TreeTransform where the conflict is resolved.
487 :param suffix_to_remove: Either 'THIS' or 'OTHER'
488
489 The resolution is symmetric, when taking THIS, OTHER is deleted and
490 item.THIS is renamed into item and vice-versa.
491 """
492 try:
493 # Delete 'item.THIS' or 'item.OTHER' depending on
494 # suffix_to_remove
495 tt.delete_contents(
496 tt.trans_id_tree_path(self.path + '.' + suffix_to_remove))
497 except errors.NoSuchFile:
498 # There are valid cases where 'item.suffix_to_remove' either
499 # never existed or was already deleted (including the case
500 # where the user deleted it)
501 pass
502 # Rename 'item.suffix_to_remove' (note that if
503 # 'item.suffix_to_remove' has been deleted, this is a no-op)
504 this_tid = tt.trans_id_file_id(self.file_id)
505 parent_tid = tt.get_tree_parent(this_tid)
506 tt.adjust_path(self.path, parent_tid, this_tid)
507 tt.apply()
508
509 def _take_it_with_cleanups(self, tree, suffix_to_remove):
510 tt = transform.TreeTransform(tree)
511 op = cleanup.OperationWithCleanups(self._take_it)
512 op.add_cleanup(tt.finalize)
513 op.run_simple(tt, suffix_to_remove)
514
486 def action_take_this(self, tree):515 def action_take_this(self, tree):
487 tree.remove([self.path + '.OTHER'], force=True, keep_files=False)516 self._take_it_with_cleanups(tree, 'OTHER')
488517
489 def action_take_other(self, tree):518 def action_take_other(self, tree):
490 tree.remove([self.path], force=True, keep_files=False)519 self._take_it_with_cleanups(tree, 'THIS')
491
492520
493521
494# FIXME: TextConflict is about a single file-id, there never is a conflict_path522# FIXME: TextConflict is about a single file-id, there never is a conflict_path
495523
=== modified file 'bzrlib/decorators.py'
--- bzrlib/decorators.py 2010-01-20 16:05:28 +0000
+++ bzrlib/decorators.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/delta.py'
--- bzrlib/delta.py 2009-10-29 05:54:49 +0000
+++ bzrlib/delta.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/diff.py'
--- bzrlib/diff.py 2010-02-02 06:30:43 +0000
+++ bzrlib/diff.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2006 Canonical Ltd.1# Copyright (C) 2005-2010 Canonical Ltd.
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/doc_generate/autodoc_rstx.py'
--- bzrlib/doc_generate/autodoc_rstx.py 2010-01-08 07:34:31 +0000
+++ bzrlib/doc_generate/autodoc_rstx.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006-2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/errors.py'
--- bzrlib/errors.py 2010-01-20 22:32:07 +0000
+++ bzrlib/errors.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -1297,12 +1297,13 @@
1297class BoundBranchOutOfDate(BzrError):1297class BoundBranchOutOfDate(BzrError):
12981298
1299 _fmt = ("Bound branch %(branch)s is out of date with master branch"1299 _fmt = ("Bound branch %(branch)s is out of date with master branch"
1300 " %(master)s.")1300 " %(master)s.%(extra_help)s")
13011301
1302 def __init__(self, branch, master):1302 def __init__(self, branch, master):
1303 BzrError.__init__(self)1303 BzrError.__init__(self)
1304 self.branch = branch1304 self.branch = branch
1305 self.master = master1305 self.master = master
1306 self.extra_help = ''
13061307
13071308
1308class CommitToDoubleBoundBranch(BzrError):1309class CommitToDoubleBoundBranch(BzrError):
@@ -3124,3 +3125,12 @@
31243125
3125 def __init__(self, path):3126 def __init__(self, path):
3126 self.path = path3127 self.path = path
3128
3129
3130class NoColocatedBranchSupport(BzrError):
3131
3132 _fmt = ("%(bzrdir)r does not support co-located branches.")
3133
3134 def __init__(self, bzrdir):
3135 self.bzrdir = bzrdir
3136
31273137
=== modified file 'bzrlib/export/__init__.py'
--- bzrlib/export/__init__.py 2010-01-29 12:04:38 +0000
+++ bzrlib/export/__init__.py 2010-04-06 07:24:41 +0000
@@ -19,7 +19,6 @@
19Such as non-controlled directories, tarfiles, zipfiles, etc.19Such as non-controlled directories, tarfiles, zipfiles, etc.
20"""20"""
2121
22from bzrlib.trace import mutter
23import os22import os
24import bzrlib.errors as errors23import bzrlib.errors as errors
2524
@@ -55,14 +54,16 @@
5554
56 When requesting a specific type of export, load the respective path.55 When requesting a specific type of export, load the respective path.
57 """56 """
58 def _loader(tree, dest, root, subdir, filtered):57 def _loader(tree, dest, root, subdir, filtered, per_file_timestamps):
59 mod = __import__(module, globals(), locals(), [funcname])58 mod = __import__(module, globals(), locals(), [funcname])
60 func = getattr(mod, funcname)59 func = getattr(mod, funcname)
61 return func(tree, dest, root, subdir, filtered=filtered)60 return func(tree, dest, root, subdir, filtered=filtered,
61 per_file_timestamps=per_file_timestamps)
62 register_exporter(scheme, extensions, _loader)62 register_exporter(scheme, extensions, _loader)
6363
6464
65def export(tree, dest, format=None, root=None, subdir=None, filtered=False):65def export(tree, dest, format=None, root=None, subdir=None, filtered=False,
66 per_file_timestamps=False):
66 """Export the given Tree to the specific destination.67 """Export the given Tree to the specific destination.
6768
68 :param tree: A Tree (such as RevisionTree) to export69 :param tree: A Tree (such as RevisionTree) to export
@@ -81,6 +82,9 @@
81 a directory to start exporting from.82 a directory to start exporting from.
82 :param filtered: If True, content filtering is applied to the83 :param filtered: If True, content filtering is applied to the
83 files exported.84 files exported.
85 :param per_file_timestamps: Whether to use the timestamp stored in the
86 tree rather than now(). This will do a revision lookup
87 for every file so will be significantly slower.
84 """88 """
85 global _exporters, _exporter_extensions89 global _exporters, _exporter_extensions
8690
@@ -99,7 +103,8 @@
99 raise errors.NoSuchExportFormat(format)103 raise errors.NoSuchExportFormat(format)
100 tree.lock_read()104 tree.lock_read()
101 try:105 try:
102 return _exporters[format](tree, dest, root, subdir, filtered=filtered)106 return _exporters[format](tree, dest, root, subdir, filtered=filtered,
107 per_file_timestamps=per_file_timestamps)
103 finally:108 finally:
104 tree.unlock()109 tree.unlock()
105110
106111
=== modified file 'bzrlib/export/dir_exporter.py'
--- bzrlib/export/dir_exporter.py 2010-02-04 16:06:36 +0000
+++ bzrlib/export/dir_exporter.py 2010-04-06 07:24:41 +0000
@@ -18,7 +18,6 @@
1818
19import errno19import errno
20import os20import os
21import StringIO
22import time21import time
2322
24from bzrlib import errors, osutils23from bzrlib import errors, osutils
@@ -30,7 +29,8 @@
30from bzrlib.trace import mutter29from bzrlib.trace import mutter
3130
3231
33def dir_exporter(tree, dest, root, subdir, filtered=False):32def dir_exporter(tree, dest, root, subdir, filtered=False,
33 per_file_timestamps=False):
34 """Export this tree to a new directory.34 """Export this tree to a new directory.
3535
36 `dest` should either not exist or should be empty. If it does not exist it36 `dest` should either not exist or should be empty. If it does not exist it
@@ -92,4 +92,8 @@
92 out.writelines(chunks)92 out.writelines(chunks)
93 finally:93 finally:
94 out.close()94 out.close()
95 os.utime(fullpath, (now, now))95 if per_file_timestamps:
96 mtime = tree.get_file_mtime(tree.path2id(relpath), relpath)
97 else:
98 mtime = now
99 os.utime(fullpath, (mtime, mtime))
96100
=== modified file 'bzrlib/export/tar_exporter.py'
--- bzrlib/export/tar_exporter.py 2009-03-23 14:59:43 +0000
+++ bzrlib/export/tar_exporter.py 2010-04-06 07:24:41 +0000
@@ -17,13 +17,12 @@
17"""Export a Tree to a non-versioned directory.17"""Export a Tree to a non-versioned directory.
18"""18"""
1919
20import os
21import StringIO20import StringIO
22import sys21import sys
23import tarfile22import tarfile
24import time23import time
2524
26from bzrlib import errors, export, osutils25from bzrlib import export, osutils
27from bzrlib.export import _export_iter_entries26from bzrlib.export import _export_iter_entries
28from bzrlib.filters import (27from bzrlib.filters import (
29 ContentFilterContext,28 ContentFilterContext,
@@ -32,7 +31,8 @@
32from bzrlib.trace import mutter31from bzrlib.trace import mutter
3332
3433
35def tar_exporter(tree, dest, root, subdir, compression=None, filtered=False):34def tar_exporter(tree, dest, root, subdir, compression=None, filtered=False,
35 per_file_timestamps=False):
36 """Export this tree to a new tar file.36 """Export this tree to a new tar file.
3737
38 `dest` will be created holding the contents of this tree; if it38 `dest` will be created holding the contents of this tree; if it
@@ -52,7 +52,10 @@
52 for dp, ie in _export_iter_entries(tree, subdir):52 for dp, ie in _export_iter_entries(tree, subdir):
53 filename = osutils.pathjoin(root, dp).encode('utf8')53 filename = osutils.pathjoin(root, dp).encode('utf8')
54 item = tarfile.TarInfo(filename)54 item = tarfile.TarInfo(filename)
55 item.mtime = now55 if per_file_timestamps:
56 item.mtime = tree.get_file_mtime(ie.file_id, dp)
57 else:
58 item.mtime = now
56 if ie.kind == "file":59 if ie.kind == "file":
57 item.type = tarfile.REGTYPE60 item.type = tarfile.REGTYPE
58 if tree.is_executable(ie.file_id):61 if tree.is_executable(ie.file_id):
@@ -89,9 +92,13 @@
89 ball.close()92 ball.close()
9093
9194
92def tgz_exporter(tree, dest, root, subdir, filtered=False):95def tgz_exporter(tree, dest, root, subdir, filtered=False,
93 tar_exporter(tree, dest, root, subdir, compression='gz', filtered=filtered)96 per_file_timestamps=False):
9497 tar_exporter(tree, dest, root, subdir, compression='gz',
9598 filtered=filtered, per_file_timestamps=per_file_timestamps)
96def tbz_exporter(tree, dest, root, subdir, filtered=False):99
97 tar_exporter(tree, dest, root, subdir, compression='bz2', filtered=filtered)100
101def tbz_exporter(tree, dest, root, subdir, filtered=False,
102 per_file_timestamps=False):
103 tar_exporter(tree, dest, root, subdir, compression='bz2',
104 filtered=filtered, per_file_timestamps=per_file_timestamps)
98105
=== modified file 'bzrlib/export/zip_exporter.py'
--- bzrlib/export/zip_exporter.py 2009-11-25 00:14:05 +0000
+++ bzrlib/export/zip_exporter.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2005, 2006, 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -42,7 +42,8 @@
42_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT42_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT
4343
4444
45def zip_exporter(tree, dest, root, subdir, filtered=False):45def zip_exporter(tree, dest, root, subdir, filtered=False,
46 per_file_timestamps=False):
46 """ Export this tree to a new zip file.47 """ Export this tree to a new zip file.
4748
48 `dest` will be created holding the contents of this tree; if it49 `dest` will be created holding the contents of this tree; if it
@@ -62,11 +63,15 @@
6263
63 # zipfile.ZipFile switches all paths to forward64 # zipfile.ZipFile switches all paths to forward
64 # slashes anyway, so just stick with that.65 # slashes anyway, so just stick with that.
66 if per_file_timestamps:
67 mtime = tree.get_file_mtime(ie.file_id, dp)
68 else:
69 mtime = now
65 filename = osutils.pathjoin(root, dp).encode('utf8')70 filename = osutils.pathjoin(root, dp).encode('utf8')
66 if ie.kind == "file":71 if ie.kind == "file":
67 zinfo = zipfile.ZipInfo(72 zinfo = zipfile.ZipInfo(
68 filename=filename,73 filename=filename,
69 date_time=now)74 date_time=mtime)
70 zinfo.compress_type = compression75 zinfo.compress_type = compression
71 zinfo.external_attr = _FILE_ATTR76 zinfo.external_attr = _FILE_ATTR
72 if filtered:77 if filtered:
@@ -84,14 +89,14 @@
84 # not just empty files.89 # not just empty files.
85 zinfo = zipfile.ZipInfo(90 zinfo = zipfile.ZipInfo(
86 filename=filename + '/',91 filename=filename + '/',
87 date_time=now)92 date_time=mtime)
88 zinfo.compress_type = compression93 zinfo.compress_type = compression
89 zinfo.external_attr = _DIR_ATTR94 zinfo.external_attr = _DIR_ATTR
90 zipf.writestr(zinfo,'')95 zipf.writestr(zinfo,'')
91 elif ie.kind == "symlink":96 elif ie.kind == "symlink":
92 zinfo = zipfile.ZipInfo(97 zinfo = zipfile.ZipInfo(
93 filename=(filename + '.lnk'),98 filename=(filename + '.lnk'),
94 date_time=now)99 date_time=mtime)
95 zinfo.compress_type = compression100 zinfo.compress_type = compression
96 zinfo.external_attr = _FILE_ATTR101 zinfo.external_attr = _FILE_ATTR
97 zipf.writestr(zinfo, ie.symlink_target)102 zipf.writestr(zinfo, ie.symlink_target)
98103
=== modified file 'bzrlib/globbing.py'
--- bzrlib/globbing.py 2010-01-11 16:44:02 +0000
+++ bzrlib/globbing.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2008 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
22
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/graph.py'
--- bzrlib/graph.py 2009-11-30 03:16:22 +0000
+++ bzrlib/graph.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/groupcompress.py'
--- bzrlib/groupcompress.py 2009-12-01 03:35:25 +0000
+++ bzrlib/groupcompress.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/help.py'
--- bzrlib/help.py 2009-12-02 15:24:34 +0000
+++ bzrlib/help.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2006 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/help_topics/en/authentication.txt'
--- bzrlib/help_topics/en/authentication.txt 2010-01-03 03:33:10 +0000
+++ bzrlib/help_topics/en/authentication.txt 2010-04-06 07:24:41 +0000
@@ -58,10 +58,10 @@
58against a host. But, by using ``.htaccess`` files, for example, it is possible58against a host. But, by using ``.htaccess`` files, for example, it is possible
59to define several (``user, realm, password``) for a given ``host``. So what is59to define several (``user, realm, password``) for a given ``host``. So what is
60really needed is (``user``, ``password``, ``host``, ``path``). The ``realm`` is60really needed is (``user``, ``password``, ``host``, ``path``). The ``realm`` is
61not taken into account in the defitions, but will displayed if bzr prompts you61not taken into account in the definitions, but will displayed if bzr prompts
62for a password.62you for a password.
6363
64``HTTP proxy`` can be handled as ``HTTP`` (or ``HTTPS``) by explicitely64``HTTP proxy`` can be handled as ``HTTP`` (or ``HTTPS``) by explicitly
65specifying the appropriate port.65specifying the appropriate port.
6666
67To take all schemes into account, the password will be deduced from a set of67To take all schemes into account, the password will be deduced from a set of
@@ -165,7 +165,7 @@
165Source hosting provider165Source hosting provider
166~~~~~~~~~~~~~~~~~~~~~~~166~~~~~~~~~~~~~~~~~~~~~~~
167167
168In the shp.net (fictious) domain, each project has its own site::168In the shp.net (fictitious) domain, each project has its own site::
169169
170 [shpnet domain]170 [shpnet domain]
171 # we use sftp, but ssh is the scheme used for authentication171 # we use sftp, but ssh is the scheme used for authentication
172172
=== modified file 'bzrlib/help_topics/en/configuration.txt'
--- bzrlib/help_topics/en/configuration.txt 2010-01-03 03:33:10 +0000
+++ bzrlib/help_topics/en/configuration.txt 2010-04-06 07:24:41 +0000
@@ -116,7 +116,49 @@
116Overriding the default site plugin directory:116Overriding the default site plugin directory:
117``BZR_PLUGIN_PATH='/path/to/my/site/plugins:-site':+user``117``BZR_PLUGIN_PATH='/path/to/my/site/plugins:-site':+user``
118118
119119BZR_DISABLE_PLUGINS
120~~~~~~~~~~~~~~~~~~~
121
122Under special circumstances (mostly when trying to diagnose a
123bug), it's better to disable a plugin (or several) rather than
124uninstalling them completely. Such plugins can be specified in
125the ``BZR_DISABLE_PLUGINS`` environment variable.
126
127In that case, ``bzr`` will stop loading the specified plugins and
128will raise an import error if you try to import them explicitly.
129
130Example:
131~~~~~~~~
132
133Disabling ``myplugin`` and ``yourplugin``:
134``BZR_DISABLE_PLUGINS='myplugin:yourplugin'``
135
136BZR_PLUGINS_AT
137~~~~~~~~~~~~~~
138
139When adding a new feature or working on a bug in a plugin,
140developers often need to use a specific version of a given
141plugin. Since python requires that the directory containing the
142code is named like the plugin itself this make it impossible to
143use arbitrary directory names (using a two-level directory scheme
144is inconvenient). ``BZR_PLUGINS_AT`` allows such directories even
145if they don't appear in ``BZR_PLUGIN_PATH`` .
146
147Plugins specified in this environment variable takes precedence
148over the ones in ``BZR_PLUGIN_PATH``.
149
150The variable specified a list of ``plugin_name@plugin path``,
151``plugin_name`` being the name of the plugin as it appears in
152python module paths, ``plugin_path`` being the path to the
153directory containing the plugin code itself
154(i.e. ``plugins/myplugin`` not ``plugins``). Use ':' as the list
155separator, use ';' on windows.
156
157Example:
158~~~~~~~~
159
160Using a specific version of ``myplugin``:
161``BZR_PLUGINS_AT='myplugin@/home/me/bugfixes/123456-myplugin``
120162
121BZRPATH163BZRPATH
122~~~~~~~164~~~~~~~
123165
=== modified file 'bzrlib/hooks.py'
--- bzrlib/hooks.py 2010-01-15 03:58:20 +0000
+++ bzrlib/hooks.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/index.py'
--- bzrlib/index.py 2009-12-02 17:59:15 +0000
+++ bzrlib/index.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/info.py'
--- bzrlib/info.py 2009-11-03 09:32:17 +0000
+++ bzrlib/info.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/inventory.py'
--- bzrlib/inventory.py 2009-11-13 19:19:11 +0000
+++ bzrlib/inventory.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/lockdir.py'
--- bzrlib/lockdir.py 2010-01-15 02:27:31 +0000
+++ bzrlib/lockdir.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -252,7 +252,7 @@
252 if info is None:252 if info is None:
253 raise LockFailed(self, "lock was renamed into place, but "253 raise LockFailed(self, "lock was renamed into place, but "
254 "now is missing!")254 "now is missing!")
255 if info['nonce'] != self.nonce:255 if info.get('nonce') != self.nonce:
256 self._trace("rename succeeded, "256 self._trace("rename succeeded, "
257 "but lock is still held by someone else")257 "but lock is still held by someone else")
258 raise LockContention(self)258 raise LockContention(self)
@@ -430,7 +430,7 @@
430 def peek(self):430 def peek(self):
431 """Check if the lock is held by anyone.431 """Check if the lock is held by anyone.
432432
433 If it is held, this returns the lock info structure as a rio Stanza,433 If it is held, this returns the lock info structure as a dict
434 which contains some information about the current lock holder.434 which contains some information about the current lock holder.
435 Otherwise returns None.435 Otherwise returns None.
436 """436 """
@@ -459,8 +459,14 @@
459 return s.to_string()459 return s.to_string()
460460
461 def _parse_info(self, info_bytes):461 def _parse_info(self, info_bytes):
462 # TODO: Handle if info_bytes is empty462 stanza = rio.read_stanza(osutils.split_lines(info_bytes))
463 return rio.read_stanza(osutils.split_lines(info_bytes)).as_dict()463 if stanza is None:
464 # see bug 185013; we fairly often end up with the info file being
465 # empty after an interruption; we could log a message here but
466 # there may not be much we can say
467 return {}
468 else:
469 return stanza.as_dict()
464470
465 def attempt_lock(self):471 def attempt_lock(self):
466 """Take the lock; fail if it's already held.472 """Take the lock; fail if it's already held.
@@ -611,11 +617,16 @@
611 def _format_lock_info(self, info):617 def _format_lock_info(self, info):
612 """Turn the contents of peek() into something for the user"""618 """Turn the contents of peek() into something for the user"""
613 lock_url = self.transport.abspath(self.path)619 lock_url = self.transport.abspath(self.path)
614 delta = time.time() - int(info['start_time'])620 start_time = info.get('start_time')
621 if start_time is None:
622 time_ago = '(unknown)'
623 else:
624 time_ago = format_delta(time.time() - int(info['start_time']))
615 return [625 return [
616 'lock %s' % (lock_url,),626 'lock %s' % (lock_url,),
617 'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,627 'held by %s on host %s [process #%s]' %
618 'locked %s' % (format_delta(delta),),628 tuple([info.get(x, '<unknown>') for x in ['user', 'hostname', 'pid']]),
629 'locked %s' % (time_ago,),
619 ]630 ]
620631
621 def validate_token(self, token):632 def validate_token(self, token):
622633
=== modified file 'bzrlib/merge.py'
--- bzrlib/merge.py 2010-02-12 12:22:11 +0000
+++ bzrlib/merge.py 2010-04-06 07:24:41 +0000
@@ -130,7 +130,7 @@
130 """130 """
131 affected_files = self.affected_files131 affected_files = self.affected_files
132 if affected_files is None:132 if affected_files is None:
133 config = self.merger.this_tree.branch.get_config()133 config = self.merger.this_branch.get_config()
134 # Until bzr provides a better policy for caching the config, we134 # Until bzr provides a better policy for caching the config, we
135 # just add the part we're interested in to the params to avoid135 # just add the part we're interested in to the params to avoid
136 # reading the config files repeatedly (bazaar.conf, location.conf,136 # reading the config files repeatedly (bazaar.conf, location.conf,
@@ -1173,6 +1173,7 @@
1173 return 'conflict'1173 return 'conflict'
11741174
1175 @staticmethod1175 @staticmethod
1176 @deprecated_method(deprecated_in((2, 2, 0)))
1176 def scalar_three_way(this_tree, base_tree, other_tree, file_id, key):1177 def scalar_three_way(this_tree, base_tree, other_tree, file_id, key):
1177 """Do a three-way test on a scalar.1178 """Do a three-way test on a scalar.
1178 Return "this", "other" or "conflict", depending whether a value wins.1179 Return "this", "other" or "conflict", depending whether a value wins.
11791180
=== modified file 'bzrlib/merge_directive.py'
--- bzrlib/merge_directive.py 2009-11-28 00:48:03 +0000
+++ bzrlib/merge_directive.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/msgeditor.py'
--- bzrlib/msgeditor.py 2010-01-12 04:31:02 +0000
+++ bzrlib/msgeditor.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2009 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/osutils.py'
--- bzrlib/osutils.py 2010-02-11 16:32:32 +0000
+++ bzrlib/osutils.py 2010-04-06 07:24:41 +0000
@@ -21,11 +21,11 @@
21 S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)21 S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
22import sys22import sys
23import time23import time
24import codecs
24import warnings25import warnings
2526
26from bzrlib.lazy_import import lazy_import27from bzrlib.lazy_import import lazy_import
27lazy_import(globals(), """28lazy_import(globals(), """
28import codecs
29from datetime import datetime29from datetime import datetime
30import errno30import errno
31from ntpath import (abspath as _nt_abspath,31from ntpath import (abspath as _nt_abspath,
@@ -85,8 +85,11 @@
85# be opened in binary mode, rather than text mode.85# be opened in binary mode, rather than text mode.
86# On other platforms, O_BINARY doesn't exist, because86# On other platforms, O_BINARY doesn't exist, because
87# they always open in binary mode, so it is okay to87# they always open in binary mode, so it is okay to
88# OR with 0 on those platforms88# OR with 0 on those platforms.
89# O_NOINHERIT and O_TEXT exists only on win32 too.
89O_BINARY = getattr(os, 'O_BINARY', 0)90O_BINARY = getattr(os, 'O_BINARY', 0)
91O_TEXT = getattr(os, 'O_TEXT', 0)
92O_NOINHERIT = getattr(os, 'O_NOINHERIT', 0)
9093
9194
92def get_unicode_argv():95def get_unicode_argv():
@@ -663,7 +666,7 @@
663def sha_file_by_name(fname):666def sha_file_by_name(fname):
664 """Calculate the SHA1 of a file by reading the full text"""667 """Calculate the SHA1 of a file by reading the full text"""
665 s = sha()668 s = sha()
666 f = os.open(fname, os.O_RDONLY | O_BINARY)669 f = os.open(fname, os.O_RDONLY | O_BINARY | O_NOINHERIT)
667 try:670 try:
668 while True:671 while True:
669 b = os.read(f, 1<<16)672 b = os.read(f, 1<<16)
@@ -1346,6 +1349,27 @@
1346 normalized_filename = _inaccessible_normalized_filename1349 normalized_filename = _inaccessible_normalized_filename
13471350
13481351
1352def set_signal_handler(signum, handler, restart_syscall=True):
1353 """A wrapper for signal.signal that also calls siginterrupt(signum, False)
1354 on platforms that support that.
1355
1356 :param restart_syscall: if set, allow syscalls interrupted by a signal to
1357 automatically restart (by calling `signal.siginterrupt(signum,
1358 False)`). May be ignored if the feature is not available on this
1359 platform or Python version.
1360 """
1361 old_handler = signal.signal(signum, handler)
1362 if restart_syscall:
1363 try:
1364 siginterrupt = signal.siginterrupt
1365 except AttributeError: # siginterrupt doesn't exist on this platform, or for this version of
1366 # Python.
1367 pass
1368 else:
1369 siginterrupt(signum, False)
1370 return old_handler
1371
1372
1349default_terminal_width = 801373default_terminal_width = 80
1350"""The default terminal width for ttys.1374"""The default terminal width for ttys.
13511375
@@ -1440,12 +1464,21 @@
1440 if width is not None:1464 if width is not None:
1441 os.environ['COLUMNS'] = str(width)1465 os.environ['COLUMNS'] = str(width)
14421466
1443if sys.platform == 'win32':1467
1444 # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from ReadConsoleInput but1468_registered_sigwinch = False
1445 # I've no idea how to plug that in the current design -- vila 200912161469
1446 pass1470def watch_sigwinch():
1447else:1471 """Register for SIGWINCH, once and only once."""
1448 signal.signal(signal.SIGWINCH, _terminal_size_changed)1472 global _registered_sigwinch
1473 if not _registered_sigwinch:
1474 if sys.platform == 'win32':
1475 # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from
1476 # ReadConsoleInput but I've no idea how to plug that in
1477 # the current design -- vila 20091216
1478 pass
1479 else:
1480 set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
1481 _registered_sigwinch = True
14491482
14501483
1451def supports_executable():1484def supports_executable():
@@ -2108,3 +2141,46 @@
2108 else:2141 else:
2109 data, _ = self.encode(object, self.errors)2142 data, _ = self.encode(object, self.errors)
2110 self.stream.write(data)2143 self.stream.write(data)
2144
2145if sys.platform == 'win32':
2146 def open_file(filename, mode='r', bufsize=-1):
2147 """This function is used to override the ``open`` builtin.
2148
2149 But it uses O_NOINHERIT flag so the file handle is not inherited by
2150 child processes. Deleting or renaming a closed file opened with this
2151 function is not blocking child processes.
2152 """
2153 writing = 'w' in mode
2154 appending = 'a' in mode
2155 updating = '+' in mode
2156 binary = 'b' in mode
2157
2158 flags = O_NOINHERIT
2159 # see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx
2160 # for flags for each modes.
2161 if binary:
2162 flags |= O_BINARY
2163 else:
2164 flags |= O_TEXT
2165
2166 if writing:
2167 if updating:
2168 flags |= os.O_RDWR
2169 else:
2170 flags |= os.O_WRONLY
2171 flags |= os.O_CREAT | os.O_TRUNC
2172 elif appending:
2173 if updating:
2174 flags |= os.O_RDWR
2175 else:
2176 flags |= os.O_WRONLY
2177 flags |= os.O_CREAT | os.O_APPEND
2178 else: #reading
2179 if updating:
2180 flags |= os.O_RDWR
2181 else:
2182 flags |= os.O_RDONLY
2183
2184 return os.fdopen(os.open(filename, flags), mode, bufsize)
2185else:
2186 open_file = open
21112187
=== modified file 'bzrlib/patches.py'
--- bzrlib/patches.py 2009-11-03 15:45:56 +0000
+++ bzrlib/patches.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004 - 2006, 2008 Aaron Bentley, Canonical Ltd1# Copyright (C) 2005-2010 Aaron Bentley, Canonical Ltd
2# <aaron.bentley@utoronto.ca>2# <aaron.bentley@utoronto.ca>
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
@@ -250,7 +250,13 @@
250 return shift250 return shift
251251
252252
253def iter_hunks(iter_lines):253def iter_hunks(iter_lines, allow_dirty=False):
254 '''
255 :arg iter_lines: iterable of lines to parse for hunks
256 :kwarg allow_dirty: If True, when we encounter something that is not
257 a hunk header when we're looking for one, assume the rest of the lines
258 are not part of the patch (comments or other junk). Default False
259 '''
254 hunk = None260 hunk = None
255 for line in iter_lines:261 for line in iter_lines:
256 if line == "\n":262 if line == "\n":
@@ -260,7 +266,15 @@
260 continue266 continue
261 if hunk is not None:267 if hunk is not None:
262 yield hunk268 yield hunk
263 hunk = hunk_from_header(line)269 try:
270 hunk = hunk_from_header(line)
271 except MalformedHunkHeader:
272 if allow_dirty:
273 # If the line isn't a hunk header, then we've reached the end
274 # of this patch and there's "junk" at the end. Ignore the
275 # rest of this patch.
276 return
277 raise
264 orig_size = 0278 orig_size = 0
265 mod_size = 0279 mod_size = 0
266 while orig_size < hunk.orig_range or mod_size < hunk.mod_range:280 while orig_size < hunk.orig_range or mod_size < hunk.mod_range:
@@ -339,7 +353,12 @@
339 pos += 1353 pos += 1
340354
341355
342def parse_patch(iter_lines):356def parse_patch(iter_lines, allow_dirty=False):
357 '''
358 :arg iter_lines: iterable of lines to parse
359 :kwarg allow_dirty: If True, allow the patch to have trailing junk.
360 Default False
361 '''
343 iter_lines = iter_lines_handle_nl(iter_lines)362 iter_lines = iter_lines_handle_nl(iter_lines)
344 try:363 try:
345 (orig_name, mod_name) = get_patch_names(iter_lines)364 (orig_name, mod_name) = get_patch_names(iter_lines)
@@ -347,15 +366,29 @@
347 return BinaryPatch(e.orig_name, e.mod_name)366 return BinaryPatch(e.orig_name, e.mod_name)
348 else:367 else:
349 patch = Patch(orig_name, mod_name)368 patch = Patch(orig_name, mod_name)
350 for hunk in iter_hunks(iter_lines):369 for hunk in iter_hunks(iter_lines, allow_dirty):
351 patch.hunks.append(hunk)370 patch.hunks.append(hunk)
352 return patch371 return patch
353372
354373
355def iter_file_patch(iter_lines):374def iter_file_patch(iter_lines, allow_dirty=False):
375 '''
376 :arg iter_lines: iterable of lines to parse for patches
377 :kwarg allow_dirty: If True, allow comments and other non-patch text
378 before the first patch. Note that the algorithm here can only find
379 such text before any patches have been found. Comments after the
380 first patch are stripped away in iter_hunks() if it is also passed
381 allow_dirty=True. Default False.
382 '''
383 ### FIXME: Docstring is not quite true. We allow certain comments no
384 # matter what, If they startwith '===', '***', or '#' Someone should
385 # reexamine this logic and decide if we should include those in
386 # allow_dirty or restrict those to only being before the patch is found
387 # (as allow_dirty does).
356 regex = re.compile(binary_files_re)388 regex = re.compile(binary_files_re)
357 saved_lines = []389 saved_lines = []
358 orig_range = 0390 orig_range = 0
391 beginning = True
359 for line in iter_lines:392 for line in iter_lines:
360 if line.startswith('=== ') or line.startswith('*** '):393 if line.startswith('=== ') or line.startswith('*** '):
361 continue394 continue
@@ -365,7 +398,12 @@
365 if line.startswith('-') or line.startswith(' '):398 if line.startswith('-') or line.startswith(' '):
366 orig_range -= 1399 orig_range -= 1
367 elif line.startswith('--- ') or regex.match(line):400 elif line.startswith('--- ') or regex.match(line):
368 if len(saved_lines) > 0:401 if allow_dirty and beginning:
402 # Patches can have "junk" at the beginning
403 # Stripping junk from the end of patches is handled when we
404 # parse the patch
405 beginning = False
406 elif len(saved_lines) > 0:
369 yield saved_lines407 yield saved_lines
370 saved_lines = []408 saved_lines = []
371 elif line.startswith('@@'):409 elif line.startswith('@@'):
@@ -397,8 +435,15 @@
397 yield last_line435 yield last_line
398436
399437
400def parse_patches(iter_lines):438def parse_patches(iter_lines, allow_dirty=False):
401 return [parse_patch(f.__iter__()) for f in iter_file_patch(iter_lines)]439 '''
440 :arg iter_lines: iterable of lines to parse for patches
441 :kwarg allow_dirty: If True, allow text that's not part of the patch at
442 selected places. This includes comments before and after a patch
443 for instance. Default False.
444 '''
445 return [parse_patch(f.__iter__(), allow_dirty) for f in
446 iter_file_patch(iter_lines, allow_dirty)]
402447
403448
404def difference_index(atext, btext):449def difference_index(atext, btext):
405450
=== modified file 'bzrlib/plugin.py'
--- bzrlib/plugin.py 2010-02-10 02:03:20 +0000
+++ bzrlib/plugin.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2007, 2008, 2010 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -67,15 +67,6 @@
67 return _plugins_disabled67 return _plugins_disabled
6868
6969
70@deprecated_function(deprecated_in((2, 0, 0)))
71def get_default_plugin_path():
72 """Get the DEFAULT_PLUGIN_PATH"""
73 global DEFAULT_PLUGIN_PATH
74 if DEFAULT_PLUGIN_PATH is None:
75 DEFAULT_PLUGIN_PATH = osutils.pathjoin(config.config_dir(), 'plugins')
76 return DEFAULT_PLUGIN_PATH
77
78
79def disable_plugins():70def disable_plugins():
80 """Disable loading plugins.71 """Disable loading plugins.
8172
@@ -100,6 +91,19 @@
100 if path is None:91 if path is None:
101 path = get_standard_plugins_path()92 path = get_standard_plugins_path()
102 _mod_plugins.__path__ = path93 _mod_plugins.__path__ = path
94 PluginImporter.reset()
95 # Set up a blacklist for disabled plugins
96 disabled_plugins = os.environ.get('BZR_DISABLE_PLUGINS', None)
97 if disabled_plugins is not None:
98 for name in disabled_plugins.split(os.pathsep):
99 PluginImporter.blacklist.add('bzrlib.plugins.' + name)
100 # Set up a the specific paths for plugins
101 specific_plugins = os.environ.get('BZR_PLUGINS_AT', None)
102 if specific_plugins is not None:
103 for spec in specific_plugins.split(os.pathsep):
104 plugin_name, plugin_path = spec.split('@')
105 PluginImporter.specific_paths[
106 'bzrlib.plugins.%s' % plugin_name] = plugin_path
103 return path107 return path
104108
105109
@@ -188,12 +192,12 @@
188 paths = []192 paths = []
189 for p in env_paths + defaults:193 for p in env_paths + defaults:
190 if p.startswith('+'):194 if p.startswith('+'):
191 # Resolve reference if they are known195 # Resolve references if they are known
192 try:196 try:
193 p = refs[p[1:]]197 p = refs[p[1:]]
194 except KeyError:198 except KeyError:
195 # Leave them untouched otherwise, user may have paths starting199 # Leave them untouched so user can still use paths starting
196 # with '+'...200 # with '+'
197 pass201 pass
198 _append_new_path(paths, p)202 _append_new_path(paths, p)
199203
@@ -211,7 +215,7 @@
211 files (and whatever other extensions are used in the platform,215 files (and whatever other extensions are used in the platform,
212 such as *.pyd).216 such as *.pyd).
213217
214 load_from_dirs() provides the underlying mechanism and is called with218 load_from_path() provides the underlying mechanism and is called with
215 the default directory list to provide the normal behaviour.219 the default directory list to provide the normal behaviour.
216220
217 :param path: The list of paths to search for plugins. By default,221 :param path: The list of paths to search for plugins. By default,
@@ -240,6 +244,11 @@
240244
241 The python module path for bzrlib.plugins will be modified to be 'dirs'.245 The python module path for bzrlib.plugins will be modified to be 'dirs'.
242 """246 """
247 # Explicitly load the plugins with a specific path
248 for fullname, path in PluginImporter.specific_paths.iteritems():
249 name = fullname[len('bzrlib.plugins.'):]
250 _load_plugin_module(name, path)
251
243 # We need to strip the trailing separators here as well as in the252 # We need to strip the trailing separators here as well as in the
244 # set_plugins_path function because calling code can pass anything in to253 # set_plugins_path function because calling code can pass anything in to
245 # this function, and since it sets plugins.__path__, it should set it to254 # this function, and since it sets plugins.__path__, it should set it to
@@ -259,70 +268,99 @@
259load_from_dirs = load_from_path268load_from_dirs = load_from_path
260269
261270
271def _find_plugin_module(dir, name):
272 """Check if there is a valid python module that can be loaded as a plugin.
273
274 :param dir: The directory where the search is performed.
275 :param path: An existing file path, either a python file or a package
276 directory.
277
278 :return: (name, path, description) name is the module name, path is the
279 file to load and description is the tuple returned by
280 imp.get_suffixes().
281 """
282 path = osutils.pathjoin(dir, name)
283 if os.path.isdir(path):
284 # Check for a valid __init__.py file, valid suffixes depends on -O and
285 # can be .py, .pyc and .pyo
286 for suffix, mode, kind in imp.get_suffixes():
287 if kind not in (imp.PY_SOURCE, imp.PY_COMPILED):
288 # We don't recognize compiled modules (.so, .dll, etc)
289 continue
290 init_path = osutils.pathjoin(path, '__init__' + suffix)
291 if os.path.isfile(init_path):
292 return name, init_path, (suffix, mode, kind)
293 else:
294 for suffix, mode, kind in imp.get_suffixes():
295 if name.endswith(suffix):
296 # Clean up the module name
297 name = name[:-len(suffix)]
298 if kind == imp.C_EXTENSION and name.endswith('module'):
299 name = name[:-len('module')]
300 return name, path, (suffix, mode, kind)
301 # There is no python module here
302 return None, None, (None, None, None)
303
304
305def _load_plugin_module(name, dir):
306 """Load plugin name from dir.
307
308 :param name: The plugin name in the bzrlib.plugins namespace.
309 :param dir: The directory the plugin is loaded from for error messages.
310 """
311 if ('bzrlib.plugins.%s' % name) in PluginImporter.blacklist:
312 return
313 try:
314 exec "import bzrlib.plugins.%s" % name in {}
315 except KeyboardInterrupt:
316 raise
317 except errors.IncompatibleAPI, e:
318 trace.warning("Unable to load plugin %r. It requested API version "
319 "%s of module %s but the minimum exported version is %s, and "
320 "the maximum is %s" %
321 (name, e.wanted, e.api, e.minimum, e.current))
322 except Exception, e:
323 trace.warning("%s" % e)
324 if re.search('\.|-| ', name):
325 sanitised_name = re.sub('[-. ]', '_', name)
326 if sanitised_name.startswith('bzr_'):
327 sanitised_name = sanitised_name[len('bzr_'):]
328 trace.warning("Unable to load %r in %r as a plugin because the "
329 "file path isn't a valid module name; try renaming "
330 "it to %r." % (name, dir, sanitised_name))
331 else:
332 trace.warning('Unable to load plugin %r from %r' % (name, dir))
333 trace.log_exception_quietly()
334 if 'error' in debug.debug_flags:
335 trace.print_exception(sys.exc_info(), sys.stderr)
336
337
262def load_from_dir(d):338def load_from_dir(d):
263 """Load the plugins in directory d.339 """Load the plugins in directory d.
264340
265 d must be in the plugins module path already.341 d must be in the plugins module path already.
342 This function is called once for each directory in the module path.
266 """343 """
267 # Get the list of valid python suffixes for __init__.py?
268 # this includes .py, .pyc, and .pyo (depending on if we are running -O)
269 # but it doesn't include compiled modules (.so, .dll, etc)
270 valid_suffixes = [suffix for suffix, mod_type, flags in imp.get_suffixes()
271 if flags in (imp.PY_SOURCE, imp.PY_COMPILED)]
272 package_entries = ['__init__'+suffix for suffix in valid_suffixes]
273 plugin_names = set()344 plugin_names = set()
274 for f in os.listdir(d):345 for p in os.listdir(d):
275 path = osutils.pathjoin(d, f)346 name, path, desc = _find_plugin_module(d, p)
276 if os.path.isdir(path):347 if name is not None:
277 for entry in package_entries:348 if name == '__init__':
278 # This directory should be a package, and thus added to349 # We do nothing with the __init__.py file in directories from
279 # the list350 # the bzrlib.plugins module path, we may want to, one day
280 if os.path.isfile(osutils.pathjoin(path, entry)):351 # -- vila 20100316.
281 break352 continue # We don't load __init__.py in the plugins dirs
282 else: # This directory is not a package353 elif getattr(_mod_plugins, name, None) is not None:
283 continue354 # The module has already been loaded from another directory
284 else:355 # during a previous call.
285 for suffix_info in imp.get_suffixes():356 # FIXME: There should be a better way to report masked plugins
286 if f.endswith(suffix_info[0]):357 # -- vila 20100316
287 f = f[:-len(suffix_info[0])]358 trace.mutter('Plugin name %s already loaded', name)
288 if suffix_info[2] == imp.C_EXTENSION and f.endswith('module'):
289 f = f[:-len('module')]
290 break
291 else:359 else:
292 continue360 plugin_names.add(name)
293 if f == '__init__':
294 continue # We don't load __init__.py again in the plugin dir
295 elif getattr(_mod_plugins, f, None):
296 trace.mutter('Plugin name %s already loaded', f)
297 else:
298 # trace.mutter('add plugin name %s', f)
299 plugin_names.add(f)
300361
301 for name in plugin_names:362 for name in plugin_names:
302 try:363 _load_plugin_module(name, d)
303 exec "import bzrlib.plugins.%s" % name in {}
304 except KeyboardInterrupt:
305 raise
306 except errors.IncompatibleAPI, e:
307 trace.warning("Unable to load plugin %r. It requested API version "
308 "%s of module %s but the minimum exported version is %s, and "
309 "the maximum is %s" %
310 (name, e.wanted, e.api, e.minimum, e.current))
311 except Exception, e:
312 trace.warning("%s" % e)
313 ## import pdb; pdb.set_trace()
314 if re.search('\.|-| ', name):
315 sanitised_name = re.sub('[-. ]', '_', name)
316 if sanitised_name.startswith('bzr_'):
317 sanitised_name = sanitised_name[len('bzr_'):]
318 trace.warning("Unable to load %r in %r as a plugin because the "
319 "file path isn't a valid module name; try renaming "
320 "it to %r." % (name, d, sanitised_name))
321 else:
322 trace.warning('Unable to load plugin %r from %r' % (name, d))
323 trace.log_exception_quietly()
324 if 'error' in debug.debug_flags:
325 trace.print_exception(sys.exc_info(), sys.stderr)
326364
327365
328def plugins():366def plugins():
@@ -485,3 +523,77 @@
485 return version_string523 return version_string
486524
487 __version__ = property(_get__version__)525 __version__ = property(_get__version__)
526
527
528class _PluginImporter(object):
529 """An importer tailored to bzr specific needs.
530
531 This is a singleton that takes care of:
532 - disabled plugins specified in 'blacklist',
533 - plugins that needs to be loaded from specific directories.
534 """
535
536 def __init__(self):
537 self.reset()
538
539 def reset(self):
540 self.blacklist = set()
541 self.specific_paths = {}
542
543 def find_module(self, fullname, parent_path=None):
544 """Search a plugin module.
545
546 Disabled plugins raise an import error, plugins with specific paths
547 returns a specific loader.
548
549 :return: None if the plugin doesn't need special handling, self
550 otherwise.
551 """
552 if not fullname.startswith('bzrlib.plugins.'):
553 return None
554 if fullname in self.blacklist:
555 raise ImportError('%s is disabled' % fullname)
556 if fullname in self.specific_paths:
557 return self
558 return None
559
560 def load_module(self, fullname):
561 """Load a plugin from a specific directory."""
562 # We are called only for specific paths
563 plugin_path = self.specific_paths[fullname]
564 loading_path = None
565 package = False
566 if os.path.isdir(plugin_path):
567 for suffix, mode, kind in imp.get_suffixes():
568 if kind not in (imp.PY_SOURCE, imp.PY_COMPILED):
569 # We don't recognize compiled modules (.so, .dll, etc)
570 continue
571 init_path = osutils.pathjoin(plugin_path, '__init__' + suffix)
572 if os.path.isfile(init_path):
573 loading_path = init_path
574 package = True
575 break
576 else:
577 for suffix, mode, kind in imp.get_suffixes():
578 if plugin_path.endswith(suffix):
579 loading_path = plugin_path
580 break
581 if loading_path is None:
582 raise ImportError('%s cannot be loaded from %s'
583 % (fullname, plugin_path))
584 f = open(loading_path, mode)
585 try:
586 mod = imp.load_module(fullname, f, loading_path,
587 (suffix, mode, kind))
588 if package:
589 # The plugin can contain modules, so be ready
590 mod.__path__ = [plugin_path]
591 mod.__package__ = fullname
592 return mod
593 finally:
594 f.close()
595
596
597# Install a dedicated importer for plugins requiring special handling
598PluginImporter = _PluginImporter()
599sys.meta_path.append(PluginImporter)
488600
=== modified file 'bzrlib/plugins/launchpad/__init__.py'
--- bzrlib/plugins/launchpad/__init__.py 2010-02-18 04:10:53 +0000
+++ bzrlib/plugins/launchpad/__init__.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 - 2010 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
17"""Launchpad.net integration plugin for Bazaar."""17"""Launchpad.net integration plugin for Bazaar."""
1818
19# The XMLRPC server address can be overridden by setting the environment19# The XMLRPC server address can be overridden by setting the environment
20# variable $BZR_LP_XMLRPL_URL20# variable $BZR_LP_XMLRPC_URL
2121
22# see http://bazaar-vcs.org/Specs/BranchRegistrationTool22# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
2323
2424
=== modified file 'bzrlib/plugins/launchpad/lp_api.py'
--- bzrlib/plugins/launchpad/lp_api.py 2010-02-18 03:44:44 +0000
+++ bzrlib/plugins/launchpad/lp_api.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/plugins/launchpad/lp_directory.py'
--- bzrlib/plugins/launchpad/lp_directory.py 2009-07-03 14:24:23 +0000
+++ bzrlib/plugins/launchpad/lp_directory.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/plugins/launchpad/test_lp_api.py'
--- bzrlib/plugins/launchpad/test_lp_api.py 2010-01-25 17:48:22 +0000
+++ bzrlib/plugins/launchpad/test_lp_api.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/plugins/launchpad/test_lp_directory.py'
--- bzrlib/plugins/launchpad/test_lp_directory.py 2010-01-25 15:55:48 +0000
+++ bzrlib/plugins/launchpad/test_lp_directory.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/plugins/launchpad/test_lp_open.py'
--- bzrlib/plugins/launchpad/test_lp_open.py 2009-12-08 10:04:18 +0000
+++ bzrlib/plugins/launchpad/test_lp_open.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/progress.py'
--- bzrlib/progress.py 2010-02-10 17:52:08 +0000
+++ bzrlib/progress.py 2010-04-06 07:24:41 +0000
@@ -316,8 +316,3 @@
316 else:316 else:
317 self.cur_phase += 1317 self.cur_phase += 1
318 self.pb.update(self.message, self.cur_phase, self.total)318 self.pb.update(self.message, self.cur_phase, self.total)
319
320
321_progress_bar_types = {}
322_progress_bar_types['dummy'] = DummyProgress
323_progress_bar_types['none'] = DummyProgress
324319
=== modified file 'bzrlib/reconcile.py'
--- bzrlib/reconcile.py 2010-01-07 01:30:20 +0000
+++ bzrlib/reconcile.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/reconfigure.py'
--- bzrlib/reconfigure.py 2009-10-06 14:40:37 +0000
+++ bzrlib/reconfigure.py 2010-04-06 07:24:41 +0000
@@ -368,7 +368,7 @@
368 local_branch = self.local_branch368 local_branch = self.local_branch
369 if self._create_reference:369 if self._create_reference:
370 format = branch.BranchReferenceFormat().initialize(self.bzrdir,370 format = branch.BranchReferenceFormat().initialize(self.bzrdir,
371 reference_branch)371 target_branch=reference_branch)
372 if self._destroy_tree:372 if self._destroy_tree:
373 self.bzrdir.destroy_workingtree()373 self.bzrdir.destroy_workingtree()
374 if self._create_tree:374 if self._create_tree:
375375
=== modified file 'bzrlib/remote.py'
--- bzrlib/remote.py 2010-02-13 02:15:58 +0000
+++ bzrlib/remote.py 2010-04-06 07:24:41 +0000
@@ -242,12 +242,14 @@
242 self._ensure_real()242 self._ensure_real()
243 self._real_bzrdir.destroy_repository()243 self._real_bzrdir.destroy_repository()
244244
245 def create_branch(self):245 def create_branch(self, name=None):
246 # as per meta1 formats - just delegate to the format object which may246 # as per meta1 formats - just delegate to the format object which may
247 # be parameterised.247 # be parameterised.
248 real_branch = self._format.get_branch_format().initialize(self)248 real_branch = self._format.get_branch_format().initialize(self,
249 name=name)
249 if not isinstance(real_branch, RemoteBranch):250 if not isinstance(real_branch, RemoteBranch):
250 result = RemoteBranch(self, self.find_repository(), real_branch)251 result = RemoteBranch(self, self.find_repository(), real_branch,
252 name=name)
251 else:253 else:
252 result = real_branch254 result = real_branch
253 # BzrDir.clone_on_transport() uses the result of create_branch but does255 # BzrDir.clone_on_transport() uses the result of create_branch but does
@@ -259,10 +261,10 @@
259 self._next_open_branch_result = result261 self._next_open_branch_result = result
260 return result262 return result
261263
262 def destroy_branch(self):264 def destroy_branch(self, name=None):
263 """See BzrDir.destroy_branch"""265 """See BzrDir.destroy_branch"""
264 self._ensure_real()266 self._ensure_real()
265 self._real_bzrdir.destroy_branch()267 self._real_bzrdir.destroy_branch(name=name)
266 self._next_open_branch_result = None268 self._next_open_branch_result = None
267269
268 def create_workingtree(self, revision_id=None, from_branch=None):270 def create_workingtree(self, revision_id=None, from_branch=None):
@@ -318,8 +320,9 @@
318 """See BzrDir._get_tree_branch()."""320 """See BzrDir._get_tree_branch()."""
319 return None, self.open_branch()321 return None, self.open_branch()
320322
321 def open_branch(self, _unsupported=False, ignore_fallbacks=False):323 def open_branch(self, name=None, unsupported=False,
322 if _unsupported:324 ignore_fallbacks=False):
325 if unsupported:
323 raise NotImplementedError('unsupported flag support not implemented yet.')326 raise NotImplementedError('unsupported flag support not implemented yet.')
324 if self._next_open_branch_result is not None:327 if self._next_open_branch_result is not None:
325 # See create_branch for details.328 # See create_branch for details.
@@ -330,14 +333,14 @@
330 if response[0] == 'ref':333 if response[0] == 'ref':
331 # a branch reference, use the existing BranchReference logic.334 # a branch reference, use the existing BranchReference logic.
332 format = BranchReferenceFormat()335 format = BranchReferenceFormat()
333 return format.open(self, _found=True, location=response[1],336 return format.open(self, name=name, _found=True,
334 ignore_fallbacks=ignore_fallbacks)337 location=response[1], ignore_fallbacks=ignore_fallbacks)
335 branch_format_name = response[1]338 branch_format_name = response[1]
336 if not branch_format_name:339 if not branch_format_name:
337 branch_format_name = None340 branch_format_name = None
338 format = RemoteBranchFormat(network_name=branch_format_name)341 format = RemoteBranchFormat(network_name=branch_format_name)
339 return RemoteBranch(self, self.find_repository(), format=format,342 return RemoteBranch(self, self.find_repository(), format=format,
340 setup_stacking=not ignore_fallbacks)343 setup_stacking=not ignore_fallbacks, name=name)
341344
342 def _open_repo_v1(self, path):345 def _open_repo_v1(self, path):
343 verb = 'BzrDir.find_repository'346 verb = 'BzrDir.find_repository'
@@ -420,9 +423,9 @@
420 """Return the path to be used for this bzrdir in a remote call."""423 """Return the path to be used for this bzrdir in a remote call."""
421 return client.remote_path_from_transport(self.root_transport)424 return client.remote_path_from_transport(self.root_transport)
422425
423 def get_branch_transport(self, branch_format):426 def get_branch_transport(self, branch_format, name=None):
424 self._ensure_real()427 self._ensure_real()
425 return self._real_bzrdir.get_branch_transport(branch_format)428 return self._real_bzrdir.get_branch_transport(branch_format, name=name)
426429
427 def get_repository_transport(self, repository_format):430 def get_repository_transport(self, repository_format):
428 self._ensure_real()431 self._ensure_real()
@@ -1229,10 +1232,11 @@
1229 return self._real_repository.add_inventory(revid, inv, parents)1232 return self._real_repository.add_inventory(revid, inv, parents)
12301233
1231 def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,1234 def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1232 parents):1235 parents, basis_inv=None, propagate_caches=False):
1233 self._ensure_real()1236 self._ensure_real()
1234 return self._real_repository.add_inventory_by_delta(basis_revision_id,1237 return self._real_repository.add_inventory_by_delta(basis_revision_id,
1235 delta, new_revision_id, parents)1238 delta, new_revision_id, parents, basis_inv=basis_inv,
1239 propagate_caches=propagate_caches)
12361240
1237 def add_revision(self, rev_id, rev, inv=None, config=None):1241 def add_revision(self, rev_id, rev, inv=None, config=None):
1238 self._ensure_real()1242 self._ensure_real()
@@ -2021,26 +2025,29 @@
2021 def network_name(self):2025 def network_name(self):
2022 return self._network_name2026 return self._network_name
20232027
2024 def open(self, a_bzrdir, ignore_fallbacks=False):2028 def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2025 return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)2029 return a_bzrdir.open_branch(name=name,
2030 ignore_fallbacks=ignore_fallbacks)
20262031
2027 def _vfs_initialize(self, a_bzrdir):2032 def _vfs_initialize(self, a_bzrdir, name):
2028 # Initialisation when using a local bzrdir object, or a non-vfs init2033 # Initialisation when using a local bzrdir object, or a non-vfs init
2029 # method is not available on the server.2034 # method is not available on the server.
2030 # self._custom_format is always set - the start of initialize ensures2035 # self._custom_format is always set - the start of initialize ensures
2031 # that.2036 # that.
2032 if isinstance(a_bzrdir, RemoteBzrDir):2037 if isinstance(a_bzrdir, RemoteBzrDir):
2033 a_bzrdir._ensure_real()2038 a_bzrdir._ensure_real()
2034 result = self._custom_format.initialize(a_bzrdir._real_bzrdir)2039 result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2040 name)
2035 else:2041 else:
2036 # We assume the bzrdir is parameterised; it may not be.2042 # We assume the bzrdir is parameterised; it may not be.
2037 result = self._custom_format.initialize(a_bzrdir)2043 result = self._custom_format.initialize(a_bzrdir, name)
2038 if (isinstance(a_bzrdir, RemoteBzrDir) and2044 if (isinstance(a_bzrdir, RemoteBzrDir) and
2039 not isinstance(result, RemoteBranch)):2045 not isinstance(result, RemoteBranch)):
2040 result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)2046 result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2047 name=name)
2041 return result2048 return result
20422049
2043 def initialize(self, a_bzrdir):2050 def initialize(self, a_bzrdir, name=None):
2044 # 1) get the network name to use.2051 # 1) get the network name to use.
2045 if self._custom_format:2052 if self._custom_format:
2046 network_name = self._custom_format.network_name()2053 network_name = self._custom_format.network_name()
@@ -2052,20 +2059,23 @@
2052 network_name = reference_format.network_name()2059 network_name = reference_format.network_name()
2053 # Being asked to create on a non RemoteBzrDir:2060 # Being asked to create on a non RemoteBzrDir:
2054 if not isinstance(a_bzrdir, RemoteBzrDir):2061 if not isinstance(a_bzrdir, RemoteBzrDir):
2055 return self._vfs_initialize(a_bzrdir)2062 return self._vfs_initialize(a_bzrdir, name=name)
2056 medium = a_bzrdir._client._medium2063 medium = a_bzrdir._client._medium
2057 if medium._is_remote_before((1, 13)):2064 if medium._is_remote_before((1, 13)):
2058 return self._vfs_initialize(a_bzrdir)2065 return self._vfs_initialize(a_bzrdir, name=name)
2059 # Creating on a remote bzr dir.2066 # Creating on a remote bzr dir.
2060 # 2) try direct creation via RPC2067 # 2) try direct creation via RPC
2061 path = a_bzrdir._path_for_remote_call(a_bzrdir._client)2068 path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2069 if name is not None:
2070 # XXX JRV20100304: Support creating colocated branches
2071 raise errors.NoColocatedBranchSupport(self)
2062 verb = 'BzrDir.create_branch'2072 verb = 'BzrDir.create_branch'
2063 try:2073 try:
2064 response = a_bzrdir._call(verb, path, network_name)2074 response = a_bzrdir._call(verb, path, network_name)
2065 except errors.UnknownSmartMethod:2075 except errors.UnknownSmartMethod:
2066 # Fallback - use vfs methods2076 # Fallback - use vfs methods
2067 medium._remember_remote_is_before((1, 13))2077 medium._remember_remote_is_before((1, 13))
2068 return self._vfs_initialize(a_bzrdir)2078 return self._vfs_initialize(a_bzrdir, name=name)
2069 if response[0] != 'ok':2079 if response[0] != 'ok':
2070 raise errors.UnexpectedSmartServerResponse(response)2080 raise errors.UnexpectedSmartServerResponse(response)
2071 # Turn the response into a RemoteRepository object.2081 # Turn the response into a RemoteRepository object.
@@ -2079,7 +2089,7 @@
2079 a_bzrdir._client)2089 a_bzrdir._client)
2080 remote_repo = RemoteRepository(repo_bzrdir, repo_format)2090 remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2081 remote_branch = RemoteBranch(a_bzrdir, remote_repo,2091 remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2082 format=format, setup_stacking=False)2092 format=format, setup_stacking=False, name=name)
2083 # XXX: We know this is a new branch, so it must have revno 0, revid2093 # XXX: We know this is a new branch, so it must have revno 0, revid
2084 # NULL_REVISION. Creating the branch locked would make this be unable2094 # NULL_REVISION. Creating the branch locked would make this be unable
2085 # to be wrong; here its simply very unlikely to be wrong. RBC 200902252095 # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
@@ -2112,7 +2122,7 @@
2112 """2122 """
21132123
2114 def __init__(self, remote_bzrdir, remote_repository, real_branch=None,2124 def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2115 _client=None, format=None, setup_stacking=True):2125 _client=None, format=None, setup_stacking=True, name=None):
2116 """Create a RemoteBranch instance.2126 """Create a RemoteBranch instance.
21172127
2118 :param real_branch: An optional local implementation of the branch2128 :param real_branch: An optional local implementation of the branch
@@ -2124,6 +2134,7 @@
2124 :param setup_stacking: If True make an RPC call to determine the2134 :param setup_stacking: If True make an RPC call to determine the
2125 stacked (or not) status of the branch. If False assume the branch2135 stacked (or not) status of the branch. If False assume the branch
2126 is not stacked.2136 is not stacked.
2137 :param name: Colocated branch name
2127 """2138 """
2128 # We intentionally don't call the parent class's __init__, because it2139 # We intentionally don't call the parent class's __init__, because it
2129 # will try to assign to self.tags, which is a property in this subclass.2140 # will try to assign to self.tags, which is a property in this subclass.
@@ -2149,6 +2160,7 @@
2149 # Fill out expected attributes of branch for bzrlib API users.2160 # Fill out expected attributes of branch for bzrlib API users.
2150 self._clear_cached_state()2161 self._clear_cached_state()
2151 self.base = self.bzrdir.root_transport.base2162 self.base = self.bzrdir.root_transport.base
2163 self._name = name
2152 self._control_files = None2164 self._control_files = None
2153 self._lock_mode = None2165 self._lock_mode = None
2154 self._lock_token = None2166 self._lock_token = None
@@ -2219,7 +2231,7 @@
2219 'to use vfs implementation')2231 'to use vfs implementation')
2220 self.bzrdir._ensure_real()2232 self.bzrdir._ensure_real()
2221 self._real_branch = self.bzrdir._real_bzrdir.open_branch(2233 self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2222 ignore_fallbacks=self._real_ignore_fallbacks)2234 ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
2223 if self.repository._real_repository is None:2235 if self.repository._real_repository is None:
2224 # Give the remote repository the matching real repo.2236 # Give the remote repository the matching real repo.
2225 real_repo = self._real_branch.repository2237 real_repo = self._real_branch.repository
22262238
=== modified file 'bzrlib/revisionspec.py'
--- bzrlib/revisionspec.py 2009-10-27 14:04:29 +0000
+++ bzrlib/revisionspec.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/revisiontree.py'
--- bzrlib/revisiontree.py 2010-01-20 23:21:35 +0000
+++ bzrlib/revisiontree.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/serializer.py'
--- bzrlib/serializer.py 2009-12-03 04:55:02 +0000
+++ bzrlib/serializer.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/shellcomplete.py'
--- bzrlib/shellcomplete.py 2009-11-02 22:24:29 +0000
+++ bzrlib/shellcomplete.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2005, 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/bzrdir.py'
--- bzrlib/smart/bzrdir.py 2010-01-12 01:10:03 +0000
+++ bzrlib/smart/bzrdir.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/client.py'
--- bzrlib/smart/client.py 2010-01-15 06:55:33 +0000
+++ bzrlib/smart/client.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006-2008 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/medium.py'
--- bzrlib/smart/medium.py 2010-01-15 07:26:46 +0000
+++ bzrlib/smart/medium.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/protocol.py'
--- bzrlib/smart/protocol.py 2009-12-21 17:00:29 +0000
+++ bzrlib/smart/protocol.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/repository.py'
--- bzrlib/smart/repository.py 2010-02-10 02:17:15 +0000
+++ bzrlib/smart/repository.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2010 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/request.py'
--- bzrlib/smart/request.py 2010-01-11 05:58:22 +0000
+++ bzrlib/smart/request.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/server.py'
--- bzrlib/smart/server.py 2010-02-09 20:28:26 +0000
+++ bzrlib/smart/server.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2008 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/smart/vfs.py'
--- bzrlib/smart/vfs.py 2009-10-23 04:22:05 +0000
+++ bzrlib/smart/vfs.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/static_tuple.py'
--- bzrlib/static_tuple.py 2009-11-28 21:54:08 +0000
+++ bzrlib/static_tuple.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/status.py'
--- bzrlib/status.py 2009-12-02 15:24:34 +0000
+++ bzrlib/status.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/switch.py'
--- bzrlib/switch.py 2010-01-12 03:53:21 +0000
+++ bzrlib/switch.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd.1# Copyright (C) 2007, 2009, 2010 Canonical Ltd.
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/TestUtil.py'
--- bzrlib/tests/TestUtil.py 2009-12-05 09:04:19 +0000
+++ bzrlib/tests/TestUtil.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2006 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2# Author: Robert Collins <robert.collins@canonical.com>2# Author: Robert Collins <robert.collins@canonical.com>
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/__init__.py'
--- bzrlib/tests/__init__.py 2010-02-18 02:15:48 +0000
+++ bzrlib/tests/__init__.py 2010-04-06 07:24:41 +0000
@@ -1519,6 +1519,8 @@
1519 'BZR_PROGRESS_BAR': None,1519 'BZR_PROGRESS_BAR': None,
1520 'BZR_LOG': None,1520 'BZR_LOG': None,
1521 'BZR_PLUGIN_PATH': None,1521 'BZR_PLUGIN_PATH': None,
1522 'BZR_DISABLE_PLUGINS': None,
1523 'BZR_PLUGINS_AT': None,
1522 'BZR_CONCURRENCY': None,1524 'BZR_CONCURRENCY': None,
1523 # Make sure that any text ui tests are consistent regardless of1525 # Make sure that any text ui tests are consistent regardless of
1524 # the environment the test case is run in; you may want tests that1526 # the environment the test case is run in; you may want tests that
@@ -1671,7 +1673,33 @@
1671 unicodestr = log_contents.decode('utf8', 'replace')1673 unicodestr = log_contents.decode('utf8', 'replace')
1672 log_contents = unicodestr.encode('utf8')1674 log_contents = unicodestr.encode('utf8')
1673 if not keep_log_file:1675 if not keep_log_file:
1674 self._log_file.close()1676 close_attempts = 0
1677 max_close_attempts = 100
1678 first_close_error = None
1679 while close_attempts < max_close_attempts:
1680 close_attempts += 1
1681 try:
1682 self._log_file.close()
1683 except IOError, ioe:
1684 if ioe.errno is None:
1685 # No errno implies 'close() called during
1686 # concurrent operation on the same file object', so
1687 # retry. Probably a thread is trying to write to
1688 # the log file.
1689 if first_close_error is None:
1690 first_close_error = ioe
1691 continue
1692 raise
1693 else:
1694 break
1695 if close_attempts > 1:
1696 sys.stderr.write(
1697 'Unable to close log file on first attempt, '
1698 'will retry: %s\n' % (first_close_error,))
1699 if close_attempts == max_close_attempts:
1700 sys.stderr.write(
1701 'Unable to close log file after %d attempts.\n'
1702 % (max_close_attempts,))
1675 self._log_file = None1703 self._log_file = None
1676 # Permit multiple calls to get_log until we clean it up in1704 # Permit multiple calls to get_log until we clean it up in
1677 # finishLogFile1705 # finishLogFile
16781706
=== modified file 'bzrlib/tests/blackbox/test_annotate.py'
--- bzrlib/tests/blackbox/test_annotate.py 2010-01-07 12:32:37 +0000
+++ bzrlib/tests/blackbox/test_annotate.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2# -*- coding: utf-8 -*-2# -*- coding: utf-8 -*-
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- bzrlib/tests/blackbox/test_branch.py 2010-02-09 21:29:20 +0000
+++ bzrlib/tests/blackbox/test_branch.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_break_lock.py'
--- bzrlib/tests/blackbox/test_break_lock.py 2009-03-23 14:59:43 +0000
+++ bzrlib/tests/blackbox/test_break_lock.py 2010-04-06 07:24:41 +0000
@@ -60,7 +60,7 @@
60 local_branch.bind(self.master_branch)60 local_branch.bind(self.master_branch)
61 checkoutdir = bzrlib.bzrdir.BzrDir.create('checkout')61 checkoutdir = bzrlib.bzrdir.BzrDir.create('checkout')
62 bzrlib.branch.BranchReferenceFormat().initialize(62 bzrlib.branch.BranchReferenceFormat().initialize(
63 checkoutdir, local_branch)63 checkoutdir, target_branch=local_branch)
64 self.wt = checkoutdir.create_workingtree()64 self.wt = checkoutdir.create_workingtree()
6565
66 def test_break_lock_help(self):66 def test_break_lock_help(self):
6767
=== modified file 'bzrlib/tests/blackbox/test_cat.py'
--- bzrlib/tests/blackbox/test_cat.py 2010-02-11 09:21:45 +0000
+++ bzrlib/tests/blackbox/test_cat.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2# -*- coding: utf-8 -*-2# -*- coding: utf-8 -*-
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/blackbox/test_checkout.py'
--- bzrlib/tests/blackbox/test_checkout.py 2009-12-01 06:07:41 +0000
+++ bzrlib/tests/blackbox/test_checkout.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2009 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_debug.py'
--- bzrlib/tests/blackbox/test_debug.py 2009-12-16 22:29:31 +0000
+++ bzrlib/tests/blackbox/test_debug.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_exceptions.py'
--- bzrlib/tests/blackbox/test_exceptions.py 2009-12-22 23:09:50 +0000
+++ bzrlib/tests/blackbox/test_exceptions.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_export.py'
--- bzrlib/tests/blackbox/test_export.py 2009-11-25 00:14:05 +0000
+++ bzrlib/tests/blackbox/test_export.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2008 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -293,3 +293,13 @@
293 tree.commit('more setup')293 tree.commit('more setup')
294 out, err = self.run_bzr('export exported branch/subdir')294 out, err = self.run_bzr('export exported branch/subdir')
295 self.assertEqual(['foo.txt'], os.listdir('exported'))295 self.assertEqual(['foo.txt'], os.listdir('exported'))
296
297 def test_dir_export_per_file_timestamps(self):
298 tree = self.example_branch()
299 self.build_tree_contents([('branch/har', 'foo')])
300 tree.add('har')
301 tree.commit('setup', timestamp=42)
302 self.run_bzr('export --per-file-timestamps t branch')
303 har_st = os.stat('t/har')
304 self.assertEquals(42, har_st.st_mtime)
305
296306
=== modified file 'bzrlib/tests/blackbox/test_filtered_view_ops.py'
--- bzrlib/tests/blackbox/test_filtered_view_ops.py 2009-12-14 15:51:36 +0000
+++ bzrlib/tests/blackbox/test_filtered_view_ops.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_help.py'
--- bzrlib/tests/blackbox/test_help.py 2010-01-14 16:41:04 +0000
+++ bzrlib/tests/blackbox/test_help.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_ignore.py'
--- bzrlib/tests/blackbox/test_ignore.py 2009-10-23 10:41:15 +0000
+++ bzrlib/tests/blackbox/test_ignore.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_info.py'
--- bzrlib/tests/blackbox/test_info.py 2010-02-18 02:39:23 +0000
+++ bzrlib/tests/blackbox/test_info.py 2010-04-06 07:24:41 +0000
@@ -1228,7 +1228,8 @@
1228 # Do a light checkout of the heavy one1228 # Do a light checkout of the heavy one
1229 transport.mkdir('tree/lightcheckout')1229 transport.mkdir('tree/lightcheckout')
1230 lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')1230 lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1231 branch.BranchReferenceFormat().initialize(lco_dir, co_branch)1231 branch.BranchReferenceFormat().initialize(lco_dir,
1232 target_branch=co_branch)
1232 lco_dir.create_workingtree()1233 lco_dir.create_workingtree()
1233 lco_tree = lco_dir.open_workingtree()1234 lco_tree = lco_dir.open_workingtree()
12341235
12351236
=== modified file 'bzrlib/tests/blackbox/test_init.py'
--- bzrlib/tests/blackbox/test_init.py 2009-11-08 02:23:13 +0000
+++ bzrlib/tests/blackbox/test_init.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_ls.py'
--- bzrlib/tests/blackbox/test_ls.py 2009-11-30 00:33:52 +0000
+++ bzrlib/tests/blackbox/test_ls.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_merge.py'
--- bzrlib/tests/blackbox/test_merge.py 2009-12-10 17:16:19 +0000
+++ bzrlib/tests/blackbox/test_merge.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_mv.py'
--- bzrlib/tests/blackbox/test_mv.py 2009-11-17 01:08:08 +0000
+++ bzrlib/tests/blackbox/test_mv.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_nick.py'
--- bzrlib/tests/blackbox/test_nick.py 2009-03-23 14:59:43 +0000
+++ bzrlib/tests/blackbox/test_nick.py 2010-04-06 07:24:41 +0000
@@ -30,11 +30,11 @@
30 self.make_branch_and_tree('me.dev')30 self.make_branch_and_tree('me.dev')
31 os.chdir('me.dev')31 os.chdir('me.dev')
32 nick = self.run_bzr('nick')[0]32 nick = self.run_bzr('nick')[0]
33 self.assertEqual(nick, 'me.dev\n')33 self.assertEqual('me.dev\n', nick)
34 # set the nickname34 # set the nickname
35 self.run_bzr("nick moo")35 self.run_bzr("nick moo")
36 nick = self.run_bzr('nick')[0]36 nick = self.run_bzr('nick')[0]
37 self.assertEqual(nick, 'moo\n')37 self.assertEqual('moo\n', nick)
3838
39 def test_autonick_urlencoded(self):39 def test_autonick_urlencoded(self):
40 # https://bugs.launchpad.net/bzr/+bug/66857 -- nick was printed40 # https://bugs.launchpad.net/bzr/+bug/66857 -- nick was printed
@@ -42,30 +42,30 @@
42 self.make_branch_and_tree('!repo')42 self.make_branch_and_tree('!repo')
43 os.chdir('!repo')43 os.chdir('!repo')
44 nick = self.run_bzr('nick')[0]44 nick = self.run_bzr('nick')[0]
45 self.assertEqual(nick, '!repo\n')45 self.assertEqual('!repo\n', nick)
4646
47 def test_bound_nick(self):47 def test_bound_nick(self):
48 """Check that nick works well for checkouts."""48 """Check that nick works well for checkouts."""
49 base = self.make_branch_and_tree('base')49 base = self.make_branch_and_tree('base')
50 child = self.make_branch_and_tree('child')50 child = self.make_branch_and_tree('child')
51 os.chdir('child')51 os.chdir('child')
52 self.assertEqual(self.run_bzr('nick')[0][:-1], 'child')52 self.assertEqual('child', self.run_bzr('nick')[0][:-1])
53 self.assertEqual(child.branch.get_config().has_explicit_nickname(),53 self.assertEqual(False,
54 False)54 child.branch.get_config().has_explicit_nickname())
55 self.run_bzr('bind ../base')55 self.run_bzr('bind ../base')
56 self.assertEqual(self.run_bzr('nick')[0][:-1], base.branch.nick)56 self.assertEqual(base.branch.nick, self.run_bzr('nick')[0][:-1])
57 self.assertEqual(child.branch.get_config().has_explicit_nickname(),57 self.assertEqual(False,
58 False)58 child.branch.get_config().has_explicit_nickname())
5959
60 self.run_bzr('unbind')60 self.run_bzr('unbind')
61 self.run_bzr("nick explicit_nick")61 self.run_bzr("nick explicit_nick")
62 self.assertEqual(self.run_bzr('nick')[0][:-1], "explicit_nick")62 self.assertEqual("explicit_nick", self.run_bzr('nick')[0][:-1])
63 self.assertEqual(child.branch.get_config()._get_explicit_nickname(),63 self.assertEqual("explicit_nick",
64 "explicit_nick")64 child.branch.get_config()._get_explicit_nickname())
65 self.run_bzr('bind ../base')65 self.run_bzr('bind ../base')
66 self.assertEqual(self.run_bzr('nick')[0][:-1], base.branch.nick)66 self.assertEqual(base.branch.nick, self.run_bzr('nick')[0][:-1])
67 self.assertEqual(child.branch.get_config()._get_explicit_nickname(),67 self.assertEqual(base.branch.nick,
68 base.branch.nick)68 child.branch.get_config()._get_explicit_nickname())
6969
70 def test_boundless_nick(self):70 def test_boundless_nick(self):
71 """Nick defaults to implicit local nick when bound branch is AWOL"""71 """Nick defaults to implicit local nick when bound branch is AWOL"""
@@ -73,8 +73,8 @@
73 child = self.make_branch_and_tree('child')73 child = self.make_branch_and_tree('child')
74 os.chdir('child')74 os.chdir('child')
75 self.run_bzr('bind ../base')75 self.run_bzr('bind ../base')
76 self.assertEqual(self.run_bzr('nick')[0][:-1], base.branch.nick)76 self.assertEqual(base.branch.nick, self.run_bzr('nick')[0][:-1])
77 self.assertEqual(child.branch.get_config().has_explicit_nickname(),77 self.assertEqual(False,
78 False)78 child.branch.get_config().has_explicit_nickname())
79 osutils.rmtree('../base')79 osutils.rmtree('../base')
80 self.assertEqual(self.run_bzr('nick')[0][:-1], 'child')80 self.assertEqual('child', self.run_bzr('nick')[0][:-1])
8181
=== modified file 'bzrlib/tests/blackbox/test_non_ascii.py'
--- bzrlib/tests/blackbox/test_non_ascii.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/blackbox/test_non_ascii.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_pull.py'
--- bzrlib/tests/blackbox/test_pull.py 2010-01-29 11:17:16 +0000
+++ bzrlib/tests/blackbox/test_pull.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2010 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- bzrlib/tests/blackbox/test_push.py 2010-02-11 09:21:45 +0000
+++ bzrlib/tests/blackbox/test_push.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2007, 2008 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_remerge.py'
--- bzrlib/tests/blackbox/test_remerge.py 2009-12-10 23:11:35 +0000
+++ bzrlib/tests/blackbox/test_remerge.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_send.py'
--- bzrlib/tests/blackbox/test_send.py 2010-02-11 09:21:45 +0000
+++ bzrlib/tests/blackbox/test_send.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2# Authors: Aaron Bentley2# Authors: Aaron Bentley
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/blackbox/test_serve.py'
--- bzrlib/tests/blackbox/test_serve.py 2010-01-07 03:03:01 +0000
+++ bzrlib/tests/blackbox/test_serve.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_shared_repository.py'
--- bzrlib/tests/blackbox/test_shared_repository.py 2010-01-12 01:10:03 +0000
+++ bzrlib/tests/blackbox/test_shared_repository.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_shelve.py'
--- bzrlib/tests/blackbox/test_shelve.py 2009-12-11 05:48:21 +0000
+++ bzrlib/tests/blackbox/test_shelve.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_status.py'
--- bzrlib/tests/blackbox/test_status.py 2009-07-08 14:37:25 +0000
+++ bzrlib/tests/blackbox/test_status.py 2010-04-06 07:24:41 +0000
@@ -498,7 +498,8 @@
498 def make_branch_and_tree(self, relpath):498 def make_branch_and_tree(self, relpath):
499 source = self.make_branch(pathjoin('..', relpath))499 source = self.make_branch(pathjoin('..', relpath))
500 checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)500 checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
501 bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)501 bzrlib.branch.BranchReferenceFormat().initialize(checkout,
502 target_branch=source)
502 return checkout.create_workingtree()503 return checkout.create_workingtree()
503504
504505
505506
=== modified file 'bzrlib/tests/blackbox/test_switch.py'
--- bzrlib/tests/blackbox/test_switch.py 2010-01-12 03:53:21 +0000
+++ bzrlib/tests/blackbox/test_switch.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2# -*- coding: utf-8 -*-2# -*- coding: utf-8 -*-
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/blackbox/test_too_much.py'
--- bzrlib/tests/blackbox/test_too_much.py 2009-12-02 15:24:34 +0000
+++ bzrlib/tests/blackbox/test_too_much.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/blackbox/test_uncommit.py'
--- bzrlib/tests/blackbox/test_uncommit.py 2010-02-10 17:52:08 +0000
+++ bzrlib/tests/blackbox/test_uncommit.py 2010-04-06 07:24:41 +0000
@@ -216,7 +216,7 @@
216216
217 def test_uncommit_shows_log_with_revision_id(self):217 def test_uncommit_shows_log_with_revision_id(self):
218 wt = self.create_simple_tree()218 wt = self.create_simple_tree()
219 219
220 script = ScriptRunner()220 script = ScriptRunner()
221 script.run_script(self, """221 script.run_script(self, """
222$ cd tree222$ cd tree
223223
=== modified file 'bzrlib/tests/blackbox/test_update.py'
--- bzrlib/tests/blackbox/test_update.py 2010-02-10 17:52:08 +0000
+++ bzrlib/tests/blackbox/test_update.py 2010-04-06 07:24:41 +0000
@@ -1,5 +1,4 @@
1# Copyright (C) 2006-2010 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2# -*- coding: utf-8 -*-
3#2#
4# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -196,7 +195,8 @@
196195
197 self.build_tree(['checkout1/'])196 self.build_tree(['checkout1/'])
198 checkout_dir = bzrdir.BzrDirMetaFormat1().initialize('checkout1')197 checkout_dir = bzrdir.BzrDirMetaFormat1().initialize('checkout1')
199 branch.BranchReferenceFormat().initialize(checkout_dir, master.branch)198 branch.BranchReferenceFormat().initialize(checkout_dir,
199 target_branch=master.branch)
200 checkout1 = checkout_dir.create_workingtree('m1')200 checkout1 = checkout_dir.create_workingtree('m1')
201201
202 # Create a second branch, with an extra commit202 # Create a second branch, with an extra commit
@@ -341,6 +341,7 @@
341 # now update (and get conflicts)341 # now update (and get conflicts)
342 out, err = self.run_bzr('update lightweight', retcode=1)342 out, err = self.run_bzr('update lightweight', retcode=1)
343 self.assertEqual('', out)343 self.assertEqual('', out)
344 # NB: these conflicts are actually in the source code
344 self.assertFileEqual('''\345 self.assertFileEqual('''\
345<<<<<<< TREE346<<<<<<< TREE
346lightweight local changes347lightweight local changes
@@ -358,6 +359,7 @@
358 # check we get the second conflict359 # check we get the second conflict
359 out, err = self.run_bzr('update lightweight', retcode=1)360 out, err = self.run_bzr('update lightweight', retcode=1)
360 self.assertEqual('', out)361 self.assertEqual('', out)
362 # NB: these conflicts are actually in the source code
361 self.assertFileEqual('''\363 self.assertFileEqual('''\
362<<<<<<< TREE364<<<<<<< TREE
363lightweight+checkout365lightweight+checkout
@@ -366,4 +368,3 @@
366>>>>>>> MERGE-SOURCE368>>>>>>> MERGE-SOURCE
367''',369''',
368 'lightweight/file')370 'lightweight/file')
369
370371
=== modified file 'bzrlib/tests/blackbox/test_versioning.py'
--- bzrlib/tests/blackbox/test_versioning.py 2009-08-28 05:00:33 +0000
+++ bzrlib/tests/blackbox/test_versioning.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2005, 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -29,16 +29,29 @@
29from bzrlib.workingtree import WorkingTree29from bzrlib.workingtree import WorkingTree
3030
3131
32class TestMkdir(TestCaseWithTransport):
33
34 def test_mkdir_fails_cleanly(self):
35 """'mkdir' fails cleanly when no working tree is available.
36 https://bugs.edge.launchpad.net/bzr/+bug/138600
37 """
38 # Since there is a safety working tree above us, we create a bare repo
39 # here locally.
40 shared_repo = self.make_repository('.')
41 self.run_bzr(['mkdir', 'abc'], retcode=3)
42 self.failIfExists('abc')
43
44
32class TestVersioning(TestCaseInTempDir):45class TestVersioning(TestCaseInTempDir):
3346
34 def test_mkdir(self):47 def test_mkdir(self):
35 """Basic 'bzr mkdir' operation"""48 """Basic 'bzr mkdir' operation"""
3649
37 self.run_bzr('init')50 self.run_bzr('init')
38 self.run_bzr('mkdir foo')51 self.run_bzr(['mkdir', 'foo'])
39 self.assert_(os.path.isdir('foo'))52 self.assert_(os.path.isdir('foo'))
4053
41 self.run_bzr('mkdir foo', retcode=3)54 self.run_bzr(['mkdir', 'foo'], retcode=3)
4255
43 wt = WorkingTree.open('.')56 wt = WorkingTree.open('.')
4457
@@ -54,12 +67,12 @@
54 """'bzr mkdir' operation in subdirectory"""67 """'bzr mkdir' operation in subdirectory"""
5568
56 self.run_bzr('init')69 self.run_bzr('init')
57 self.run_bzr('mkdir dir')70 self.run_bzr(['mkdir', 'dir'])
58 self.assert_(os.path.isdir('dir'))71 self.assert_(os.path.isdir('dir'))
5972
60 os.chdir('dir')73 os.chdir('dir')
61 self.log('Run mkdir in subdir')74 self.log('Run mkdir in subdir')
62 self.run_bzr('mkdir subdir')75 self.run_bzr(['mkdir', 'subdir'])
63 self.assert_(os.path.isdir('subdir'))76 self.assert_(os.path.isdir('subdir'))
64 os.chdir('..')77 os.chdir('..')
6578
@@ -86,7 +99,7 @@
86 self.run_bzr('init')99 self.run_bzr('init')
87 os.chdir('../..')100 os.chdir('../..')
88101
89 self.run_bzr('mkdir dir a/dir a/b/dir')102 self.run_bzr(['mkdir', 'dir', 'a/dir', 'a/b/dir'])
90 self.failUnless(os.path.isdir('dir'))103 self.failUnless(os.path.isdir('dir'))
91 self.failUnless(os.path.isdir('a/dir'))104 self.failUnless(os.path.isdir('a/dir'))
92 self.failUnless(os.path.isdir('a/b/dir'))105 self.failUnless(os.path.isdir('a/b/dir'))
93106
=== modified file 'bzrlib/tests/commands/test_branch.py'
--- bzrlib/tests/commands/test_branch.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_branch.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_cat.py'
--- bzrlib/tests/commands/test_cat.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/commands/test_cat.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_checkout.py'
--- bzrlib/tests/commands/test_checkout.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_checkout.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_commit.py'
--- bzrlib/tests/commands/test_commit.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_commit.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -53,8 +53,7 @@
53 # commit do not provide a directory parameter, we have to change dir53 # commit do not provide a directory parameter, we have to change dir
54 # manually54 # manually
55 os.chdir('local')55 os.chdir('local')
56 # cmd_commit translates BoundBranchOutOfDate into BzrCommandError56 self.assertRaises(errors.BoundBranchOutOfDate, commit.run,
57 self.assertRaises(errors.BzrCommandError, commit.run,
58 message=u'empty commit', unchanged=True)57 message=u'empty commit', unchanged=True)
59 self.assertEquals(1, len(self.connections))58 self.assertEquals(1, len(self.connections))
6059
6160
=== modified file 'bzrlib/tests/commands/test_init.py'
--- bzrlib/tests/commands/test_init.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_init.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_init_repository.py'
--- bzrlib/tests/commands/test_init_repository.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_init_repository.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_merge.py'
--- bzrlib/tests/commands/test_merge.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_merge.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_missing.py'
--- bzrlib/tests/commands/test_missing.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_missing.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_pull.py'
--- bzrlib/tests/commands/test_pull.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_pull.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_push.py'
--- bzrlib/tests/commands/test_push.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_push.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/commands/test_update.py'
--- bzrlib/tests/commands/test_update.py 2010-01-11 12:37:53 +0000
+++ bzrlib/tests/commands/test_update.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/ftp_server/__init__.py'
--- bzrlib/tests/ftp_server/__init__.py 2010-01-07 03:03:01 +0000
+++ bzrlib/tests/ftp_server/__init__.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/ftp_server/medusa_based.py'
--- bzrlib/tests/ftp_server/medusa_based.py 2010-02-09 17:35:07 +0000
+++ bzrlib/tests/ftp_server/medusa_based.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/ftp_server/pyftpdlib_based.py'
--- bzrlib/tests/ftp_server/pyftpdlib_based.py 2010-02-09 17:33:44 +0000
+++ bzrlib/tests/ftp_server/pyftpdlib_based.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/http_server.py'
--- bzrlib/tests/http_server.py 2010-02-09 20:49:50 +0000
+++ bzrlib/tests/http_server.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/http_utils.py'
--- bzrlib/tests/http_utils.py 2010-01-07 03:03:01 +0000
+++ bzrlib/tests/http_utils.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_branch/test_branch.py'
--- bzrlib/tests/per_branch/test_branch.py 2010-02-11 09:27:55 +0000
+++ bzrlib/tests/per_branch/test_branch.py 2010-04-06 07:24:41 +0000
@@ -379,6 +379,23 @@
379 self.assertEqual(committed.properties["branch-nick"],379 self.assertEqual(committed.properties["branch-nick"],
380 "My happy branch")380 "My happy branch")
381381
382 def test_create_colocated(self):
383 try:
384 repo = self.make_repository('.', shared=True)
385 except errors.IncompatibleFormat:
386 return
387 self.assertEquals(0, len(repo.bzrdir.list_branches()))
388 try:
389 child_branch1 = self.branch_format.initialize(repo.bzrdir,
390 name='branch1')
391 except (errors.UninitializableFormat, errors.NoColocatedBranchSupport):
392 # branch references are not default init'able and
393 # not all bzrdirs support colocated branches.
394 return
395 self.assertEquals(1, len(repo.bzrdir.list_branches()))
396 self.branch_format.initialize(repo.bzrdir, name='branch2')
397 self.assertEquals(2, len(repo.bzrdir.list_branches()))
398
382 def test_create_open_branch_uses_repository(self):399 def test_create_open_branch_uses_repository(self):
383 try:400 try:
384 repo = self.make_repository('.', shared=True)401 repo = self.make_repository('.', shared=True)
385402
=== modified file 'bzrlib/tests/per_branch/test_iter_merge_sorted_revisions.py'
--- bzrlib/tests/per_branch/test_iter_merge_sorted_revisions.py 2009-12-03 23:34:38 +0000
+++ bzrlib/tests/per_branch/test_iter_merge_sorted_revisions.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_branch/test_parent.py'
--- bzrlib/tests/per_branch/test_parent.py 2009-11-08 03:00:33 +0000
+++ bzrlib/tests/per_branch/test_parent.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2006 Canonical Ltd1# Copyright (C) 2005, 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_bzrdir/test_bzrdir.py'
--- bzrlib/tests/per_bzrdir/test_bzrdir.py 2010-02-15 22:58:59 +0000
+++ bzrlib/tests/per_bzrdir/test_bzrdir.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -247,11 +247,22 @@
247 try:247 try:
248 bzrdir.destroy_branch()248 bzrdir.destroy_branch()
249 except (errors.UnsupportedOperation, errors.TransportNotPossible):249 except (errors.UnsupportedOperation, errors.TransportNotPossible):
250 raise TestNotApplicable('Format does not support destroying tree')250 raise TestNotApplicable('Format does not support destroying branch')
251 self.assertRaises(errors.NotBranchError, bzrdir.open_branch)251 self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
252 bzrdir.create_branch()252 bzrdir.create_branch()
253 bzrdir.open_branch()253 bzrdir.open_branch()
254254
255 def test_destroy_colocated_branch(self):
256 branch = self.make_branch('branch')
257 bzrdir = branch.bzrdir
258 try:
259 colo_branch = bzrdir.create_branch('colo')
260 except errors.NoColocatedBranchSupport:
261 raise TestNotApplicable('BzrDir does not do colocated branches')
262 bzrdir.destroy_branch("colo")
263 self.assertRaises(errors.NotBranchError, bzrdir.open_branch,
264 "colo")
265
255 def test_destroy_repository(self):266 def test_destroy_repository(self):
256 repo = self.make_repository('repository')267 repo = self.make_repository('repository')
257 bzrdir = repo.bzrdir268 bzrdir = repo.bzrdir
@@ -523,7 +534,7 @@
523 dir = self.make_bzrdir('source')534 dir = self.make_bzrdir('source')
524 try:535 try:
525 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,536 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
526 referenced_branch)537 target_branch=referenced_branch)
527 except errors.IncompatibleFormat:538 except errors.IncompatibleFormat:
528 # this is ok too, not all formats have to support references.539 # this is ok too, not all formats have to support references.
529 return540 return
@@ -626,7 +637,7 @@
626 dir = self.make_bzrdir('source')637 dir = self.make_bzrdir('source')
627 try:638 try:
628 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,639 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
629 referenced_branch)640 target_branch=referenced_branch)
630 except errors.IncompatibleFormat:641 except errors.IncompatibleFormat:
631 # this is ok too, not all formats have to support references.642 # this is ok too, not all formats have to support references.
632 return643 return
@@ -691,7 +702,7 @@
691 dir = self.make_bzrdir('source')702 dir = self.make_bzrdir('source')
692 try:703 try:
693 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,704 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
694 referenced_branch)705 target_branch=referenced_branch)
695 except errors.IncompatibleFormat:706 except errors.IncompatibleFormat:
696 # this is ok too, not all formats have to support references.707 # this is ok too, not all formats have to support references.
697 return708 return
@@ -966,7 +977,7 @@
966 dir = self.make_bzrdir('source')977 dir = self.make_bzrdir('source')
967 try:978 try:
968 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,979 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
969 referenced_branch)980 target_branch=referenced_branch)
970 except errors.IncompatibleFormat:981 except errors.IncompatibleFormat:
971 # this is ok too, not all formats have to support references.982 # this is ok too, not all formats have to support references.
972 return983 return
@@ -986,7 +997,7 @@
986 dir = self.make_bzrdir('source')997 dir = self.make_bzrdir('source')
987 try:998 try:
988 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,999 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
989 referenced_tree.branch)1000 target_branch=referenced_tree.branch)
990 except errors.IncompatibleFormat:1001 except errors.IncompatibleFormat:
991 # this is ok too, not all formats have to support references.1002 # this is ok too, not all formats have to support references.
992 return1003 return
@@ -1012,7 +1023,7 @@
1012 dir = self.make_bzrdir('source')1023 dir = self.make_bzrdir('source')
1013 try:1024 try:
1014 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,1025 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
1015 referenced_tree.branch)1026 target_branch=referenced_tree.branch)
1016 except errors.IncompatibleFormat:1027 except errors.IncompatibleFormat:
1017 # this is ok too, not all formats have to support references.1028 # this is ok too, not all formats have to support references.
1018 return1029 return
@@ -1077,7 +1088,7 @@
1077 dir = self.make_bzrdir('source')1088 dir = self.make_bzrdir('source')
1078 try:1089 try:
1079 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,1090 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
1080 referenced_branch)1091 target_branch=referenced_branch)
1081 except errors.IncompatibleFormat:1092 except errors.IncompatibleFormat:
1082 # this is ok too, not all formats have to support references.1093 # this is ok too, not all formats have to support references.
1083 return1094 return
@@ -1103,7 +1114,7 @@
1103 dir = self.make_bzrdir('source')1114 dir = self.make_bzrdir('source')
1104 try:1115 try:
1105 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,1116 reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
1106 referenced_branch)1117 target_branch=referenced_branch)
1107 except errors.IncompatibleFormat:1118 except errors.IncompatibleFormat:
1108 # this is ok too, not all formats have to support references.1119 # this is ok too, not all formats have to support references.
1109 return1120 return
@@ -1410,6 +1421,23 @@
1410 self.failUnless(isinstance(made_branch, bzrlib.branch.Branch))1421 self.failUnless(isinstance(made_branch, bzrlib.branch.Branch))
1411 self.assertEqual(made_control, made_branch.bzrdir)1422 self.assertEqual(made_control, made_branch.bzrdir)
14121423
1424 def test_create_colo_branch(self):
1425 # a bzrdir can construct a branch and repository for itself.
1426 if not self.bzrdir_format.is_supported():
1427 # unsupported formats are not loopback testable
1428 # because the default open will not open them and
1429 # they may not be initializable.
1430 raise TestNotApplicable('Control dir format not supported')
1431 t = get_transport(self.get_url())
1432 made_control = self.bzrdir_format.initialize(t.base)
1433 made_repo = made_control.create_repository()
1434 try:
1435 made_branch = made_control.create_branch("colo")
1436 except errors.NoColocatedBranchSupport:
1437 raise TestNotApplicable('Colocated branches not supported')
1438 self.failUnless(isinstance(made_branch, bzrlib.branch.Branch))
1439 self.assertEqual(made_control, made_branch.bzrdir)
1440
1413 def test_open_branch(self):1441 def test_open_branch(self):
1414 if not self.bzrdir_format.is_supported():1442 if not self.bzrdir_format.is_supported():
1415 # unsupported formats are not loopback testable1443 # unsupported formats are not loopback testable
@@ -1858,7 +1886,7 @@
1858 thisdir = self.make_bzrdir('this')1886 thisdir = self.make_bzrdir('this')
1859 try:1887 try:
1860 bzrlib.branch.BranchReferenceFormat().initialize(1888 bzrlib.branch.BranchReferenceFormat().initialize(
1861 thisdir, master)1889 thisdir, target_branch=master)
1862 except errors.IncompatibleFormat:1890 except errors.IncompatibleFormat:
1863 return1891 return
1864 unused_repo = thisdir.create_repository()1892 unused_repo = thisdir.create_repository()
18651893
=== modified file 'bzrlib/tests/per_foreign_vcs/__init__.py'
--- bzrlib/tests/per_foreign_vcs/__init__.py 2009-11-12 22:57:55 +0000
+++ bzrlib/tests/per_foreign_vcs/__init__.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_foreign_vcs/test_repository.py'
--- bzrlib/tests/per_foreign_vcs/test_repository.py 2009-11-27 03:25:07 +0000
+++ bzrlib/tests/per_foreign_vcs/test_repository.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_interbranch/test_push.py'
--- bzrlib/tests/per_interbranch/test_push.py 2010-02-09 21:31:52 +0000
+++ bzrlib/tests/per_interbranch/test_push.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2007, 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_intertree/__init__.py'
--- bzrlib/tests/per_intertree/__init__.py 2009-11-12 23:10:43 +0000
+++ bzrlib/tests/per_intertree/__init__.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_pack_repository.py'
--- bzrlib/tests/per_pack_repository.py 2010-02-11 09:21:45 +0000
+++ bzrlib/tests/per_pack_repository.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_repository/test_check.py'
--- bzrlib/tests/per_repository/test_check.py 2009-12-16 22:29:31 +0000
+++ bzrlib/tests/per_repository/test_check.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_repository/test_check_reconcile.py'
--- bzrlib/tests/per_repository/test_check_reconcile.py 2009-12-16 22:29:31 +0000
+++ bzrlib/tests/per_repository/test_check_reconcile.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_repository_reference/test_check.py'
--- bzrlib/tests/per_repository_reference/test_check.py 2009-12-16 22:29:31 +0000
+++ bzrlib/tests/per_repository_reference/test_check.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_transport.py'
--- bzrlib/tests/per_transport.py 2010-02-09 20:44:50 +0000
+++ bzrlib/tests/per_transport.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -1083,6 +1083,52 @@
1083 subdir.stat('./file')1083 subdir.stat('./file')
1084 subdir.stat('.')1084 subdir.stat('.')
10851085
1086 def test_hardlink(self):
1087 from stat import ST_NLINK
1088
1089 t = self.get_transport()
1090
1091 source_name = "original_target"
1092 link_name = "target_link"
1093
1094 self.build_tree([source_name], transport=t)
1095
1096 try:
1097 t.hardlink(source_name, link_name)
1098
1099 self.failUnless(t.has(source_name))
1100 self.failUnless(t.has(link_name))
1101
1102 st = t.stat(link_name)
1103 self.failUnlessEqual(st[ST_NLINK], 2)
1104 except TransportNotPossible:
1105 raise TestSkipped("Transport %s does not support hardlinks." %
1106 self._server.__class__)
1107
1108 def test_symlink(self):
1109 from stat import S_ISLNK
1110
1111 t = self.get_transport()
1112
1113 source_name = "original_target"
1114 link_name = "target_link"
1115
1116 self.build_tree([source_name], transport=t)
1117
1118 try:
1119 t.symlink(source_name, link_name)
1120
1121 self.failUnless(t.has(source_name))
1122 self.failUnless(t.has(link_name))
1123
1124 st = t.stat(link_name)
1125 self.failUnless(S_ISLNK(st.st_mode))
1126 except TransportNotPossible:
1127 raise TestSkipped("Transport %s does not support symlinks." %
1128 self._server.__class__)
1129 except IOError:
1130 raise tests.KnownFailure("Paramiko fails to create symlinks during tests")
1131
1086 def test_list_dir(self):1132 def test_list_dir(self):
1087 # TODO: Test list_dir, just try once, and if it throws, stop testing1133 # TODO: Test list_dir, just try once, and if it throws, stop testing
1088 t = self.get_transport()1134 t = self.get_transport()
10891135
=== modified file 'bzrlib/tests/per_tree/test_get_file_with_stat.py'
--- bzrlib/tests/per_tree/test_get_file_with_stat.py 2009-11-18 15:47:16 +0000
+++ bzrlib/tests/per_tree/test_get_file_with_stat.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_tree/test_iter_search_rules.py'
--- bzrlib/tests/per_tree/test_iter_search_rules.py 2009-12-03 05:21:09 +0000
+++ bzrlib/tests/per_tree/test_iter_search_rules.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_tree/test_path_content_summary.py'
--- bzrlib/tests/per_tree/test_path_content_summary.py 2009-11-10 19:38:37 +0000
+++ bzrlib/tests/per_tree/test_path_content_summary.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2009 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_tree/test_revision_tree.py'
--- bzrlib/tests/per_tree/test_revision_tree.py 2009-07-10 07:14:02 +0000
+++ bzrlib/tests/per_tree/test_revision_tree.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -16,11 +16,14 @@
1616
17"""Tests for Tree.revision_tree."""17"""Tests for Tree.revision_tree."""
1818
19from bzrlib import errors19from bzrlib import (
20from bzrlib.tests.per_tree import TestCaseWithTree20 errors,
2121 tests,
2222 )
23class TestRevisionTree(TestCaseWithTree):23from bzrlib.tests import per_tree
24
25
26class TestRevisionTree(per_tree.TestCaseWithTree):
2427
25 def create_tree_no_parents_no_content(self):28 def create_tree_no_parents_no_content(self):
26 tree = self.make_branch_and_tree('.')29 tree = self.make_branch_and_tree('.')
2730
=== modified file 'bzrlib/tests/per_workingtree/test_content_filters.py'
--- bzrlib/tests/per_workingtree/test_content_filters.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/per_workingtree/test_content_filters.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/per_workingtree/test_is_ignored.py'
--- bzrlib/tests/per_workingtree/test_is_ignored.py 2010-01-01 21:26:25 +0000
+++ bzrlib/tests/per_workingtree/test_is_ignored.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2# Authors: Robert Collins <robert.collins@canonical.com>2# Authors: Robert Collins <robert.collins@canonical.com>
3#3#
4# This program is free software; you can redistribute it and/or modify4# This program is free software; you can redistribute it and/or modify
55
=== modified file 'bzrlib/tests/per_workingtree/test_revision_tree.py'
--- bzrlib/tests/per_workingtree/test_revision_tree.py 2009-07-10 07:14:02 +0000
+++ bzrlib/tests/per_workingtree/test_revision_tree.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006 Canonical Ltd1# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -23,11 +23,15 @@
23so these tests are testing that when there is a cache, it performs correctly.23so these tests are testing that when there is a cache, it performs correctly.
24"""24"""
2525
26from bzrlib import errors26from bzrlib import (
27from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree27 branchbuilder,
2828 errors,
2929 tests,
30class TestRevisionTree(TestCaseWithWorkingTree):30 )
31from bzrlib.tests import per_workingtree
32
33
34class TestRevisionTree(per_workingtree.TestCaseWithWorkingTree):
3135
32 def test_get_zeroth_basis_tree_via_revision_tree(self):36 def test_get_zeroth_basis_tree_via_revision_tree(self):
33 tree = self.make_branch_and_tree('.')37 tree = self.make_branch_and_tree('.')
@@ -83,3 +87,50 @@
83 return87 return
84 repository_revision_tree = tree.branch.repository.revision_tree(rev1)88 repository_revision_tree = tree.branch.repository.revision_tree(rev1)
85 self.assertTreesEqual(repository_revision_tree, cached_revision_tree)89 self.assertTreesEqual(repository_revision_tree, cached_revision_tree)
90
91
92class TestRevisionTreeKind(per_workingtree.TestCaseWithWorkingTree):
93
94 def make_branch_with_merged_deletions(self, relpath='tree'):
95 tree = self.make_branch_and_tree(relpath)
96 files = ['a', 'b/', 'b/c']
97 self.build_tree(files, line_endings='binary',
98 transport=tree.bzrdir.root_transport)
99 tree.set_root_id('root-id')
100 tree.add(files, ['a-id', 'b-id', 'c-id'])
101 tree.commit('a, b and b/c', rev_id='base')
102 tree2 = tree.bzrdir.sprout(relpath + '2').open_workingtree()
103 # Delete 'a' in tree
104 tree.remove('a', keep_files=False)
105 tree.commit('remove a', rev_id='this')
106 # Delete 'c' in tree2
107 tree2.remove('b/c', keep_files=False)
108 tree2.remove('b', keep_files=False)
109 tree2.commit('remove b/c', rev_id='other')
110 # Merge tree2 into tree
111 tree.merge_from_branch(tree2.branch)
112 return tree
113
114 def test_kind_parent_tree(self):
115 tree = self.make_branch_with_merged_deletions()
116 tree.lock_read()
117 self.addCleanup(tree.unlock)
118 parents = tree.get_parent_ids()
119 self.assertEqual(['this', 'other'], parents)
120 basis = tree.revision_tree(parents[0])
121 basis.lock_read()
122 self.addCleanup(basis.unlock)
123 self.assertRaises(errors.NoSuchId, basis.kind, 'a-id')
124 self.assertEqual(['directory', 'file'],
125 [basis.kind('b-id'), basis.kind('c-id')])
126 try:
127 other = tree.revision_tree(parents[1])
128 except errors.NoSuchRevisionInTree:
129 raise tests.TestNotApplicable(
130 'Tree type %s caches only the basis revision tree.'
131 % type(tree))
132 other.lock_read()
133 self.addCleanup(other.unlock)
134 self.assertRaises(errors.NoSuchId, other.kind, 'b-id')
135 self.assertRaises(errors.NoSuchId, other.kind, 'c-id')
136 self.assertEqual('file', other.kind('a-id'))
86137
=== modified file 'bzrlib/tests/per_workingtree/test_workingtree.py'
--- bzrlib/tests/per_workingtree/test_workingtree.py 2010-02-13 01:50:29 +0000
+++ bzrlib/tests/per_workingtree/test_workingtree.py 2010-04-06 07:24:41 +0000
@@ -423,7 +423,8 @@
423 made_control = self.bzrdir_format.initialize('new')423 made_control = self.bzrdir_format.initialize('new')
424 source.branch.repository.clone(made_control)424 source.branch.repository.clone(made_control)
425 source.branch.clone(made_control)425 source.branch.clone(made_control)
426 made_tree = self.workingtree_format.initialize(made_control, revision_id='a')426 made_tree = self.workingtree_format.initialize(made_control,
427 revision_id='a')
427 self.assertEqual(['a'], made_tree.get_parent_ids())428 self.assertEqual(['a'], made_tree.get_parent_ids())
428429
429 def test_update_sets_last_revision(self):430 def test_update_sets_last_revision(self):
@@ -447,7 +448,8 @@
447 # current format448 # current format
448 self.build_tree(['checkout/', 'tree/file'])449 self.build_tree(['checkout/', 'tree/file'])
449 checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')450 checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
450 branch.BranchReferenceFormat().initialize(checkout, main_branch)451 branch.BranchReferenceFormat().initialize(checkout,
452 target_branch=main_branch)
451 old_tree = self.workingtree_format.initialize(checkout)453 old_tree = self.workingtree_format.initialize(checkout)
452 # now commit to 'tree'454 # now commit to 'tree'
453 wt.add('file')455 wt.add('file')
@@ -514,7 +516,8 @@
514 # current format516 # current format
515 self.build_tree(['checkout/', 'tree/file'])517 self.build_tree(['checkout/', 'tree/file'])
516 checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')518 checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
517 branch.BranchReferenceFormat().initialize(checkout, main_branch)519 branch.BranchReferenceFormat().initialize(checkout,
520 target_branch=main_branch)
518 old_tree = self.workingtree_format.initialize(checkout)521 old_tree = self.workingtree_format.initialize(checkout)
519 # now commit to 'tree'522 # now commit to 'tree'
520 wt.add('file')523 wt.add('file')
521524
=== modified file 'bzrlib/tests/script.py'
--- bzrlib/tests/script.py 2010-01-16 10:06:21 +0000
+++ bzrlib/tests/script.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/stub_sftp.py'
--- bzrlib/tests/stub_sftp.py 2010-02-11 09:27:55 +0000
+++ bzrlib/tests/stub_sftp.py 2010-04-06 07:24:41 +0000
@@ -297,14 +297,14 @@
297 threading.Thread(target=self._callback, args=(s,)).start()297 threading.Thread(target=self._callback, args=(s,)).start()
298 except socket.error, x:298 except socket.error, x:
299 sys.excepthook(*sys.exc_info())299 sys.excepthook(*sys.exc_info())
300 warning('Socket error during accept() within unit test server'300 trace.warning('Socket error during accept() '
301 ' thread: %r' % x)301 'within unit test server thread: %r' % x)
302 except Exception, x:302 except Exception, x:
303 # probably a failed test; unit test thread will log the303 # probably a failed test; unit test thread will log the
304 # failure/error304 # failure/error
305 sys.excepthook(*sys.exc_info())305 sys.excepthook(*sys.exc_info())
306 warning('Exception from within unit test server thread: %r' %306 trace.warning(
307 x)307 'Exception from within unit test server thread: %r' % x)
308308
309309
310class SocketDelay(object):310class SocketDelay(object):
@@ -438,13 +438,15 @@
438 if not (backing_server is None or438 if not (backing_server is None or
439 isinstance(backing_server, test_server.LocalURLServer)):439 isinstance(backing_server, test_server.LocalURLServer)):
440 raise AssertionError(440 raise AssertionError(
441 "backing_server should not be %r, because this can only serve the "441 'backing_server should not be %r, because this can only serve '
442 "local current working directory." % (backing_server,))442 'the local current working directory.' % (backing_server,))
443 self._original_vendor = ssh._ssh_vendor_manager._cached_ssh_vendor443 self._original_vendor = ssh._ssh_vendor_manager._cached_ssh_vendor
444 ssh._ssh_vendor_manager._cached_ssh_vendor = self._vendor444 ssh._ssh_vendor_manager._cached_ssh_vendor = self._vendor
445 # FIXME: the following block should certainly just be self._homedir =
446 # osutils.getcwd() but that fails badly on Unix -- vila 20100224
445 if sys.platform == 'win32':447 if sys.platform == 'win32':
446 # Win32 needs to use the UNICODE api448 # Win32 needs to use the UNICODE api
447 self._homedir = getcwd()449 self._homedir = os.getcwdu()
448 else:450 else:
449 # But Linux SFTP servers should just deal in bytestreams451 # But Linux SFTP servers should just deal in bytestreams
450 self._homedir = os.getcwd()452 self._homedir = os.getcwd()
451453
=== modified file 'bzrlib/tests/test__annotator.py'
--- bzrlib/tests/test__annotator.py 2009-12-22 16:47:36 +0000
+++ bzrlib/tests/test__annotator.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__bencode.py'
--- bzrlib/tests/test__bencode.py 2009-12-23 04:19:34 +0000
+++ bzrlib/tests/test__bencode.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2009 Canonical Ltd1# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__chk_map.py'
--- bzrlib/tests/test__chk_map.py 2009-12-22 16:28:47 +0000
+++ bzrlib/tests/test__chk_map.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__chunks_to_lines.py'
--- bzrlib/tests/test__chunks_to_lines.py 2009-12-22 17:14:45 +0000
+++ bzrlib/tests/test__chunks_to_lines.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__dirstate_helpers.py'
--- bzrlib/tests/test__dirstate_helpers.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/test__dirstate_helpers.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__groupcompress.py'
--- bzrlib/tests/test__groupcompress.py 2009-12-22 15:50:40 +0000
+++ bzrlib/tests/test__groupcompress.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__known_graph.py'
--- bzrlib/tests/test__known_graph.py 2009-12-22 15:50:40 +0000
+++ bzrlib/tests/test__known_graph.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__rio.py'
--- bzrlib/tests/test__rio.py 2009-12-22 16:28:47 +0000
+++ bzrlib/tests/test__rio.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__simple_set.py'
--- bzrlib/tests/test__simple_set.py 2009-12-22 15:50:40 +0000
+++ bzrlib/tests/test__simple_set.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__static_tuple.py'
--- bzrlib/tests/test__static_tuple.py 2010-02-18 01:10:16 +0000
+++ bzrlib/tests/test__static_tuple.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test__walkdirs_win32.py'
--- bzrlib/tests/test__walkdirs_win32.py 2009-12-21 18:03:49 +0000
+++ bzrlib/tests/test__walkdirs_win32.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test_branch.py'
--- bzrlib/tests/test_branch.py 2010-02-10 17:52:08 +0000
+++ bzrlib/tests/test_branch.py 2010-04-06 07:24:41 +0000
@@ -123,16 +123,16 @@
123 """See BzrBranchFormat.get_format_string()."""123 """See BzrBranchFormat.get_format_string()."""
124 return "Sample branch format."124 return "Sample branch format."
125125
126 def initialize(self, a_bzrdir):126 def initialize(self, a_bzrdir, name=None):
127 """Format 4 branches cannot be created."""127 """Format 4 branches cannot be created."""
128 t = a_bzrdir.get_branch_transport(self)128 t = a_bzrdir.get_branch_transport(self, name=name)
129 t.put_bytes('format', self.get_format_string())129 t.put_bytes('format', self.get_format_string())
130 return 'A branch'130 return 'A branch'
131131
132 def is_supported(self):132 def is_supported(self):
133 return False133 return False
134134
135 def open(self, transport, _found=False, ignore_fallbacks=False):135 def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
136 return "opened branch."136 return "opened branch."
137137
138138
@@ -438,7 +438,7 @@
438 t.mkdir('branch')438 t.mkdir('branch')
439 branch_dir = bzrdirformat.initialize(self.get_url('branch'))439 branch_dir = bzrdirformat.initialize(self.get_url('branch'))
440 made_branch = _mod_branch.BranchReferenceFormat().initialize(440 made_branch = _mod_branch.BranchReferenceFormat().initialize(
441 branch_dir, target_branch)441 branch_dir, target_branch=target_branch)
442 self.assertEqual(made_branch.base, target_branch.base)442 self.assertEqual(made_branch.base, target_branch.base)
443 opened_branch = branch_dir.open_branch()443 opened_branch = branch_dir.open_branch()
444 self.assertEqual(opened_branch.base, target_branch.base)444 self.assertEqual(opened_branch.base, target_branch.base)
445445
=== modified file 'bzrlib/tests/test_branchbuilder.py'
--- bzrlib/tests/test_branchbuilder.py 2009-05-07 05:08:46 +0000
+++ bzrlib/tests/test_branchbuilder.py 2010-04-06 07:24:41 +0000
@@ -171,6 +171,15 @@
171 rev = branch.repository.get_revision(rev_id)171 rev = branch.repository.get_revision(rev_id)
172 self.assertEqual(u'Foo', rev.message)172 self.assertEqual(u'Foo', rev.message)
173173
174 def test_commit_message_callback(self):
175 builder = BranchBuilder(self.get_transport().clone('foo'))
176 rev_id = builder.build_snapshot(None, None,
177 [('add', (u'', None, 'directory', None))],
178 message_callback=lambda x:u'Foo')
179 branch = builder.get_branch()
180 rev = branch.repository.get_revision(rev_id)
181 self.assertEqual(u'Foo', rev.message)
182
174 def test_modify_file(self):183 def test_modify_file(self):
175 builder = self.build_a_rev()184 builder = self.build_a_rev()
176 rev_id2 = builder.build_snapshot('B-id', None,185 rev_id2 = builder.build_snapshot('B-id', None,
177186
=== modified file 'bzrlib/tests/test_btree_index.py'
--- bzrlib/tests/test_btree_index.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/test_btree_index.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008, 2009 Canonical Ltd1# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test_bzrdir.py'
--- bzrlib/tests/test_bzrdir.py 2010-02-11 09:21:45 +0000
+++ bzrlib/tests/test_bzrdir.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
36 )36 )
37import bzrlib.branch37import bzrlib.branch
38from bzrlib.errors import (NotBranchError,38from bzrlib.errors import (NotBranchError,
39 NoColocatedBranchSupport,
39 UnknownFormatError,40 UnknownFormatError,
40 UnsupportedFormatError,41 UnsupportedFormatError,
41 )42 )
@@ -206,8 +207,10 @@
206 """See BzrDir.open_repository."""207 """See BzrDir.open_repository."""
207 return SampleRepository(self)208 return SampleRepository(self)
208209
209 def create_branch(self):210 def create_branch(self, name=None):
210 """See BzrDir.create_branch."""211 """See BzrDir.create_branch."""
212 if name is not None:
213 raise NoColocatedBranchSupport(self)
211 return SampleBranch(self)214 return SampleBranch(self)
212215
213 def create_workingtree(self):216 def create_workingtree(self):
@@ -468,7 +471,8 @@
468 # Make stackable source branch with an unstackable repo format.471 # Make stackable source branch with an unstackable repo format.
469 source_bzrdir = self.make_bzrdir('source')472 source_bzrdir = self.make_bzrdir('source')
470 pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)473 pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
471 source_branch = bzrlib.branch.BzrBranchFormat7().initialize(source_bzrdir)474 source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
475 source_bzrdir)
472 # Make a directory with a default stacking policy476 # Make a directory with a default stacking policy
473 parent_bzrdir = self.make_bzrdir('parent')477 parent_bzrdir = self.make_bzrdir('parent')
474 stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')478 stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
475479
=== modified file 'bzrlib/tests/test_cleanup.py'
--- bzrlib/tests/test_cleanup.py 2009-12-16 22:29:31 +0000
+++ bzrlib/tests/test_cleanup.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2009 Canonical Ltd1# Copyright (C) 2009, 2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test_cmdline.py'
--- bzrlib/tests/test_cmdline.py 2010-02-18 02:15:48 +0000
+++ bzrlib/tests/test_cmdline.py 2010-04-06 07:24:41 +0000
@@ -85,7 +85,7 @@
85 def test_double_escape(self):85 def test_double_escape(self):
86 self.assertAsTokens([(True, u'foo\\\\bar')], u'"foo\\\\bar"')86 self.assertAsTokens([(True, u'foo\\\\bar')], u'"foo\\\\bar"')
87 self.assertAsTokens([(False, u'foo\\\\bar')], u"foo\\\\bar")87 self.assertAsTokens([(False, u'foo\\\\bar')], u"foo\\\\bar")
88 88
89 def test_multiple_quoted_args(self):89 def test_multiple_quoted_args(self):
90 self.assertAsTokens([(True, u'x x'), (True, u'y y')],90 self.assertAsTokens([(True, u'x x'), (True, u'y y')],
91 u'"x x" "y y"')91 u'"x x" "y y"')
9292
=== modified file 'bzrlib/tests/test_commands.py'
--- bzrlib/tests/test_commands.py 2010-01-14 13:17:33 +0000
+++ bzrlib/tests/test_commands.py 2010-04-06 07:24:41 +0000
@@ -24,6 +24,7 @@
24 config,24 config,
25 errors,25 errors,
26 option,26 option,
27 symbol_versioning,
27 tests,28 tests,
28 )29 )
29from bzrlib.commands import display_command30from bzrlib.commands import display_command
@@ -276,32 +277,45 @@
276277
277class TestGetMissingCommandHook(tests.TestCase):278class TestGetMissingCommandHook(tests.TestCase):
278279
279 def test_fires_on_get_cmd_object(self):280 def hook_missing(self):
280 # The get_missing_command(cmd) hook fires when commands are delivered to the281 """Hook get_missing_command for testing."""
281 # ui.282 self.hook_calls = []
282 hook_calls = []
283 class ACommand(commands.Command):283 class ACommand(commands.Command):
284 """A sample command."""284 """A sample command."""
285 def get_missing_cmd(cmd_name):285 def get_missing_cmd(cmd_name):
286 hook_calls.append(('called', cmd_name))286 self.hook_calls.append(('called', cmd_name))
287 if cmd_name in ('foo', 'info'):287 if cmd_name in ('foo', 'info'):
288 return ACommand()288 return ACommand()
289 commands.Command.hooks.install_named_hook(289 commands.Command.hooks.install_named_hook(
290 "get_missing_command", get_missing_cmd, None)290 "get_missing_command", get_missing_cmd, None)
291 self.ACommand = ACommand
292
293 def test_fires_on_get_cmd_object(self):
294 # The get_missing_command(cmd) hook fires when commands are delivered to the
295 # ui.
296 self.hook_missing()
291 # create a command directly, should not fire297 # create a command directly, should not fire
292 cmd = ACommand()298 self.cmd = self.ACommand()
293 self.assertEqual([], hook_calls)299 self.assertEqual([], self.hook_calls)
294 # ask by name, should fire and give us our command300 # ask by name, should fire and give us our command
295 cmd = commands.get_cmd_object('foo')301 cmd = commands.get_cmd_object('foo')
296 self.assertEqual([('called', 'foo')], hook_calls)302 self.assertEqual([('called', 'foo')], self.hook_calls)
297 self.assertIsInstance(cmd, ACommand)303 self.assertIsInstance(cmd, self.ACommand)
298 del hook_calls[:]304 del self.hook_calls[:]
299 # ask by a name that is supplied by a builtin - the hook should not305 # ask by a name that is supplied by a builtin - the hook should not
300 # fire and we still get our object.306 # fire and we still get our object.
301 commands.install_bzr_command_hooks()307 commands.install_bzr_command_hooks()
302 cmd = commands.get_cmd_object('info')308 cmd = commands.get_cmd_object('info')
303 self.assertNotEqual(None, cmd)309 self.assertNotEqual(None, cmd)
304 self.assertEqual(0, len(hook_calls))310 self.assertEqual(0, len(self.hook_calls))
311
312 def test_skipped_on_HelpCommandIndex_get_topics(self):
313 # The get_missing_command(cmd_name) hook is not fired when
314 # looking up help topics.
315 self.hook_missing()
316 topic = commands.HelpCommandIndex()
317 topics = topic.get_topics('foo')
318 self.assertEqual([], self.hook_calls)
305319
306320
307class TestListCommandHook(tests.TestCase):321class TestListCommandHook(tests.TestCase):
@@ -323,3 +337,10 @@
323 cmds = list(commands.all_command_names())337 cmds = list(commands.all_command_names())
324 self.assertEqual(['called'], hook_calls)338 self.assertEqual(['called'], hook_calls)
325 self.assertSubset(['foo', 'bar'], cmds)339 self.assertSubset(['foo', 'bar'], cmds)
340
341class TestDeprecations(tests.TestCase):
342
343 def test_shlex_split_unicode_deprecation(self):
344 res = self.applyDeprecated(
345 symbol_versioning.deprecated_in((2, 2, 0)),
346 commands.shlex_split_unicode, 'whatever')
326347
=== modified file 'bzrlib/tests/test_commit.py'
--- bzrlib/tests/test_commit.py 2010-02-13 01:50:29 +0000
+++ bzrlib/tests/test_commit.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2008 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test_config.py'
--- bzrlib/tests/test_config.py 2010-01-25 17:48:22 +0000
+++ bzrlib/tests/test_config.py 2010-04-06 07:24:41 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd1# Copyright (C) 2005-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
55
=== modified file 'bzrlib/tests/test_conflicts.py'
--- bzrlib/tests/test_conflicts.py 2010-02-10 17:52:08 +0000
+++ bzrlib/tests/test_conflicts.py 2010-04-06 07:24:41 +0000
@@ -18,15 +18,32 @@
18import os18import os
1919
20from bzrlib import (20from bzrlib import (
21 branchbuilder,
21 bzrdir,22 bzrdir,
22 conflicts,23 conflicts,
23 errors,24 errors,
24 option,25 option,
25 tests,26 tests,
27 workingtree,
26 )28 )
27from bzrlib.tests import script29from bzrlib.tests import script
2830
2931
32def load_tests(standard_tests, module, loader):
33 result = loader.suiteClass()
34
35 sp_tests, remaining_tests = tests.split_suite_by_condition(
36 standard_tests, tests.condition_isinstance((
37 TestResolveContentConflicts,
38 )))
39 tests.multiply_tests(sp_tests, content_conflict_scenarios(), result)
40
41 # No parametrization for the remaining tests
42 result.addTests(remaining_tests)
43
44 return result
45
46
30# TODO: Test commit with some added, and added-but-missing files47# TODO: Test commit with some added, and added-but-missing files
31# RBC 20060124 is that not tested in test_commit.py ?48# RBC 20060124 is that not tested in test_commit.py ?
3249
@@ -69,15 +86,15 @@
69 ('hello.sploo.OTHER', 'yellowworld2'),86 ('hello.sploo.OTHER', 'yellowworld2'),
70 ])87 ])
71 tree.lock_read()88 tree.lock_read()
72 self.assertEqual(6, len(list(tree.list_files())))89 self.assertLength(6, list(tree.list_files()))
73 tree.unlock()90 tree.unlock()
74 tree_conflicts = tree.conflicts()91 tree_conflicts = tree.conflicts()
75 self.assertEqual(2, len(tree_conflicts))92 self.assertLength(2, tree_conflicts)
76 self.assertTrue('hello' in tree_conflicts[0].path)93 self.assertTrue('hello' in tree_conflicts[0].path)
77 self.assertTrue('hello.sploo' in tree_conflicts[1].path)94 self.assertTrue('hello.sploo' in tree_conflicts[1].path)
78 conflicts.restore('hello')95 conflicts.restore('hello')
79 conflicts.restore('hello.sploo')96 conflicts.restore('hello.sploo')
80 self.assertEqual(0, len(tree.conflicts()))97 self.assertLength(0, tree.conflicts())
81 self.assertFileEqual('hello world2', 'hello')98 self.assertFileEqual('hello world2', 'hello')
82 self.assertFalse(os.path.lexists('hello.sploo'))99 self.assertFalse(os.path.lexists('hello.sploo'))
83 self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')100 self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
@@ -192,59 +209,99 @@
192 pass209 pass
193210
194211
195class TestResolveContentConflicts(TestResolveConflicts):212def content_conflict_scenarios():
196213 return [('file,None', dict(_this_actions='modify_file',
197 # FIXME: We need to add the reverse case (delete in trunk, modify in214 _check_this='file_has_more_content',
198 # branch) but that could wait until the resolution mechanism is implemented.215 _other_actions='delete_file',
199216 _check_other='file_doesnt_exist',
200 preamble = """217 )),
201$ bzr init trunk218 ('None,file', dict(_this_actions='delete_file',
202$ cd trunk219 _check_this='file_doesnt_exist',
203$ echo 'trunk content' >file220 _other_actions='modify_file',
204$ bzr add file221 _check_other='file_has_more_content',
205$ bzr commit -m 'Create trunk'222 )),
206223 ]
207$ bzr branch . ../branch224
208$ cd ../branch225
209$ bzr rm file226class TestResolveContentConflicts(tests.TestCaseWithTransport):
210$ bzr commit -m 'Delete file'227
211228 # Set by load_tests
212$ cd ../trunk229 this_actions = None
213$ echo 'more content' >>file
214$ bzr commit -m 'Modify file'
215
216$ cd ../branch
217$ bzr merge ../trunk
2182>+N file.OTHER
2192>Contents conflict in file
2202>1 conflicts encountered.
221"""
222
223 def test_take_this(self):
224 self.run_script("""
225$ bzr rm file.OTHER --force # a simple rm file.OTHER is valid too
226$ bzr resolve file
227$ bzr commit --strict -m 'No more conflicts nor unknown files'
228""")
229
230 def test_take_other(self):
231 self.run_script("""
232$ bzr mv file.OTHER file
233$ bzr resolve file
234$ bzr commit --strict -m 'No more conflicts nor unknown files'
235""")
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches