Merge lp:~spiv/bzr/merge-into-merger into lp:bzr

Proposed by Andrew Bennetts
Status: Merged
Merged at revision: 5365
Proposed branch: lp:~spiv/bzr/merge-into-merger
Merge into: lp:bzr
Diff against target: 7915 lines (+4126/-2400) (has conflicts)
66 files modified
NEWS (+1607/-32)
bzr (+4/-0)
bzrlib/__init__.py (+8/-0)
bzrlib/benchmarks/__init__.py (+0/-206)
bzrlib/benchmarks/bench_add.py (+0/-32)
bzrlib/benchmarks/bench_bench.py (+0/-101)
bzrlib/benchmarks/bench_bundle.py (+0/-207)
bzrlib/benchmarks/bench_cache_utf8.py (+0/-226)
bzrlib/benchmarks/bench_checkout.py (+0/-29)
bzrlib/benchmarks/bench_info.py (+0/-37)
bzrlib/benchmarks/bench_inventory.py (+0/-39)
bzrlib/benchmarks/bench_log.py (+0/-117)
bzrlib/benchmarks/bench_osutils.py (+0/-37)
bzrlib/benchmarks/bench_pack.py (+0/-54)
bzrlib/benchmarks/bench_rocks.py (+0/-28)
bzrlib/benchmarks/bench_sftp.py (+0/-101)
bzrlib/benchmarks/bench_startup.py (+0/-91)
bzrlib/benchmarks/bench_status.py (+0/-52)
bzrlib/benchmarks/bench_tags.py (+0/-58)
bzrlib/benchmarks/bench_transform.py (+0/-43)
bzrlib/benchmarks/bench_workingtree.py (+0/-111)
bzrlib/benchmarks/bench_xml.py (+0/-87)
bzrlib/benchmarks/tree_creator/__init__.py (+0/-175)
bzrlib/benchmarks/tree_creator/heavily_merged.py (+0/-75)
bzrlib/benchmarks/tree_creator/many_commit.py (+0/-68)
bzrlib/benchmarks/tree_creator/simple_many_commit.py (+0/-47)
bzrlib/branch.py (+4/-0)
bzrlib/builtins.py (+173/-6)
bzrlib/bundle/__init__.py (+8/-2)
bzrlib/chk_map.py (+4/-7)
bzrlib/config.py (+11/-0)
bzrlib/conflicts.py (+18/-1)
bzrlib/errors.py (+112/-52)
bzrlib/globbing.py (+166/-48)
bzrlib/help_topics/en/conflict-types.txt (+180/-0)
bzrlib/help_topics/en/patterns.txt (+19/-3)
bzrlib/merge.py (+209/-20)
bzrlib/progress.py (+8/-3)
bzrlib/shelf_ui.py (+7/-0)
bzrlib/tests/__init__.py (+227/-1)
bzrlib/tests/blackbox/test_add.py (+6/-0)
bzrlib/tests/blackbox/test_branch.py (+4/-0)
bzrlib/tests/blackbox/test_break_lock.py (+19/-0)
bzrlib/tests/blackbox/test_checkout.py (+4/-0)
bzrlib/tests/blackbox/test_commit.py (+57/-19)
bzrlib/tests/blackbox/test_diff.py (+34/-15)
bzrlib/tests/blackbox/test_ignore.py (+31/-6)
bzrlib/tests/blackbox/test_selftest.py (+4/-1)
bzrlib/tests/features.py (+21/-0)
bzrlib/tests/per_transport.py (+49/-0)
bzrlib/tests/per_workingtree/test_is_ignored.py (+25/-13)
bzrlib/tests/per_workingtree/test_symlinks.py (+101/-0)
bzrlib/tests/test_chk_map.py (+19/-0)
bzrlib/tests/test_config.py (+35/-4)
bzrlib/tests/test_errors.py (+111/-38)
bzrlib/tests/test_globbing.py (+43/-1)
bzrlib/tests/test_http.py (+146/-0)
bzrlib/tests/test_merge.py (+427/-88)
bzrlib/tests/test_progress.py (+37/-4)
bzrlib/tests/test_selftest.py (+6/-0)
bzrlib/tests/test_ui.py (+16/-6)
bzrlib/ui/text.py (+57/-9)
doc/developers/index.txt (+18/-0)
doc/developers/testing.txt (+59/-0)
doc/en/mini-tutorial/index.txt (+21/-0)
setup.py (+11/-0)
Text conflict in NEWS
Text conflict in bzr
Text conflict in bzrlib/__init__.py
Conflict: can't delete bzrlib/benchmarks because it is not empty.  Not deleting.
Conflict because bzrlib/benchmarks is not versioned, but has versioned children.  Versioned directory.
Contents conflict in bzrlib/benchmarks/bench_commit.py
Contents conflict in bzrlib/benchmarks/bench_dirstate.py
Contents conflict in bzrlib/benchmarks/bench_knit.py
Conflict: can't delete bzrlib/benchmarks/tree_creator because it is not empty.  Not deleting.
Conflict because bzrlib/benchmarks/tree_creator is not versioned, but has versioned children.  Versioned directory.
Contents conflict in bzrlib/benchmarks/tree_creator/kernel_like.py
Text conflict in bzrlib/builtins.py
Text conflict in bzrlib/bundle/__init__.py
Text conflict in bzrlib/config.py
Text conflict in bzrlib/conflicts.py
Text conflict in bzrlib/errors.py
Text conflict in bzrlib/globbing.py
Text conflict in bzrlib/help_topics/en/conflict-types.txt
Text conflict in bzrlib/help_topics/en/patterns.txt
Text conflict in bzrlib/merge.py
Text conflict in bzrlib/progress.py
Text conflict in bzrlib/shelf_ui.py
Text conflict in bzrlib/tests/__init__.py
Text conflict in bzrlib/tests/blackbox/test_add.py
Text conflict in bzrlib/tests/blackbox/test_branch.py
Text conflict in bzrlib/tests/blackbox/test_break_lock.py
Text conflict in bzrlib/tests/blackbox/test_checkout.py
Text conflict in bzrlib/tests/blackbox/test_commit.py
Text conflict in bzrlib/tests/blackbox/test_diff.py
Text conflict in bzrlib/tests/blackbox/test_ignore.py
Text conflict in bzrlib/tests/blackbox/test_selftest.py
Text conflict in bzrlib/tests/features.py
Text conflict in bzrlib/tests/per_transport.py
Text conflict in bzrlib/tests/per_workingtree/test_symlinks.py
Text conflict in bzrlib/tests/test_config.py
Text conflict in bzrlib/tests/test_errors.py
Text conflict in bzrlib/tests/test_globbing.py
Text conflict in bzrlib/tests/test_http.py
Text conflict in bzrlib/tests/test_merge.py
Text conflict in bzrlib/tests/test_selftest.py
Text conflict in bzrlib/tests/test_ui.py
Text conflict in bzrlib/ui/text.py
Text conflict in doc/developers/index.txt
Text conflict in doc/developers/testing.txt
Text conflict in doc/en/mini-tutorial/index.txt
Text conflict in setup.py
To merge this branch: bzr merge lp:~spiv/bzr/merge-into-merger
Reviewer Review Type Date Requested Status
Robert Collins (community) Needs Fixing
Review via email: mp+28824@code.launchpad.net

Description of the change

This patch adds a merger that can add part or all of an unrelated tree
to its this_tree. This is intended to be used by bzr-builder to allow
“merging” of a debian/ directory from a parallel import of a branch
(i.e. package import vs. upstream import).

First, the drawbacks:
 - there's some ugly code to make it usable with the existing Merger
   interfaces, which don't have support for the extra parameters this
   uses.
 - there's some conceptual overlap with cmd_join/tree.subsume
 - the name isn't great. John's original plugin for this called it
   “merge-into”, but maybe a verb like “incorporate”, “join”,
   “join-part”, [etc] would be better. Suggestions welcome!

As far as the ugliness goes, I'd love suggestions but hope it doesn't
block this patch. I think what's needed is to decompose classes like
"Merger" into smaller pieces like MergeParams, etc, but refactoring it
looks like a long task. (I started another branch that attempts this,
but got daunted. After chatting with Martin about it I'm going to try
submit at least some incremental improvements as separate proposals.)

Perhaps it shouldn't be part of the merge module at all, but
conceptually it seems to fit ok: it can have conflicts to report, if
merging a full tree will want to fetch history into the target
repository, can use non-tip revisions of branches, etc.

I think the overlap is acceptable because for some cases it is a better
approach than subsume:
 - it doesn't require other_tree on disk; it can work directly from a
   branch, and
 - it doesn't require a full tree just to get one small directory of it.
   This will be a nice win with large trees.

These cases are relevant to the bzr-builder use-case (consider e.g.
merging debian/ from the 'linux' package imports into a bzr-git import
of upstream).

Also, the core code is actually pretty small and straightforward, so the
burden of the overlap isn't so huge. And the implementation uses
inventory methods that are public and reasonably performant with 2a
(whereas subsume's current implementation works by mutating an inventory
from dirstate via its _byid dict).

This patch would also be a good foundation for fixing the merge-into
plugin that has been broken for a while. This patch implements all of
the tricky bits currently in that plugin, leaving it free to simply
focus on providing a UI. (This history of this patch includes an
updated cmd_merge_into it could use.)

Finally, thanks to John for the merge-into plugin. His plugin was the
starting point for this patch.

To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

184 + def _entries_to_incorporate(self):

^- I wonder if this could be written without tree.inventory.

All the path2id calls can just be replaced with tree.path2id(). The call for "if root_id in inventory" can be replaced with "tree.id2path(file_id)" (we may need to trap an exception, though, which is a bit ugly.)

This:
  subdir = other_inv[subdir_id]

Gets replaced by:
  subdir = other_tree.iter_entries_by_dir(subdir_id).next()[1]

Which isn't very pretty either, but should do the job.

We don't have to, but it might be nice to get away from accessing the .inventory attribute.

_Wrapper is ugly, but I can understand why you do it. I'm a bit curious why we don't need to have __setattr__ defined, though.

I haven't gone through all the tests yet, but I figured I'd give some feedback and start the conversation.

Revision history for this message
Robert Collins (lifeless) wrote :

id2path('random') -> None
So I think that that is fine.

I'm still ambivalent about avoiding inventory - inventory is the /model/ for the tree, after all. Anyhow, looks doable here.

_finish_transform doesn't pair well with compute_transform. Perhaps finish_computing_transform?

The new exception should be in errors.py until we change our policy on that.

Rather than _Wrapper I suggest MergeTypeParameteriser. Or something like that. Long but less 'zomg I need to read the code' than Wrapper ;)

I think your tests really belong in the main merge test script, merge_into was at most a plugin name, and this is core code - its tests should be matching the module the code is in as per our convention for finding tests.

What do you think of making an existing-but-empty dir be replaced rather than conflicted ?

review: Needs Fixing
Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Robert Collins wrote:
> Review: Needs Fixing
> id2path('random') -> None
> So I think that that is fine.

You're thinking 'path2id':
>>> t.id2path('xxx')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 4, in id2path_read_locked
  File "bzrlib\workingtree_4.py", line 449, in id2path
    raise errors.NoSuchId(tree=self, file_id=file_id)
bzrlib.errors.NoSuchId: The file id "xxx" is not present in the tree
<WorkingTree6 of C:/Users/jameinel/dev/bzr/bzr.dev>.

>>> print t.path2id('xxx')
None

(Yes, they aren't symmetric.)
>
> I'm still ambivalent about avoiding inventory - inventory is the /model/ for the tree, after all. Anyhow, looks doable here.

Well, mostly it is about not having to compute 30k InventoryEntries when
you only want 1. Potentially we could make a much lazier inventory, but
we certainly aren't there (today) for Dirstate code.

>
> _finish_transform doesn't pair well with compute_transform. Perhaps finish_computing_transform?
>
> The new exception should be in errors.py until we change our policy on that.
>
> Rather than _Wrapper I suggest MergeTypeParameteriser. Or something like that. Long but less 'zomg I need to read the code' than Wrapper ;)
John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkwwmT4ACgkQJdeBCYSNAAODlgCfTdNGyxYp7ts8f5M4E83GgRKc
O5wAoJh18G4KfahG62bKlmuf987Cyztx
=sCtl
-----END PGP SIGNATURE-----

Revision history for this message
Andrew Bennetts (spiv) wrote :

John A Meinel wrote:
> 184 + def _entries_to_incorporate(self):
>
> ^- I wonder if this could be written without tree.inventory.

As it turns out: not really. I'll explain why:

> All the path2id calls can just be replaced with tree.path2id(). The call for
> "if root_id in inventory" can be replaced with "tree.id2path(file_id)" (we may
> need to trap an exception, though, which is a bit ugly.)
>
> This:
> subdir = other_inv[subdir_id]
>
> Gets replaced by:
> subdir = other_tree.iter_entries_by_dir(subdir_id).next()[1]
>
> Which isn't very pretty either, but should do the job.

This all works fine...

What doesn't work is replacing this:

        for ignored_path, entry in other_tree.inventory.iter_entries_by_dir(subdir_id):

Tree.iter_entries_by_dir doesn't have the same interface as
Inventory.iter_entries_by_dir; it lacks the from_dir parameter (which is what is
used at the moment). You can only pass specific_file_ids and yield_parents,
there's no way to iter just a subdirectory with Tree.iter_entries_by_dir.

This could probably be corrected fairly easily (and probably should be), but it
wouldn't matter anyway, because the implementation simply thunks through to
self.inventory.iter_entries_by_dir anyway. So the practical benefit to using
more complex code to avoid other_tree.inventory seems to be zero at the moment.
I don't see see any other methods on tree that can iterate a partial tree
without generating an inventory from the dirstate.

So, I don't think we should make this change right now, especially as you say:

> We don't have to, but it might be nice to get away from accessing the .inventory attribute.

Thanks for making me more familiar with the inner workings of our Tree code,
though ;)

On to Robert comments:

Robert Collins wrote:
[...]
>
> _finish_transform doesn't pair well with compute_transform. Perhaps finish_computing_transform?

Thanks, changed as you suggest.

> The new exception should be in errors.py until we change our policy on that.

We already did.
<http://doc.bazaar.canonical.com/bzr.dev/developers/HACKING.html> says:

“Many errors are defined in bzrlib/errors.py but it’s OK for new errors to be
added near the place where they are used.”

> Rather than _Wrapper I suggest MergeTypeParameteriser. Or something like that. Long but less 'zomg I need to read the code' than Wrapper ;)

Agreed. Changed.

> I think your tests really belong in the main merge test script, merge_into was
> at most a plugin name, and this is core code - its tests should be matching
> the module the code is in as per our convention for finding tests.

Good point. Changed.

> What do you think of making an existing-but-empty dir be replaced rather than conflicted ?

I'm ambivalent. I don't really have a real use case either way, although I can
imagine them. The conservative route (conflict) satisfies the immediate goal
(support taking debian/ dirs from parallel imports into the upstream
branch). If you have a use case or other strong reason then I'm happy to
change from conflict to replace.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-07-21 22:29:45 +0000
3+++ NEWS 2010-07-29 06:48:01 +0000
4@@ -5,6 +5,7 @@
5 .. contents:: List of Releases
6 :depth: 1
7
8+<<<<<<< TREE
9 bzr 2.3b1
10 #########
11
12@@ -1564,6 +1565,1540 @@
13 * The test progress bar no longer distinguishes tests that 'errored' from
14 tests that 'failed' - they're all just failures.
15 (Martin Pool)
16+=======
17+bzr 2.2rc1
18+##########
19+
20+:Codename: ???
21+:2.2rc1: NOT RELEASED YET
22+
23+Compatibility Breaks
24+********************
25+
26+* BzrError subclasses no longer support the name "message" to be used
27+ as an argument for __init__ or in _fmt format specification as this
28+ breaks in some Python versions. errors.LockError.__init__ argument
29+ is now named "msg" instead of earlier "message".
30+ (Parth Malwankar, #603461)
31+
32+* The old ``bzr selftest --benchmark`` option has been removed.
33+ <https://launchpad.net/bzr-usertest> is an actively-maintained
34+ macrobenchmark suite.
35+ (Martin Pool)
36+
37+New Features
38+************
39+
40+Bug Fixes
41+*********
42+
43+* ``bzr ignore PATTERNS`` exits with error if a bad pattern is supplied.
44+ ``InvalidPattern`` exception error message now shows faulting
45+ regular expression.
46+ (Parth Malwankar #300062)
47+
48+* Configuration files in ``${BZR_HOME}`` are now written in an atomic
49+ way which should help avoid problems with concurrent writers.
50+ (Vincent Ladeuil, #525571)
51+
52+* Don't traceback trying to unversion children files of an already
53+ unversioned directory. (Vincent Ladeuil, #494221)
54+
55+* ``HTTP/1.1` test servers now set a ``Content-Length`` header to comply
56+ with pedantic ``HTTP/1.1`` clients. (Vincent Ladeuil, #568421)
57+
58+* Progress bars prefer to truncate the text message rather than the
59+ counters. The spinner is shown between the network transfer indicator
60+ and the progress message. (Martin Pool)
61+
62+* Recursive binding for checkouts is now detected by bzr. A clear error
63+ message is shown to the user. (Parth Malwankar, #405192)
64+
65+Improvements
66+************
67+
68+* Add ``bzrlib.merge.MergeIntoMerger``, which can merge part or all of a
69+ tree, and works with unrelated branches. (Andrew Bennetts)
70+
71+Documentation
72+*************
73+
74+* ``bzr help patterns`` now explains case insensitive patterns and
75+ points to Python regular expression documentation.
76+ (Parth Malwankar, #594386)
77+
78+API Changes
79+***********
80+
81+* Delete ``ProgressTask.note``, which was deprecated in 2.1.
82+
83+Internals
84+*********
85+
86+Testing
87+*******
88+
89+* Unit test added to ensure that "message" is not uses as a format variable
90+ name in BzrError subclasses as this conflicts with some Python versions.
91+ (Parth Malwankar, #603461)
92+
93+bzr 2.2b4
94+#########
95+
96+:Codename: Monkey Magic
97+:2.2b4: 2004-07-09
98+
99+
100+This fourth and final beta in the 2.2 series now stabilizes the internal
101+APIs. Plugin authors are recommended to ensure their releases are
102+compatible, so that 2.2rc1 can be a true release candidate, containing
103+stable and compatible plugin versions.
104+
105+For users of bzrlib as a library, one of the primary changes is to request
106+that they call ``bzrlib.initialize`` and use the returned context manager
107+appropriately.
108+
109+Better interaction with ``bzr-loom`` to make sure branching from a loom
110+even over a smart server still yields a local loom. Not to mention lots of
111+bugfixes over 2.2b3.
112+
113+Compatibility Breaks
114+********************
115+
116+* bzrlib library users now need to call ``__enter__`` and ``__exit__`` on
117+ the result of ``bzrlib.initialize``. This change was made when fixing
118+ the bad habit recent bzr versions have had of leaving progress bars
119+ behind on the screen. That required calling another function before
120+ exiting the program, and it made sense to provide a full context
121+ manager at the same time. (Robert Collins)
122+
123+* The ``bzr`` front end now requires a ``bzrlib.ui.ui_factory`` which is a
124+ context manager in the Python 2.5 and above sense. The bzrlib base class
125+ is such a manager, but third party UI factories which do not derive from
126+ ``bzrlib.ui.UIFactory`` will be incompatible with the command line front
127+ end.
128+
129+* URLs like ``foo:bar/baz`` are now always parsed as a URL with scheme "foo"
130+ and path "bar/baz", even if bzr does not recognize "foo" as a known URL
131+ scheme. Previously these URLs would be treated as local paths.
132+ (Gordon Tyler)
133+
134+
135+New Features
136+************
137+
138+* Support ``--directory`` option for a number of additional commands:
139+ conflicts, merge-directive, missing, resolve, shelve, switch,
140+ unshelve, whoami. (Martin von Gagern, #527878)
141+
142+Bug Fixes
143+*********
144+
145+* ``bzr branch`` to a new repository with a default stacking policy no
146+ longer transfers the full history unnecessarily.
147+ (Andrew Bennetts, #597942)
148+
149+* ``bzr init`` does not recursively scan directory contents anymore
150+ leading to faster init for directories with existing content.
151+ (Martin [gz], Parth Malwankar, #501307)
152+
153+* ``bzr log --exclude-common-ancestry`` is now taken into account for
154+ linear ancetries. (Vincent Ladeuil, #575631)
155+
156+* ``bzr log -r branch:REMOTE`` can now properly log the remote branch,
157+ rather than trying to fetch the data locally and failing because of a
158+ readonly error. (Martin von Gagern, #149270)
159+
160+* ``bzr pull`` now works when a lp: URL is explicitly defined as the parent
161+ or pull location in locations.conf or branch.conf.
162+ (Gordon Tyler, #534787)
163+
164+* ``bzr reconfigure --unstacked`` now works with branches accessed via a
165+ smart server. (Andrew Bennetts, #551525)
166+
167+* ``BzrDir.find_branches`` should ignore branches with missing repositories.
168+ (Marius Kruger, Robert Collins)
169+
170+* ``BzrDir.find_bzrdirs`` should ignore dirs that raises PermissionDenied.
171+ (Marius Kruger, Robert Collins)
172+
173+* Ensure that wrong path specifications in ``BZR_PLUGINS_AT`` display
174+ proper error messages. (Vincent Ladeuil, #591215)
175+
176+* Explicitly removing ``--profile-imports`` option from parsed command-line
177+ arguments on Windows, because bzr script does the same.
178+ (Alexander Belchenko, #588277)
179+
180+* Fetching was slightly confused about the best code to use and was
181+ using a new code path for all branches, resulting in more lookups than
182+ necessary on old branches. (Robert Collins, #593515)
183+
184+* Final fix for 'no help for command' issue. We now show a clean message
185+ when a command has no help, document how to set help more clearly, and
186+ test that all commands available to the test suite have help.
187+ (Robert Collins, #177500)
188+
189+* Invalid patterns supplied to ``Globster`` or ``lazy_regex`` now raise
190+ ``InvalidPattern`` exception showing clear error message to the user.
191+ (Parth Malwankar #300062)
192+
193+* Progress output is cleaned up when exiting. (Aaron Bentley)
194+
195+* Raise ValueError instead of a string exception.
196+ (John Arbash Meinel, #586926)
197+
198+* Relative imports in plugins are now handled correctly when using
199+ BZR_PLUGINS_AT. (Vincent Ladeuil, #588959)
200+
201+* ``ScriptRunner`` now strips off leading indentation from test scripts,
202+ which previously caused "SyntaxError: No command for line".
203+ (Martin Pool)
204+
205+* Show unicode filenames in diff headers using terminal encoding.
206+ (Alexander Belchenko, Bug #382699)
207+ NOTE for Windows users: If user need to save diff to file then user need to
208+ change encoding of the terminal to ANSI encoding with command ``chcp XXX``
209+ (e.g. ``chcp 1251`` for Russian Windows).
210+
211+* URL displayed for use with ``break-lock`` when smart server sees lock
212+ contention are now valid. Default timeout for lock contention retry is
213+ now 30 seconds instead of 300 seconds.
214+ (Parth Malwankar, #250451)
215+
216+* ``walkdirs`` now raises a useful message when the filenames are not using
217+ the filesystem encoding. (Eric Moritz, #488519)
218+
219+* Enable debugging of bzr on windows with pdb and other tools. This was
220+ broken because we call GetCommandLineW on windows. The fix adjusts the
221+ command line we get to be the same length as sys.argv.
222+ (Jason Spashett, Alexander Belchenko, #587868)
223+
224+Improvements
225+************
226+
227+* Bazaar now reads data from SSH connections more efficiently on platforms
228+ that provide the ``socketpair`` function, and when using paramiko.
229+ (Andrew Bennetts, #590637)
230+
231+* ``Branch.copy_content_into`` is now a convenience method dispatching to
232+ a ``InterBranch`` multi-method. This permits ``bzr-loom`` and other
233+ plugins to intercept this even when a ``RemoteBranch`` proxy is in use.
234+ (Robert Collins, #201613)
235+
236+* ``Branch`` formats can now be loaded lazily by registering a
237+ ``MetaDirBranchFormatFactory`` rather than an actual format. This will
238+ cause the named format class to be loaded only when an enumeration of
239+ formats is needed or when the format string for the object is
240+ encountered. (Robert Collins, Jelmer Vernooij)
241+
242+* The encoding that bzr uses to output things other than file content can
243+ now be overridden via the output_encoding configuration option.
244+ (Martin Pool, #340394)
245+
246+* Use lazy imports in ``bzrlib/merge.py`` so that plugins like ``news_merge``
247+ do not cause modules to be loaded unnecessarily just because the plugin
248+ registers a merge hook. This improves ``bzr rocks`` time by about 25%
249+ in a default installation (with just the core plugins).
250+ (Andrew Bennetts)
251+
252+Documentation
253+*************
254+
255+* Added ``regression`` tag to our tags list. (Robert Collins)
256+
257+* Improved our release checklist to have a bit less churn and leave things
258+ ready-to-go for the next action (including other people doing
259+ development). (Robert Collins)
260+
261+* Remove obsolete discussion of PQM in documentation about how to
262+ contribute to Bazaar. (Martin Pool, #588444)
263+
264+API Changes
265+***********
266+
267+* ``bzrlib.branch.InterBranch._get_branch_formats_to_test`` now returns
268+ an iterable of format pairs, rather than just a single pair, permitting
269+ InterBranch objects that work with multiple permutations to be
270+ comprehensively tested. (Robert Collins)
271+
272+* ``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
273+ profiles when concurrent profile requests are made. Instead the profile
274+ requests will be serialised. Reentrant requests will now deadlock.
275+ (Robert Collins)
276+
277+* ``bzrlib.knit.KnitSequenceMatcher``, which has been deprecated since
278+ 2007, has been deleted. Use ``PatienceSequenceMatcher`` from
279+ ``bzrlib.patiencediff`` instead. (Andrew Bennetts)
280+
281+* ``bzrlib.re_compile_checked`` is now deprecated. Caller should handle
282+ ``bzrlib.errors.InvalidPattern`` exception thrown by ``re.match`` in
283+ case the default error message not suitable for the use case.
284+ (Parth Malwankar)
285+
286+* ``bzrlib.tests.blackbox.ExternalBase`` is deprecated. It provided only
287+ one method ``check_output``, and we now recommend checking command
288+ output using ``run_script``. (Martin Pool)
289+
290+* ``bzrlib.transport.ssh.SSHVendor.connect_ssh`` now returns an object
291+ that implements the interface of ``bzrlib.transport.ssh.SSHConnection``.
292+ Third-party implementations of ``SSHVendor`` may need to be updated
293+ accordingly. Similarly, any code using ``SSHConnection`` directly will
294+ need to be updated. (Andrew Bennetts)
295+
296+* The constructor of ``bzrilb.smart.medium.SmartSSHClientMedium`` has
297+ changed to take an ``SSHParams`` instance (replacing many individual
298+ values). (Andrew Bennetts)
299+
300+Internals
301+*********
302+
303+* ``bzrlib.osutils.get_terminal_encoding`` will now only mutter its
304+ selection when explicitly requested; this avoids many duplicate calls
305+ being logged when helpers, wrappers and older code that manually calls
306+ it are executed it is now logged deliberately by the ui setup code.
307+ (Robert Collins)
308+
309+* Improved ``bzrlib.urlutils`` to handle lp:foo/bar URLs. (Gordon Tyler)
310+
311+* ``bzrlib._c_static_tuple.StaticTuple`` now implements ``__sizeof__``, so
312+ that ``sys.getsizeof`` and other memory analysis tools will report more
313+ accurate results. (Andrew Bennetts)
314+
315+* The symbol_versioning module can now cleanup after itself -
316+ ``suppress_deprecation_warnings`` now returns a cleanup function.
317+ (Robert Collins)
318+
319+Testing
320+*******
321+
322+* Add ``bzrlib.tests.fixtures`` to hold code for setting up objects
323+ to test. (Martin Pool)
324+
325+* ``test_import_tariff`` now respects BZR_PLUGINS_AT and BZR_PLUGINS_DISABLE.
326+ (Vincent Ladeuil, #595587)
327+
328+bzr 2.2b3
329+#########
330+
331+:2.2b3: 2010-05-28
332+
333+This third beta in the 2.2 series brings with it all the goodness of 2.1.2
334+and 2.0.6 (though it preceeds 2.0.6 slightly). Of particular note for
335+users are compatibility fixes with bzr 1.5 and below servers, a hopeful
336+end to the EINTR errors caused by SIGWINCH interactions, a shiny new
337+bash completion script and bzr will no longer guess at identity details -
338+it was too unreliable in reality. Use ``bzr whoami`` on every new install.
339+For developers we have some API changes which may impact plugins as well
340+as a bunch of our regular improvements to internal clarity and test
341+support.
342+
343+Compatibility Breaks
344+********************
345+
346+* An API break has been made to the lock_write method of ``Branch`` and
347+ ``Repository`` objects; they now return ``branch.BranchWriteLockResult``
348+ and ``repository.RepositoryWriteLockResult`` objects. This makes
349+ changing the API in future easier and permits some cleaner calling code.
350+ The lock_read method has also changed from having no defined return
351+ value to returning ``LogicalLockResult`` objects.
352+ (Robert Collins)
353+
354+* ``bzr`` does not try to guess the username as ``username@hostname``
355+ and requires it to be explictly set. This can be set using ``bzr
356+ whoami``. (Parth Malwankar, #549310)
357+
358+* ``bzrlib.commands.Command`` will now raise ValueError during
359+ construction if there is no __doc__ set. (Note, this will be reverted in
360+ 2.2b4) (Robert Collins)
361+
362+* The source tree no longer contains a contrib/zsh/_bzr completion
363+ script. The new file contrib/zsh/README suggests alternatives.
364+ (Martin von Gagern, #560030)
365+
366+New Features
367+************
368+
369+* ``bzr commit`` accepts ``-p`` (for "patch") as a shorter name for
370+ ``--show-diff``.
371+ (Parth Malwankar, #571467)
372+
373+* ``bzr ignore`` now supports a ``--default-rules`` option that displays
374+ the default ignore rules used by bzr. The flag ``--old-default-rules``
375+ is no longer supported by ``ignore``.
376+ (Parth Malwankar, #538703)
377+
378+* ``bzr pack`` now supports a ``--clean-obsolete-packs`` option that
379+ can save disk space by deleting obsolete pack files created during the
380+ pack operation.
381+ (Parth Malwankar, #304320)
382+
383+* New command line option ``--authors`` to ``bzr log`` allows users to
384+ select which of the apparent authors and committer should be
385+ included in the log. Defaults depend on format. (Martin von Gagern, #513322)
386+
387+* Support ``--directory`` option for a number of additional commands:
388+ added, annotate, bind, cat, cat-revision, clean-tree, deleted,
389+ export, ignore, ignored, lookup-revision, ls, modified, nick,
390+ re-sign, unbind, unknowns.
391+ (Martin von Gagern, #527878)
392+
393+* The bash_completion plugin from the bzr-bash-completion project has
394+ been merged into the tree. It provides a bash-completion command and
395+ replaces the outdated ``contrib/bash/bzr`` script with a version
396+ using the plugin. (Martin von Gagern, #560030)
397+
398+* A new transport based on GIO (the gnome i/o library) provides access to
399+ samba shares, webdav using gio+smb and gio+dav. It is also possible to
400+ use gio for some already existing transport methods as gio+file,
401+ gio+sftp, gio+ftp.
402+ (Mattias Eriksson)
403+
404+Bug Fixes
405+*********
406+
407+* Alias information shown by ``bzr help`` is now accurate. This
408+ was showing an internal object name for some plugin aliases.
409+ (Parth Malwankar, #584650)
410+
411+* ``.bazaar``, ``.bazaar/bazaar.conf`` and ``.bzr.log`` inherit user and
412+ group ownership from the containing directory. This allow bzr to work
413+ better with sudo.
414+ (Martin <gzlist@googlemail.com>, Parth Malwankar, #376388)
415+
416+* ``bzr clean-tree`` should not delete nested bzrdirs. Required for proper
417+ support of bzr-externals and scmproj plugins.
418+ (Alexander Belchenko, bug #572098)
419+
420+* ``bzr ignore`` will no longer add duplicate patterns to .bzrignore.
421+ (Gordon Tyler, #572092)
422+
423+* ``bzr log --exclude-common-ancestry -r X..Y`` displays the revisions that
424+ are part of Y ancestry but not part of X ancestry (aka the graph
425+ difference).
426+ (Vincent Ladeuil, #320119)
427+
428+* ``bzr lp-propose`` which was switched to use production Launchpad API
429+ servers a few commits ago has been reverted to use edge: there is a
430+ problem with using production which isn't trivially obvious, so we've
431+ filed a bug to track it, and until thats fixed will be using edge.
432+ (Robert Collins, #583667)
433+
434+* ``bzr rm`` should not refuse to delete directories which contained a file
435+ which has been moved elsewhere in the tree after the previous commit.
436+ (Marius Kruger, Daniel Watkins, #129880)
437+
438+* ``bzr selftest --parallel=fork`` wait for its children avoiding zombies.
439+ (Vincent Ladeuil, #566670)
440+
441+* ``bzr selftest`` should not use ui.note() since it's not unicode safe.
442+ (Vincent Ladeuil, #563997)
443+
444+* CommitBuilder refuses to create revisions whose trees have no root.
445+ (Aaron Bentley)
446+
447+* Do not register a SIGWINCH signal handler, instead just poll for the
448+ terminal width as needed. This avoids the "Interrupted System Call"
449+ problems that occur on POSIX with all currently released versions of
450+ Python.
451+ (Andrew Bennetts, #583941)
452+
453+* Don't mention --no-strict when we just issue the warning about unclean trees.
454+ (Vincent Ladeuil, #401599)
455+
456+* Fixed ``AssertionError`` when accessing smart servers running Bazaar
457+ versions before 1.6.
458+ (Andrew Bennetts, #528041)
459+
460+* Improved progress bar for fetch (2a format only). Bazaar now shows an
461+ estimate of the number of records to be fetched vs actually fetched.
462+ (Parth Malwankar, #374740, #538868)
463+
464+* Reduce peak memory by one copy of compressed text.
465+ (John Arbash Meinel, #566940)
466+
467+* ``RemoteBranch.lock_write`` raises ``ReadOnlyError`` if called during a
468+ read lock, rather than causing an ``AttributeError``.
469+ (Andrew Bennetts, Данило Шеган, #582781)
470+
471+* Selftest was failing with testtools 0.9.3, which caused an
472+ AssertionError raised from a cleanUp to be reported as a Failure, not an
473+ Error, breaking on of our test hygiene tests.
474+ (Robert Collins, Vincent Ladeuil).
475+
476+* ``set_user_option`` with a dict on remote branches no longer fails with
477+ an AttributeError. There is a new ``Branch.set_config_option_dict`` RPC
478+ to support this efficiently.
479+ (Andrew Bennetts, #430382)
480+
481+* Show the filenames when a file rename fails so that the error will be
482+ more comprehensible.
483+ (Martin Pool, #491763)
484+
485+* Support Pyrex 0.9.9, required changing how we handle exceptions in Pyrex.
486+ (John Arbash Meinel, #582656)
487+
488+* Unicode characters in aliases are now handled correctly and do not cause
489+ UnicodeEncodeError exception. (Parth Malwankar, #529930)
490+
491+* Unicode commit messages that are the same as a file name no longer cause
492+ UnicodeEncodeError. ``ui.text.show_warning`` now handles unicode
493+ messages.
494+ (Parth Malwankar, #563646)
495+
496+* Using bzr with `lp:` urls behind an http proxy should work.
497+ (Robert Collins, #558343)
498+
499+* When passing a file to ``UTF8DirReader`` make sure to close the current
500+ directory file handle after the chdir fails. Otherwise when passing many
501+ filenames into a command line ``bzr status`` we would leak descriptors.
502+ (John Arbash Meinel, #583486)
503+
504+Improvements
505+************
506+
507+* ``append_revisions_only`` will now be interpreted as a boolean and a
508+ warning emitted if illegal values are used. Note that for projects
509+ that needs to maintain compatibility with previsous bzr versions,
510+ only 'True' and 'False' strings must be used (previous versions of
511+ bzr will interpret all strings differing from 'True'
512+ (case-sensitive) as false.
513+ (Brian de Alwis, Vincent Ladeuil)
514+
515+* ``bzr ls`` now supports short options for existing long options.
516+ ``-k/--kind``, ``-i/--ignored``, ``-u/--unknown`` and ``-0/--null``.
517+ (Parth Malwankar, #181124)
518+
519+* ``Config.get_user_option_as_bool`` will now warn if a value cannot
520+ be interpreted as a boolean.
521+ (Vincent Ladeuil)
522+
523+* The all-in-one Windows installer will now be built with docstrings stripped
524+ from the library zip, reducing the size and slightly improving cold startup
525+ time. Bundled plugins are unchanged for the moment, but if adding other new
526+ plugins to an all-in-one installation, ensure they are compiled and
527+ installed with -O1 or help may not work. (Martin [gz])
528+
529+Documentation
530+*************
531+
532+API Changes
533+***********
534+
535+* Added ``bzrlib.merge.PerFileMerger``, a more convenient way to write
536+ some kinds of ``merge_file_content`` hook functions.
537+ (Andrew Bennetts)
538+
539+* `BzrDir`, `Branch`, `Repository` and `WorkingTree` now all support `user_url`,
540+ `user_transport`, `control_url` and `control_transport` members pointing
541+ respectively to the directory containing the ``.bzr`` control directory,
542+ and to the directory within ``.bzr`` used for the particular component.
543+ All of them inherit from `ControlComponent` which provides default
544+ implementations.
545+ (Martin Pool)
546+
547+* Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
548+ expected to return an object which can be used to unlock them. This reduces
549+ duplicate code when using cleanups. The previous 'tokens's returned by
550+ ``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
551+ on the result of the lock_write. ``repository.RepositoryWriteLockResult``
552+ and ``branch.BranchWriteLockResult`` document this. (Robert Collins)
553+
554+* ``Repository.refresh_data`` may now be called in a write group on
555+ pack-based repositories. Older repositories will still raise an error
556+ in this case. Subclasses of ``Repository`` can still override
557+ ``Repository._refresh_data``, but are now responsible for raising
558+ ``bzrlib.repository.IsInWriteGroupError`` if they do not support
559+ ``refresh_data`` during a write group.
560+ (Andrew Bennetts, #574236)
561+
562+Internals
563+*********
564+
565+* ``chk_map._bytes_to_text_key`` is now an optimized function to extract
566+ the (file-id, revision-id) key from a CHKInventory entry. This can
567+ potentially shave 5-10% time off during a large fetch. Related to bug
568+ #562666. (John Arbash Meinel)
569+
570+* ``log._get_info_for_log_files`` now takes an add_cleanup callable.
571+ (Robert Collins)
572+
573+* ``_remember_remote_is_before`` no longer raises AssertionError when
574+ suboptimal network behaviour is noticed; instead it just mutters to the
575+ log file (and warns the user if they have set the ``hpss`` debug flag).
576+ This was causing unnecessary aborts for performance bugs that are minor
577+ at worst.
578+ (Andrew Bennetts, #528041)
579+
580+* Permit bzr to run under ``python -OO`` which reduces the size of bytecode
581+ files loaded from disk. To ensure docstrings needed for help are never
582+ stripped, the prefix ``__doc__ =`` should now be used.
583+ (Martin <gzlist@googlemail.com>)
584+
585+* No longer require zlib headers to build extensions, and remove the need
586+ for seperate copy of zlib library on windows.
587+ (John Arbash Meinel, Martin <gzlist@googlemail.com>, #66923)
588+
589+Testing
590+*******
591+
592+* Added ``bzrlib.tests.matchers`` as a place to put matchers, along with
593+ our first in-tree matcher. See the module docstring for details.
594+ (Robert Collins)
595+
596+* ``bzr selftest --parallel=subprocess`` now works correctly on win32.
597+ (Gordon Tyler, #551332)
598+
599+* Workaround ``Crypto.Random`` check leading to spurious test
600+ failures on Lucid, FreeBSD and gentoo.
601+ (Vincent Ladeuil, #528436)
602+
603+* New class ``ExecutableFeature`` for checking the availability of
604+ executables on the ``PATH``. Migrated from bash_completion plugin.
605+ (Martin von Gagern)
606+
607+bzr 2.2b2
608+#########
609+
610+:2.2b2: 2010-04-16
611+
612+This is a somewhat early second beta of the 2.2 series, to fix a python2.4
613+incompatibility in the 2.2b1 release. It also includes a swag of
614+performance, usability and correctness improvements: test feedback on all
615+of these would be welcome.
616+
617+
618+New Features
619+************
620+
621+* ``bzr diff`` now supports a --format option, which can be used to
622+ select alternative diff formats. (Jelmer Vernooij, #555994)
623+
624+Bug Fixes
625+*********
626+
627+* ``bzr dpush``, ``bzr push`` and ``bzr send`` will now issue a warning
628+ instead of failing when dirty trees are involved. The corresponding
629+ ``dpush_strict``, ``push_strict`` and ``send_strict`` should be set to
630+ True explicitly to get the previous behaviour.
631+ (Vincent Ladeuil, #519319)
632+
633+* ``bzr export`` to tar file does not fail if any parent directory
634+ contains unicode characters. This works around upstream Python bug
635+ http://bugs.python.org/issue8396 .
636+ (Parth Malwankar, #413406)
637+
638+* ``bzr switch`` does not die if a ConfigurableFileMerger is used.
639+ (Aaron Bentley, #559436)
640+
641+* ``bzr update`` when a pending merge in the working tree has been merged
642+ into the master branch will no longer claim that old commits have become
643+ pending merges. (Robert Collins, #562079)
644+
645+* ``bzrlib.mutabletree.MutableTree.commit`` will now support a passed in
646+ config as in previous versions of bzrlib. (Robert Collins)
647+
648+* Fix glitch in the warning about unclean trees display.
649+ (Vincent Ladeuil, #562665)
650+
651+* Fixed Python2.4 incompatibilities in the bzr2.2b1 source tarball.
652+ (Martin Pool)
653+
654+* Help messages generated by ``RegistryOption.from_kwargs`` list the
655+ switches in alphabetical order, rather than in an undefined order.
656+ (Martin von Gagern, #559409)
657+
658+* Make sure the ``ExecutablePath`` and ``InterpreterPath`` are set in
659+ Apport crash reports, to avoid "This problem report applies to a program
660+ which is not installed any more" error.
661+ (Martin Pool, James Westby, #528114)
662+
663+* Reset ``siginterrupt`` flag to False every time we handle a signal
664+ installed with ``set_signal_handler(..., restart_syscall=True)`` (from
665+ ``bzrlib.osutils``. Reduces the likelihood of "Interrupted System Call"
666+ errors compared to registering ``signal.signal`` directly.
667+ (Andrew Bennetts)
668+
669+* When invoked with a range revision, ``bzr log`` doesn't show revisions
670+ that are not part of the Y revisions ancestry anymore when invoked with
671+ -rX..Y.
672+ (Vincent Ladeuil, #474807)
673+
674+* Properly handle ``param_name`` attribute for ``ListOption``.
675+ (Martin von Gagern, 387117)
676+
677+Improvements
678+************
679+
680+* ``bzr commit`` will prompt before using a commit message that was
681+ generated by a template and not edited by the user.
682+ (Robert Collins, #530265)
683+
684+* ``bzr diff`` read-locks the trees and branches only once, saving about
685+ 10-20ms on ``bzr diff`` in a bzr.dev tree.
686+ (Andrew Bennetts)
687+
688+* ``bzr missing`` read-locks the branches only once.
689+ (Andrew Bennetts)
690+
691+* ``bzr pull`` locks the branches and tree only once.
692+ (Andrew Bennetts)
693+
694+* Index lookups in pack repositories search recently hit pack files first.
695+ In repositories with many pack files this can greatly reduce the
696+ number of files accessed, the number of bytes read, and the number of
697+ read calls. An incremental pull via plain HTTP takes half the time and
698+ bytes for a moderately large repository. (Andrew Bennetts)
699+
700+* Index lookups only re-order the indexes when the hit files aren't
701+ already first. Reduces the cost of reordering
702+ (John Arbash Meinel, #562429)
703+
704+* Less code is loaded at startup. (Cold-cache start time is about 10-20%
705+ less.)
706+ (Martin Pool, #553017)
707+
708+API Changes
709+***********
710+
711+* ``bzrlib.diff.get_trees_and_branches_to_diff`` is deprecated. Use
712+ ``get_trees_and_branches_to_diff_locked`` instead.
713+ (Andrew Bennetts)
714+
715+* ``TreeTransform.commit`` supports the full set of commit parameters, and
716+ auto-determines branch nick if not supplied. (Aaron Bentley)
717+
718+Internals
719+*********
720+
721+* ``bzrlib.commands.Command.run_direct`` is no longer needed - the pre
722+ 2.1 method of calling run() to perform testing or direct use via the API
723+ is now possible again. As part of this, the _operation attribute on
724+ Command is now transient and only exists for the duration of ``run()``.
725+ (Robert Collins)
726+
727+bzr 2.2b1
728+#########
729+
730+:2.2b1: 2010-04-01
731+
732+This is the first beta of the 2.2 series, leading up to a 2.2.0
733+release in July or August. Beta releases are suitable for everyday use
734+but may cause some incompatibilities with plugins. Some plugins may need
735+small updates to work with 2.2b1.
736+
737+2.2b1 includes some changes to make merge conflicts easier to understand
738+and resolve. It also removes some old unnecessary code, and loads
739+somewhat less code at startup. It starts adding a common infrastructure
740+for dealing with colocated named branches, which can be implemented in
741+various ways in either bzr native or foreign formats. On Ubuntu and
742+other platforms with the apport bug-reporting library, there's an easier
743+path to report problems with bzr. We plan to continue with these themes
744+through the 2.2 series.
745+
746+Over thirty bugs have been fixed, including in the log command, exporting
747+to tarballs, restarting interrupted system calls, portability of compiled
748+extensions, making backups during upgrade, and locking on ftp.
749+
750+Compatibility Breaks
751+********************
752+
753+* BTreeGraphIndex can now take an offset to indicate that the data starts
754+ somewhere other than then beginning of the file. (John Arbash Meinel)
755+
756+* Deleted very old hidden commands ``versionedfile-list``,
757+ ``weave-plan-merge``, ``weave-merge-text``.
758+ (Martin Pool)
759+
760+* ``Repository.get_inventory_sha1()`` and ``Repository.get_revision_xml()``
761+ have been removed. (Jelmer Vernooij)
762+
763+* ``Repository.get_revision_inventory()`` has been removed in favor of
764+ ``Repository.get_inventory()``. (Jelmer Vernooij)
765+
766+* All test servers have been moved out of the bzrlib.transport hierarchy to
767+ bzrlib.tests.test_server *except* for MemoryServer, ChrootServer and
768+ PathFilteringServer. ``bzrlib`` users may encounter test failures that can
769+ be fixed by updating the related imports from ``bzrlib.transport.xxx`` to
770+ ``bzrlib.tests.test_server``.
771+ (Vincent Ladeuil)
772+
773+* ``BranchReferenceFormat.initialize()`` now takes an optional name argument
774+ as its second parameter, for consistency with the initialize() method of
775+ other formats. (Jelmer Vernooij)
776+
777+New Features
778+************
779+
780+* Added ``bzr remove-branch`` command that can remove a local or remote
781+ branch. (Jelmer Vernooij, #276295)
782+
783+* ``bzr export`` now takes an optional argument ``--per-file-timestamps``
784+ to set file mtimes to the last timestamp of the last revision in which
785+ they were changed rather than the current time. (Jelmer Vernooij)
786+
787+* If the Apport crash-reporting tool is available, bzr crashes are now
788+ stored into the ``/var/crash`` apport spool directory, and the user is
789+ invited to report them to the developers from there, either
790+ automatically or by running ``apport-bug``. No information is sent
791+ without specific permission from the user. (Martin Pool, #515052)
792+
793+* Parsing of command lines, for example in ``diff --using``, no longer
794+ treats backslash as an escape character on Windows. (Gordon Tyler,
795+ #392248)
796+
797+* Plugins can be disabled by defining ``BZR_DISABLE_PLUGINS`` as
798+ a list of plugin names separated by ':' (';' on windows).
799+ (Vincent Ladeuil, #411413)
800+
801+* Plugins can be loaded from arbitrary locations by defining
802+ ``BZR_PLUGINS_AT`` as a list of name@path separated by ':' (';' on
803+ windows). This takes precedence over ``BZR_PLUGIN_PATH`` for the
804+ specified plugins. This is targeted at plugin developers for punctual
805+ needs and *not* intended to replace ``BZR_PLUGIN_PATH``.
806+ (Vincent Ladeuil, #82693)
807+
808+* Tag names can now be determined automatically by ``automatic_tag_name``
809+ hooks on ``Branch`` if they are not specified on the command line.
810+ (Jelmer Vernooij)
811+
812+* Tree-shape conflicts can be resolved by providing ``--take-this`` and
813+ ``--take-other`` to the ``bzr resolve`` command. Just marking the conflict
814+ as resolved is still accessible via the ``--done`` default action.
815+ (Vincent Ladeuil)
816+
817+* Merges can be proposed on Launchpad with the new lp-propose-merge command.
818+ (Aaron Bentley, Jonathan Lange)
819+
820+Bug Fixes
821+*********
822+
823+* Added docstring for ``Tree.iter_changes``
824+ (John Arbash Meinel, #304182)
825+
826+* Allow additional arguments to
827+ ``RemoteRepository.add_inventory_by_delta()``. (Jelmer Vernooij, #532631)
828+
829+* Allow exporting a single file using ``bzr export``.
830+ (Michal Junák, #511987)
831+
832+* Allow syscalls to automatically restart when ``TextUIFactory``'s
833+ SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
834+ IO, which are often poorly handled by Python's libraries and parts of
835+ bzrlib. (Andrew Bennetts, #496813)
836+
837+* Avoid infinite recursion when probing for apport.
838+ (Vincent Ladeuil, #516934)
839+
840+* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
841+ (Martin Pool, #331095)
842+
843+* Avoid truncating svn URLs.
844+ (Martin Pool, Martin von Gagern, #545185)
845+
846+* ``bzr add`` will not add conflict related files unless explicitly required.
847+ (Vincent Ladeuil, #322767, #414589)
848+
849+* ``bzr dump-btree`` now works on ``*.cix`` and ``*.six`` files. Those
850+ indices do not have reference lists, so ``dump-btree`` will simply show
851+ ``None`` instead. (Andrew Bennetts, #488607)
852+
853+* ``bzr help`` will no longer trigger the get_missing_command hook when
854+ doing a topic lookup. This avoids prompting (like 'no command plugins/loom,
855+ did you mean log?') when getting help. In future we may trigger the hook
856+ deliberately when no help topics match from any help index.
857+ (Robert Collins, #396261)
858+
859+* ``bzr log -n0 -r..A.B.C`` should not crash but just consider the None
860+ revspec as representing the first revision of the branch.
861+ (Vincent Ladeuil, #519862)
862+
863+* ``bzr remove-tree`` can now remove multiple working trees.
864+ (Jared Hance, Andrew Bennetts, #253137)
865+
866+* ``bzr resolve --take-this`` and ``--take-other`` now correctly renames
867+ the kept file on content conflicts where one side deleted the file.
868+ (Vincent Ladeuil, #529968)
869+
870+* ``bzr upgrade`` now creates the ``backup.bzr`` directory with the same
871+ permissions as ``.bzr`` directory on a POSIX OS.
872+ (Parth Malwankar, #262450)
873+
874+* ``bzr upgrade`` now names backup directory as ``backup.bzr.~N~`` instead
875+ of ``backup.bzr``. This directory is ignored by bzr commands such as
876+ ``add``.
877+ (Parth Malwankar, #335033, #300001)
878+
879+* Cope with non-utf8 characters inside ``.bzrignore``.
880+ (Jason Spashett, #183504)
881+
882+* Correctly interpret "451 Rename/move failure: Directory not empty" from
883+ ftp servers while trying to take a lock.
884+ (Martin Pool, #528722)
885+
886+* DirStateRevisionTree.kind() was returning wrong result when 'kind'
887+ changes occured between the workingtree and one of its parents.
888+ (Vincent Ladeuil, #535547)
889+
890+* Fix ``log`` to better check ancestors even if merged revisions are involved.
891+ (Vincent Ladeuil, #476293)
892+
893+* Loading a plugin from a given path with ``BZR_PLUGINS_AT`` doesn't depend
894+ on os.lisdir() order and is now reliable.
895+ (Vincent Ladeuil, #552922).
896+
897+* Many IO operations that returned ``EINTR`` were retried even if it
898+ wasn't safe to do so via careless use of ``until_no_eintr``. Bazaar now
899+ only retries operations that are safe to retry, and in some cases has
900+ switched to operations that can be retried (e.g. ``sock.send`` rather than
901+ ``sock.sendall``).
902+ (Andrew Bennetts, Martin <gzlist@googlemail.com>, #496813)
903+
904+* Path conflicts now support --take-this and --take-other even when a
905+ deletion is involved.
906+ (Vincent Ladeuil, #531967)
907+
908+* Network transfer amounts and rates are now displayed in SI units according
909+ to the Ubuntu Units Policy <https://wiki.ubuntu.com/UnitsPolicy>.
910+ (Gordon Tyler, #514399)
911+
912+* Support kind markers for socket and fifo filesystem objects. This
913+ prevents ``bzr status --short`` from crashing when those files are
914+ present. (John Arbash Meinel, #303275)
915+
916+* ``bzr mkdir DIR`` will not create DIR unless DIR's parent is a versioned
917+ directory. (Parth Malwankar, #138600)
918+
919+* SSH child processes will now ignore SIGQUIT on nix systems so breaking into
920+ the debugger won't kill the session.
921+ (Martin <gzlist@googlemail.com>, #162502)
922+
923+* Tolerate patches with leading noise in ``bzr-handle-patch``.
924+ (Toshio Kuratomi, Martin Pool, #502076)
925+
926+* ``update -r`` now supports updating to revisions that are not on
927+ mainline (i.e. it supports dotted revisions).
928+ (Parth Malwankar, #517800)
929+
930+* Use first apparent author not committer in GNU Changelog format.
931+ (Martin von Gagern, #513322)
932+
933+API Changes
934+***********
935+
936+* ``bzrlib.merge_directive._BaseMergeDirective`` has been renamed to
937+ ``bzrlib.merge_directive.BaseMergeDirective`` and is now public.
938+ (Jelmer Vernooij)
939+
940+* ``BranchFormat.initialize`` now takes an optional ``name`` of the colocated
941+ branch to create. (Jelmer Vernooij)
942+
943+* ``BzrDir.get_branch_transport`` now takes an optional ``name`` of the
944+ colocated branch to open. (Jelmer Vernooij)
945+
946+* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
947+ can set a signal handler and call ``signal.siginterrupt(signum,
948+ False)`` for it, if the platform and Python version supports it.
949+ (Andrew Bennetts, #496813)
950+
951+* New ``bzrlib.initialize`` is recommended for programs using bzrlib to
952+ run when starting up; it sets up several things that previously needed
953+ to be done separately.
954+ (Martin Pool, #507710)
955+
956+* Exporters now support a ``per_file_timestamps`` argument to write out the
957+ timestamp of the commit in which a file revision was introduced.
958+ (Jelmer Vernooij)
959+
960+* New method ``BzrDir.list_branches()`` that returns a sequence of branches
961+ present in a control directory. (Jelmer Vernooij)
962+
963+* New method ``Repository.get_known_graph_ancestry()``.
964+ (Jelmer Vernooij, #495502)
965+
966+* New transport methods ``readlink``, ``symlink`` and ``hardlink``.
967+ (Neil Santos)
968+
969+* Remove unused ``CommandFailed`` exception.
970+ (Martin Pool)
971+
972+Internals
973+*********
974+
975+* ``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
976+ ``message_callback`` in the same way that commit does. (Robert Collins)
977+
978+* ``bzrlib.builtins.Commit.run`` raises ``bzrlib.errors.BoundBranchOutOfDate``
979+ rather than ``bzrlib.errors.BzrCommandError`` when the bound branch is out
980+ of date. (Gary van der Merwe)
981+
982+* ``bzrlib.commands.run_bzr`` is more extensible: callers can supply the
983+ functions to load or disable plugins if they wish to use a different
984+ plugin mechanism; the --help, --version and no-command name code paths
985+ now use the generic pluggable command lookup infrastructure.
986+ (Robert Collins)
987+
988+* ``bzrlib.errors.BoundBranchOutOfDate`` has a new field ``extra_help``
989+ which can be set to add extra help to the error. (Gary van der Merwe)
990+
991+* New method ``Branch.automatic_tag_name`` that can be used to find the
992+ tag name for a particular revision automatically. (Jelmer Vernooij)
993+
994+* The methods ``BzrDir.create_branch()``, ``BzrDir.destroy_branch()`` and
995+ ``BzrDir.open_branch()`` now take an optional ``name`` argument.
996+ (Jelmer Vernooij)
997+
998+Testing
999+*******
1000+
1001+* bzr now has a ``.testr.conf`` file in its source tree configured
1002+ appropriately for running tests with Testrepository
1003+ (``https://launchpad.net/testrepository``). (Robert Collins)
1004+
1005+* Documentation about testing with ``subunit`` has been tweaked.
1006+ (Robert Collins)
1007+
1008+* Known failures has been added for resolve --take-other on ParentLoop
1009+ conflicts. This reflects bug #537956 without fixing it.
1010+ (Vincent Ladeuil)
1011+
1012+* New ``bzrlib.tests.test_import_tariff`` can make assertions about what
1013+ Python modules are loaded, to guard against startup time or library
1014+ dependency regressions.
1015+ (Martin Pool)
1016+
1017+* PQM will now run with subunit output. To analyze a PQM error use
1018+ tribunal, or cat log | subunit-filter | subunit2pyunit. (Robert Collins)
1019+
1020+* Stop sending apport crash files to ``.cache`` in the directory from
1021+ which ``bzr selftest`` was run. (Martin Pool, #422350)
1022+
1023+* Tests no longer fail if "close() called during concurrent
1024+ operation on the same file object" occurs when closing the log file
1025+ (which can happen if a thread tries to write to the log file at the
1026+ wrong moment). An warning will be written to ``stderr`` when this
1027+ happens, and another warning will be written if the log file could not
1028+ be closed after retrying 100 times. (Andrew Bennetts, #531746)
1029+
1030+bzr 2.1.3
1031+#########
1032+
1033+:Codename: Do run run
1034+:2.1.3: NOT RELEASED YET
1035+
1036+Compatibility Breaks
1037+********************
1038+
1039+New Features
1040+************
1041+
1042+Bug Fixes
1043+*********
1044+
1045+* Configuration files in ``${BZR_HOME}`` are now written in an atomic
1046+ way which should help avoid problems with concurrent writers.
1047+ (Vincent Ladeuil, #525571)
1048+
1049+* Don't traceback trying to unversion children files of an already
1050+ unversioned directory. (Vincent Ladeuil, #494221)
1051+
1052+* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
1053+ which can result in "missing referenced chk root keys" errors when
1054+ fetching from repositories with affected revisions.
1055+ (Andrew Bennetts, #522637)
1056+
1057+* Raise ValueError instead of a string exception.
1058+ (John Arbash Meinel, #586926)
1059+
1060+Improvements
1061+************
1062+
1063+Documentation
1064+*************
1065+
1066+API Changes
1067+***********
1068+
1069+Internals
1070+*********
1071+
1072+Testing
1073+*******
1074+
1075+bzr 2.1.2
1076+#########
1077+
1078+:2.1.2: 2010-05-28
1079+
1080+This release fixes two critical networking issues with older servers and
1081+with interrupted system call errors when pushing or pulling. We recommend
1082+upgrading to anyone running a 2.1.x version of bzr.
1083+
1084+Bug Fixes
1085+*********
1086+
1087+* ``bzr clean-tree`` should not delete nested bzrdirs. Required for proper
1088+ support of bzr-externals and scmproj plugins.
1089+ (Alexander Belchenko, bug #572098)
1090+
1091+* ``bzr switch`` does not die if a ConfigurableFileMerger is used.
1092+ (Aaron Bentley, #559436)
1093+
1094+* Do not register a SIGWINCH signal handler, instead just poll for the
1095+ terminal width as needed. This avoids the "Interrupted System Call"
1096+ problems that occur on POSIX with all currently released versions of
1097+ Python.
1098+ (Andrew Bennetts, #583941)
1099+
1100+* Fixed ``AssertionError`` when accessing smart servers running Bazaar
1101+ versions before 1.6.
1102+ (Andrew Bennetts, #528041)
1103+
1104+* Reset ``siginterrupt`` flag to False every time we handle a signal
1105+ installed with ``set_signal_handler(..., restart_syscall=True)`` (from
1106+ ``bzrlib.osutils``. Reduces the likelihood of "Interrupted System Call"
1107+ errors compared to registering ``signal.signal`` directly.
1108+ (Andrew Bennetts)
1109+
1110+* Reduce peak memory by one copy of compressed text.
1111+ (John Arbash Meinel, #566940)
1112+
1113+* Support Pyrex 0.9.9, required changing how we handle exceptions in Pyrex.
1114+ (John Arbash Meinel, #582656)
1115+
1116+* When passing a file to ``UTF8DirReader`` make sure to close the current
1117+ directory file handle after the chdir fails. Otherwise when passing many
1118+ filenames into a command line ``bzr status`` we would leak descriptors.
1119+ (John Arbash Meinel, #583486)
1120+
1121+Internals
1122+*********
1123+
1124+* ``_remember_remote_is_before`` no longer raises AssertionError when
1125+ suboptimal network behaviour is noticed; instead it just mutters to the
1126+ log file (and warns the user if they have set the ``hpss`` debug flag).
1127+ This was causing unnecessary aborts for performance bugs that are minor
1128+ at worst.
1129+ (Andrew Bennetts, #528041)
1130+
1131+
1132+bzr 2.1.1
1133+#########
1134+
1135+:2.1.1: 2010-03-24
1136+
1137+This is a small bugfix release. Upgrading is recommended for anyone
1138+running 2.1.0 or earlier.
1139+
1140+Bug Fixes
1141+*********
1142+
1143+* Allow syscalls to automatically restart when ``TextUIFactory``'s
1144+ SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
1145+ IO, which are often poorly handled by Python's libraries and parts of
1146+ bzrlib. (Andrew Bennetts, #496813)
1147+
1148+* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
1149+ (Martin Pool, #331095)
1150+
1151+* Fix plugin packaging on Windows. (Ian Clatworthy, #524162)
1152+
1153+* Fix stub sftp test server to call os.getcwdu().
1154+ (Vincent Ladeuil, #526221, #526353)
1155+
1156+* Fixed CHM generation by moving the NEWS section template into
1157+ a separate file. (Ian Clatworthy, #524184)
1158+
1159+* Merge correctly when this_tree is not a WorkingTree. (Aaron Bentley)
1160+
1161+* Register SIGWINCH handler only when creating a ``TextUIFactory``; avoids
1162+ problems importing bzrlib from a non-main thread.
1163+ (Elliot Murphy, #521989)
1164+
1165+* Repositories accessed via a smart server now reject being stacked on a
1166+ repository in an incompatible format, as is the case when accessing them
1167+ via other methods. This was causing fetches from those repositories via
1168+ a smart server (e.g. using ``bzr branch``) to receive invalid data.
1169+ (Andrew Bennetts, #562380)
1170+
1171+* Standardize the error handling when creating a new ``StaticTuple``
1172+ (problems will raise TypeError). (Matt Nordhoff, #457979)
1173+
1174+* Warn if pyrex is too old to compile the new ``SimpleSet`` and
1175+ ``StaticTuple`` extensions, rather than having the build fail randomly.
1176+ (John Arbash Meinel, #449776)
1177+
1178+Documentation
1179+*************
1180+
1181+* Added a link to the Desktop Guide. (Ian Clatworthy)
1182+
1183+* Added What's New in Bazaar 2.1 document. (Ian Clatworthy)
1184+
1185+* Drop Google Analytics from the core docs as they caused problems
1186+ in the CHM files. (Ian Clatworthy, #502010)
1187+
1188+API Changes
1189+***********
1190+
1191+* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
1192+ can set a signal handler and call ``signal.siginterrupt(signum,
1193+ False)`` for it, if the platform and Python version supports it.
1194+ (Andrew Bennetts, #496813)
1195+
1196+
1197+bzr 2.1.0
1198+#########
1199+
1200+:Codename: Strasbourg
1201+:2.1.0: 2010-02-11
1202+
1203+This release marks our second long-term-stable series. The Bazaar team
1204+has decided that we will continue to make bugfix-only 2.0.x and 2.1.x
1205+releases, along with 2.2 development releases.
1206+
1207+This is a fairly incremental update, focusing on polish and bugfixing.
1208+There are no changes for supported disk formats. Key updates include
1209+reduced memory consumption for many operations, a new per-file merge
1210+hook, ignore patterns can now include '!' to exclude files, globbing
1211+support for all commands on Windows, and support for addressing home
1212+directories via ``bzr+ssh://host/~/`` syntax.
1213+
1214+Users are encouraged to upgrade from the 2.0 stable series.
1215+
1216+Bug Fixes
1217+*********
1218+
1219+* Don't require testtools to use sftp.
1220+ (Vincent Ladeuil, #516183)
1221+
1222+* Fix "AttributeError in Inter1and2Helper" during fetch.
1223+ (Martin Pool, #513432)
1224+
1225+* ``bzr update`` performs the two merges in a more logical order and will stop
1226+ when it encounters conflicts.
1227+ (Gerard Krol, #113809)
1228+
1229+* Give a better error message when doing ``bzr bind`` in an already bound
1230+ branch. (Neil Martinsen-Burrell, #513063)
1231+
1232+* Ignore ``KeyError`` from ``remove_index`` during ``_abort_write_group``
1233+ in a pack repository, which can happen harmlessly if the abort occurs during
1234+ finishing the write group. Also use ``bzrlib.cleanup`` so that any
1235+ other errors that occur while aborting the individual packs won't be
1236+ hidden by secondary failures when removing the corresponding indices.
1237+ (Andrew Bennetts, #423015)
1238+
1239+* Set the mtime of files exported to a directory by ``bzr export`` all to
1240+ the same value to avoid confusing ``make`` and other date-based build
1241+ systems. (Robert Collins, #515631)
1242+
1243+Improvements
1244+************
1245+
1246+* Fetching into experimental formats will now print a warning. (Jelmer
1247+ Vernooij)
1248+
1249+API Changes
1250+***********
1251+
1252+* ``Repository.deserialise_inventory`` has been renamed to
1253+ ``Repository._deserialise_inventory`` to indicate it is private.
1254+ (Jelmer Vernooij)
1255+
1256+* ``Repository.get_inventory_xml`` has been renamed to
1257+ ``Repository._get_inventory_xml`` to indicate it is private.
1258+ (Jelmer Vernooij)
1259+
1260+* ``Repository.serialise_inventory`` has been renamed to
1261+ ``Repository._serialise_inventory`` to indicate it is private.
1262+
1263+* Using the ``bzrlib.chk_map`` module from within multiple threads at the
1264+ same time was broken due to race conditions with a module level page
1265+ cache. This shows up as a KeyError in the ``bzrlib.lru_cache`` code with
1266+ ``bzrlib.chk_map`` in the backtrace, and can be triggered without using
1267+ the same high level objects such as ``bzrlib.repository.Repository``
1268+ from different threads. chk_map now uses a thread local cache which may
1269+ increase memory pressure on processes using threads.
1270+ (Robert Collins, John Arbash Meinel, #514090)
1271+
1272+* The new ``merge_file_content`` should now be ok with tests to avoid
1273+ regressions.
1274+ (Vincent Ladeuil, #515597)
1275+
1276+Internals
1277+*********
1278+
1279+* Use ``bzrlib.cleanup`` rather than less robust ``try``/``finally``
1280+ blocks in several places in ``bzrlib.merge``. This avoids masking prior
1281+ errors when errors like ``ImmortalPendingDeletion`` occur during cleanup
1282+ in ``do_merge``.
1283+ (Andrew Bennetts, #517275)
1284+
1285+API Changes
1286+***********
1287+
1288+* The ``remove_index`` method of
1289+ ``bzrlib.repofmt.pack_repo.AggregateIndex`` no longer takes a ``pack``
1290+ argument. This argument was always ignored.
1291+ (Andrew Bennetts, #423015)
1292+
1293+bzr 2.1.0rc2
1294+############
1295+
1296+:Codename: after the bubbles
1297+:2.1.0rc2: 2010-01-29
1298+
1299+This is a quick-turn-around to update a small issue with our new per-file
1300+merge hook. We expect no major changes from this to the final 2.1.0.
1301+
1302+API Changes
1303+***********
1304+
1305+* The new ``merge_file_content`` hook point has been altered to provide a
1306+ better API where state for extensions can be stored rather than the
1307+ too-simple function based approach. This fixes a performance regression
1308+ where branch configuration would be parsed per-file during merge. As
1309+ part of this the included news_merger has been refactored into a base
1310+ helper class ``bzrlib.merge.ConfigurableFileMerger``.
1311+ (Robert Collins, John Arbash Meinel, #513822)
1312+
1313+
1314+bzr 2.1.0rc1
1315+############
1316+
1317+:Codename: the 'new' stable
1318+:2.1.0rc1: 2009-01-21
1319+
1320+This is the first stable release candidate for Bazaar's 2.1 series. From
1321+this point onwards, the 2.1 series will be considered stable (as the 2.0
1322+series) and only bugfixes are expected to be incorporated. The dozen or so
1323+bugfixes in the 2.0.4 release are also included in this release (along
1324+with more than 15 more bugfixes). Some of the interesting features are
1325+support for per-file merge hooks, ``bzr unshelve --preview``, support
1326+for using ! in ignore files to exclude files from being ignored, a small
1327+memory leak was squashed, and many ``ObjectNotLocked`` errors were fixed.
1328+This looks to be a very good start for a new stable series.
1329+
1330+
1331+New Features
1332+************
1333+
1334+* Add bug information to log output when available.
1335+ (Neil Martinsen-Burrell, Guillermo Gonzalez, #251729)
1336+
1337+* Added ``merge_file_content`` hook point to ``Merger``, allowing plugins
1338+ to register custom merge logic, e.g. to provide smarter merging for
1339+ particular files.
1340+
1341+* Bazaar now includes the ``news_merge`` plugin. It is disabled by
1342+ default, to enable it add a ``news_merge_files`` option to your
1343+ configuration. Consult ``bzr help news_merge`` for more information.
1344+ (Andrew Bennetts)
1345+
1346+* ``bzr branch`` now takes a ``--bind`` option. This lets you
1347+ branch and bind all in one command. (Ian Clatworthy)
1348+
1349+* ``bzr switch`` now takes a ``--revision`` option, to allow switching to
1350+ a specific revision of a branch. (Daniel Watkins, #183559)
1351+
1352+* ``bzr unshelve --preview`` can now be used to show how a patch on the
1353+ shelf would be applied to the working tree.
1354+ (Guilherme Salgado, #308122)
1355+
1356+* ``bzr update`` now takes a ``--revision`` argument. This lets you
1357+ change the revision of the working tree to any revision in the
1358+ ancestry of the current or master branch. (Matthieu Moy, Mark Hammond,
1359+ Martin Pool, #45719)
1360+
1361+* ``-Dbytes`` can now be used to display the total number of bytes
1362+ transferred for the current command. This information is always logged
1363+ to ``.bzr.log`` for later inspection. (John Arbash Meinel)
1364+
1365+* New ignore patterns. Patterns prefixed with '!' are exceptions to
1366+ ignore patterns and take precedence over regular ignores. Such
1367+ exceptions are used to specify files that should be versioned which
1368+ would otherwise be ignored. Patterns prefixed with '!!' act as regular
1369+ ignore patterns, but have highest precedence, even over the '!'
1370+ exception patterns. (John Whitley, #428031)
1371+
1372+* The ``supress_warnings`` configuration option has been introduced to disable
1373+ various warnings (it currently only supports the ``format_deprecation``
1374+ warning). The new option can be set in any of the following locations:
1375+ ``bazaar.conf``, ``locations.conf`` and/or ``branch.conf``.
1376+ (Ted Gould, Matthew Fuller, Vincent Ladeuil)
1377+
1378+Bug Fixes
1379+*********
1380+
1381+* Always show a message if an OS error occurs while trying to run a
1382+ user-specified commit message editor.
1383+ (Martin Pool, #504842)
1384+
1385+* ``bzr diff`` will now use the epoch when it is unable to determine
1386+ the timestamp of a file, if the revision it was introduced in is a
1387+ ghost. (Jelmer Vernooij, #295611)
1388+
1389+* ``bzr switch -b`` can now create branches that are located using directory
1390+ services such as ``lp:``, even when the branch name doesn't contain a
1391+ '/'. (Neil Martinsen-Burrell, #495263)
1392+
1393+* ``bzr unshelve`` has improved messages about what it is doing.
1394+ (Neil Martinsen-Burrell, #496917)
1395+
1396+* Concurrent autopacking is more resilient to already-renamed pack files.
1397+ If we find that a file we are about to obsolete is already obsoleted, we
1398+ do not try to rename it, and we leave the file in ``obsolete_packs``.
1399+ The code is also fault tolerant if a file goes missing, assuming that
1400+ another process already removed the file.
1401+ (John Arbash Meinel, Gareth White, #507557)
1402+
1403+* Fix "Too many concurrent requests" in reconcile when network connection
1404+ fails. (Andrew Bennetts, #503878)
1405+
1406+* Fixed a side effect mutation of ``RemoteBzrDirFormat._network_name``
1407+ that caused some tests to fail when run in a non-default order.
1408+ Probably no user impact. (Martin Pool, #504102)
1409+
1410+* Fixed ``ObjectNotLocked`` error in ``bzr cat -rbranch:../foo FILE``.
1411+ (Andrew Bennetts, #506274)
1412+
1413+* FTP transports support Unicode paths by encoding/decoding them as utf8.
1414+ (Vincent Ladeuil, #472161)
1415+
1416+* Listen to the SIGWINCH signal to update the terminal width.
1417+ (Vincent Ladeuil, #316357)
1418+
1419+* Progress bars are now hidden when ``--quiet`` is given.
1420+ (Martin Pool, #320035)
1421+
1422+* ``SilentUIFactory`` now supports ``make_output_stream`` and discards
1423+ whatever is written to it. This un-breaks some plugin tests that
1424+ depended on this behaviour.
1425+ (Martin Pool, #499757)
1426+
1427+* When operations update the working tree, all affected files should end
1428+ up with the same mtime. (eg. when versioning a generated file, if you
1429+ update the source and the generated file together, the generated file
1430+ should appear up-to-date.)
1431+ (John Arbash Meinel, Martin <gzlist>, #488724)
1432+
1433+Improvements
1434+************
1435+
1436+* Added ``add_cleanup`` and ``cleanup_now`` to ``bzrlib.command.Command``.
1437+ All the builtin commands now use ``add_cleanup`` rather than
1438+ ``try``/``finally`` blocks where applicable as it is simpler and more
1439+ robust. (Andrew Bennetts)
1440+
1441+* All except a small number of storage formats are now hidden, making
1442+ the help for numerous commands far more digestible. (Ian Clatworthy)
1443+
1444+* Attempts to open a shared repository as a branch (e.g. ``bzr branch
1445+ path/to/repo``) will now include "location is a repository" as a hint in
1446+ the error message. (Brian de Alwis, Andrew Bennetts, #440952)
1447+
1448+* Push will now inform the user when they are trying to push to a foreign
1449+ VCS for which roundtripping is not supported, and will suggest them to
1450+ use dpush. (Jelmer Vernooij)
1451+
1452+* The version of bzr being run is now written to the log file.
1453+ (__monty__, #257170)
1454+
1455+* Transport network activity indicator is shown more of the time when
1456+ Bazaar is doing network IO.
1457+ (Martin Pool)
1458+
1459+Documentation
1460+*************
1461+
1462+* Add documentation on creating merges with more than one parent.
1463+ (Neil Martinsen-Burrell, #481526)
1464+
1465+* Better explain the --uncommitted option of merge.
1466+ (Neil Martinsen-Burrell, #505088)
1467+
1468+* Improve discussion of pending merges in the documentation for
1469+ ``revert``. (Neil Martinsen-Burrell, #505093)
1470+
1471+* Improved help for ``bzr send``.
1472+ (Martin Pool, Bojan Nikolic)
1473+
1474+* There is a System Administrator's Guide in ``doc/en/admin-guide``,
1475+ including discussions of installation, relevant plugins, security and
1476+ backup. (Neil Martinsen-Burrell)
1477+
1478+* The ``conflicts`` help topic has been renamed to ``conflict-types``.
1479+ (Ian Clatworthy)
1480+
1481+* The User Reference is now presented as a series of topics.
1482+ Many of the included topics have link and format tweaks applied.
1483+ (Ian Clatworthy)
1484+
1485+API Changes
1486+***********
1487+
1488+* Added ``cachedproperty`` decorator to ``bzrlib.decorators``.
1489+ (Andrew Bennetts)
1490+
1491+* Many test features were renamed from ``FooFeature`` to ``foo_feature``
1492+ to be consistent with instances being lower case and classes being
1493+ CamelCase. For the features that were more likely to be used, we added a
1494+ deprecation thunk, but not all. (John Arbash Meinel)
1495+
1496+* Merger classes (such as ``Merge3Merger``) now expect a ``this_branch``
1497+ parameter in their constructors, and provide ``this_branch`` as an
1498+ attribute. (Andrew Bennetts)
1499+
1500+* The Branch hooks pre_change_branch_tip no longer masks exceptions raised
1501+ by plugins - the original exceptions are now preserved. (Robert Collins)
1502+
1503+* The Transport ``Server.tearDown`` method is now renamed to
1504+ ``stop_server`` and ``setUp`` to ``start_server`` for consistency with
1505+ our normal naming pattern, and to avoid confusion with Python's
1506+ ``TestCase.tearDown``. (Martin Pool)
1507+
1508+* ``WorkingTree.update`` implementations must now accept a ``revision``
1509+ parameter.
1510+
1511+Internals
1512+*********
1513+
1514+* Added ``BzrDir.open_branchV3`` smart server request, which can receive
1515+ a string of details (such as "location is a repository") as part of a
1516+ ``nobranch`` response. (Andrew Bennetts, #440952)
1517+
1518+* New helper osutils.UnicodeOrBytesToBytesWriter which encodes unicode
1519+ objects but passes str objects straight through. This is used for
1520+ selftest but may be useful for diff and other operations that generate
1521+ mixed output. (Robert Collins)
1522+
1523+* New exception ``NoRoundtrippingSupport``, for use by foreign branch
1524+ plugins. (Jelmer Vernooij)
1525+
1526+Testing
1527+*******
1528+
1529+* ``bzrlib.tests.permute_for_extension`` is a helper that simplifies
1530+ running all tests in the current module, once against a pure python
1531+ implementation, and once against an extension (pyrex/C) implementation.
1532+ It can be used to dramatically simplify the implementation of
1533+ ``load_tests``. (John Arbash Meinel)
1534+
1535+* ``bzrlib.tests.TestCase`` now subclasses ``testtools.testcase.TestCase``.
1536+ This permits features in testtools such as getUniqueInteger and
1537+ getUniqueString to be used. Because of this, testtools version 0.9.2 or
1538+ newer is now a dependency to run bzr selftest. Running with versions of
1539+ testtools less than 0.9.2 will cause bzr to error while loading the test
1540+ suite. (Robert Collins)
1541+
1542+* Shell-like tests now support the command "mv" for moving files. The
1543+ syntax for ``mv file1 file2``, ``mv dir1 dir2`` and ``mv file dir`` is
1544+ supported. (Neil Martinsen-Burrell)
1545+
1546+* The test progress bar no longer distinguishes tests that 'errored' from
1547+ tests that 'failed' - they're all just failures.
1548+ (Martin Pool)
1549+>>>>>>> MERGE-SOURCE
1550
1551 bzr 2.0.6
1552 #########
1553@@ -1589,38 +3124,78 @@
1554 permissions as ``.bzr`` directory on a POSIX OS.
1555 (Parth Malwankar, #262450)
1556
1557-* Don't traceback trying to unversion children files of an already
1558- unversioned directory. (Vincent Ladeuil, #494221)
1559-
1560-* Raise ValueError instead of a string exception.
1561- (John Arbash Meinel, #586926)
1562-
1563-* Reduce peak memory by one copy of compressed text.
1564- (John Arbash Meinel, #566940)
1565-
1566-* Repositories accessed via a smart server now reject being stacked on a
1567- repository in an incompatible format, as is the case when accessing them
1568- via other methods. This was causing fetches from those repositories via
1569- a smart server (e.g. using ``bzr branch``) to receive invalid data.
1570- (Andrew Bennetts, #562380)
1571-
1572-* Selftest with versions of subunit that support ``stopTestRun`` will no longer
1573- error. This error was caused by 2.0 not being updated when upstream
1574- python merged the end of run patch, which chose ``stopTestRun`` rather than
1575- ``done``. (Robert Collins, #571437)
1576-
1577-* When passing a file to ``UTF8DirReader`` make sure to close the current
1578- directory file handle after the chdir fails. Otherwise when passing many
1579- filenames into a command line ``bzr status`` we would leak descriptors.
1580- (John Arbash Meinel, #583486)
1581-
1582-
1583-Testing
1584-*******
1585-
1586-* ``build_tree_contents`` can create symlinks.
1587- (Martin Pool, John Arbash Meinel)
1588-
1589+<<<<<<< TREE
1590+* Don't traceback trying to unversion children files of an already
1591+ unversioned directory. (Vincent Ladeuil, #494221)
1592+
1593+* Raise ValueError instead of a string exception.
1594+ (John Arbash Meinel, #586926)
1595+
1596+* Reduce peak memory by one copy of compressed text.
1597+ (John Arbash Meinel, #566940)
1598+
1599+* Repositories accessed via a smart server now reject being stacked on a
1600+ repository in an incompatible format, as is the case when accessing them
1601+ via other methods. This was causing fetches from those repositories via
1602+ a smart server (e.g. using ``bzr branch``) to receive invalid data.
1603+ (Andrew Bennetts, #562380)
1604+
1605+* Selftest with versions of subunit that support ``stopTestRun`` will no longer
1606+ error. This error was caused by 2.0 not being updated when upstream
1607+ python merged the end of run patch, which chose ``stopTestRun`` rather than
1608+ ``done``. (Robert Collins, #571437)
1609+
1610+* When passing a file to ``UTF8DirReader`` make sure to close the current
1611+ directory file handle after the chdir fails. Otherwise when passing many
1612+ filenames into a command line ``bzr status`` we would leak descriptors.
1613+ (John Arbash Meinel, #583486)
1614+
1615+
1616+Testing
1617+*******
1618+
1619+* ``build_tree_contents`` can create symlinks.
1620+ (Martin Pool, John Arbash Meinel)
1621+
1622+=======
1623+* Don't traceback trying to unversion children files of an already
1624+ unversioned directory. (Vincent Ladeuil, #494221)
1625+
1626+* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
1627+ which can result in "missing referenced chk root keys" errors when
1628+ fetching from repositories with affected revisions.
1629+ (Andrew Bennetts, #522637)
1630+
1631+* Raise ValueError instead of a string exception.
1632+ (John Arbash Meinel, #586926)
1633+
1634+* Reduce peak memory by one copy of compressed text.
1635+ (John Arbash Meinel, #566940)
1636+
1637+* Repositories accessed via a smart server now reject being stacked on a
1638+ repository in an incompatible format, as is the case when accessing them
1639+ via other methods. This was causing fetches from those repositories via
1640+ a smart server (e.g. using ``bzr branch``) to receive invalid data.
1641+ (Andrew Bennetts, #562380)
1642+
1643+* Selftest with versions of subunit that support ``stopTestRun`` will no longer
1644+ error. This error was caused by 2.0 not being updated when upstream
1645+ python merged the end of run patch, which chose ``stopTestRun`` rather than
1646+ ``done``. (Robert Collins, #571437)
1647+
1648+* When passing a file to ``UTF8DirReader`` make sure to close the current
1649+ directory file handle after the chdir fails. Otherwise when passing many
1650+ filenames into a command line ``bzr status`` we would leak descriptors.
1651+ (John Arbash Meinel, #583486)
1652+
1653+
1654+Testing
1655+*******
1656+
1657+* ``build_tree_contents`` can create symlinks.
1658+ (Martin Pool, John Arbash Meinel)
1659+
1660+>>>>>>> MERGE-SOURCE
1661
1662 bzr 2.0.5
1663 #########
1664
1665=== modified file 'bzr'
1666--- bzr 2010-07-13 07:44:02 +0000
1667+++ bzr 2010-07-29 06:48:01 +0000
1668@@ -23,7 +23,11 @@
1669 import warnings
1670
1671 # update this on each release
1672+<<<<<<< TREE
1673 _script_version = (2, 3, 0)
1674+=======
1675+_script_version = (2, 2, 0)
1676+>>>>>>> MERGE-SOURCE
1677
1678 try:
1679 version_info = sys.version_info
1680
1681=== modified file 'bzrlib/__init__.py'
1682--- bzrlib/__init__.py 2010-07-13 07:44:02 +0000
1683+++ bzrlib/__init__.py 2010-07-29 06:48:01 +0000
1684@@ -52,11 +52,19 @@
1685 # Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
1686 # releaselevel of 'dev' for unreleased under-development code.
1687
1688+<<<<<<< TREE
1689 version_info = (2, 3, 0, 'dev', 1)
1690
1691 # API compatibility version
1692 api_minimum_version = (2, 2, 0)
1693
1694+=======
1695+version_info = (2, 2, 0, 'beta', 4)
1696+
1697+# API compatibility version
1698+api_minimum_version = (2, 2, 0)
1699+
1700+>>>>>>> MERGE-SOURCE
1701
1702 def _format_version_tuple(version_info):
1703 """Turn a version number 2, 3 or 5-tuple into a short string.
1704
1705=== removed file 'bzrlib/benchmarks/__init__.py'
1706--- bzrlib/benchmarks/__init__.py 2009-06-10 03:56:49 +0000
1707+++ bzrlib/benchmarks/__init__.py 1970-01-01 00:00:00 +0000
1708@@ -1,206 +0,0 @@
1709-# Copyright (C) 2006 Canonical Ltd
1710-#
1711-# This program is free software; you can redistribute it and/or modify
1712-# it under the terms of the GNU General Public License as published by
1713-# the Free Software Foundation; either version 2 of the License, or
1714-# (at your option) any later version.
1715-#
1716-# This program is distributed in the hope that it will be useful,
1717-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1718-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1719-# GNU General Public License for more details.
1720-#
1721-# You should have received a copy of the GNU General Public License
1722-# along with this program; if not, write to the Free Software
1723-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1724-
1725-"""Benchmark test suite for bzr."""
1726-
1727-from bzrlib import (
1728- bzrdir,
1729- )
1730-from bzrlib import plugin as _mod_plugin
1731-import bzrlib.branch
1732-from bzrlib.tests.TestUtil import TestLoader
1733-from bzrlib.tests.blackbox import ExternalBase
1734-
1735-
1736-class Benchmark(ExternalBase):
1737- """A Test class which provides helpers for writing benchmark tests."""
1738-
1739- def make_kernel_like_tree(self, url=None, root='.',
1740- link_working=False):
1741- """Setup a temporary tree roughly like a kernel tree.
1742-
1743- :param url: Creat the kernel like tree as a lightweight checkout
1744- of a new branch created at url.
1745- :param root: Path where the tree will be created.
1746- :param link_working: instead of creating a new copy of all files
1747- just hardlink the working tree. Tests must request this, because
1748- they must break links if they want to change the files
1749- :return: A newly created tree.
1750- """
1751- from bzrlib.benchmarks.tree_creator.kernel_like import (
1752- KernelLikeTreeCreator,
1753- )
1754- creator = KernelLikeTreeCreator(self, link_working=link_working,
1755- url=url)
1756- return creator.create(root=root)
1757-
1758- def make_kernel_like_added_tree(self, root='.',
1759- link_working=True,
1760- hot_cache=True):
1761- """Make a kernel like tree, with all files added
1762-
1763- :param root: Where to create the files
1764- :param link_working: Instead of copying all of the working tree
1765- files, just hardlink them to the cached files. Tests can unlink
1766- files that they will change.
1767- :param hot_cache: Run through the newly created tree and make sure
1768- the stat-cache is correct. The old way of creating a freshly
1769- added tree always had a hot cache.
1770- """
1771- from bzrlib.benchmarks.tree_creator.kernel_like import (
1772- KernelLikeAddedTreeCreator,
1773- )
1774- creator = KernelLikeAddedTreeCreator(self, link_working=link_working,
1775- hot_cache=hot_cache)
1776- return creator.create(root=root)
1777-
1778- def make_kernel_like_committed_tree(self, root='.',
1779- link_working=True,
1780- link_bzr=False,
1781- hot_cache=True):
1782- """Make a kernel like tree, with all files added and committed
1783-
1784- :param root: Where to create the files
1785- :param link_working: Instead of copying all of the working tree
1786- files, just hardlink them to the cached files. Tests can unlink
1787- files that they will change.
1788- :param link_bzr: Hardlink the .bzr directory. For readonly
1789- operations this is safe, and shaves off a lot of setup time
1790- """
1791- from bzrlib.benchmarks.tree_creator.kernel_like import (
1792- KernelLikeCommittedTreeCreator,
1793- )
1794- creator = KernelLikeCommittedTreeCreator(self,
1795- link_working=link_working,
1796- link_bzr=link_bzr,
1797- hot_cache=hot_cache)
1798- return creator.create(root=root)
1799-
1800- def make_kernel_like_inventory(self):
1801- """Create an inventory with the properties of a kernel-like tree
1802-
1803- This should be equivalent to a committed kernel like tree, not
1804- just a working tree.
1805- """
1806- from bzrlib.benchmarks.tree_creator.kernel_like import (
1807- KernelLikeInventoryCreator,
1808- )
1809- creator = KernelLikeInventoryCreator(self)
1810- return creator.create()
1811-
1812- def make_many_commit_tree(self, directory_name='.',
1813- hardlink=False):
1814- """Create a tree with many commits.
1815-
1816- No file changes are included. Not hardlinking the working tree,
1817- because there are no working tree files.
1818- """
1819- from bzrlib.benchmarks.tree_creator.simple_many_commit import (
1820- SimpleManyCommitTreeCreator,
1821- )
1822- creator = SimpleManyCommitTreeCreator(self, link_bzr=hardlink)
1823- return creator.create(root=directory_name)
1824-
1825- def make_heavily_merged_tree(self, directory_name='.',
1826- hardlink=False):
1827- """Create a tree in which almost every commit is a merge.
1828-
1829- No file changes are included. This produces two trees,
1830- one of which is returned. Except for the first commit, every
1831- commit in its revision-history is a merge another commit in the other
1832- tree. Not hardlinking the working tree, because there are no working
1833- tree files.
1834- """
1835- from bzrlib.benchmarks.tree_creator.heavily_merged import (
1836- HeavilyMergedTreeCreator,
1837- )
1838- creator = HeavilyMergedTreeCreator(self, link_bzr=hardlink)
1839- return creator.create(root=directory_name)
1840-
1841- def create_with_commits(self, num_files, num_commits, directory_name='.',
1842- hardlink=False):
1843- """Create a tree with many files and many commits. Every commit changes
1844- exactly one file.
1845-
1846- :param num_files: number of files to be created
1847- :param num_commits: number of commits in the newly created tree
1848- """
1849- from bzrlib.benchmarks.tree_creator.many_commit import (
1850- ManyCommitTreeCreator,
1851- )
1852- creator = ManyCommitTreeCreator(self, link_bzr=hardlink,
1853- num_files=num_files,
1854- num_commits=num_commits)
1855- tree = creator.create(root=directory_name)
1856- files = ["%s/%s" % (directory_name, fn) for fn in creator.files]
1857- return tree, files
1858-
1859- def commit_some_revisions(self, tree, files, num_commits,
1860- changes_per_commit):
1861- """Commit a specified number of revisions to some files in a tree,
1862- makeing a specified number of changes per commit.
1863-
1864- :param tree: The tree in which the changes happen.
1865- :param files: The list of files where changes should occur.
1866- :param num_commits: The number of commits
1867- :param changes_per_commit: The number of files that are touched in
1868- each commit.
1869- """
1870- for j in range(num_commits):
1871- for i in range(changes_per_commit):
1872- fn = files[(i + j) % changes_per_commit]
1873- content = range(i) + [i, i, i, '']
1874- f = open(fn, "w")
1875- try:
1876- f.write("\n".join([str(k) for k in content]))
1877- finally:
1878- f.close()
1879- tree.commit("new revision")
1880-
1881-
1882-def test_suite():
1883- """Build and return a TestSuite which contains benchmark tests only."""
1884- testmod_names = [ \
1885- 'bzrlib.benchmarks.bench_add',
1886- 'bzrlib.benchmarks.bench_bench',
1887- 'bzrlib.benchmarks.bench_bundle',
1888- 'bzrlib.benchmarks.bench_cache_utf8',
1889- 'bzrlib.benchmarks.bench_checkout',
1890- 'bzrlib.benchmarks.bench_commit',
1891- 'bzrlib.benchmarks.bench_dirstate',
1892- 'bzrlib.benchmarks.bench_info',
1893- 'bzrlib.benchmarks.bench_inventory',
1894- 'bzrlib.benchmarks.bench_knit',
1895- 'bzrlib.benchmarks.bench_log',
1896- 'bzrlib.benchmarks.bench_pack',
1897- 'bzrlib.benchmarks.bench_osutils',
1898- 'bzrlib.benchmarks.bench_rocks',
1899- 'bzrlib.benchmarks.bench_startup',
1900- 'bzrlib.benchmarks.bench_status',
1901- 'bzrlib.benchmarks.bench_tags',
1902- 'bzrlib.benchmarks.bench_transform',
1903- 'bzrlib.benchmarks.bench_workingtree',
1904- 'bzrlib.benchmarks.bench_sftp',
1905- 'bzrlib.benchmarks.bench_xml',
1906- ]
1907- suite = TestLoader().loadTestsFromModuleNames(testmod_names)
1908-
1909- # Load any benchmarks from plugins
1910- for name, plugin in _mod_plugin.plugins().items():
1911- if getattr(plugin.module, 'bench_suite', None) is not None:
1912- suite.addTest(plugin.module.bench_suite())
1913-
1914- return suite
1915
1916=== removed file 'bzrlib/benchmarks/bench_add.py'
1917--- bzrlib/benchmarks/bench_add.py 2009-03-23 14:59:43 +0000
1918+++ bzrlib/benchmarks/bench_add.py 1970-01-01 00:00:00 +0000
1919@@ -1,32 +0,0 @@
1920-# Copyright (C) 2006 Canonical Ltd
1921-#
1922-# This program is free software; you can redistribute it and/or modify
1923-# it under the terms of the GNU General Public License as published by
1924-# the Free Software Foundation; either version 2 of the License, or
1925-# (at your option) any later version.
1926-#
1927-# This program is distributed in the hope that it will be useful,
1928-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1929-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1930-# GNU General Public License for more details.
1931-#
1932-# You should have received a copy of the GNU General Public License
1933-# along with this program; if not, write to the Free Software
1934-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1935-
1936-"""Tests for bzr add performance."""
1937-
1938-
1939-from bzrlib.benchmarks import Benchmark
1940-
1941-
1942-class AddBenchmark(Benchmark):
1943- """Benchmarks for 'bzr add'"""
1944-
1945- def test_one_add_kernel_like_tree(self):
1946- """Adding a kernel sized tree should be bearable (<5secs) fast."""
1947- self.make_kernel_like_tree(link_working=True)
1948- # on roberts machine: this originally took: 25936ms/32244ms
1949- # after making smart_add use the parent_ie: 5033ms/ 9368ms
1950- # plain os.walk takes 213ms on this tree
1951- self.time(self.run_bzr, 'add')
1952
1953=== removed file 'bzrlib/benchmarks/bench_bench.py'
1954--- bzrlib/benchmarks/bench_bench.py 2009-03-23 14:59:43 +0000
1955+++ bzrlib/benchmarks/bench_bench.py 1970-01-01 00:00:00 +0000
1956@@ -1,101 +0,0 @@
1957-# Copyright (C) 2006 Canonical Ltd
1958-#
1959-# This program is free software; you can redistribute it and/or modify
1960-# it under the terms of the GNU General Public License as published by
1961-# the Free Software Foundation; either version 2 of the License, or
1962-# (at your option) any later version.
1963-#
1964-# This program is distributed in the hope that it will be useful,
1965-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1966-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1967-# GNU General Public License for more details.
1968-#
1969-# You should have received a copy of the GNU General Public License
1970-# along with this program; if not, write to the Free Software
1971-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1972-
1973-"""Tests for bzr benchmark utilities performance."""
1974-
1975-from bzrlib import (
1976- osutils,
1977- )
1978-from bzrlib.benchmarks import Benchmark
1979-from bzrlib.benchmarks.tree_creator.kernel_like import (
1980- KernelLikeTreeCreator,
1981- KernelLikeAddedTreeCreator,
1982- KernelLikeCommittedTreeCreator,
1983- )
1984-from bzrlib.tests import TestSkipped
1985-
1986-
1987-class MakeKernelLikeTreeBenchmark(Benchmark):
1988- """Benchmark creating benchmark trees."""
1989-
1990- def test_make_kernel_like_tree(self):
1991- """Making a kernel sized tree should be ~ 5seconds on modern disk."""
1992- # on roberts machine: this originally took: 7372ms/ 7479ms
1993- # with the LocalTransport._abspath call: 3730ms/ 3778ms
1994- # with AtomicFile tuning: 2888ms/ 2926ms
1995- # switching to transport.append_bytes: 1468ms/ 2849ms
1996- self.time(self.make_kernel_like_tree)
1997-
1998- def test_02_make_kernel_like_tree(self):
1999- """Hardlinking a kernel-like working tree should be ~1s"""
2000- # make sure kernel_like_tree is cached
2001- creator = KernelLikeTreeCreator(self, link_working=True)
2002- if not creator.is_caching_enabled():
2003- raise TestSkipped('caching is disabled')
2004- creator.ensure_cached()
2005- self.time(creator.create, root='bar')
2006-
2007- def test_03_make_kernel_like_added_tree(self):
2008- """Time the first creation of a kernel like added tree"""
2009- creator = KernelLikeAddedTreeCreator(self)
2010- creator.disable_cache()
2011- self.time(creator.create, root='foo')
2012-
2013- def test_04_make_kernel_like_added_tree(self):
2014- """Time the second creation of a kernel like added tree
2015- (this should be a clone)
2016- """
2017- # make sure kernel_like_added_tree is cached
2018- creator = KernelLikeAddedTreeCreator(self, link_working=True)
2019- if not creator.is_caching_enabled():
2020- # Caching is disabled, this test is meaningless
2021- raise TestSkipped('caching is disabled')
2022- creator.ensure_cached()
2023- self.time(creator.create, root='bar')
2024-
2025- def test_05_make_kernel_like_committed_tree(self):
2026- """Time the first creation of a committed kernel like tree"""
2027- creator = KernelLikeCommittedTreeCreator(self)
2028- creator.disable_cache()
2029- self.time(creator.create, root='foo')
2030-
2031- def test_06_make_kernel_like_committed_tree(self):
2032- """Time the second creation of a committed kernel like tree
2033- (this should be a clone)
2034- """
2035- creator = KernelLikeCommittedTreeCreator(self,
2036- link_working=True,
2037- link_bzr=False)
2038- if not creator.is_caching_enabled():
2039- # Caching is disabled, this test is meaningless
2040- raise TestSkipped('caching is disabled')
2041- creator.ensure_cached()
2042- self.time(creator.create, root='bar')
2043-
2044- def test_07_make_kernel_like_committed_tree_hardlink(self):
2045- """Time the creation of a committed kernel like tree
2046- (this should also hardlink the .bzr/ directory)
2047- """
2048- creator = KernelLikeCommittedTreeCreator(self,
2049- link_working=True,
2050- link_bzr=True)
2051- if not creator.is_caching_enabled():
2052- # Caching is disabled, this test is meaningless
2053- raise TestSkipped('caching is disabled')
2054- creator.ensure_cached()
2055- self.time(creator.create, root='bar')
2056-
2057-
2058
2059=== removed file 'bzrlib/benchmarks/bench_bundle.py'
2060--- bzrlib/benchmarks/bench_bundle.py 2009-03-23 14:59:43 +0000
2061+++ bzrlib/benchmarks/bench_bundle.py 1970-01-01 00:00:00 +0000
2062@@ -1,207 +0,0 @@
2063-# Copyright (C) 2006 Canonical Ltd
2064-#
2065-# This program is free software; you can redistribute it and/or modify
2066-# it under the terms of the GNU General Public License as published by
2067-# the Free Software Foundation; either version 2 of the License, or
2068-# (at your option) any later version.
2069-#
2070-# This program is distributed in the hope that it will be useful,
2071-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2072-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2073-# GNU General Public License for more details.
2074-#
2075-# You should have received a copy of the GNU General Public License
2076-# along with this program; if not, write to the Free Software
2077-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2078-
2079-"""Tests for bzr bundle performance."""
2080-
2081-from cStringIO import StringIO
2082-import os
2083-import shutil
2084-
2085-from bzrlib import bzrdir
2086-from bzrlib.benchmarks import Benchmark
2087-from bzrlib.branch import Branch
2088-from bzrlib.bundle.apply_bundle import install_bundle
2089-from bzrlib.bundle.serializer import read_bundle, write_bundle
2090-from bzrlib.revision import NULL_REVISION
2091-from bzrlib.revisionspec import RevisionSpec
2092-from bzrlib.workingtree import WorkingTree
2093-
2094-
2095-class BundleBenchmark(Benchmark):
2096- """Benchmarks for bzr bundle performance and bzr merge with a bundle."""
2097-
2098- def test_create_bundle_known_kernel_like_tree(self):
2099- """Create a bundle for a kernel sized tree with no ignored, unknowns,
2100- or added and one commit.
2101- """
2102- self.make_kernel_like_committed_tree()
2103- self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
2104-
2105- def test_create_bundle_many_commit_tree (self):
2106- """Create a bundle for a tree with many commits but no changes."""
2107- self.make_many_commit_tree()
2108- self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
2109-
2110- def test_create_bundle_heavily_merged_tree(self):
2111- """Create a bundle for a heavily merged tree."""
2112- self.make_heavily_merged_tree()
2113- self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
2114-
2115- def test_apply_bundle_known_kernel_like_tree(self):
2116- """Create a bundle for a kernel sized tree with no ignored, unknowns,
2117- or added and one commit.
2118- """
2119- tree = self.make_kernel_like_committed_tree('tree')
2120-
2121- f = open('bundle', 'wb')
2122- try:
2123- write_bundle(tree.branch.repository, tree.last_revision(),
2124- NULL_REVISION, f)
2125- finally:
2126- f.close()
2127-
2128- tree2 = self.make_branch_and_tree('branch_a')
2129- os.chdir('branch_a')
2130- self.time(self.run_bzr, ['merge', '../bundle'])
2131-
2132-
2133-class BundleLibraryLevelWriteBenchmark(Benchmark):
2134- """ Benchmarks for the write_bundle library function. """
2135-
2136- def _time_read_write(self):
2137- branch, relpath = Branch.open_containing("a")
2138- revision_history = branch.revision_history()
2139- bundle_text = StringIO()
2140- self.time(write_bundle, branch.repository, revision_history[-1],
2141- NULL_REVISION, bundle_text)
2142- bundle_text.seek(0)
2143- target_tree = self.make_branch_and_tree('b')
2144- bundle = self.time(read_bundle, bundle_text)
2145- self.time(install_bundle, target_tree.branch.repository, bundle)
2146-
2147- def test_few_files_small_tree_1_revision(self):
2148- os.mkdir("a")
2149- tree, files = self.create_with_commits(5, 1, directory_name="a")
2150- self.commit_some_revisions(tree, files[:5], 1, 1)
2151- self._time_read_write()
2152-
2153- def test_few_files_small_tree_100_revision(self):
2154- os.mkdir("a")
2155- tree, files = self.create_with_commits(5, 1, directory_name="a")
2156- self.commit_some_revisions(tree, files[:5], 100, 1)
2157- self._time_read_write()
2158-
2159- def test_few_files_moderate_tree_1_revision(self):
2160- os.mkdir("a")
2161- tree, files = self.create_with_commits(100, 1, directory_name="a")
2162- self.commit_some_revisions(tree, files[:5], 1, 1)
2163- self._time_read_write()
2164-
2165- def test_few_files_moderate_tree_100_revision(self):
2166- os.mkdir("a")
2167- tree, files = self.create_with_commits(100, 1, directory_name="a")
2168- self.commit_some_revisions(tree, files[:5], 100, 1)
2169- self._time_read_write()
2170-
2171- def test_some_files_moderate_tree_1_revision(self):
2172- os.mkdir("a")
2173- tree, files = self.create_with_commits(100, 1, directory_name="a")
2174- self.commit_some_revisions(tree, files[:100], 1, 1)
2175- self._time_read_write()
2176-
2177- def test_few_files_big_tree_1_revision(self):
2178- os.mkdir("a")
2179- tree, files = self.create_with_commits(1000, 1, directory_name="a")
2180- self.commit_some_revisions(tree, files[:5], 1, 1)
2181- self._time_read_write()
2182-
2183- def test_some_files_big_tree_1_revision(self):
2184- os.mkdir("a")
2185- tree, files = self.create_with_commits(1000, 1, directory_name="a")
2186- self.commit_some_revisions(tree, files[:100], 1, 1)
2187- self._time_read_write()
2188-
2189-
2190-class BundleLibraryLevelInstallBenchmark(Benchmark):
2191- """ Benchmarks for the install_bundle library function. """
2192-
2193- def _time_read_write(self):
2194- branch, relpath = Branch.open_containing("a")
2195- revision_history = branch.revision_history()
2196- bundle_text = StringIO()
2197- write_bundle(branch.repository, revision_history[-1],
2198- NULL_REVISION, bundle_text)
2199- bundle_text.seek(0)
2200- target_tree = self.make_branch_and_tree('b')
2201- bundle = self.time(read_bundle, bundle_text)
2202- self.time(install_bundle, target_tree.branch.repository, bundle)
2203-
2204- def test_few_files_small_tree_1_revision(self):
2205- os.mkdir("a")
2206- tree, files = self.create_with_commits(5, 1, directory_name="a")
2207- self.commit_some_revisions(tree, files[:5], 1, 1)
2208- self._time_read_write()
2209-
2210- def test_few_files_small_tree_100_revision(self):
2211- os.mkdir("a")
2212- tree, files = self.create_with_commits(5, 1, directory_name="a")
2213- self.commit_some_revisions(tree, files[:5], 100, 1)
2214- self._time_read_write()
2215-
2216- def test_few_files_moderate_tree_1_revision(self):
2217- os.mkdir("a")
2218- tree, files = self.create_with_commits(100, 1, directory_name="a")
2219- self.commit_some_revisions(tree, files[:5], 1, 1)
2220- self._time_read_write()
2221-
2222- def test_few_files_moderate_tree_100_revision(self):
2223- os.mkdir("a")
2224- tree, files = self.create_with_commits(100, 1, directory_name="a")
2225- self.commit_some_revisions(tree, files[:5], 100, 1)
2226- self._time_read_write()
2227-
2228- def test_some_files_moderate_tree_1_revision(self):
2229- os.mkdir("a")
2230- tree, files = self.create_with_commits(100, 1, directory_name="a")
2231- self.commit_some_revisions(tree, files[:100], 1, 1)
2232- self._time_read_write()
2233-
2234- def test_few_files_big_tree_1_revision(self):
2235- os.mkdir("a")
2236- tree, files = self.create_with_commits(1000, 1, directory_name="a")
2237- self.commit_some_revisions(tree, files[:5], 1, 1)
2238- self._time_read_write()
2239-
2240- def test_some_files_big_tree_1_revision(self):
2241- os.mkdir("a")
2242- tree, files = self.create_with_commits(1000, 1, directory_name="a")
2243- self.commit_some_revisions(tree, files[:100], 1, 1)
2244- self._time_read_write()
2245-
2246-
2247-if __name__ == '__main__':
2248- # USE the following if you want to regenerate the above test functions
2249- for treesize, treesize_h in [(5, "small"), (100, "moderate"),
2250- (1000, "big")]:
2251- for bundlefiles, bundlefiles_h in [(5, "few"), (100, "some")]:
2252- if bundlefiles > treesize:
2253- continue
2254- for num_revisions in [1, 100]:
2255- if (num_revisions >= 100 and
2256- (bundlefiles >= 100 or treesize >= 1000)):
2257- # Skip the 100x100x? tests.
2258- # And the 100x?x1000
2259- continue
2260- code = """\
2261- def test_%s_files_%s_tree_%s_revision(self):
2262- os.mkdir("a")
2263- tree, files = self.create_with_commits(%s, 1, directory_name="a")
2264- self.commit_some_revisions(tree, files[:%s], %s, 1)
2265- self._time_read_write()
2266-""" % (bundlefiles_h, treesize_h, num_revisions,
2267- treesize, bundlefiles, num_revisions)
2268- print code
2269-
2270
2271=== removed file 'bzrlib/benchmarks/bench_cache_utf8.py'
2272--- bzrlib/benchmarks/bench_cache_utf8.py 2009-03-23 14:59:43 +0000
2273+++ bzrlib/benchmarks/bench_cache_utf8.py 1970-01-01 00:00:00 +0000
2274@@ -1,226 +0,0 @@
2275-# Copyright (C) 2006 Canonical Ltd
2276-#
2277-# This program is free software; you can redistribute it and/or modify
2278-# it under the terms of the GNU General Public License as published by
2279-# the Free Software Foundation; either version 2 of the License, or
2280-# (at your option) any later version.
2281-#
2282-# This program is distributed in the hope that it will be useful,
2283-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2284-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2285-# GNU General Public License for more details.
2286-#
2287-# You should have received a copy of the GNU General Public License
2288-# along with this program; if not, write to the Free Software
2289-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2290-
2291-
2292-"""Tests for encoding performance."""
2293-
2294-from bzrlib import (
2295- cache_utf8,
2296- osutils,
2297- )
2298-
2299-from bzrlib.benchmarks import Benchmark
2300-
2301-
2302-_normal_revision_id = (u'john@arbash-meinel.com-20060801200018'
2303- u'-cafa6272d9b8cac4')
2304-_unicode_revision_id = (u'\u062c\u0648\u062c\u0648@\xe5rbash-meinel.com-'
2305- u'\xb5\xb5\xb5-20060801200018-cafa6272d9b8cac4')
2306-
2307-_normal_revision_id_utf8 = _normal_revision_id.encode('utf-8')
2308-_unicode_revision_id_utf8 = _unicode_revision_id.encode('utf-8')
2309-
2310-
2311-class EncodingBenchmark(Benchmark):
2312- """Benchmark the time to encode strings."""
2313-
2314- def setUp(self):
2315- super(EncodingBenchmark, self).setUp()
2316- # Make sure we start and end with a clean cache
2317- cache_utf8.clear_encoding_cache()
2318- self.addCleanup(cache_utf8.clear_encoding_cache)
2319-
2320- def encode_1M(self, revision_id):
2321- """Encode the given revision id 1 million times"""
2322- # In a real kernel tree there are 7.7M lines of code
2323- # so the initial import actually has to encode a revision
2324- # id to store annotated lines one time for every line.
2325- for i in xrange(1000000):
2326- revision_id.encode('utf8')
2327-
2328- def encode_cached_1M(self, revision_id):
2329- """Encode the given revision id 1 million times using the cache"""
2330- encode = cache_utf8.encode
2331- for i in xrange(1000000):
2332- encode(revision_id)
2333-
2334- def encode_multi(self, revision_list, count):
2335- """Encode each entry in the list count times"""
2336- for i in xrange(count):
2337- for revision_id in revision_list:
2338- revision_id.encode('utf-8')
2339-
2340- def encode_cached_multi(self, revision_list, count):
2341- """Encode each entry in the list count times"""
2342- encode = cache_utf8.encode
2343- for i in xrange(count):
2344- for revision_id in revision_list:
2345- encode(revision_id)
2346-
2347- def test_encode_1_by_1M_ascii(self):
2348- """Test encoding a single revision id 1 million times."""
2349- self.time(self.encode_1M, _normal_revision_id)
2350-
2351- def test_encode_1_by_1M_ascii_cached(self):
2352- """Test encoding a single revision id 1 million times."""
2353- self.time(self.encode_cached_1M, _normal_revision_id)
2354-
2355- def test_encode_1_by_1M_ascii_str(self):
2356- # We have places that think they have a unicode revision id
2357- # but actually, they have a plain string. So .encode(utf8)
2358- # actually has to decode from ascii, and then encode into utf8
2359- self.time(self.encode_1M, str(_normal_revision_id))
2360-
2361- def test_encode_1_by_1M_ascii_str_cached(self):
2362- self.time(self.encode_cached_1M, str(_normal_revision_id))
2363-
2364- def test_encode_1_by_1M_unicode(self):
2365- """Test encoding a single revision id 1 million times."""
2366- self.time(self.encode_1M, _unicode_revision_id)
2367-
2368- def test_encode_1_by_1M_unicode_cached(self):
2369- """Test encoding a single revision id 1 million times."""
2370- self.time(self.encode_cached_1M, _unicode_revision_id)
2371-
2372- def test_encode_1k_by_1k_ascii(self):
2373- """Test encoding 5 revisions 100k times"""
2374- revisions = [unicode(osutils.rand_chars(60)) for x in xrange(1000)]
2375- self.time(self.encode_multi, revisions, 1000)
2376-
2377- def test_encode_1k_by_1k_ascii_cached(self):
2378- """Test encoding 5 revisions 100k times"""
2379- revisions = [unicode(osutils.rand_chars(60)) for x in xrange(1000)]
2380- self.time(self.encode_cached_multi, revisions, 1000)
2381-
2382- def test_encode_1k_by_1k_unicode(self):
2383- """Test encoding 5 revisions 100k times"""
2384- revisions = [u'\u062c\u0648\u062c\u0648' +
2385- unicode(osutils.rand_chars(60)) for x in xrange(1000)]
2386- self.time(self.encode_multi, revisions, 1000)
2387-
2388- def test_encode_1k_by_1k_unicode_cached(self):
2389- """Test encoding 5 revisions 100k times"""
2390- revisions = [u'\u062c\u0648\u062c\u0648' +
2391- unicode(osutils.rand_chars(60)) for x in xrange(1000)]
2392- self.time(self.encode_cached_multi, revisions, 1000)
2393-
2394- def test_encode_500K_by_1_ascii(self):
2395- revisions = [unicode("test%07d" % x) for x in xrange(500000)]
2396- self.time(self.encode_multi, revisions, 1)
2397-
2398- def test_encode_500K_by_1_ascii_cached(self):
2399- revisions = [unicode("test%07d" % x) for x in xrange(500000)]
2400- self.time(self.encode_cached_multi, revisions, 1)
2401-
2402- def test_encode_500K_by_1_unicode(self):
2403- revisions = [u'\u062c\u0648\u062c\u0648' +
2404- unicode("%07d" % x) for x in xrange(500000)]
2405- self.time(self.encode_multi, revisions, 1)
2406-
2407- def test_encode_500K_by_1_unicode_cached(self):
2408- revisions = [u'\u062c\u0648\u062c\u0648' +
2409- unicode("%07d" % x) for x in xrange(500000)]
2410- self.time(self.encode_cached_multi, revisions, 1)
2411-
2412-
2413-class DecodingBenchmarks(Benchmark):
2414- """Benchmark the time to decode strings."""
2415-
2416- def setUp(self):
2417- super(DecodingBenchmarks, self).setUp()
2418- # Make sure we start and end with a clean cache
2419- cache_utf8.clear_encoding_cache()
2420- self.addCleanup(cache_utf8.clear_encoding_cache)
2421-
2422- def decode_1M(self, revision_id):
2423- for i in xrange(1000000):
2424- revision_id.decode('utf8')
2425-
2426- def decode_cached_1M(self, revision_id):
2427- decode = cache_utf8.decode
2428- for i in xrange(1000000):
2429- decode(revision_id)
2430-
2431- def decode_multi(self, revision_list, count):
2432- for i in xrange(count):
2433- for revision_id in revision_list:
2434- revision_id.decode('utf-8')
2435-
2436- def decode_cached_multi(self, revision_list, count):
2437- decode = cache_utf8.decode
2438- for i in xrange(count):
2439- for revision_id in revision_list:
2440- decode(revision_id)
2441-
2442- def test_decode_1_by_1M_ascii(self):
2443- """Test decoding a single revision id 1 million times."""
2444- self.time(self.decode_1M, _normal_revision_id_utf8)
2445-
2446- def test_decode_1_by_1M_ascii_cached(self):
2447- """Test decoding a single revision id 1 million times."""
2448- self.time(self.decode_cached_1M, _normal_revision_id_utf8)
2449-
2450- def test_decode_1_by_1M_unicode(self):
2451- """Test decoding a single revision id 1 million times."""
2452- self.time(self.decode_1M, _unicode_revision_id_utf8)
2453-
2454- def test_decode_1_by_1M_unicode_cached(self):
2455- """Test decoding a single revision id 1 million times."""
2456- self.time(self.decode_cached_1M, _unicode_revision_id_utf8)
2457-
2458- def test_decode_1k_by_1k_ascii(self):
2459- """Test decoding 5 revisions 100k times"""
2460- revisions = [osutils.rand_chars(60) for x in xrange(1000)]
2461- self.time(self.decode_multi, revisions, 1000)
2462-
2463- def test_decode_1k_by_1k_ascii_cached(self):
2464- """Test decoding 5 revisions 100k times"""
2465- revisions = [osutils.rand_chars(60) for x in xrange(1000)]
2466- self.time(self.decode_cached_multi, revisions, 1000)
2467-
2468- def test_decode_1k_by_1k_unicode(self):
2469- """Test decoding 5 revisions 100k times"""
2470- revisions = [(u'\u062c\u0648\u062c\u0648' +
2471- unicode(osutils.rand_chars(60))).encode('utf8')
2472- for x in xrange(1000)]
2473- self.time(self.decode_multi, revisions, 1000)
2474-
2475- def test_decode_1k_by_1k_unicode_cached(self):
2476- """Test decoding 5 revisions 100k times"""
2477- revisions = [(u'\u062c\u0648\u062c\u0648' +
2478- unicode(osutils.rand_chars(60))).encode('utf8')
2479- for x in xrange(1000)]
2480- self.time(self.decode_cached_multi, revisions, 1000)
2481-
2482- def test_decode_500K_by_1_ascii(self):
2483- revisions = [("test%07d" % x) for x in xrange(500000)]
2484- self.time(self.decode_multi, revisions, 1)
2485-
2486- def test_decode_500K_by_1_ascii_cached(self):
2487- revisions = [("test%07d" % x) for x in xrange(500000)]
2488- self.time(self.decode_cached_multi, revisions, 1)
2489-
2490- def test_decode_500K_by_1_unicode(self):
2491- revisions = [(u'\u062c\u0648\u062c\u0648' +
2492- unicode("%07d" % x)).encode('utf-8')
2493- for x in xrange(500000)]
2494- self.time(self.decode_multi, revisions, 1)
2495-
2496- def test_decode_500K_by_1_unicode_cached(self):
2497- revisions = [(u'\u062c\u0648\u062c\u0648' +
2498- unicode("%07d" % x)).encode('utf-8')
2499- for x in xrange(500000)]
2500- self.time(self.decode_cached_multi, revisions, 1)
2501
2502=== removed file 'bzrlib/benchmarks/bench_checkout.py'
2503--- bzrlib/benchmarks/bench_checkout.py 2009-03-23 14:59:43 +0000
2504+++ bzrlib/benchmarks/bench_checkout.py 1970-01-01 00:00:00 +0000
2505@@ -1,29 +0,0 @@
2506-# Copyright (C) 2006 Canonical Ltd
2507-#
2508-# This program is free software; you can redistribute it and/or modify
2509-# it under the terms of the GNU General Public License as published by
2510-# the Free Software Foundation; either version 2 of the License, or
2511-# (at your option) any later version.
2512-#
2513-# This program is distributed in the hope that it will be useful,
2514-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2515-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2516-# GNU General Public License for more details.
2517-#
2518-# You should have received a copy of the GNU General Public License
2519-# along with this program; if not, write to the Free Software
2520-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2521-
2522-"""Tests for bzr tree building (checkout) performance."""
2523-
2524-
2525-from bzrlib.benchmarks import Benchmark
2526-
2527-
2528-class CheckoutBenchmark(Benchmark):
2529- """Benchmarks for ``'bzr checkout'`` performance."""
2530-
2531- def test_build_kernel_like_tree(self):
2532- """Checkout of a clean kernel sized tree should be (<10secs)."""
2533- self.make_kernel_like_committed_tree(link_bzr=True)
2534- self.time(self.run_bzr, ['checkout', '--lightweight', '.', 'acheckout'])
2535
2536=== renamed file 'bzrlib/benchmarks/bench_commit.py' => 'bzrlib/benchmarks/bench_commit.py.THIS'
2537=== renamed file 'bzrlib/benchmarks/bench_dirstate.py' => 'bzrlib/benchmarks/bench_dirstate.py.THIS'
2538=== removed file 'bzrlib/benchmarks/bench_info.py'
2539--- bzrlib/benchmarks/bench_info.py 2009-03-23 14:59:43 +0000
2540+++ bzrlib/benchmarks/bench_info.py 1970-01-01 00:00:00 +0000
2541@@ -1,37 +0,0 @@
2542-# Copyright (C) 2006 Canonical Ltd
2543-#
2544-# This program is free software; you can redistribute it and/or modify
2545-# it under the terms of the GNU General Public License as published by
2546-# the Free Software Foundation; either version 2 of the License, or
2547-# (at your option) any later version.
2548-#
2549-# This program is distributed in the hope that it will be useful,
2550-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2551-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2552-# GNU General Public License for more details.
2553-#
2554-# You should have received a copy of the GNU General Public License
2555-# along with this program; if not, write to the Free Software
2556-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2557-
2558-"""Tests for bzr info performance."""
2559-
2560-
2561-from bzrlib.benchmarks import Benchmark
2562-
2563-
2564-class InfoBenchmark(Benchmark):
2565- """This is a stub. Use this benchmark with a network transport.
2566- Currently "bzr info sftp://..." takes > 4 min"""
2567-
2568- def test_no_ignored_unknown_kernel_like_tree(self):
2569- """Info in a kernel sized tree with no ignored or unknowns. """
2570- self.make_kernel_like_added_tree()
2571- self.time(self.run_bzr, 'info')
2572-
2573- def test_no_changes_known_kernel_like_tree(self):
2574- """Info in a kernel sized tree with no ignored, unknowns, or added."""
2575- self.make_kernel_like_committed_tree()
2576- self.time(self.run_bzr, 'info')
2577-
2578-
2579
2580=== removed file 'bzrlib/benchmarks/bench_inventory.py'
2581--- bzrlib/benchmarks/bench_inventory.py 2009-03-23 14:59:43 +0000
2582+++ bzrlib/benchmarks/bench_inventory.py 1970-01-01 00:00:00 +0000
2583@@ -1,39 +0,0 @@
2584-# Copyright (C) 2006 Canonical Ltd
2585-#
2586-# This program is free software; you can redistribute it and/or modify
2587-# it under the terms of the GNU General Public License as published by
2588-# the Free Software Foundation; either version 2 of the License, or
2589-# (at your option) any later version.
2590-#
2591-# This program is distributed in the hope that it will be useful,
2592-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2593-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2594-# GNU General Public License for more details.
2595-#
2596-# You should have received a copy of the GNU General Public License
2597-# along with this program; if not, write to the Free Software
2598-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2599-
2600-"""Tests for `bzrlib.inventory.Inventory` performance."""
2601-
2602-
2603-import bzrlib.inventory
2604-from bzrlib.benchmarks import Benchmark
2605-
2606-
2607-class InvBenchmark(Benchmark):
2608- """Benchmarks for building large inventories."""
2609-
2610- def test_make_10824_inv_entries(self):
2611- """Making 10824 inv entries should be quick."""
2612- entries = []
2613- def make_10824_entries():
2614- for counter in xrange(10000):
2615- bzrlib.inventory.make_entry('file', 'foo',
2616- "a_parent_id")
2617- for counter in xrange(824):
2618- bzrlib.inventory.make_entry('directory', 'foo',
2619- "a_parent_id")
2620- # on roberts machine: this originally took: 533ms/ 600ms
2621- # fixing slots to be vaguely accurate : 365ms/ 419ms
2622- self.time(make_10824_entries)
2623
2624=== renamed file 'bzrlib/benchmarks/bench_knit.py' => 'bzrlib/benchmarks/bench_knit.py.THIS'
2625=== removed file 'bzrlib/benchmarks/bench_log.py'
2626--- bzrlib/benchmarks/bench_log.py 2009-03-23 14:59:43 +0000
2627+++ bzrlib/benchmarks/bench_log.py 1970-01-01 00:00:00 +0000
2628@@ -1,117 +0,0 @@
2629-# Copyright (C) 2006 Canonical Ltd
2630-#
2631-# This program is free software; you can redistribute it and/or modify
2632-# it under the terms of the GNU General Public License as published by
2633-# the Free Software Foundation; either version 2 of the License, or
2634-# (at your option) any later version.
2635-#
2636-# This program is distributed in the hope that it will be useful,
2637-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2638-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2639-# GNU General Public License for more details.
2640-#
2641-# You should have received a copy of the GNU General Public License
2642-# along with this program; if not, write to the Free Software
2643-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2644-
2645-"""Tests for tree transform performance"""
2646-
2647-import os
2648-import sys
2649-
2650-from bzrlib.benchmarks import Benchmark
2651-from bzrlib.log import log_formatter, show_log
2652-from bzrlib.osutils import pathjoin
2653-from cStringIO import StringIO
2654-from bzrlib.transform import TreeTransform
2655-from bzrlib.workingtree import WorkingTree
2656-
2657-
2658-class LinesDone(Exception):
2659- """Raised when `LineConsumer` reaches the required number of lines."""
2660- pass
2661-
2662-
2663-class LineConsumer(object):
2664- """Count lines that are produced.
2665-
2666- When the required number of lines have been reached, raise `LinesDone`.
2667- """
2668-
2669- def __init__(self, required_lines):
2670- """Create a new consumer.
2671-
2672- :param required_lines: How many lines must be produced.
2673- :type required_lines: integer
2674- """
2675- self.required_lines = required_lines
2676-
2677- def write(self, text):
2678- """Write some text to the black hole.
2679-
2680- But count how many lines have been written.
2681-
2682- :param text: A string that would be written.
2683- :raise LinesDone: when the required number of lines has been reached.
2684- :return: None
2685- """
2686- self.required_lines -= text.count('\n')
2687- if self.required_lines < 0:
2688- raise LinesDone()
2689-
2690-
2691-class LogBenchmark(Benchmark):
2692- """Benchmarks for ``'bzr log'`` performance."""
2693-
2694- def test_log(self):
2695- """Run log in a many-commit tree."""
2696- tree = self.make_many_commit_tree(hardlink=True)
2697- lf = log_formatter('long', to_file=StringIO())
2698- self.time(show_log, tree.branch, lf, direction='reverse')
2699-
2700- def test_merge_log(self):
2701- """Run log in a tree with many merges"""
2702- tree = self.make_heavily_merged_tree(hardlink=True)
2703- lf = log_formatter('short', to_file=StringIO())
2704- self.time(show_log, tree.branch, lf, direction='reverse')
2705-
2706- def test_log_screenful(self):
2707- """Simulate log --long|less"""
2708- self.screenful_tester('long')
2709-
2710- def test_log_screenful_line(self):
2711- """Simulate log --line|less"""
2712- self.screenful_tester('line')
2713-
2714- def test_log_screenful_short(self):
2715- """Simulate log --short|less"""
2716- self.screenful_tester('short')
2717-
2718- def screenful_tester(self, formatter):
2719- """Run show_log, but stop after 25 lines are generated"""
2720- tree = self.make_many_commit_tree(hardlink=True)
2721- def log_screenful():
2722- lf = log_formatter(formatter, to_file=LineConsumer(25))
2723- try:
2724- show_log(tree.branch, lf, direction='reverse')
2725- except LinesDone:
2726- pass
2727- else:
2728- raise Exception, "LinesDone not raised"
2729- self.time(log_screenful)
2730-
2731- def test_cmd_log(self):
2732- """Test execution of the log command."""
2733- tree = self.make_many_commit_tree(hardlink=True)
2734- self.time(self.run_bzr, ['log', '-r', '-4..'])
2735-
2736- def test_cmd_log_subprocess(self):
2737- """Text startup and execution of the log command."""
2738- tree = self.make_many_commit_tree(hardlink=True)
2739- self.time(self.run_bzr_subprocess, 'log', '-r', '-4..')
2740-
2741- def test_log_verbose(self):
2742- """'verbose' log -- shows file changes"""
2743- tree = self.make_many_commit_tree(hardlink=True)
2744- lf = log_formatter('long', to_file=StringIO())
2745- self.time(show_log, tree.branch, lf, direction='reverse', verbose=True)
2746
2747=== removed file 'bzrlib/benchmarks/bench_osutils.py'
2748--- bzrlib/benchmarks/bench_osutils.py 2009-03-23 14:59:43 +0000
2749+++ bzrlib/benchmarks/bench_osutils.py 1970-01-01 00:00:00 +0000
2750@@ -1,37 +0,0 @@
2751-# Copyright (C) 2006 Canonical Ltd
2752-#
2753-# This program is free software; you can redistribute it and/or modify
2754-# it under the terms of the GNU General Public License as published by
2755-# the Free Software Foundation; either version 2 of the License, or
2756-# (at your option) any later version.
2757-#
2758-# This program is distributed in the hope that it will be useful,
2759-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2760-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2761-# GNU General Public License for more details.
2762-#
2763-# You should have received a copy of the GNU General Public License
2764-# along with this program; if not, write to the Free Software
2765-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2766-
2767-"""Tests for bzr osutils functions performance."""
2768-
2769-
2770-from bzrlib.benchmarks import Benchmark
2771-import bzrlib.osutils as osutils
2772-
2773-
2774-class WalkDirsBenchmark(Benchmark):
2775- """Benchmarks for `bzrlib.osutils.walkdirs`"""
2776-
2777- def test_walkdirs_kernel_like_tree(self):
2778- """Walking a kernel sized tree is fast!(150ms)."""
2779- self.make_kernel_like_tree(link_working=True)
2780- # on roberts machine: this originally took: 157ms/4177ms
2781- # plain os.walk takes 213ms on this tree
2782- # with the pyrex readdir module: 77ms/5423ms
2783- def dowalk():
2784- for dirblock in osutils.walkdirs('.'):
2785- if dirblock[0][1] == '.bzr':
2786- del dirblock[0]
2787- self.time(dowalk)
2788
2789=== removed file 'bzrlib/benchmarks/bench_pack.py'
2790--- bzrlib/benchmarks/bench_pack.py 2009-03-23 14:59:43 +0000
2791+++ bzrlib/benchmarks/bench_pack.py 1970-01-01 00:00:00 +0000
2792@@ -1,54 +0,0 @@
2793-# Copyright (C) 2007 Canonical Ltd
2794-#
2795-# This program is free software; you can redistribute it and/or modify
2796-# it under the terms of the GNU General Public License as published by
2797-# the Free Software Foundation; either version 2 of the License, or
2798-# (at your option) any later version.
2799-#
2800-# This program is distributed in the hope that it will be useful,
2801-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2802-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2803-# GNU General Public License for more details.
2804-#
2805-# You should have received a copy of the GNU General Public License
2806-# along with this program; if not, write to the Free Software
2807-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2808-
2809-"""Benchmarks for pack performance"""
2810-
2811-import os
2812-
2813-from bzrlib import (
2814- pack,
2815- )
2816-from bzrlib.benchmarks import Benchmark
2817-
2818-
2819-class BenchPack(Benchmark):
2820- """Benchmark pack performance."""
2821-
2822- def test_insert_one_gig_1k_chunks_no_names_disk(self):
2823- # test real disk writing of many small chunks.
2824- # useful for testing whether buffer sizes are right
2825- transport = self.get_transport()
2826- stream = transport.open_write_stream('pack.pack')
2827- writer = pack.ContainerWriter(stream.write)
2828- self.write_1_gig(writer)
2829- stream.close()
2830-
2831- def test_insert_one_gig_1k_chunks_no_names_null(self):
2832- # write to dev/null so we test the pack processing.
2833- transport = self.get_transport()
2834- dev_null = open('/dev/null', 'wb')
2835- writer = pack.ContainerWriter(dev_null.write)
2836- self.write_1_gig(writer)
2837- dev_null.close()
2838-
2839- def write_1_gig(self, writer):
2840- one_k = "A" * 1024
2841- writer.begin()
2842- def write_1g():
2843- for hunk in xrange(1024 * 1024):
2844- writer.add_bytes_record(one_k, [])
2845- self.time(write_1g)
2846- writer.end()
2847
2848=== removed file 'bzrlib/benchmarks/bench_rocks.py'
2849--- bzrlib/benchmarks/bench_rocks.py 2009-03-23 14:59:43 +0000
2850+++ bzrlib/benchmarks/bench_rocks.py 1970-01-01 00:00:00 +0000
2851@@ -1,28 +0,0 @@
2852-# Copyright (C) 2006 Canonical Ltd
2853-#
2854-# This program is free software; you can redistribute it and/or modify
2855-# it under the terms of the GNU General Public License as published by
2856-# the Free Software Foundation; either version 2 of the License, or
2857-# (at your option) any later version.
2858-#
2859-# This program is distributed in the hope that it will be useful,
2860-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2861-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2862-# GNU General Public License for more details.
2863-#
2864-# You should have received a copy of the GNU General Public License
2865-# along with this program; if not, write to the Free Software
2866-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2867-
2868-"""Benchmarks of bzr rocks."""
2869-
2870-
2871-from bzrlib.benchmarks import Benchmark
2872-
2873-
2874-class RocksBenchmark(Benchmark):
2875- """Benchmarks for ``'bzr rocks'``"""
2876-
2877- def test_rocks(self):
2878- """Test the startup overhead by running a do-nothing command"""
2879- self.time(self.run_bzr_subprocess, 'rocks')
2880
2881=== removed file 'bzrlib/benchmarks/bench_sftp.py'
2882--- bzrlib/benchmarks/bench_sftp.py 2009-03-23 14:59:43 +0000
2883+++ bzrlib/benchmarks/bench_sftp.py 1970-01-01 00:00:00 +0000
2884@@ -1,101 +0,0 @@
2885-# Copyright (C) 2006 Canonical Ltd
2886-#
2887-# This program is free software; you can redistribute it and/or modify
2888-# it under the terms of the GNU General Public License as published by
2889-# the Free Software Foundation; either version 2 of the License, or
2890-# (at your option) any later version.
2891-#
2892-# This program is distributed in the hope that it will be useful,
2893-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2894-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2895-# GNU General Public License for more details.
2896-#
2897-# You should have received a copy of the GNU General Public License
2898-# along with this program; if not, write to the Free Software
2899-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2900-
2901-"""Tests for bzr performance over SFTP"""
2902-
2903-import os
2904-
2905-from bzrlib import (
2906- bzrdir,
2907- )
2908-from bzrlib.benchmarks import Benchmark
2909-from bzrlib.tests import test_sftp_transport, TestSkipped
2910-
2911-try:
2912- import paramiko
2913- paramiko_loaded = True
2914-except ImportError:
2915- paramiko_loaded = False
2916-
2917-
2918-class SFTPBenchmark(Benchmark):
2919- """Benchmark branch, push and pull across a local sftp connection."""
2920-
2921- def setUp(self):
2922- super(SFTPBenchmark, self).setUp()
2923- if not paramiko_loaded:
2924- raise TestSkipped('you must have paramiko to run this test')
2925- test_sftp_transport.set_test_transport_to_sftp(self)
2926-
2927- def test_branch(self):
2928- os.mkdir("a")
2929- tree, files = self.create_with_commits(100, 100, "a")
2930- self.time(bzrdir.BzrDir.open(self.get_url('a')).sprout, "b")
2931-
2932- def create_commit_and_pull(self, num_pull_revisions):
2933- os.mkdir("a")
2934- tree, files = self.create_with_commits(100, 100, "a")
2935- rbzrdir = bzrdir.BzrDir.open(self.get_url('a'))
2936- b2 = tree.bzrdir.sprout("b") # branch
2937- # change a few files and commit
2938- self.commit_some_revisions(tree, files, num_pull_revisions, 20)
2939- self.time(b2.open_branch().pull, rbzrdir.open_branch())
2940-
2941- def test_pull_1(self):
2942- self.create_commit_and_pull(1)
2943-
2944- def test_pull_10(self):
2945- self.create_commit_and_pull(10)
2946-
2947- def test_pull_100(self):
2948- self.create_commit_and_pull(100)
2949-
2950- def create_commit_and_push(self, num_push_revisions):
2951- os.mkdir("a")
2952- tree, files = self.create_with_commits(100, 100, "a")
2953- rbzrdir = bzrdir.BzrDir.open(self.get_url('a'))
2954- b2 = tree.bzrdir.sprout("b") # branch
2955- wtree = b2.open_workingtree()
2956- # change a few files and commit
2957- self.commit_some_revisions(
2958- wtree, ["b/%i" for i in range(100)],
2959- num_commits=num_push_revisions,
2960- changes_per_commit=20)
2961- self.time(rbzrdir.open_branch().pull, wtree.branch)
2962-
2963- def test_initial_push(self):
2964- os.mkdir('a')
2965- tree, files = self.create_with_commits(100, 100, "a")
2966- self.time(tree.bzrdir.clone, self.get_url('b'),
2967- revision_id=tree.last_revision())
2968-
2969- def test_push_1(self):
2970- self.create_commit_and_push(1)
2971-
2972- def test_push_10(self):
2973- self.create_commit_and_push(10)
2974-
2975- def test_push_100(self):
2976- self.create_commit_and_push(100)
2977-
2978-
2979-class SFTPSlowSocketBenchmark(SFTPBenchmark):
2980- """Benchmarks of SFTP performance with a 30ms delay per roundtrip."""
2981-
2982- def setUp(self):
2983- super(SFTPSlowSocketBenchmark, self).setUp()
2984- self.get_server().add_latency = 0.03
2985-
2986
2987=== removed file 'bzrlib/benchmarks/bench_startup.py'
2988--- bzrlib/benchmarks/bench_startup.py 2009-03-23 14:59:43 +0000
2989+++ bzrlib/benchmarks/bench_startup.py 1970-01-01 00:00:00 +0000
2990@@ -1,91 +0,0 @@
2991-# Copyright (C) 2006 Canonical Ltd
2992-#
2993-# This program is free software; you can redistribute it and/or modify
2994-# it under the terms of the GNU General Public License as published by
2995-# the Free Software Foundation; either version 2 of the License, or
2996-# (at your option) any later version.
2997-#
2998-# This program is distributed in the hope that it will be useful,
2999-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3000-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3001-# GNU General Public License for more details.
3002-#
3003-# You should have received a copy of the GNU General Public License
3004-# along with this program; if not, write to the Free Software
3005-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3006-
3007-"""Benchmarks of bzr startup time, for some simple operations."""
3008-
3009-
3010-from bzrlib.benchmarks import Benchmark
3011-
3012-
3013-class StartupBenchmark(Benchmark):
3014- """Benchmark startup costs for certain bzr commands."""
3015-
3016- def make_simple_tree(self):
3017- """A small, simple tree. No caching needed"""
3018- tree = self.make_branch_and_tree('.')
3019- self.build_tree(['a', 'b/', 'b/c'])
3020- tree.add(['a', 'b', 'b/c'])
3021- return tree
3022-
3023- def make_simple_committed_tree(self):
3024- tree = self.make_simple_tree()
3025- tree.commit('simple commit')
3026- return tree
3027-
3028- def test___version(self):
3029- """Test the startup overhead of plain bzr --version"""
3030- self.time(self.run_bzr_subprocess, '--version')
3031-
3032- def test_branch(self):
3033- """Test the time to branch this into other"""
3034- tree = self.make_simple_committed_tree()
3035- self.time(self.run_bzr_subprocess, 'branch', '.', 'other')
3036-
3037- def test_commit(self):
3038- """Test execution of simple commit"""
3039- tree = self.make_simple_tree()
3040- self.time(self.run_bzr_subprocess, 'commit', '-m', 'init simple tree')
3041-
3042- def test_diff(self):
3043- """Test simple diff time"""
3044- tree = self.make_simple_committed_tree()
3045- self.time(self.run_bzr_subprocess, 'diff')
3046-
3047- def test_help(self):
3048- """Test the startup overhead of plain bzr help"""
3049- self.time(self.run_bzr_subprocess, 'help')
3050-
3051- def test_help_commands(self):
3052- """startup time for bzr help commands, which has to load more"""
3053- self.time(self.run_bzr_subprocess, 'help', 'commands')
3054-
3055- def test_log(self):
3056- """Test simple log time"""
3057- tree = self.make_simple_committed_tree()
3058- self.time(self.run_bzr_subprocess, 'log')
3059-
3060- def test_missing(self):
3061- """Test simple missing time"""
3062- tree = self.make_simple_committed_tree()
3063- other = tree.bzrdir.sprout('other')
3064- self.time(self.run_bzr_subprocess, 'missing', working_dir='other')
3065-
3066- def test_pull(self):
3067- """Test simple pull time"""
3068- tree = self.make_simple_committed_tree()
3069- other = tree.bzrdir.sprout('other')
3070- # There should be nothing to pull, and this should be determined
3071- # quickly
3072- self.time(self.run_bzr_subprocess, 'pull', working_dir='other')
3073-
3074- def test_rocks(self):
3075- """Test the startup overhead by running a do-nothing command"""
3076- self.time(self.run_bzr_subprocess, 'rocks')
3077-
3078- def test_status(self):
3079- """Test simple status time"""
3080- tree = self.make_simple_committed_tree()
3081- self.time(self.run_bzr_subprocess, 'status')
3082
3083=== removed file 'bzrlib/benchmarks/bench_status.py'
3084--- bzrlib/benchmarks/bench_status.py 2009-03-23 14:59:43 +0000
3085+++ bzrlib/benchmarks/bench_status.py 1970-01-01 00:00:00 +0000
3086@@ -1,52 +0,0 @@
3087-# Copyright (C) 2006, 2007 Canonical Ltd
3088-#
3089-# This program is free software; you can redistribute it and/or modify
3090-# it under the terms of the GNU General Public License as published by
3091-# the Free Software Foundation; either version 2 of the License, or
3092-# (at your option) any later version.
3093-#
3094-# This program is distributed in the hope that it will be useful,
3095-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3096-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3097-# GNU General Public License for more details.
3098-#
3099-# You should have received a copy of the GNU General Public License
3100-# along with this program; if not, write to the Free Software
3101-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3102-
3103-"""Tests for bzr status performance."""
3104-
3105-
3106-from bzrlib.benchmarks import Benchmark
3107-
3108-
3109-class StatusBenchmark(Benchmark):
3110- """Benchmarks for ``'bzr status'``."""
3111-
3112- def test_no_ignored_unknown_kernel_like_tree(self):
3113- """Status in a kernel sized tree with no ignored or unknowns.
3114-
3115- This should be bearable (<2secs) fast.
3116- """
3117- self.make_kernel_like_added_tree()
3118- # on robertc's machine the first sample of this took 1687ms/15994ms
3119- self.time(self.run_bzr, 'status')
3120-
3121- def test_no_changes_known_kernel_like_tree(self):
3122- """Status in a kernel sized tree with no ignored, unknowns, or added."""
3123- self.make_kernel_like_committed_tree(link_bzr=True)
3124- self.time(self.run_bzr, 'status')
3125-
3126- def test_single_file_no_changes_known_kernel_like_tree(self):
3127- """Status in a kernel sized tree with no ignored, unknowns, or added
3128- of a single file."""
3129- self.make_kernel_like_committed_tree()
3130- #XXX depends on the filenames generated by make_kernel_like_tree
3131- self.time(self.run_bzr, ['status', '7/4/0/16'])
3132-
3133- def test_status_one_added_file_kernel_like_tree(self):
3134- """Status of a single added file in our stock large tree."""
3135- self.make_kernel_like_tree()
3136- self.run_bzr('add')
3137- self.run_bzr(['commit', '-m', 'initial import'])
3138- self.time(self.run_bzr, ['status', '3/3/3/10'])
3139
3140=== removed file 'bzrlib/benchmarks/bench_tags.py'
3141--- bzrlib/benchmarks/bench_tags.py 2009-05-27 08:33:37 +0000
3142+++ bzrlib/benchmarks/bench_tags.py 1970-01-01 00:00:00 +0000
3143@@ -1,58 +0,0 @@
3144-# Copyright (C) 2007 Canonical Ltd
3145-#
3146-# This program is free software; you can redistribute it and/or modify
3147-# it under the terms of the GNU General Public License as published by
3148-# the Free Software Foundation; either version 2 of the License, or
3149-# (at your option) any later version.
3150-#
3151-# This program is distributed in the hope that it will be useful,
3152-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3153-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3154-# GNU General Public License for more details.
3155-#
3156-# You should have received a copy of the GNU General Public License
3157-# along with this program; if not, write to the Free Software
3158-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3159-
3160-"""Test for tags serialization (indirect testing for bencode)"""
3161-
3162-
3163-import time
3164-
3165-from bzrlib.benchmarks import Benchmark
3166-import bzrlib.bencode
3167-import bzrlib.tag
3168-
3169-
3170-class TagsBencodeBenchmark(Benchmark):
3171- """Benchmark for serialization/deserialization of tags"""
3172-
3173- def setUp(self):
3174- super(TagsBencodeBenchmark, self).setUp()
3175- self.tobj = bzrlib.tag.BasicTags(None)
3176- tags = {}
3177- revid = 'j.random@example.com-20070812132500-%016d'
3178- for i in xrange(100):
3179- tags[str(i)] = revid % i
3180- self.tags = tags
3181- self.bencoded_tags = bzrlib.bencode.bencode(tags)
3182-
3183- def time_N(self, N, kallable, *args, **kwargs):
3184- def _func(N, kallable, *args, **kwargs):
3185- for i in xrange(N):
3186- kallable(*args, **kwargs)
3187- self.time(_func, N, kallable, *args, **kwargs)
3188-
3189- def test_serialize_empty_tags(self):
3190- # Measure overhead of operation
3191- self.time_N(10000, self.tobj._serialize_tag_dict, {})
3192-
3193- def test_deserialize_empty_tags(self):
3194- # Measure overhead of operation
3195- self.time_N(10000, self.tobj._deserialize_tag_dict, 'de')
3196-
3197- def test_serialize_tags(self):
3198- self.time_N(1000, self.tobj._serialize_tag_dict, self.tags)
3199-
3200- def test_deserialize_tags(self):
3201- self.time_N(1000, self.tobj._deserialize_tag_dict, self.bencoded_tags)
3202
3203=== removed file 'bzrlib/benchmarks/bench_transform.py'
3204--- bzrlib/benchmarks/bench_transform.py 2009-03-23 14:59:43 +0000
3205+++ bzrlib/benchmarks/bench_transform.py 1970-01-01 00:00:00 +0000
3206@@ -1,43 +0,0 @@
3207-# Copyright (C) 2006 Canonical Ltd
3208-#
3209-# This program is free software; you can redistribute it and/or modify
3210-# it under the terms of the GNU General Public License as published by
3211-# the Free Software Foundation; either version 2 of the License, or
3212-# (at your option) any later version.
3213-#
3214-# This program is distributed in the hope that it will be useful,
3215-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3216-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3217-# GNU General Public License for more details.
3218-#
3219-# You should have received a copy of the GNU General Public License
3220-# along with this program; if not, write to the Free Software
3221-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3222-
3223-"""Tests for tree transform performance"""
3224-
3225-import os
3226-
3227-from bzrlib.benchmarks import Benchmark
3228-from bzrlib.osutils import pathjoin
3229-from bzrlib.transform import TreeTransform
3230-from bzrlib.workingtree import WorkingTree
3231-
3232-
3233-class TransformBenchmark(Benchmark):
3234- """Benchmarks for `bzrlib.transform`"""
3235-
3236- def test_canonicalize_path(self):
3237- """Canonicalizing paths should be fast."""
3238- wt = self.make_kernel_like_tree(link_working=True)
3239- paths = []
3240- for dirpath, dirnames, filenames in os.walk('.'):
3241- paths.extend(pathjoin(dirpath, d) for d in dirnames)
3242- paths.extend(pathjoin(dirpath, f) for f in filenames)
3243- tt = TreeTransform(wt)
3244- self.time(self.canonicalize_paths, tt, paths)
3245- tt.finalize()
3246-
3247- def canonicalize_paths(self, tt, paths):
3248- for path in paths:
3249- tt.canonical_path(path)
3250
3251=== removed file 'bzrlib/benchmarks/bench_workingtree.py'
3252--- bzrlib/benchmarks/bench_workingtree.py 2009-03-23 14:59:43 +0000
3253+++ bzrlib/benchmarks/bench_workingtree.py 1970-01-01 00:00:00 +0000
3254@@ -1,111 +0,0 @@
3255-# Copyright (C) 2006 Canonical Ltd
3256-#
3257-# This program is free software; you can redistribute it and/or modify
3258-# it under the terms of the GNU General Public License as published by
3259-# the Free Software Foundation; either version 2 of the License, or
3260-# (at your option) any later version.
3261-#
3262-# This program is distributed in the hope that it will be useful,
3263-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3264-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3265-# GNU General Public License for more details.
3266-#
3267-# You should have received a copy of the GNU General Public License
3268-# along with this program; if not, write to the Free Software
3269-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3270-
3271-"""Tests for bzr working tree performance."""
3272-
3273-import os
3274-
3275-from bzrlib import ignores
3276-from bzrlib.benchmarks import Benchmark
3277-from bzrlib.workingtree import WorkingTree
3278-
3279-
3280-class WorkingTreeBenchmark(Benchmark):
3281- """Benchmarks for `bzrlib.workingtree` performance."""
3282-
3283- def test_list_files_kernel_like_tree(self):
3284- tree = self.make_kernel_like_added_tree()
3285- tree.lock_read()
3286- try:
3287- self.time(list, tree.list_files())
3288- finally:
3289- tree.unlock()
3290-
3291- def test_list_files_unknown_kernel_like_tree(self):
3292- tree = self.make_kernel_like_tree(link_working=True)
3293- tree = WorkingTree.open('.')
3294- # Bzr only traverses directories if they are versioned
3295- # So add all the directories, but not the files, yielding
3296- # lots of unknown files.
3297- for root, dirs, files in os.walk('.'):
3298- if '.bzr' in dirs:
3299- dirs.remove('.bzr')
3300- if root == '.':
3301- continue
3302- tree.add(root)
3303- tree.lock_read()
3304- try:
3305- self.time(list, tree.list_files())
3306- finally:
3307- tree.unlock()
3308-
3309- def test_is_ignored_single_call(self):
3310- """How long does is_ignored take to initialise and check one file."""
3311- t = self.make_branch_and_tree('.')
3312- self.time(t.is_ignored, "CVS")
3313-
3314- def test_is_ignored_10824_calls(self):
3315- """How long does is_ignored take to initialise and check one file."""
3316- t = self.make_branch_and_tree('.')
3317- def call_is_ignored_10824_not_ignored():
3318- for x in xrange(10824):
3319- t.is_ignored(str(x))
3320- self.time(call_is_ignored_10824_not_ignored)
3321-
3322- def test_is_ignored_10_patterns(self):
3323- t = self.make_branch_and_tree('.')
3324- ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 9)])
3325- ignores.add_runtime_ignores(['./foo', 'foo/bar'])
3326- self.time(t.is_ignored,'bar')
3327- ignores._runtime_ignores = set()
3328-
3329- def test_is_ignored_50_patterns(self):
3330- t = self.make_branch_and_tree('.')
3331- ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 49)])
3332- ignores.add_runtime_ignores(['./foo', 'foo/bar'])
3333- self.time(t.is_ignored,'bar')
3334- ignores._runtime_ignores = set()
3335-
3336- def test_is_ignored_100_patterns(self):
3337- t = self.make_branch_and_tree('.')
3338- ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 99)])
3339- ignores.add_runtime_ignores(['./foo', 'foo/bar'])
3340- self.time(t.is_ignored,'bar')
3341- ignores._runtime_ignores = set()
3342-
3343- def test_is_ignored_1000_patterns(self):
3344- t = self.make_branch_and_tree('.')
3345- ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 999)])
3346- ignores.add_runtime_ignores(['./foo', 'foo/bar'])
3347- self.time(t.is_ignored,'bar')
3348- ignores._runtime_ignores = set()
3349-
3350- def test_walkdirs_kernel_like_tree(self):
3351- """Walking a kernel sized tree is fast!(150ms)."""
3352- self.make_kernel_like_tree()
3353- self.run_bzr('add')
3354- tree = WorkingTree.open('.')
3355- # on roberts machine: this originally took: 157ms/4177ms
3356- # plain os.walk takes 213ms on this tree
3357- self.time(list, tree.walkdirs())
3358-
3359- def test_walkdirs_kernel_like_tree_unknown(self):
3360- """Walking a kernel sized tree is fast!(150ms)."""
3361- self.make_kernel_like_tree()
3362- tree = WorkingTree.open('.')
3363- # on roberts machine: this originally took: 157ms/4177ms
3364- # plain os.walk takes 213ms on this tree
3365- self.time(list, tree.walkdirs())
3366
3367=== removed file 'bzrlib/benchmarks/bench_xml.py'
3368--- bzrlib/benchmarks/bench_xml.py 2009-03-23 14:59:43 +0000
3369+++ bzrlib/benchmarks/bench_xml.py 1970-01-01 00:00:00 +0000
3370@@ -1,87 +0,0 @@
3371-# Copyright (C) 2006 Canonical Ltd
3372-#
3373-# This program is free software; you can redistribute it and/or modify
3374-# it under the terms of the GNU General Public License as published by
3375-# the Free Software Foundation; either version 2 of the License, or
3376-# (at your option) any later version.
3377-#
3378-# This program is distributed in the hope that it will be useful,
3379-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3380-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3381-# GNU General Public License for more details.
3382-#
3383-# You should have received a copy of the GNU General Public License
3384-# along with this program; if not, write to the Free Software
3385-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3386-
3387-"""Tests for bzr xml serialization performance."""
3388-
3389-from bzrlib import (
3390- cache_utf8,
3391- xml5,
3392- )
3393-from bzrlib.benchmarks import Benchmark
3394-
3395-
3396-class BenchXMLSerializer(Benchmark):
3397- """Benchmarks for serializing to/from XML."""
3398-
3399- def test_write_to_string_kernel_like_inventory(self):
3400- # On jam's machine, ElementTree serializer took: 2161ms/13487ms
3401- # with Robert's serializer: 631ms/10770ms
3402- # with Entity escaper: 487ms/11636ms
3403- # caching Entity escaper, empty cache: 448ms/ 9489ms
3404- # caching Entity escaper, full cache: 375ms/ 9489ms
3405- # passing around function: 406ms/ 8942ms
3406- # cached, passing around function: 328ms/11248ms
3407- # removing extra function: 354ms/ 8942ms
3408- # cached, removing extra function: 275ms/11248ms
3409- # no cache, real utf8: 363ms/11697ms
3410- # cached, real utf8: 272ms/12827ms
3411- # Really all we want is a real inventory
3412- inv = self.make_kernel_like_inventory()
3413-
3414- xml5._clear_cache()
3415- # We want a real tree with lots of file ids and sha strings, etc.
3416- self.time(xml5.serializer_v5.write_inventory_to_string, inv)
3417-
3418- def test_write_kernel_like_inventory(self):
3419- # Really all we want is a real inventory
3420- inv = self.make_kernel_like_inventory()
3421-
3422- xml5._clear_cache()
3423- f = open('kernel-like-inventory', 'wb')
3424- try:
3425- # We want a real tree with lots of file ids and sha strings, etc.
3426- self.time(xml5.serializer_v5.write_inventory, inv, f)
3427- finally:
3428- f.close()
3429-
3430- def test_write_to_string_cached_kernel_like_inventory(self):
3431- inv = self.make_kernel_like_inventory()
3432-
3433- xml5._clear_cache()
3434- # We want a real tree with lots of file ids and sha strings, etc.
3435- xml5.serializer_v5.write_inventory_to_string(inv)
3436-
3437- self.time(xml5.serializer_v5.write_inventory_to_string, inv)
3438-
3439- def test_read_from_string_kernel_like_inventory(self):
3440- inv = self.make_kernel_like_inventory()
3441- as_str = xml5.serializer_v5.write_inventory_to_string(inv)
3442-
3443- cache_utf8.clear_encoding_cache()
3444- read_inv = self.time(xml5.serializer_v5.read_inventory_from_string,
3445- as_str)
3446- # TODO: make sure the final inventory is equal as a sanity check
3447-
3448- def test_read_from_string_cached_kernel_like_inventory(self):
3449- cache_utf8.clear_encoding_cache()
3450- inv = self.make_kernel_like_inventory()
3451- as_str = xml5.serializer_v5.write_inventory_to_string(inv)
3452-
3453- xml5.serializer_v5.read_inventory_from_string(as_str)
3454-
3455- read_inv = self.time(xml5.serializer_v5.read_inventory_from_string,
3456- as_str)
3457- # TODO: make sure the final inventory is equal as a sanity check
3458
3459=== removed file 'bzrlib/benchmarks/tree_creator/__init__.py'
3460--- bzrlib/benchmarks/tree_creator/__init__.py 2009-03-23 14:59:43 +0000
3461+++ bzrlib/benchmarks/tree_creator/__init__.py 1970-01-01 00:00:00 +0000
3462@@ -1,175 +0,0 @@
3463-# Copyright (C) 2006 Canonical Ltd
3464-#
3465-# This program is free software; you can redistribute it and/or modify
3466-# it under the terms of the GNU General Public License as published by
3467-# the Free Software Foundation; either version 2 of the License, or
3468-# (at your option) any later version.
3469-#
3470-# This program is distributed in the hope that it will be useful,
3471-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3472-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3473-# GNU General Public License for more details.
3474-#
3475-# You should have received a copy of the GNU General Public License
3476-# along with this program; if not, write to the Free Software
3477-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3478-
3479-"""Base implementation of TreeCreator classes
3480-
3481-These are classes that are used to easily create test trees.
3482-"""
3483-
3484-import os
3485-import shutil
3486-
3487-from bzrlib import (
3488- osutils,
3489- workingtree,
3490- )
3491-
3492-
3493-class TreeCreator(object):
3494- """Just a basic class which is used to create various test trees"""
3495-
3496- CACHE_ROOT = None
3497-
3498- def __init__(self, test, tree_name,
3499- link_bzr=False,
3500- link_working=False,
3501- hot_cache=True):
3502- """Instantiate a new creator object, supply the id of the tree
3503-
3504- :param test: A TestCaseWithTransport object (most creators need
3505- we need the build_tree functionality)
3506- """
3507-
3508- self._cache_root = TreeCreator.CACHE_ROOT
3509- self._test = test
3510- self._tree_name = tree_name
3511- self._link_bzr = link_bzr
3512- self._link_working = link_working
3513- self._hot_cache = hot_cache
3514- if not osutils.hardlinks_good():
3515- self._link_working = self._link_bzr = False
3516-
3517- def is_caching_enabled(self):
3518- """Will we try to cache the tree we create?"""
3519- return self._cache_root is not None
3520-
3521- def is_cached(self):
3522- """Is this tree already cached?"""
3523- cache_dir = self._get_cache_dir()
3524- if cache_dir is None:
3525- return False
3526- return os.path.exists(cache_dir)
3527-
3528- def disable_cache(self):
3529- """Do not use the cache"""
3530- self._cache_root = None
3531-
3532- def ensure_cached(self):
3533- """If caching, make sure the cached copy exists"""
3534- cache_dir = self._get_cache_dir()
3535- if cache_dir is None:
3536- return
3537-
3538- if not self.is_cached():
3539- self._create_tree(root=cache_dir, in_cache=True)
3540-
3541- def create(self, root):
3542- """Create a new tree at 'root'.
3543-
3544- :return: A WorkingTree object.
3545- """
3546- cache_dir = self._get_cache_dir()
3547- if cache_dir is None:
3548- # Not caching
3549- return self._create_tree(root, in_cache=False)
3550-
3551- self.ensure_cached()
3552-
3553- return self._clone_cached_tree(root)
3554-
3555- def _get_cache_dir(self):
3556- """Get the directory to use for caching this tree
3557-
3558- :return: The path to use for caching. If None, caching is disabled
3559- """
3560- if self._cache_root is None:
3561- return None
3562- return osutils.pathjoin(self._cache_root, self._tree_name)
3563-
3564- def _create_tree(self, root, in_cache=False):
3565- """Create the desired tree in the given location.
3566-
3567- Children should override this function to provide the actual creation
3568- of the desired tree. This will be called by 'create()'. If it is
3569- building a tree in the cache, before copying it to the real target,
3570- it will pass in_cache=True
3571- """
3572- raise NotImplemented(self._create_tree)
3573-
3574- def _clone_cached_tree(self, dest):
3575- """Copy the contents of the cached dir into the destination
3576- Optionally hardlink certain pieces of the tree.
3577-
3578- This is just meant as a helper function for child classes
3579-
3580- :param dest: The destination to copy things to
3581- """
3582- # We use shutil.copyfile so that we don't copy permissions
3583- # because most of our source trees are marked readonly to
3584- # prevent modifying in the case of hardlinks
3585- handlers = {'file':shutil.copyfile}
3586- if osutils.hardlinks_good():
3587- if self._link_working:
3588- if self._link_bzr:
3589- handlers = {'file':os.link}
3590- else:
3591- # Don't hardlink files inside bzr
3592- def file_handler(source, dest):
3593- if '.bzr/' in source:
3594- shutil.copyfile(source, dest)
3595- else:
3596- os.link(source, dest)
3597- handlers = {'file':file_handler}
3598- elif self._link_bzr:
3599- # Only link files inside .bzr/
3600- def file_handler(source, dest):
3601- if '.bzr/' in source:
3602- os.link(source, dest)
3603- else:
3604- shutil.copyfile(source, dest)
3605- handlers = {'file':file_handler}
3606-
3607- source = self._get_cache_dir()
3608- osutils.copy_tree(source, dest, handlers=handlers)
3609- tree = workingtree.WorkingTree.open(dest)
3610- if self._hot_cache:
3611- tree.lock_write()
3612- try:
3613- # tree._hashcache.scan() just checks and removes
3614- # entries that are out of date
3615- # we need to actually store new ones
3616- for path, ie in tree.inventory.iter_entries_by_dir():
3617- tree.get_file_sha1(ie.file_id, path)
3618- finally:
3619- tree.unlock()
3620- # If we didn't iterate the tree, the hash cache is technically
3621- # invalid, and it would be better to remove it, but there is
3622- # no public api for that.
3623- return tree
3624-
3625- def _protect_files(self, root):
3626- """Chmod all files underneath 'root' to prevent writing
3627-
3628- This is a helper function for child classes.
3629-
3630- :param root: The base directory to modify
3631- """
3632- for dirinfo, entries in osutils.walkdirs(root):
3633- for relpath, name, kind, st, abspath in entries:
3634- if kind == 'file':
3635- os.chmod(abspath, 0440)
3636-
3637-
3638
3639=== removed file 'bzrlib/benchmarks/tree_creator/heavily_merged.py'
3640--- bzrlib/benchmarks/tree_creator/heavily_merged.py 2009-03-23 14:59:43 +0000
3641+++ bzrlib/benchmarks/tree_creator/heavily_merged.py 1970-01-01 00:00:00 +0000
3642@@ -1,75 +0,0 @@
3643-# Copyright (C) 2006 Canonical Ltd
3644-#
3645-# This program is free software; you can redistribute it and/or modify
3646-# it under the terms of the GNU General Public License as published by
3647-# the Free Software Foundation; either version 2 of the License, or
3648-# (at your option) any later version.
3649-#
3650-# This program is distributed in the hope that it will be useful,
3651-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3652-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3653-# GNU General Public License for more details.
3654-#
3655-# You should have received a copy of the GNU General Public License
3656-# along with this program; if not, write to the Free Software
3657-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3658-
3659-"""Tree creator for many commits, but no changes"""
3660-
3661-import errno
3662-import os
3663-
3664-from bzrlib import (
3665- bzrdir,
3666- )
3667-
3668-from bzrlib.benchmarks.tree_creator import TreeCreator
3669-
3670-
3671-class HeavilyMergedTreeCreator(TreeCreator):
3672- """Create a tree in which almost every commit is a merge.
3673-
3674- No file changes are included. This produces two trees,
3675- one of which is returned. Except for the first commit, every
3676- commit in its revision-history is a merge of another commit in the other
3677- tree.
3678- Not hardlinking the working tree, because there are no working tree files.
3679- """
3680-
3681- def __init__(self, test, link_bzr=True):
3682- super(HeavilyMergedTreeCreator, self).__init__(test,
3683- tree_name='heavily_merged_tree',
3684- link_bzr=link_bzr,
3685- link_working=False,
3686- hot_cache=True)
3687-
3688- def _create_tree(self, root, in_cache=False):
3689- try:
3690- os.mkdir(root)
3691- except (IOError, OSError), e:
3692- if e.errno not in (errno.EEXIST,):
3693- raise
3694-
3695- tree = bzrdir.BzrDir.create_standalone_workingtree(root)
3696- tree.lock_write()
3697- try:
3698- tree2 = tree.bzrdir.sprout(root + '/tree2').open_workingtree()
3699- tree2.lock_write()
3700- try:
3701- for i in xrange(250):
3702- revision_id = tree.commit('no-changes commit %d-a' % i)
3703- tree2.branch.fetch(tree.branch, revision_id)
3704- tree2.add_parent_tree_id(revision_id)
3705- revision_id = tree2.commit('no-changes commit %d-b' % i)
3706- tree.branch.fetch(tree2.branch, revision_id)
3707- tree.add_parent_tree_id(revision_id)
3708- tree.set_parent_ids(tree.get_parent_ids()[:1])
3709- finally:
3710- tree2.unlock()
3711- finally:
3712- tree.unlock()
3713- if in_cache:
3714- self._protect_files(root+'/.bzr')
3715- return tree
3716-
3717-
3718
3719=== renamed file 'bzrlib/benchmarks/tree_creator/kernel_like.py' => 'bzrlib/benchmarks/tree_creator/kernel_like.py.THIS'
3720=== removed file 'bzrlib/benchmarks/tree_creator/many_commit.py'
3721--- bzrlib/benchmarks/tree_creator/many_commit.py 2009-03-23 14:59:43 +0000
3722+++ bzrlib/benchmarks/tree_creator/many_commit.py 1970-01-01 00:00:00 +0000
3723@@ -1,68 +0,0 @@
3724-# Copyright (C) 2006 Canonical Ltd
3725-#
3726-# This program is free software; you can redistribute it and/or modify
3727-# it under the terms of the GNU General Public License as published by
3728-# the Free Software Foundation; either version 2 of the License, or
3729-# (at your option) any later version.
3730-#
3731-# This program is distributed in the hope that it will be useful,
3732-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3733-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3734-# GNU General Public License for more details.
3735-#
3736-# You should have received a copy of the GNU General Public License
3737-# along with this program; if not, write to the Free Software
3738-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3739-
3740-"""Tree creator for many commits, including file changes."""
3741-
3742-from bzrlib import (
3743- bzrdir,
3744- )
3745-
3746-from bzrlib.benchmarks.tree_creator import TreeCreator
3747-
3748-
3749-class ManyCommitTreeCreator(TreeCreator):
3750- """Create an tree many files and many commits."""
3751-
3752- def __init__(self, test, link_bzr=False, num_files=10, num_commits=10):
3753- tree_name = 'many_files_many_commit_tree_%d_%d' % (
3754- num_files, num_commits)
3755- super(ManyCommitTreeCreator, self).__init__(test,
3756- tree_name=tree_name,
3757- link_bzr=link_bzr,
3758- link_working=False,
3759- hot_cache=True)
3760- self.files = ["%s" % (i, ) for i in range(num_files)]
3761- self.num_files = num_files
3762- self.num_commits = num_commits
3763-
3764- def _create_tree(self, root, in_cache=False):
3765- num_files = self.num_files
3766- num_commits = self.num_commits
3767- files = ["%s/%s" % (root, fn) for fn in self.files]
3768- for fn in files:
3769- f = open(fn, "wb")
3770- try:
3771- f.write("some content\n")
3772- finally:
3773- f.close()
3774- tree = bzrdir.BzrDir.create_standalone_workingtree(root)
3775- tree.add(self.files)
3776- tree.lock_write()
3777- try:
3778- tree.commit('initial commit')
3779- for i in range(num_commits):
3780- fn = files[i % len(files)]
3781- content = range(i) + [i, i, i, ""]
3782- f = open(fn, "wb")
3783- try:
3784- f.write("\n".join([str(i) for i in content]))
3785- finally:
3786- f.close()
3787- tree.commit("changing file %s" % fn)
3788- finally:
3789- tree.unlock()
3790- return tree
3791-
3792
3793=== removed file 'bzrlib/benchmarks/tree_creator/simple_many_commit.py'
3794--- bzrlib/benchmarks/tree_creator/simple_many_commit.py 2009-03-23 14:59:43 +0000
3795+++ bzrlib/benchmarks/tree_creator/simple_many_commit.py 1970-01-01 00:00:00 +0000
3796@@ -1,47 +0,0 @@
3797-# Copyright (C) 2006 Canonical Ltd
3798-#
3799-# This program is free software; you can redistribute it and/or modify
3800-# it under the terms of the GNU General Public License as published by
3801-# the Free Software Foundation; either version 2 of the License, or
3802-# (at your option) any later version.
3803-#
3804-# This program is distributed in the hope that it will be useful,
3805-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3806-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3807-# GNU General Public License for more details.
3808-#
3809-# You should have received a copy of the GNU General Public License
3810-# along with this program; if not, write to the Free Software
3811-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3812-
3813-"""Tree creator for many commits, but no changes"""
3814-
3815-from bzrlib import (
3816- bzrdir,
3817- )
3818-
3819-from bzrlib.benchmarks.tree_creator import TreeCreator
3820-
3821-
3822-class SimpleManyCommitTreeCreator(TreeCreator):
3823- """Create an empty tree with lots of commits"""
3824-
3825- def __init__(self, test, link_bzr=False):
3826- super(SimpleManyCommitTreeCreator, self).__init__(test,
3827- tree_name='many_commit_tree',
3828- link_bzr=link_bzr,
3829- link_working=False,
3830- hot_cache=True)
3831-
3832- def _create_tree(self, root, in_cache=False):
3833- tree = bzrdir.BzrDir.create_standalone_workingtree(root)
3834- tree.lock_write()
3835- try:
3836- for i in xrange(1000):
3837- tree.commit('no-changes commit %d' % i)
3838- finally:
3839- tree.unlock()
3840- if in_cache:
3841- self._protect_files(root+'/.bzr')
3842-
3843- return tree
3844
3845=== modified file 'bzrlib/branch.py'
3846--- bzrlib/branch.py 2010-07-22 23:01:51 +0000
3847+++ bzrlib/branch.py 2010-07-29 06:48:01 +0000
3848@@ -246,9 +246,13 @@
3849 if not local and not config.has_explicit_nickname():
3850 try:
3851 master = self.get_master_branch(possible_transports)
3852+ if master and self.user_url == master.user_url:
3853+ raise errors.RecursiveBind(self.user_url)
3854 if master is not None:
3855 # return the master branch value
3856 return master.nick
3857+ except errors.RecursiveBind, e:
3858+ raise e
3859 except errors.BzrError, e:
3860 # Silently fall back to local implicit nick if the master is
3861 # unavailable
3862
3863=== modified file 'bzrlib/builtins.py'
3864--- bzrlib/builtins.py 2010-07-20 10:18:05 +0000
3865+++ bzrlib/builtins.py 2010-07-29 06:48:01 +0000
3866@@ -171,10 +171,60 @@
3867
3868 :return: workingtree, [relative_paths]
3869 """
3870+<<<<<<< TREE
3871 return WorkingTree.open_containing_paths(
3872 file_list, default_directory='.',
3873 canonicalize=True,
3874 apply_view=True)
3875+=======
3876+ if file_list is None or len(file_list) == 0:
3877+ tree = WorkingTree.open_containing(default_branch)[0]
3878+ if tree.supports_views() and apply_view:
3879+ view_files = tree.views.lookup_view()
3880+ if view_files:
3881+ file_list = view_files
3882+ view_str = views.view_display_str(view_files)
3883+ note("Ignoring files outside view. View is %s" % view_str)
3884+ return tree, file_list
3885+ tree = WorkingTree.open_containing(file_list[0])[0]
3886+ return tree, safe_relpath_files(tree, file_list, canonicalize,
3887+ apply_view=apply_view)
3888+
3889+
3890+def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
3891+ """Convert file_list into a list of relpaths in tree.
3892+
3893+ :param tree: A tree to operate on.
3894+ :param file_list: A list of user provided paths or None.
3895+ :param apply_view: if True and a view is set, apply it or check that
3896+ specified files are within it
3897+ :return: A list of relative paths.
3898+ :raises errors.PathNotChild: When a provided path is in a different tree
3899+ than tree.
3900+ """
3901+ if file_list is None:
3902+ return None
3903+ if tree.supports_views() and apply_view:
3904+ view_files = tree.views.lookup_view()
3905+ else:
3906+ view_files = []
3907+ new_list = []
3908+ # tree.relpath exists as a "thunk" to osutils, but canonical_relpath
3909+ # doesn't - fix that up here before we enter the loop.
3910+ if canonicalize:
3911+ fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
3912+ else:
3913+ fixer = tree.relpath
3914+ for filename in file_list:
3915+ try:
3916+ relpath = fixer(osutils.dereference_path(filename))
3917+ if view_files and not osutils.is_inside_any(view_files, relpath):
3918+ raise errors.FileOutsideView(filename, view_files)
3919+ new_list.append(relpath)
3920+ except errors.PathNotChild:
3921+ raise errors.FileInWrongBranch(tree.branch, filename)
3922+ return new_list
3923+>>>>>>> MERGE-SOURCE
3924
3925
3926 def _get_view_info_for_change_reporter(tree):
3927@@ -718,6 +768,7 @@
3928 raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
3929
3930 revision = _get_one_revision('inventory', revision)
3931+<<<<<<< TREE
3932 work_tree, file_list = WorkingTree.open_containing_paths(file_list)
3933 self.add_cleanup(work_tree.lock_read().unlock)
3934 if revision is not None:
3935@@ -740,6 +791,30 @@
3936 entries = tree.inventory.entries()
3937
3938 self.cleanup_now()
3939+=======
3940+ work_tree, file_list = tree_files(file_list)
3941+ self.add_cleanup(work_tree.lock_read().unlock)
3942+ if revision is not None:
3943+ tree = revision.as_tree(work_tree.branch)
3944+
3945+ extra_trees = [work_tree]
3946+ self.add_cleanup(tree.lock_read().unlock)
3947+ else:
3948+ tree = work_tree
3949+ extra_trees = []
3950+
3951+ if file_list is not None:
3952+ file_ids = tree.paths2ids(file_list, trees=extra_trees,
3953+ require_versioned=True)
3954+ # find_ids_across_trees may include some paths that don't
3955+ # exist in 'tree'.
3956+ entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
3957+ for file_id in file_ids if file_id in tree)
3958+ else:
3959+ entries = tree.inventory.entries()
3960+
3961+ self.cleanup_now()
3962+>>>>>>> MERGE-SOURCE
3963 for path, entry in entries:
3964 if kind and kind != entry.kind:
3965 continue
3966@@ -789,9 +864,15 @@
3967 names_list = []
3968 if len(names_list) < 2:
3969 raise errors.BzrCommandError("missing file argument")
3970+<<<<<<< TREE
3971 tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
3972 self.add_cleanup(tree.lock_tree_write().unlock)
3973 self._run(tree, names_list, rel_names, after)
3974+=======
3975+ tree, rel_names = tree_files(names_list, canonicalize=False)
3976+ self.add_cleanup(tree.lock_tree_write().unlock)
3977+ self._run(tree, names_list, rel_names, after)
3978+>>>>>>> MERGE-SOURCE
3979
3980 def run_auto(self, names_list, after, dry_run):
3981 if names_list is not None and len(names_list) > 1:
3982@@ -800,10 +881,16 @@
3983 if after:
3984 raise errors.BzrCommandError('--after cannot be specified with'
3985 ' --auto.')
3986+<<<<<<< TREE
3987 work_tree, file_list = WorkingTree.open_containing_paths(
3988 names_list, default_directory='.')
3989 self.add_cleanup(work_tree.lock_tree_write().unlock)
3990 rename_map.RenameMap.guess_renames(work_tree, dry_run)
3991+=======
3992+ work_tree, file_list = tree_files(names_list, default_branch='.')
3993+ self.add_cleanup(work_tree.lock_tree_write().unlock)
3994+ rename_map.RenameMap.guess_renames(work_tree, dry_run)
3995+>>>>>>> MERGE-SOURCE
3996
3997 def _run(self, tree, names_list, rel_names, after):
3998 into_existing = osutils.isdir(names_list[-1])
3999@@ -1162,12 +1249,17 @@
4000
4001 def run(self, from_location, to_location=None, revision=None,
4002 hardlink=False, stacked=False, standalone=False, no_tree=False,
4003+<<<<<<< TREE
4004 use_existing_dir=False, switch=False, bind=False,
4005 files_from=None):
4006+=======
4007+ use_existing_dir=False, switch=False, bind=False):
4008+>>>>>>> MERGE-SOURCE
4009 from bzrlib import switch as _mod_switch
4010 from bzrlib.tag import _merge_tags_if_possible
4011 accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
4012 from_location)
4013+<<<<<<< TREE
4014 if not (hardlink or files_from):
4015 # accelerator_tree is usually slower because you have to read N
4016 # files (no readahead, lots of seeks, etc), but allow the user to
4017@@ -1175,6 +1267,8 @@
4018 accelerator_tree = None
4019 if files_from is not None and files_from != from_location:
4020 accelerator_tree = WorkingTree.open(files_from)
4021+=======
4022+>>>>>>> MERGE-SOURCE
4023 revision = _get_one_revision('branch', revision)
4024 self.add_cleanup(br_from.lock_read().unlock)
4025 if revision is not None:
4026@@ -2689,6 +2783,14 @@
4027 "NAME_PATTERN or --default-rules.")
4028 name_pattern_list = [globbing.normalize_pattern(p)
4029 for p in name_pattern_list]
4030+ bad_patterns = ''
4031+ for p in name_pattern_list:
4032+ if not globbing.Globster.is_pattern_valid(p):
4033+ bad_patterns += ('\n %s' % p)
4034+ if bad_patterns:
4035+ msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
4036+ ui.ui_factory.show_error(msg)
4037+ raise errors.InvalidPattern('')
4038 for name_pattern in name_pattern_list:
4039 if (name_pattern[0] == '/' or
4040 (len(name_pattern) > 1 and name_pattern[1] == ':')):
4041@@ -3164,9 +3266,15 @@
4042 specific_files=selected_list,
4043 allow_pointless=unchanged, strict=strict, local=local,
4044 reporter=None, verbose=verbose, revprops=properties,
4045+<<<<<<< TREE
4046 authors=author, timestamp=commit_stamp,
4047 timezone=offset,
4048 exclude=tree.safe_relpath_files(exclude))
4049+=======
4050+ authors=author, timestamp=commit_stamp,
4051+ timezone=offset,
4052+ exclude=safe_relpath_files(tree, exclude))
4053+>>>>>>> MERGE-SOURCE
4054 except PointlessCommit:
4055 raise errors.BzrCommandError("No changes to commit."
4056 " Use --unchanged to commit anyhow.")
4057@@ -3506,15 +3614,21 @@
4058 'throughout the test suite.',
4059 type=get_transport_type),
4060 Option('benchmark',
4061- help='Run the benchmarks rather than selftests.'),
4062+ help='Run the benchmarks rather than selftests.',
4063+ hidden=True),
4064 Option('lsprof-timed',
4065 help='Generate lsprof output for benchmarked'
4066 ' sections of code.'),
4067+<<<<<<< TREE
4068 Option('lsprof-tests',
4069 help='Generate lsprof output for each test.'),
4070 Option('cache-dir', type=str,
4071 help='Cache intermediate benchmark output in this '
4072 'directory.'),
4073+=======
4074+ Option('lsprof-tests',
4075+ help='Generate lsprof output for each test.'),
4076+>>>>>>> MERGE-SOURCE
4077 Option('first',
4078 help='Run all tests, but run specified tests first.',
4079 short_name='f',
4080@@ -3554,20 +3668,16 @@
4081
4082 def run(self, testspecs_list=None, verbose=False, one=False,
4083 transport=None, benchmark=None,
4084- lsprof_timed=None, cache_dir=None,
4085+ lsprof_timed=None,
4086 first=False, list_only=False,
4087 randomize=None, exclude=None, strict=False,
4088 load_list=None, debugflag=None, starting_with=None, subunit=False,
4089 parallel=None, lsprof_tests=False):
4090 from bzrlib.tests import selftest
4091- import bzrlib.benchmarks as benchmarks
4092- from bzrlib.benchmarks import tree_creator
4093
4094 # Make deprecation warnings visible, unless -Werror is set
4095 symbol_versioning.activate_deprecation_warnings(override=False)
4096
4097- if cache_dir is not None:
4098- tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
4099 if testspecs_list is not None:
4100 pattern = '|'.join(testspecs_list)
4101 else:
4102@@ -3592,6 +3702,7 @@
4103 self.additional_selftest_args.setdefault(
4104 'suite_decorators', []).append(parallel)
4105 if benchmark:
4106+<<<<<<< TREE
4107 test_suite_factory = benchmarks.test_suite
4108 # Unless user explicitly asks for quiet, be verbose in benchmarks
4109 verbose = not is_quiet()
4110@@ -3620,6 +3731,30 @@
4111 }
4112 selftest_kwargs.update(self.additional_selftest_args)
4113 result = selftest(**selftest_kwargs)
4114+=======
4115+ raise errors.BzrCommandError(
4116+ "--benchmark is no longer supported from bzr 2.2; "
4117+ "use bzr-usertest instead")
4118+ test_suite_factory = None
4119+ selftest_kwargs = {"verbose": verbose,
4120+ "pattern": pattern,
4121+ "stop_on_failure": one,
4122+ "transport": transport,
4123+ "test_suite_factory": test_suite_factory,
4124+ "lsprof_timed": lsprof_timed,
4125+ "lsprof_tests": lsprof_tests,
4126+ "matching_tests_first": first,
4127+ "list_only": list_only,
4128+ "random_seed": randomize,
4129+ "exclude_pattern": exclude,
4130+ "strict": strict,
4131+ "load_list": load_list,
4132+ "debug_flags": debugflag,
4133+ "starting_with": starting_with
4134+ }
4135+ selftest_kwargs.update(self.additional_selftest_args)
4136+ result = selftest(**selftest_kwargs)
4137+>>>>>>> MERGE-SOURCE
4138 return int(not result)
4139
4140
4141@@ -4068,6 +4203,7 @@
4142 from bzrlib.conflicts import restore
4143 if merge_type is None:
4144 merge_type = _mod_merge.Merge3Merger
4145+<<<<<<< TREE
4146 tree, file_list = WorkingTree.open_containing_paths(file_list)
4147 self.add_cleanup(tree.lock_write().unlock)
4148 parents = tree.get_parent_ids()
4149@@ -4088,6 +4224,28 @@
4150 interesting_ids.add(file_id)
4151 if tree.kind(file_id) != "directory":
4152 continue
4153+=======
4154+ tree, file_list = tree_files(file_list)
4155+ self.add_cleanup(tree.lock_write().unlock)
4156+ parents = tree.get_parent_ids()
4157+ if len(parents) != 2:
4158+ raise errors.BzrCommandError("Sorry, remerge only works after normal"
4159+ " merges. Not cherrypicking or"
4160+ " multi-merges.")
4161+ repository = tree.branch.repository
4162+ interesting_ids = None
4163+ new_conflicts = []
4164+ conflicts = tree.conflicts()
4165+ if file_list is not None:
4166+ interesting_ids = set()
4167+ for filename in file_list:
4168+ file_id = tree.path2id(filename)
4169+ if file_id is None:
4170+ raise errors.NotVersionedError(filename)
4171+ interesting_ids.add(file_id)
4172+ if tree.kind(file_id) != "directory":
4173+ continue
4174+>>>>>>> MERGE-SOURCE
4175
4176 for name, ie in tree.inventory.iter_entries(file_id):
4177 interesting_ids.add(ie.file_id)
4178@@ -4184,12 +4342,21 @@
4179
4180 def run(self, revision=None, no_backup=False, file_list=None,
4181 forget_merges=None):
4182+<<<<<<< TREE
4183 tree, file_list = WorkingTree.open_containing_paths(file_list)
4184 self.add_cleanup(tree.lock_tree_write().unlock)
4185 if forget_merges:
4186 tree.set_parent_ids(tree.get_parent_ids()[:1])
4187 else:
4188 self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4189+=======
4190+ tree, file_list = tree_files(file_list)
4191+ self.add_cleanup(tree.lock_tree_write().unlock)
4192+ if forget_merges:
4193+ tree.set_parent_ids(tree.get_parent_ids()[:1])
4194+ else:
4195+ self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4196+>>>>>>> MERGE-SOURCE
4197
4198 @staticmethod
4199 def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4200
4201=== modified file 'bzrlib/bundle/__init__.py'
4202--- bzrlib/bundle/__init__.py 2010-07-15 12:53:44 +0000
4203+++ bzrlib/bundle/__init__.py 2010-07-29 06:48:01 +0000
4204@@ -14,8 +14,14 @@
4205 # along with this program; if not, write to the Free Software
4206 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4207
4208-from cStringIO import StringIO
4209-
4210+<<<<<<< TREE
4211+from cStringIO import StringIO
4212+
4213+=======
4214+from cStringIO import StringIO
4215+
4216+from bzrlib.symbol_versioning import deprecated_function, deprecated_in
4217+>>>>>>> MERGE-SOURCE
4218 from bzrlib.lazy_import import lazy_import
4219 lazy_import(globals(), """
4220 from bzrlib import (
4221
4222=== modified file 'bzrlib/chk_map.py'
4223--- bzrlib/chk_map.py 2010-05-11 10:45:26 +0000
4224+++ bzrlib/chk_map.py 2010-07-29 06:48:01 +0000
4225@@ -90,8 +90,6 @@
4226 _INTERESTING_NEW_SIZE = 50
4227 # If a ChildNode shrinks by more than this amount, we check for a remap
4228 _INTERESTING_SHRINKAGE_LIMIT = 20
4229-# If we delete more than this many nodes applying a delta, we check for a remap
4230-_INTERESTING_DELETES_LIMIT = 5
4231
4232
4233 def _search_key_plain(key):
4234@@ -135,7 +133,7 @@
4235 into the map; if old_key is not None, then the old mapping
4236 of old_key is removed.
4237 """
4238- delete_count = 0
4239+ has_deletes = False
4240 # Check preconditions first.
4241 as_st = StaticTuple.from_sequence
4242 new_items = set([as_st(key) for (old, key, value) in delta
4243@@ -148,12 +146,11 @@
4244 for old, new, value in delta:
4245 if old is not None and old != new:
4246 self.unmap(old, check_remap=False)
4247- delete_count += 1
4248+ has_deletes = True
4249 for old, new, value in delta:
4250 if new is not None:
4251 self.map(new, value)
4252- if delete_count > _INTERESTING_DELETES_LIMIT:
4253- trace.mutter("checking remap as %d deletions", delete_count)
4254+ if has_deletes:
4255 self._check_remap()
4256 return self._save()
4257
4258@@ -573,7 +570,7 @@
4259 """Check if nodes can be collapsed."""
4260 self._ensure_root()
4261 if type(self._root_node) is InternalNode:
4262- self._root_node._check_remap(self._store)
4263+ self._root_node = self._root_node._check_remap(self._store)
4264
4265 def _save(self):
4266 """Save the map completely.
4267
4268=== modified file 'bzrlib/config.py'
4269--- bzrlib/config.py 2010-07-13 16:10:20 +0000
4270+++ bzrlib/config.py 2010-07-29 06:48:01 +0000
4271@@ -478,12 +478,23 @@
4272 def _get_nickname(self):
4273 return self.get_user_option('nickname')
4274
4275+<<<<<<< TREE
4276 def _write_config_file(self):
4277 atomic_file = atomicfile.AtomicFile(self._get_filename())
4278 self._get_parser().write(atomic_file)
4279 atomic_file.commit()
4280 atomic_file.close()
4281
4282+=======
4283+ def _write_config_file(self):
4284+ filename = self._get_filename()
4285+ atomic_file = atomicfile.AtomicFile(filename)
4286+ self._get_parser().write(atomic_file)
4287+ atomic_file.commit()
4288+ atomic_file.close()
4289+ osutils.copy_ownership_from_path(filename)
4290+
4291+>>>>>>> MERGE-SOURCE
4292
4293 class GlobalConfig(IniBasedConfig):
4294 """The configuration that should be used for a specific location."""
4295
4296=== modified file 'bzrlib/conflicts.py'
4297--- bzrlib/conflicts.py 2010-07-16 15:35:43 +0000
4298+++ bzrlib/conflicts.py 2010-07-29 06:48:01 +0000
4299@@ -24,7 +24,12 @@
4300 import errno
4301
4302 from bzrlib import (
4303- cleanup,
4304+<<<<<<< TREE
4305+ cleanup,
4306+=======
4307+ builtins,
4308+ cleanup,
4309+>>>>>>> MERGE-SOURCE
4310 commands,
4311 errors,
4312 osutils,
4313@@ -141,6 +146,18 @@
4314 action = 'done'
4315 if action == 'auto':
4316 if file_list is None:
4317+ if action is None:
4318+ # FIXME: There is a special case here related to the option
4319+ # handling that could be clearer and easier to discover by
4320+ # providing an --auto action (bug #344013 and #383396) and
4321+ # make it mandatory instead of implicit and active only
4322+ # when no file_list is provided -- vila 091229
4323+ action = 'auto'
4324+ else:
4325+ if action is None:
4326+ action = 'done'
4327+ if action == 'auto':
4328+ if file_list is None:
4329 un_resolved, resolved = tree.auto_resolve()
4330 if len(un_resolved) > 0:
4331 trace.note('%d conflict(s) auto-resolved.', len(resolved))
4332
4333=== modified file 'bzrlib/diff.py'
4334=== modified file 'bzrlib/errors.py'
4335--- bzrlib/errors.py 2010-07-20 10:50:44 +0000
4336+++ bzrlib/errors.py 2010-07-29 06:48:01 +0000
4337@@ -949,11 +949,8 @@
4338 # original exception is available as e.original_error
4339 #
4340 # New code should prefer to raise specific subclasses
4341- def __init__(self, message):
4342- # Python 2.5 uses a slot for StandardError.message,
4343- # so use a different variable name. We now work around this in
4344- # BzrError.__str__, but this member name is kept for compatability.
4345- self.msg = message
4346+ def __init__(self, msg):
4347+ self.msg = msg
4348
4349
4350 class LockActive(LockError):
4351@@ -1179,8 +1176,13 @@
4352
4353 class InvalidRevisionSpec(BzrError):
4354
4355+<<<<<<< TREE
4356 _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
4357 " %(branch_url)s%(extra)s")
4358+=======
4359+ _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
4360+ " %(branch)s%(extra)s")
4361+>>>>>>> MERGE-SOURCE
4362
4363 def __init__(self, spec, branch, extra=None):
4364 BzrError.__init__(self, branch=branch, spec=spec)
4365@@ -1381,12 +1383,12 @@
4366
4367 class WeaveParentMismatch(WeaveError):
4368
4369- _fmt = "Parents are mismatched between two revisions. %(message)s"
4370+ _fmt = "Parents are mismatched between two revisions. %(msg)s"
4371
4372
4373 class WeaveInvalidChecksum(WeaveError):
4374
4375- _fmt = "Text did not match it's checksum: %(message)s"
4376+ _fmt = "Text did not match it's checksum: %(msg)s"
4377
4378
4379 class WeaveTextDiffers(WeaveError):
4380@@ -1440,7 +1442,7 @@
4381
4382 class VersionedFileInvalidChecksum(VersionedFileError):
4383
4384- _fmt = "Text did not match its checksum: %(message)s"
4385+ _fmt = "Text did not match its checksum: %(msg)s"
4386
4387
4388 class KnitError(InternalBzrError):
4389@@ -3121,47 +3123,105 @@
4390 def __init__(self, source_branch, target_branch):
4391 self.source_branch = source_branch
4392 self.target_branch = target_branch
4393-
4394-
4395-class NoRoundtrippingSupport(BzrError):
4396-
4397- _fmt = ("Roundtripping is not supported between %(source_branch)r and "
4398- "%(target_branch)r.")
4399-
4400- internal_error = True
4401-
4402- def __init__(self, source_branch, target_branch):
4403- self.source_branch = source_branch
4404- self.target_branch = target_branch
4405-
4406-
4407-class FileTimestampUnavailable(BzrError):
4408-
4409- _fmt = "The filestamp for %(path)s is not available."
4410-
4411- internal_error = True
4412-
4413- def __init__(self, path):
4414- self.path = path
4415-
4416-
4417-class NoColocatedBranchSupport(BzrError):
4418-
4419- _fmt = ("%(bzrdir)r does not support co-located branches.")
4420-
4421- def __init__(self, bzrdir):
4422- self.bzrdir = bzrdir
4423-
4424-class NoWhoami(BzrError):
4425-
4426- _fmt = ('Unable to determine your name.\n'
4427- "Please, set your name with the 'whoami' command.\n"
4428- 'E.g. bzr whoami "Your Name <name@example.com>"')
4429-
4430-class InvalidPattern(BzrError):
4431-
4432- _fmt = ('Invalid pattern(s) found. %(msg)s')
4433-
4434- def __init__(self, msg):
4435- self.msg = msg
4436-
4437+<<<<<<< TREE
4438+
4439+
4440+class NoRoundtrippingSupport(BzrError):
4441+
4442+ _fmt = ("Roundtripping is not supported between %(source_branch)r and "
4443+ "%(target_branch)r.")
4444+
4445+ internal_error = True
4446+
4447+ def __init__(self, source_branch, target_branch):
4448+ self.source_branch = source_branch
4449+ self.target_branch = target_branch
4450+
4451+
4452+class FileTimestampUnavailable(BzrError):
4453+
4454+ _fmt = "The filestamp for %(path)s is not available."
4455+
4456+ internal_error = True
4457+
4458+ def __init__(self, path):
4459+ self.path = path
4460+
4461+
4462+class NoColocatedBranchSupport(BzrError):
4463+
4464+ _fmt = ("%(bzrdir)r does not support co-located branches.")
4465+
4466+ def __init__(self, bzrdir):
4467+ self.bzrdir = bzrdir
4468+
4469+class NoWhoami(BzrError):
4470+
4471+ _fmt = ('Unable to determine your name.\n'
4472+ "Please, set your name with the 'whoami' command.\n"
4473+ 'E.g. bzr whoami "Your Name <name@example.com>"')
4474+
4475+class InvalidPattern(BzrError):
4476+
4477+ _fmt = ('Invalid pattern(s) found. %(msg)s')
4478+
4479+ def __init__(self, msg):
4480+ self.msg = msg
4481+
4482+=======
4483+
4484+
4485+class NoRoundtrippingSupport(BzrError):
4486+
4487+ _fmt = ("Roundtripping is not supported between %(source_branch)r and "
4488+ "%(target_branch)r.")
4489+
4490+ internal_error = True
4491+
4492+ def __init__(self, source_branch, target_branch):
4493+ self.source_branch = source_branch
4494+ self.target_branch = target_branch
4495+
4496+
4497+class FileTimestampUnavailable(BzrError):
4498+
4499+ _fmt = "The filestamp for %(path)s is not available."
4500+
4501+ internal_error = True
4502+
4503+ def __init__(self, path):
4504+ self.path = path
4505+
4506+
4507+class NoColocatedBranchSupport(BzrError):
4508+
4509+ _fmt = ("%(bzrdir)r does not support co-located branches.")
4510+
4511+ def __init__(self, bzrdir):
4512+ self.bzrdir = bzrdir
4513+
4514+
4515+class NoWhoami(BzrError):
4516+
4517+ _fmt = ('Unable to determine your name.\n'
4518+ "Please, set your name with the 'whoami' command.\n"
4519+ 'E.g. bzr whoami "Your Name <name@example.com>"')
4520+
4521+
4522+class InvalidPattern(BzrError):
4523+
4524+ _fmt = ('Invalid pattern(s) found. %(msg)s')
4525+
4526+ def __init__(self, msg):
4527+ self.msg = msg
4528+
4529+
4530+class RecursiveBind(BzrError):
4531+
4532+ _fmt = ('Branch "%(branch_url)s" appears to be bound to itself. '
4533+ 'Please use `bzr unbind` to fix.')
4534+
4535+ def __init__(self, branch_url):
4536+ self.branch_url = branch_url
4537+
4538+>>>>>>> MERGE-SOURCE
4539
4540=== modified file 'bzrlib/globbing.py'
4541--- bzrlib/globbing.py 2010-07-09 16:16:11 +0000
4542+++ bzrlib/globbing.py 2010-07-29 06:48:01 +0000
4543@@ -179,24 +179,41 @@
4544 so are matched first, then the basename patterns, then the fullpath
4545 patterns.
4546 """
4547+ # We want to _add_patterns in a specific order (as per type_list below)
4548+ # starting with the shortest and going to the longest.
4549+ # As some Python version don't support ordered dicts the list below is
4550+ # used to select inputs for _add_pattern in a specific order.
4551+ pattern_types = [ "extension", "basename", "fullpath" ]
4552+
4553+ pattern_info = {
4554+ "extension" : {
4555+ "translator" : _sub_extension,
4556+ "prefix" : r'(?:.*/)?(?!.*/)(?:.*\.)'
4557+ },
4558+ "basename" : {
4559+ "translator" : _sub_basename,
4560+ "prefix" : r'(?:.*/)?(?!.*/)'
4561+ },
4562+ "fullpath" : {
4563+ "translator" : _sub_fullpath,
4564+ "prefix" : r''
4565+ },
4566+ }
4567+
4568 def __init__(self, patterns):
4569 self._regex_patterns = []
4570- path_patterns = []
4571- base_patterns = []
4572- ext_patterns = []
4573+ pattern_lists = {
4574+ "extension" : [],
4575+ "basename" : [],
4576+ "fullpath" : [],
4577+ }
4578 for pat in patterns:
4579 pat = normalize_pattern(pat)
4580- if pat.startswith(u'RE:') or u'/' in pat:
4581- path_patterns.append(pat)
4582- elif pat.startswith(u'*.'):
4583- ext_patterns.append(pat)
4584- else:
4585- base_patterns.append(pat)
4586- self._add_patterns(ext_patterns,_sub_extension,
4587- prefix=r'(?:.*/)?(?!.*/)(?:.*\.)')
4588- self._add_patterns(base_patterns,_sub_basename,
4589- prefix=r'(?:.*/)?(?!.*/)')
4590- self._add_patterns(path_patterns,_sub_fullpath)
4591+ pattern_lists[Globster.identify(pat)].append(pat)
4592+ pi = Globster.pattern_info
4593+ for t in Globster.pattern_types:
4594+ self._add_patterns(pattern_lists[t], pi[t]["translator"],
4595+ pi[t]["prefix"])
4596
4597 def _add_patterns(self, patterns, translator, prefix=''):
4598 while patterns:
4599@@ -211,6 +228,7 @@
4600
4601 :return A matching pattern or None if there is no matching pattern.
4602 """
4603+<<<<<<< TREE
4604 try:
4605 for regex, patterns in self._regex_patterns:
4606 match = regex.match(filename)
4607@@ -223,42 +241,133 @@
4608 mutter('Invalid pattern found in regex: %s.', e.msg)
4609 e.msg = "File ~/.bazaar/ignore or .bzrignore contains errors."
4610 raise e
4611+=======
4612+ try:
4613+ for regex, patterns in self._regex_patterns:
4614+ match = regex.match(filename)
4615+ if match:
4616+ return patterns[match.lastindex -1]
4617+ except errors.InvalidPattern, e:
4618+ # We can't show the default e.msg to the user as thats for
4619+ # the combined pattern we sent to regex. Instead we indicate to
4620+ # the user that an ignore file needs fixing.
4621+ mutter('Invalid pattern found in regex: %s.', e.msg)
4622+ e.msg = "File ~/.bazaar/ignore or .bzrignore contains error(s)."
4623+ bad_patterns = ''
4624+ for _, patterns in self._regex_patterns:
4625+ for p in patterns:
4626+ if not Globster.is_pattern_valid(p):
4627+ bad_patterns += ('\n %s' % p)
4628+ e.msg += bad_patterns
4629+ raise e
4630+>>>>>>> MERGE-SOURCE
4631 return None
4632
4633-class ExceptionGlobster(object):
4634- """A Globster that supports exception patterns.
4635-
4636- Exceptions are ignore patterns prefixed with '!'. Exception
4637- patterns take precedence over regular patterns and cause a
4638- matching filename to return None from the match() function.
4639- Patterns using a '!!' prefix are highest precedence, and act
4640- as regular ignores. '!!' patterns are useful to establish ignores
4641- that apply under paths specified by '!' exception patterns.
4642- """
4643-
4644- def __init__(self,patterns):
4645- ignores = [[], [], []]
4646- for p in patterns:
4647- if p.startswith(u'!!'):
4648- ignores[2].append(p[2:])
4649- elif p.startswith(u'!'):
4650- ignores[1].append(p[1:])
4651- else:
4652- ignores[0].append(p)
4653- self._ignores = [Globster(i) for i in ignores]
4654-
4655- def match(self, filename):
4656- """Searches for a pattern that matches the given filename.
4657-
4658- :return A matching pattern or None if there is no matching pattern.
4659- """
4660- double_neg = self._ignores[2].match(filename)
4661- if double_neg:
4662- return "!!%s" % double_neg
4663- elif self._ignores[1].match(filename):
4664- return None
4665- else:
4666- return self._ignores[0].match(filename)
4667+<<<<<<< TREE
4668+class ExceptionGlobster(object):
4669+ """A Globster that supports exception patterns.
4670+
4671+ Exceptions are ignore patterns prefixed with '!'. Exception
4672+ patterns take precedence over regular patterns and cause a
4673+ matching filename to return None from the match() function.
4674+ Patterns using a '!!' prefix are highest precedence, and act
4675+ as regular ignores. '!!' patterns are useful to establish ignores
4676+ that apply under paths specified by '!' exception patterns.
4677+ """
4678+
4679+ def __init__(self,patterns):
4680+ ignores = [[], [], []]
4681+ for p in patterns:
4682+ if p.startswith(u'!!'):
4683+ ignores[2].append(p[2:])
4684+ elif p.startswith(u'!'):
4685+ ignores[1].append(p[1:])
4686+ else:
4687+ ignores[0].append(p)
4688+ self._ignores = [Globster(i) for i in ignores]
4689+
4690+ def match(self, filename):
4691+ """Searches for a pattern that matches the given filename.
4692+
4693+ :return A matching pattern or None if there is no matching pattern.
4694+ """
4695+ double_neg = self._ignores[2].match(filename)
4696+ if double_neg:
4697+ return "!!%s" % double_neg
4698+ elif self._ignores[1].match(filename):
4699+ return None
4700+ else:
4701+ return self._ignores[0].match(filename)
4702+=======
4703+ @staticmethod
4704+ def identify(pattern):
4705+ """Returns pattern category.
4706+
4707+ :param pattern: normalized pattern.
4708+ Identify if a pattern is fullpath, basename or extension
4709+ and returns the appropriate type.
4710+ """
4711+ if pattern.startswith(u'RE:') or u'/' in pattern:
4712+ return "fullpath"
4713+ elif pattern.startswith(u'*.'):
4714+ return "extension"
4715+ else:
4716+ return "basename"
4717+
4718+ @staticmethod
4719+ def is_pattern_valid(pattern):
4720+ """Returns True if pattern is valid.
4721+
4722+ :param pattern: Normalized pattern.
4723+ is_pattern_valid() assumes pattern to be normalized.
4724+ see: globbing.normalize_pattern
4725+ """
4726+ result = True
4727+ translator = Globster.pattern_info[Globster.identify(pattern)]["translator"]
4728+ tpattern = '(%s)' % translator(pattern)
4729+ try:
4730+ re_obj = re.compile(tpattern, re.UNICODE)
4731+ re_obj.search("") # force compile
4732+ except errors.InvalidPattern, e:
4733+ result = False
4734+ return result
4735+
4736+
4737+class ExceptionGlobster(object):
4738+ """A Globster that supports exception patterns.
4739+
4740+ Exceptions are ignore patterns prefixed with '!'. Exception
4741+ patterns take precedence over regular patterns and cause a
4742+ matching filename to return None from the match() function.
4743+ Patterns using a '!!' prefix are highest precedence, and act
4744+ as regular ignores. '!!' patterns are useful to establish ignores
4745+ that apply under paths specified by '!' exception patterns.
4746+ """
4747+
4748+ def __init__(self,patterns):
4749+ ignores = [[], [], []]
4750+ for p in patterns:
4751+ if p.startswith(u'!!'):
4752+ ignores[2].append(p[2:])
4753+ elif p.startswith(u'!'):
4754+ ignores[1].append(p[1:])
4755+ else:
4756+ ignores[0].append(p)
4757+ self._ignores = [Globster(i) for i in ignores]
4758+
4759+ def match(self, filename):
4760+ """Searches for a pattern that matches the given filename.
4761+
4762+ :return A matching pattern or None if there is no matching pattern.
4763+ """
4764+ double_neg = self._ignores[2].match(filename)
4765+ if double_neg:
4766+ return "!!%s" % double_neg
4767+ elif self._ignores[1].match(filename):
4768+ return None
4769+ else:
4770+ return self._ignores[0].match(filename)
4771+>>>>>>> MERGE-SOURCE
4772
4773 class _OrderedGlobster(Globster):
4774 """A Globster that keeps pattern order."""
4775@@ -272,6 +381,7 @@
4776 self._regex_patterns = []
4777 for pat in patterns:
4778 pat = normalize_pattern(pat)
4779+<<<<<<< TREE
4780 if pat.startswith(u'RE:') or u'/' in pat:
4781 self._add_patterns([pat], _sub_fullpath)
4782 elif pat.startswith(u'*.'):
4783@@ -283,6 +393,14 @@
4784
4785
4786 _slashes = re.compile(r'[\\/]+')
4787+=======
4788+ t = Globster.identify(pat)
4789+ self._add_patterns([pat], Globster.pattern_info[t]["translator"],
4790+ Globster.pattern_info[t]["prefix"])
4791+
4792+
4793+_slashes = re.compile(r'[\\/]+')
4794+>>>>>>> MERGE-SOURCE
4795 def normalize_pattern(pattern):
4796 """Converts backslashes in path patterns to forward slashes.
4797
4798
4799=== modified file 'bzrlib/help_topics/en/conflict-types.txt'
4800--- bzrlib/help_topics/en/conflict-types.txt 2010-04-28 13:15:14 +0000
4801+++ bzrlib/help_topics/en/conflict-types.txt 2010-07-29 06:48:01 +0000
4802@@ -3,6 +3,7 @@
4803
4804 Some operations, like merge, revert and pull, modify the contents of your
4805 working tree. These modifications are programmatically generated, and so they
4806+<<<<<<< TREE
4807 may conflict with the current state of your working tree.
4808
4809 When conflicts are present in your working tree (as shown by ``bzr
4810@@ -40,6 +41,45 @@
4811
4812 Yet, whether Bazaar makes a choice or not, there are some other simple but
4813 different ways to resolve the conflict.
4814+=======
4815+may conflict with the current state of your working tree.
4816+
4817+When conflicts are present in your working tree (as shown by ``bzr
4818+conflicts``), you should resolve them and then inform bzr that the conflicts
4819+have been resolved.
4820+
4821+Resolving conflicts is sometimes not obvious. Either because the user that
4822+should resolve them is not the one responsible for their occurrence, as is the
4823+case when merging other people's work or because some conflicts are presented
4824+in a way that is not easy to understand.
4825+
4826+Bazaar tries to avoid conflicts ; its aim is to ask you to resolve the
4827+conflict if and only if there's an actual conceptual conflict in the source
4828+tree. Because Bazaar doesn't understand the real meaning of the files being
4829+versioned, it can, when faced with ambiguities, fall short in either direction
4830+trying to resolve the conflict itself. Many kinds of changes can be combined
4831+programmatically, but sometimes only a human can determine the right thing to
4832+do.
4833+
4834+When Bazaar generates a conflict, it adds information into the working tree to
4835+present the conflicting versions, and it's up to you to find the correct
4836+resolution.
4837+
4838+Whatever the conflict is, resolving it is roughly done in two steps::
4839+
4840+- modify the working tree content so that the conflicted item is now in the
4841+ state you want to keep,
4842+
4843+- inform Bazaar that the conflict is now solved and ask to cleanup any
4844+ remaining generated information (``bzr resolve <item>``).
4845+
4846+For most conflict types, there are some obvious ways to modify the working
4847+tree and put it into the desired state. For some types of conflicts, Bazaar
4848+itself already made a choice, when possible.
4849+
4850+Yet, whether Bazaar makes a choice or not, there are some other simple but
4851+different ways to resolve the conflict.
4852+>>>>>>> MERGE-SOURCE
4853
4854 Each type of conflict is explained below, and the action which must be done to
4855 resolve the conflict is outlined.
4856@@ -121,6 +161,7 @@
4857 of the file with herringbone conflict markers. It will appear that the "main
4858 copy" has been renamed to THIS or OTHER.
4859
4860+<<<<<<< TREE
4861 To resolve that kind of conflict, you should rebuild FILE from either version
4862 or a combination of both.
4863
4864@@ -158,6 +199,45 @@
4865 favor of the target branch, you need to similarly use ``tag --force`` in the
4866 source branch. (Note that pulling or pushing using --overwrite will overwrite
4867 all tags as well.)
4868+=======
4869+To resolve that kind of conflict, you should rebuild FILE from either version
4870+or a combination of both.
4871+
4872+``bzr resolve`` recognizes the following actions:
4873+
4874+- ``--action=take-this`` will issue ``bzr mv FILE.THIS FILE``,
4875+- ``--action=take-other`` will issue ``bzr mv FILE.OTHER FILE``,
4876+- ``--action=done`` will just mark the conflict as resolved.
4877+
4878+Any action will also delete the previously generated ``.BASE``, ``.THIS`` and
4879+``.OTHER`` files if they are still present in the working tree.
4880+
4881+Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4882+
4883+Tag conflicts
4884+-------------
4885+
4886+Typical message::
4887+
4888+ Conflicting tags:
4889+ version-0.1
4890+
4891+When pulling from or pushing to another branch, Bazaar informs you about tags
4892+that conflict between the two branches; that is the same tag points to two
4893+different revisions. You need not resolve these conflicts, but subsequent
4894+uses of pull or push will result in the same message.
4895+
4896+To resolve the conflict, you must apply the correct tags to either the target
4897+branch or the source branch as appropriate. Use "bzr tags --show-ids -d
4898+SOURCE_URL" to see the tags in the source branch. If you want to make the
4899+target branch's tags match the source branch, then in the target branch do
4900+``bzr tag --force -r revid:REVISION_ID CONFLICTING_TAG`` for each of the
4901+CONFLICTING_TAGs, where REVISION_ID comes from the list of tags in the source
4902+branch. You need not call "bzr resolve" after doing this. To resolve in
4903+favor of the target branch, you need to similarly use ``tag --force`` in the
4904+source branch. (Note that pulling or pushing using --overwrite will overwrite
4905+all tags as well.)
4906+>>>>>>> MERGE-SOURCE
4907
4908 Duplicate paths
4909 ---------------
4910@@ -167,6 +247,7 @@
4911 Conflict adding file FILE. Moved existing file to FILE.moved.
4912
4913 Sometimes Bazaar will attempt to create a file using a pathname that has
4914+<<<<<<< TREE
4915 already been used. The existing file will be renamed to "FILE.moved".
4916
4917 To resolve that kind of conflict, you should rebuild FILE from either version
4918@@ -181,6 +262,22 @@
4919 Note that you must get rid of FILE.moved before using ``--action=done``.
4920
4921 Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4922+=======
4923+already been used. The existing file will be renamed to "FILE.moved".
4924+
4925+To resolve that kind of conflict, you should rebuild FILE from either version
4926+or a combination of both.
4927+
4928+``bzr resolve`` recognizes the following actions::
4929+
4930+- ``--action=take-this`` will issue ``bzr rm FILE ; bzr mv FILE.moved FILE``,
4931+- ``--action=take-other`` will issue ``bzr rm FILE.moved``,
4932+- ``--action=done`` will just mark the conflict as resolved.
4933+
4934+Note that you must get rid of FILE.moved before using ``--action=done``.
4935+
4936+Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4937+>>>>>>> MERGE-SOURCE
4938
4939 Unversioned parent
4940 ------------------
4941@@ -204,6 +301,7 @@
4942
4943 Conflict adding files to FILE. Created directory.
4944
4945+<<<<<<< TREE
4946 This happens when a directory has been deleted in the target, but has new
4947 children in the source. This is similar to the "unversioned parent" conflict,
4948 except that the parent directory does not *exist*, instead of just being
4949@@ -222,6 +320,25 @@
4950 - ``--action=done`` will just mark the conflict as resolved.
4951
4952 Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4953+=======
4954+This happens when a directory has been deleted in the target, but has new
4955+children in the source. This is similar to the "unversioned parent" conflict,
4956+except that the parent directory does not *exist*, instead of just being
4957+unversioned. In this situation, Bazaar will create the missing parent.
4958+Resolving this issue depends very much on the particular scenario.
4959+
4960+To resolve that kind of conflict, you should either remove or rename the
4961+children or the directory or a combination of both.
4962+
4963+``bzr resolve`` recognizes the following actions::
4964+
4965+- ``--action=take-this`` will issue ``bzr rm directory`` including the children,
4966+- ``--action=take-other`` will acknowledge Bazaar choice to keep the children
4967+ and restoring the directory,
4968+- ``--action=done`` will just mark the conflict as resolved.
4969+
4970+Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4971+>>>>>>> MERGE-SOURCE
4972
4973 Deleting parent
4974 ---------------
4975@@ -232,6 +349,7 @@
4976
4977 This is the opposite of "missing parent". A directory is deleted in the
4978 source, but has new children in the target. Bazaar will retain the directory.
4979+<<<<<<< TREE
4980 Resolving this issue depends very much on the particular scenario.
4981
4982 To resolve that kind of conflict, you should either remove or rename the
4983@@ -245,6 +363,21 @@
4984 - ``--action=done`` will just mark the conflict as resolved.
4985
4986 Bazaar cannot auto-detect when conflicts of this kind have been resolved.
4987+=======
4988+Resolving this issue depends very much on the particular scenario.
4989+
4990+To resolve that kind of conflict, you should either remove or rename the
4991+children or the directory or a combination of both.
4992+
4993+``bzr resolve`` recognizes the following actions::
4994+
4995+- ``--action=take-this`` will acknowledge Bazaar choice to keep the directory,
4996+- ``--action=take-other`` will issue ``bzr rm directory`` including the
4997+ children,
4998+- ``--action=done`` will just mark the conflict as resolved.
4999+
5000+Bazaar cannot auto-detect when conflicts of this kind have been resolved.
The diff has been truncated for viewing.