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