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

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

Description of the change

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

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

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

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

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

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

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

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

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

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

184 + def _entries_to_incorporate(self):

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

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

This:
  subdir = other_inv[subdir_id]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This all works fine...

What doesn't work is replacing this:

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

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

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

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

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

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

On to Robert comments:

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

Thanks, changed as you suggest.

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

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

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

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

Agreed. Changed.

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

Good point. Changed.

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

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2010-07-21 22:29:45 +0000
+++ NEWS 2010-07-29 06:48:01 +0000
@@ -5,6 +5,7 @@
5.. contents:: List of Releases5.. contents:: List of Releases
6 :depth: 16 :depth: 1
77
8<<<<<<< TREE
8bzr 2.3b19bzr 2.3b1
9#########10#########
1011
@@ -1564,6 +1565,1540 @@
1564* The test progress bar no longer distinguishes tests that 'errored' from1565* The test progress bar no longer distinguishes tests that 'errored' from
1565 tests that 'failed' - they're all just failures.1566 tests that 'failed' - they're all just failures.
1566 (Martin Pool)1567 (Martin Pool)
1568=======
1569bzr 2.2rc1
1570##########
1571
1572:Codename: ???
1573:2.2rc1: NOT RELEASED YET
1574
1575Compatibility Breaks
1576********************
1577
1578* BzrError subclasses no longer support the name "message" to be used
1579 as an argument for __init__ or in _fmt format specification as this
1580 breaks in some Python versions. errors.LockError.__init__ argument
1581 is now named "msg" instead of earlier "message".
1582 (Parth Malwankar, #603461)
1583
1584* The old ``bzr selftest --benchmark`` option has been removed.
1585 <https://launchpad.net/bzr-usertest> is an actively-maintained
1586 macrobenchmark suite.
1587 (Martin Pool)
1588
1589New Features
1590************
1591
1592Bug Fixes
1593*********
1594
1595* ``bzr ignore PATTERNS`` exits with error if a bad pattern is supplied.
1596 ``InvalidPattern`` exception error message now shows faulting
1597 regular expression.
1598 (Parth Malwankar #300062)
1599
1600* Configuration files in ``${BZR_HOME}`` are now written in an atomic
1601 way which should help avoid problems with concurrent writers.
1602 (Vincent Ladeuil, #525571)
1603
1604* Don't traceback trying to unversion children files of an already
1605 unversioned directory. (Vincent Ladeuil, #494221)
1606
1607* ``HTTP/1.1` test servers now set a ``Content-Length`` header to comply
1608 with pedantic ``HTTP/1.1`` clients. (Vincent Ladeuil, #568421)
1609
1610* Progress bars prefer to truncate the text message rather than the
1611 counters. The spinner is shown between the network transfer indicator
1612 and the progress message. (Martin Pool)
1613
1614* Recursive binding for checkouts is now detected by bzr. A clear error
1615 message is shown to the user. (Parth Malwankar, #405192)
1616
1617Improvements
1618************
1619
1620* Add ``bzrlib.merge.MergeIntoMerger``, which can merge part or all of a
1621 tree, and works with unrelated branches. (Andrew Bennetts)
1622
1623Documentation
1624*************
1625
1626* ``bzr help patterns`` now explains case insensitive patterns and
1627 points to Python regular expression documentation.
1628 (Parth Malwankar, #594386)
1629
1630API Changes
1631***********
1632
1633* Delete ``ProgressTask.note``, which was deprecated in 2.1.
1634
1635Internals
1636*********
1637
1638Testing
1639*******
1640
1641* Unit test added to ensure that "message" is not uses as a format variable
1642 name in BzrError subclasses as this conflicts with some Python versions.
1643 (Parth Malwankar, #603461)
1644
1645bzr 2.2b4
1646#########
1647
1648:Codename: Monkey Magic
1649:2.2b4: 2004-07-09
1650
1651
1652This fourth and final beta in the 2.2 series now stabilizes the internal
1653APIs. Plugin authors are recommended to ensure their releases are
1654compatible, so that 2.2rc1 can be a true release candidate, containing
1655stable and compatible plugin versions.
1656
1657For users of bzrlib as a library, one of the primary changes is to request
1658that they call ``bzrlib.initialize`` and use the returned context manager
1659appropriately.
1660
1661Better interaction with ``bzr-loom`` to make sure branching from a loom
1662even over a smart server still yields a local loom. Not to mention lots of
1663bugfixes over 2.2b3.
1664
1665Compatibility Breaks
1666********************
1667
1668* bzrlib library users now need to call ``__enter__`` and ``__exit__`` on
1669 the result of ``bzrlib.initialize``. This change was made when fixing
1670 the bad habit recent bzr versions have had of leaving progress bars
1671 behind on the screen. That required calling another function before
1672 exiting the program, and it made sense to provide a full context
1673 manager at the same time. (Robert Collins)
1674
1675* The ``bzr`` front end now requires a ``bzrlib.ui.ui_factory`` which is a
1676 context manager in the Python 2.5 and above sense. The bzrlib base class
1677 is such a manager, but third party UI factories which do not derive from
1678 ``bzrlib.ui.UIFactory`` will be incompatible with the command line front
1679 end.
1680
1681* URLs like ``foo:bar/baz`` are now always parsed as a URL with scheme "foo"
1682 and path "bar/baz", even if bzr does not recognize "foo" as a known URL
1683 scheme. Previously these URLs would be treated as local paths.
1684 (Gordon Tyler)
1685
1686
1687New Features
1688************
1689
1690* Support ``--directory`` option for a number of additional commands:
1691 conflicts, merge-directive, missing, resolve, shelve, switch,
1692 unshelve, whoami. (Martin von Gagern, #527878)
1693
1694Bug Fixes
1695*********
1696
1697* ``bzr branch`` to a new repository with a default stacking policy no
1698 longer transfers the full history unnecessarily.
1699 (Andrew Bennetts, #597942)
1700
1701* ``bzr init`` does not recursively scan directory contents anymore
1702 leading to faster init for directories with existing content.
1703 (Martin [gz], Parth Malwankar, #501307)
1704
1705* ``bzr log --exclude-common-ancestry`` is now taken into account for
1706 linear ancetries. (Vincent Ladeuil, #575631)
1707
1708* ``bzr log -r branch:REMOTE`` can now properly log the remote branch,
1709 rather than trying to fetch the data locally and failing because of a
1710 readonly error. (Martin von Gagern, #149270)
1711
1712* ``bzr pull`` now works when a lp: URL is explicitly defined as the parent
1713 or pull location in locations.conf or branch.conf.
1714 (Gordon Tyler, #534787)
1715
1716* ``bzr reconfigure --unstacked`` now works with branches accessed via a
1717 smart server. (Andrew Bennetts, #551525)
1718
1719* ``BzrDir.find_branches`` should ignore branches with missing repositories.
1720 (Marius Kruger, Robert Collins)
1721
1722* ``BzrDir.find_bzrdirs`` should ignore dirs that raises PermissionDenied.
1723 (Marius Kruger, Robert Collins)
1724
1725* Ensure that wrong path specifications in ``BZR_PLUGINS_AT`` display
1726 proper error messages. (Vincent Ladeuil, #591215)
1727
1728* Explicitly removing ``--profile-imports`` option from parsed command-line
1729 arguments on Windows, because bzr script does the same.
1730 (Alexander Belchenko, #588277)
1731
1732* Fetching was slightly confused about the best code to use and was
1733 using a new code path for all branches, resulting in more lookups than
1734 necessary on old branches. (Robert Collins, #593515)
1735
1736* Final fix for 'no help for command' issue. We now show a clean message
1737 when a command has no help, document how to set help more clearly, and
1738 test that all commands available to the test suite have help.
1739 (Robert Collins, #177500)
1740
1741* Invalid patterns supplied to ``Globster`` or ``lazy_regex`` now raise
1742 ``InvalidPattern`` exception showing clear error message to the user.
1743 (Parth Malwankar #300062)
1744
1745* Progress output is cleaned up when exiting. (Aaron Bentley)
1746
1747* Raise ValueError instead of a string exception.
1748 (John Arbash Meinel, #586926)
1749
1750* Relative imports in plugins are now handled correctly when using
1751 BZR_PLUGINS_AT. (Vincent Ladeuil, #588959)
1752
1753* ``ScriptRunner`` now strips off leading indentation from test scripts,
1754 which previously caused "SyntaxError: No command for line".
1755 (Martin Pool)
1756
1757* Show unicode filenames in diff headers using terminal encoding.
1758 (Alexander Belchenko, Bug #382699)
1759 NOTE for Windows users: If user need to save diff to file then user need to
1760 change encoding of the terminal to ANSI encoding with command ``chcp XXX``
1761 (e.g. ``chcp 1251`` for Russian Windows).
1762
1763* URL displayed for use with ``break-lock`` when smart server sees lock
1764 contention are now valid. Default timeout for lock contention retry is
1765 now 30 seconds instead of 300 seconds.
1766 (Parth Malwankar, #250451)
1767
1768* ``walkdirs`` now raises a useful message when the filenames are not using
1769 the filesystem encoding. (Eric Moritz, #488519)
1770
1771* Enable debugging of bzr on windows with pdb and other tools. This was
1772 broken because we call GetCommandLineW on windows. The fix adjusts the
1773 command line we get to be the same length as sys.argv.
1774 (Jason Spashett, Alexander Belchenko, #587868)
1775
1776Improvements
1777************
1778
1779* Bazaar now reads data from SSH connections more efficiently on platforms
1780 that provide the ``socketpair`` function, and when using paramiko.
1781 (Andrew Bennetts, #590637)
1782
1783* ``Branch.copy_content_into`` is now a convenience method dispatching to
1784 a ``InterBranch`` multi-method. This permits ``bzr-loom`` and other
1785 plugins to intercept this even when a ``RemoteBranch`` proxy is in use.
1786 (Robert Collins, #201613)
1787
1788* ``Branch`` formats can now be loaded lazily by registering a
1789 ``MetaDirBranchFormatFactory`` rather than an actual format. This will
1790 cause the named format class to be loaded only when an enumeration of
1791 formats is needed or when the format string for the object is
1792 encountered. (Robert Collins, Jelmer Vernooij)
1793
1794* The encoding that bzr uses to output things other than file content can
1795 now be overridden via the output_encoding configuration option.
1796 (Martin Pool, #340394)
1797
1798* Use lazy imports in ``bzrlib/merge.py`` so that plugins like ``news_merge``
1799 do not cause modules to be loaded unnecessarily just because the plugin
1800 registers a merge hook. This improves ``bzr rocks`` time by about 25%
1801 in a default installation (with just the core plugins).
1802 (Andrew Bennetts)
1803
1804Documentation
1805*************
1806
1807* Added ``regression`` tag to our tags list. (Robert Collins)
1808
1809* Improved our release checklist to have a bit less churn and leave things
1810 ready-to-go for the next action (including other people doing
1811 development). (Robert Collins)
1812
1813* Remove obsolete discussion of PQM in documentation about how to
1814 contribute to Bazaar. (Martin Pool, #588444)
1815
1816API Changes
1817***********
1818
1819* ``bzrlib.branch.InterBranch._get_branch_formats_to_test`` now returns
1820 an iterable of format pairs, rather than just a single pair, permitting
1821 InterBranch objects that work with multiple permutations to be
1822 comprehensively tested. (Robert Collins)
1823
1824* ``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
1825 profiles when concurrent profile requests are made. Instead the profile
1826 requests will be serialised. Reentrant requests will now deadlock.
1827 (Robert Collins)
1828
1829* ``bzrlib.knit.KnitSequenceMatcher``, which has been deprecated since
1830 2007, has been deleted. Use ``PatienceSequenceMatcher`` from
1831 ``bzrlib.patiencediff`` instead. (Andrew Bennetts)
1832
1833* ``bzrlib.re_compile_checked`` is now deprecated. Caller should handle
1834 ``bzrlib.errors.InvalidPattern`` exception thrown by ``re.match`` in
1835 case the default error message not suitable for the use case.
1836 (Parth Malwankar)
1837
1838* ``bzrlib.tests.blackbox.ExternalBase`` is deprecated. It provided only
1839 one method ``check_output``, and we now recommend checking command
1840 output using ``run_script``. (Martin Pool)
1841
1842* ``bzrlib.transport.ssh.SSHVendor.connect_ssh`` now returns an object
1843 that implements the interface of ``bzrlib.transport.ssh.SSHConnection``.
1844 Third-party implementations of ``SSHVendor`` may need to be updated
1845 accordingly. Similarly, any code using ``SSHConnection`` directly will
1846 need to be updated. (Andrew Bennetts)
1847
1848* The constructor of ``bzrilb.smart.medium.SmartSSHClientMedium`` has
1849 changed to take an ``SSHParams`` instance (replacing many individual
1850 values). (Andrew Bennetts)
1851
1852Internals
1853*********
1854
1855* ``bzrlib.osutils.get_terminal_encoding`` will now only mutter its
1856 selection when explicitly requested; this avoids many duplicate calls
1857 being logged when helpers, wrappers and older code that manually calls
1858 it are executed it is now logged deliberately by the ui setup code.
1859 (Robert Collins)
1860
1861* Improved ``bzrlib.urlutils`` to handle lp:foo/bar URLs. (Gordon Tyler)
1862
1863* ``bzrlib._c_static_tuple.StaticTuple`` now implements ``__sizeof__``, so
1864 that ``sys.getsizeof`` and other memory analysis tools will report more
1865 accurate results. (Andrew Bennetts)
1866
1867* The symbol_versioning module can now cleanup after itself -
1868 ``suppress_deprecation_warnings`` now returns a cleanup function.
1869 (Robert Collins)
1870
1871Testing
1872*******
1873
1874* Add ``bzrlib.tests.fixtures`` to hold code for setting up objects
1875 to test. (Martin Pool)
1876
1877* ``test_import_tariff`` now respects BZR_PLUGINS_AT and BZR_PLUGINS_DISABLE.
1878 (Vincent Ladeuil, #595587)
1879
1880bzr 2.2b3
1881#########
1882
1883:2.2b3: 2010-05-28
1884
1885This third beta in the 2.2 series brings with it all the goodness of 2.1.2
1886and 2.0.6 (though it preceeds 2.0.6 slightly). Of particular note for
1887users are compatibility fixes with bzr 1.5 and below servers, a hopeful
1888end to the EINTR errors caused by SIGWINCH interactions, a shiny new
1889bash completion script and bzr will no longer guess at identity details -
1890it was too unreliable in reality. Use ``bzr whoami`` on every new install.
1891For developers we have some API changes which may impact plugins as well
1892as a bunch of our regular improvements to internal clarity and test
1893support.
1894
1895Compatibility Breaks
1896********************
1897
1898* An API break has been made to the lock_write method of ``Branch`` and
1899 ``Repository`` objects; they now return ``branch.BranchWriteLockResult``
1900 and ``repository.RepositoryWriteLockResult`` objects. This makes
1901 changing the API in future easier and permits some cleaner calling code.
1902 The lock_read method has also changed from having no defined return
1903 value to returning ``LogicalLockResult`` objects.
1904 (Robert Collins)
1905
1906* ``bzr`` does not try to guess the username as ``username@hostname``
1907 and requires it to be explictly set. This can be set using ``bzr
1908 whoami``. (Parth Malwankar, #549310)
1909
1910* ``bzrlib.commands.Command`` will now raise ValueError during
1911 construction if there is no __doc__ set. (Note, this will be reverted in
1912 2.2b4) (Robert Collins)
1913
1914* The source tree no longer contains a contrib/zsh/_bzr completion
1915 script. The new file contrib/zsh/README suggests alternatives.
1916 (Martin von Gagern, #560030)
1917
1918New Features
1919************
1920
1921* ``bzr commit`` accepts ``-p`` (for "patch") as a shorter name for
1922 ``--show-diff``.
1923 (Parth Malwankar, #571467)
1924
1925* ``bzr ignore`` now supports a ``--default-rules`` option that displays
1926 the default ignore rules used by bzr. The flag ``--old-default-rules``
1927 is no longer supported by ``ignore``.
1928 (Parth Malwankar, #538703)
1929
1930* ``bzr pack`` now supports a ``--clean-obsolete-packs`` option that
1931 can save disk space by deleting obsolete pack files created during the
1932 pack operation.
1933 (Parth Malwankar, #304320)
1934
1935* New command line option ``--authors`` to ``bzr log`` allows users to
1936 select which of the apparent authors and committer should be
1937 included in the log. Defaults depend on format. (Martin von Gagern, #513322)
1938
1939* Support ``--directory`` option for a number of additional commands:
1940 added, annotate, bind, cat, cat-revision, clean-tree, deleted,
1941 export, ignore, ignored, lookup-revision, ls, modified, nick,
1942 re-sign, unbind, unknowns.
1943 (Martin von Gagern, #527878)
1944
1945* The bash_completion plugin from the bzr-bash-completion project has
1946 been merged into the tree. It provides a bash-completion command and
1947 replaces the outdated ``contrib/bash/bzr`` script with a version
1948 using the plugin. (Martin von Gagern, #560030)
1949
1950* A new transport based on GIO (the gnome i/o library) provides access to
1951 samba shares, webdav using gio+smb and gio+dav. It is also possible to
1952 use gio for some already existing transport methods as gio+file,
1953 gio+sftp, gio+ftp.
1954 (Mattias Eriksson)
1955
1956Bug Fixes
1957*********
1958
1959* Alias information shown by ``bzr help`` is now accurate. This
1960 was showing an internal object name for some plugin aliases.
1961 (Parth Malwankar, #584650)
1962
1963* ``.bazaar``, ``.bazaar/bazaar.conf`` and ``.bzr.log`` inherit user and
1964 group ownership from the containing directory. This allow bzr to work
1965 better with sudo.
1966 (Martin <gzlist@googlemail.com>, Parth Malwankar, #376388)
1967
1968* ``bzr clean-tree`` should not delete nested bzrdirs. Required for proper
1969 support of bzr-externals and scmproj plugins.
1970 (Alexander Belchenko, bug #572098)
1971
1972* ``bzr ignore`` will no longer add duplicate patterns to .bzrignore.
1973 (Gordon Tyler, #572092)
1974
1975* ``bzr log --exclude-common-ancestry -r X..Y`` displays the revisions that
1976 are part of Y ancestry but not part of X ancestry (aka the graph
1977 difference).
1978 (Vincent Ladeuil, #320119)
1979
1980* ``bzr lp-propose`` which was switched to use production Launchpad API
1981 servers a few commits ago has been reverted to use edge: there is a
1982 problem with using production which isn't trivially obvious, so we've
1983 filed a bug to track it, and until thats fixed will be using edge.
1984 (Robert Collins, #583667)
1985
1986* ``bzr rm`` should not refuse to delete directories which contained a file
1987 which has been moved elsewhere in the tree after the previous commit.
1988 (Marius Kruger, Daniel Watkins, #129880)
1989
1990* ``bzr selftest --parallel=fork`` wait for its children avoiding zombies.
1991 (Vincent Ladeuil, #566670)
1992
1993* ``bzr selftest`` should not use ui.note() since it's not unicode safe.
1994 (Vincent Ladeuil, #563997)
1995
1996* CommitBuilder refuses to create revisions whose trees have no root.
1997 (Aaron Bentley)
1998
1999* Do not register a SIGWINCH signal handler, instead just poll for the
2000 terminal width as needed. This avoids the "Interrupted System Call"
2001 problems that occur on POSIX with all currently released versions of
2002 Python.
2003 (Andrew Bennetts, #583941)
2004
2005* Don't mention --no-strict when we just issue the warning about unclean trees.
2006 (Vincent Ladeuil, #401599)
2007
2008* Fixed ``AssertionError`` when accessing smart servers running Bazaar
2009 versions before 1.6.
2010 (Andrew Bennetts, #528041)
2011
2012* Improved progress bar for fetch (2a format only). Bazaar now shows an
2013 estimate of the number of records to be fetched vs actually fetched.
2014 (Parth Malwankar, #374740, #538868)
2015
2016* Reduce peak memory by one copy of compressed text.
2017 (John Arbash Meinel, #566940)
2018
2019* ``RemoteBranch.lock_write`` raises ``ReadOnlyError`` if called during a
2020 read lock, rather than causing an ``AttributeError``.
2021 (Andrew Bennetts, Данило Шеган, #582781)
2022
2023* Selftest was failing with testtools 0.9.3, which caused an
2024 AssertionError raised from a cleanUp to be reported as a Failure, not an
2025 Error, breaking on of our test hygiene tests.
2026 (Robert Collins, Vincent Ladeuil).
2027
2028* ``set_user_option`` with a dict on remote branches no longer fails with
2029 an AttributeError. There is a new ``Branch.set_config_option_dict`` RPC
2030 to support this efficiently.
2031 (Andrew Bennetts, #430382)
2032
2033* Show the filenames when a file rename fails so that the error will be
2034 more comprehensible.
2035 (Martin Pool, #491763)
2036
2037* Support Pyrex 0.9.9, required changing how we handle exceptions in Pyrex.
2038 (John Arbash Meinel, #582656)
2039
2040* Unicode characters in aliases are now handled correctly and do not cause
2041 UnicodeEncodeError exception. (Parth Malwankar, #529930)
2042
2043* Unicode commit messages that are the same as a file name no longer cause
2044 UnicodeEncodeError. ``ui.text.show_warning`` now handles unicode
2045 messages.
2046 (Parth Malwankar, #563646)
2047
2048* Using bzr with `lp:` urls behind an http proxy should work.
2049 (Robert Collins, #558343)
2050
2051* When passing a file to ``UTF8DirReader`` make sure to close the current
2052 directory file handle after the chdir fails. Otherwise when passing many
2053 filenames into a command line ``bzr status`` we would leak descriptors.
2054 (John Arbash Meinel, #583486)
2055
2056Improvements
2057************
2058
2059* ``append_revisions_only`` will now be interpreted as a boolean and a
2060 warning emitted if illegal values are used. Note that for projects
2061 that needs to maintain compatibility with previsous bzr versions,
2062 only 'True' and 'False' strings must be used (previous versions of
2063 bzr will interpret all strings differing from 'True'
2064 (case-sensitive) as false.
2065 (Brian de Alwis, Vincent Ladeuil)
2066
2067* ``bzr ls`` now supports short options for existing long options.
2068 ``-k/--kind``, ``-i/--ignored``, ``-u/--unknown`` and ``-0/--null``.
2069 (Parth Malwankar, #181124)
2070
2071* ``Config.get_user_option_as_bool`` will now warn if a value cannot
2072 be interpreted as a boolean.
2073 (Vincent Ladeuil)
2074
2075* The all-in-one Windows installer will now be built with docstrings stripped
2076 from the library zip, reducing the size and slightly improving cold startup
2077 time. Bundled plugins are unchanged for the moment, but if adding other new
2078 plugins to an all-in-one installation, ensure they are compiled and
2079 installed with -O1 or help may not work. (Martin [gz])
2080
2081Documentation
2082*************
2083
2084API Changes
2085***********
2086
2087* Added ``bzrlib.merge.PerFileMerger``, a more convenient way to write
2088 some kinds of ``merge_file_content`` hook functions.
2089 (Andrew Bennetts)
2090
2091* `BzrDir`, `Branch`, `Repository` and `WorkingTree` now all support `user_url`,
2092 `user_transport`, `control_url` and `control_transport` members pointing
2093 respectively to the directory containing the ``.bzr`` control directory,
2094 and to the directory within ``.bzr`` used for the particular component.
2095 All of them inherit from `ControlComponent` which provides default
2096 implementations.
2097 (Martin Pool)
2098
2099* Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
2100 expected to return an object which can be used to unlock them. This reduces
2101 duplicate code when using cleanups. The previous 'tokens's returned by
2102 ``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
2103 on the result of the lock_write. ``repository.RepositoryWriteLockResult``
2104 and ``branch.BranchWriteLockResult`` document this. (Robert Collins)
2105
2106* ``Repository.refresh_data`` may now be called in a write group on
2107 pack-based repositories. Older repositories will still raise an error
2108 in this case. Subclasses of ``Repository`` can still override
2109 ``Repository._refresh_data``, but are now responsible for raising
2110 ``bzrlib.repository.IsInWriteGroupError`` if they do not support
2111 ``refresh_data`` during a write group.
2112 (Andrew Bennetts, #574236)
2113
2114Internals
2115*********
2116
2117* ``chk_map._bytes_to_text_key`` is now an optimized function to extract
2118 the (file-id, revision-id) key from a CHKInventory entry. This can
2119 potentially shave 5-10% time off during a large fetch. Related to bug
2120 #562666. (John Arbash Meinel)
2121
2122* ``log._get_info_for_log_files`` now takes an add_cleanup callable.
2123 (Robert Collins)
2124
2125* ``_remember_remote_is_before`` no longer raises AssertionError when
2126 suboptimal network behaviour is noticed; instead it just mutters to the
2127 log file (and warns the user if they have set the ``hpss`` debug flag).
2128 This was causing unnecessary aborts for performance bugs that are minor
2129 at worst.
2130 (Andrew Bennetts, #528041)
2131
2132* Permit bzr to run under ``python -OO`` which reduces the size of bytecode
2133 files loaded from disk. To ensure docstrings needed for help are never
2134 stripped, the prefix ``__doc__ =`` should now be used.
2135 (Martin <gzlist@googlemail.com>)
2136
2137* No longer require zlib headers to build extensions, and remove the need
2138 for seperate copy of zlib library on windows.
2139 (John Arbash Meinel, Martin <gzlist@googlemail.com>, #66923)
2140
2141Testing
2142*******
2143
2144* Added ``bzrlib.tests.matchers`` as a place to put matchers, along with
2145 our first in-tree matcher. See the module docstring for details.
2146 (Robert Collins)
2147
2148* ``bzr selftest --parallel=subprocess`` now works correctly on win32.
2149 (Gordon Tyler, #551332)
2150
2151* Workaround ``Crypto.Random`` check leading to spurious test
2152 failures on Lucid, FreeBSD and gentoo.
2153 (Vincent Ladeuil, #528436)
2154
2155* New class ``ExecutableFeature`` for checking the availability of
2156 executables on the ``PATH``. Migrated from bash_completion plugin.
2157 (Martin von Gagern)
2158
2159bzr 2.2b2
2160#########
2161
2162:2.2b2: 2010-04-16
2163
2164This is a somewhat early second beta of the 2.2 series, to fix a python2.4
2165incompatibility in the 2.2b1 release. It also includes a swag of
2166performance, usability and correctness improvements: test feedback on all
2167of these would be welcome.
2168
2169
2170New Features
2171************
2172
2173* ``bzr diff`` now supports a --format option, which can be used to
2174 select alternative diff formats. (Jelmer Vernooij, #555994)
2175
2176Bug Fixes
2177*********
2178
2179* ``bzr dpush``, ``bzr push`` and ``bzr send`` will now issue a warning
2180 instead of failing when dirty trees are involved. The corresponding
2181 ``dpush_strict``, ``push_strict`` and ``send_strict`` should be set to
2182 True explicitly to get the previous behaviour.
2183 (Vincent Ladeuil, #519319)
2184
2185* ``bzr export`` to tar file does not fail if any parent directory
2186 contains unicode characters. This works around upstream Python bug
2187 http://bugs.python.org/issue8396 .
2188 (Parth Malwankar, #413406)
2189
2190* ``bzr switch`` does not die if a ConfigurableFileMerger is used.
2191 (Aaron Bentley, #559436)
2192
2193* ``bzr update`` when a pending merge in the working tree has been merged
2194 into the master branch will no longer claim that old commits have become
2195 pending merges. (Robert Collins, #562079)
2196
2197* ``bzrlib.mutabletree.MutableTree.commit`` will now support a passed in
2198 config as in previous versions of bzrlib. (Robert Collins)
2199
2200* Fix glitch in the warning about unclean trees display.
2201 (Vincent Ladeuil, #562665)
2202
2203* Fixed Python2.4 incompatibilities in the bzr2.2b1 source tarball.
2204 (Martin Pool)
2205
2206* Help messages generated by ``RegistryOption.from_kwargs`` list the
2207 switches in alphabetical order, rather than in an undefined order.
2208 (Martin von Gagern, #559409)
2209
2210* Make sure the ``ExecutablePath`` and ``InterpreterPath`` are set in
2211 Apport crash reports, to avoid "This problem report applies to a program
2212 which is not installed any more" error.
2213 (Martin Pool, James Westby, #528114)
2214
2215* Reset ``siginterrupt`` flag to False every time we handle a signal
2216 installed with ``set_signal_handler(..., restart_syscall=True)`` (from
2217 ``bzrlib.osutils``. Reduces the likelihood of "Interrupted System Call"
2218 errors compared to registering ``signal.signal`` directly.
2219 (Andrew Bennetts)
2220
2221* When invoked with a range revision, ``bzr log`` doesn't show revisions
2222 that are not part of the Y revisions ancestry anymore when invoked with
2223 -rX..Y.
2224 (Vincent Ladeuil, #474807)
2225
2226* Properly handle ``param_name`` attribute for ``ListOption``.
2227 (Martin von Gagern, 387117)
2228
2229Improvements
2230************
2231
2232* ``bzr commit`` will prompt before using a commit message that was
2233 generated by a template and not edited by the user.
2234 (Robert Collins, #530265)
2235
2236* ``bzr diff`` read-locks the trees and branches only once, saving about
2237 10-20ms on ``bzr diff`` in a bzr.dev tree.
2238 (Andrew Bennetts)
2239
2240* ``bzr missing`` read-locks the branches only once.
2241 (Andrew Bennetts)
2242
2243* ``bzr pull`` locks the branches and tree only once.
2244 (Andrew Bennetts)
2245
2246* Index lookups in pack repositories search recently hit pack files first.
2247 In repositories with many pack files this can greatly reduce the
2248 number of files accessed, the number of bytes read, and the number of
2249 read calls. An incremental pull via plain HTTP takes half the time and
2250 bytes for a moderately large repository. (Andrew Bennetts)
2251
2252* Index lookups only re-order the indexes when the hit files aren't
2253 already first. Reduces the cost of reordering
2254 (John Arbash Meinel, #562429)
2255
2256* Less code is loaded at startup. (Cold-cache start time is about 10-20%
2257 less.)
2258 (Martin Pool, #553017)
2259
2260API Changes
2261***********
2262
2263* ``bzrlib.diff.get_trees_and_branches_to_diff`` is deprecated. Use
2264 ``get_trees_and_branches_to_diff_locked`` instead.
2265 (Andrew Bennetts)
2266
2267* ``TreeTransform.commit`` supports the full set of commit parameters, and
2268 auto-determines branch nick if not supplied. (Aaron Bentley)
2269
2270Internals
2271*********
2272
2273* ``bzrlib.commands.Command.run_direct`` is no longer needed - the pre
2274 2.1 method of calling run() to perform testing or direct use via the API
2275 is now possible again. As part of this, the _operation attribute on
2276 Command is now transient and only exists for the duration of ``run()``.
2277 (Robert Collins)
2278
2279bzr 2.2b1
2280#########
2281
2282:2.2b1: 2010-04-01
2283
2284This is the first beta of the 2.2 series, leading up to a 2.2.0
2285release in July or August. Beta releases are suitable for everyday use
2286but may cause some incompatibilities with plugins. Some plugins may need
2287small updates to work with 2.2b1.
2288
22892.2b1 includes some changes to make merge conflicts easier to understand
2290and resolve. It also removes some old unnecessary code, and loads
2291somewhat less code at startup. It starts adding a common infrastructure
2292for dealing with colocated named branches, which can be implemented in
2293various ways in either bzr native or foreign formats. On Ubuntu and
2294other platforms with the apport bug-reporting library, there's an easier
2295path to report problems with bzr. We plan to continue with these themes
2296through the 2.2 series.
2297
2298Over thirty bugs have been fixed, including in the log command, exporting
2299to tarballs, restarting interrupted system calls, portability of compiled
2300extensions, making backups during upgrade, and locking on ftp.
2301
2302Compatibility Breaks
2303********************
2304
2305* BTreeGraphIndex can now take an offset to indicate that the data starts
2306 somewhere other than then beginning of the file. (John Arbash Meinel)
2307
2308* Deleted very old hidden commands ``versionedfile-list``,
2309 ``weave-plan-merge``, ``weave-merge-text``.
2310 (Martin Pool)
2311
2312* ``Repository.get_inventory_sha1()`` and ``Repository.get_revision_xml()``
2313 have been removed. (Jelmer Vernooij)
2314
2315* ``Repository.get_revision_inventory()`` has been removed in favor of
2316 ``Repository.get_inventory()``. (Jelmer Vernooij)
2317
2318* All test servers have been moved out of the bzrlib.transport hierarchy to
2319 bzrlib.tests.test_server *except* for MemoryServer, ChrootServer and
2320 PathFilteringServer. ``bzrlib`` users may encounter test failures that can
2321 be fixed by updating the related imports from ``bzrlib.transport.xxx`` to
2322 ``bzrlib.tests.test_server``.
2323 (Vincent Ladeuil)
2324
2325* ``BranchReferenceFormat.initialize()`` now takes an optional name argument
2326 as its second parameter, for consistency with the initialize() method of
2327 other formats. (Jelmer Vernooij)
2328
2329New Features
2330************
2331
2332* Added ``bzr remove-branch`` command that can remove a local or remote
2333 branch. (Jelmer Vernooij, #276295)
2334
2335* ``bzr export`` now takes an optional argument ``--per-file-timestamps``
2336 to set file mtimes to the last timestamp of the last revision in which
2337 they were changed rather than the current time. (Jelmer Vernooij)
2338
2339* If the Apport crash-reporting tool is available, bzr crashes are now
2340 stored into the ``/var/crash`` apport spool directory, and the user is
2341 invited to report them to the developers from there, either
2342 automatically or by running ``apport-bug``. No information is sent
2343 without specific permission from the user. (Martin Pool, #515052)
2344
2345* Parsing of command lines, for example in ``diff --using``, no longer
2346 treats backslash as an escape character on Windows. (Gordon Tyler,
2347 #392248)
2348
2349* Plugins can be disabled by defining ``BZR_DISABLE_PLUGINS`` as
2350 a list of plugin names separated by ':' (';' on windows).
2351 (Vincent Ladeuil, #411413)
2352
2353* Plugins can be loaded from arbitrary locations by defining
2354 ``BZR_PLUGINS_AT`` as a list of name@path separated by ':' (';' on
2355 windows). This takes precedence over ``BZR_PLUGIN_PATH`` for the
2356 specified plugins. This is targeted at plugin developers for punctual
2357 needs and *not* intended to replace ``BZR_PLUGIN_PATH``.
2358 (Vincent Ladeuil, #82693)
2359
2360* Tag names can now be determined automatically by ``automatic_tag_name``
2361 hooks on ``Branch`` if they are not specified on the command line.
2362 (Jelmer Vernooij)
2363
2364* Tree-shape conflicts can be resolved by providing ``--take-this`` and
2365 ``--take-other`` to the ``bzr resolve`` command. Just marking the conflict
2366 as resolved is still accessible via the ``--done`` default action.
2367 (Vincent Ladeuil)
2368
2369* Merges can be proposed on Launchpad with the new lp-propose-merge command.
2370 (Aaron Bentley, Jonathan Lange)
2371
2372Bug Fixes
2373*********
2374
2375* Added docstring for ``Tree.iter_changes``
2376 (John Arbash Meinel, #304182)
2377
2378* Allow additional arguments to
2379 ``RemoteRepository.add_inventory_by_delta()``. (Jelmer Vernooij, #532631)
2380
2381* Allow exporting a single file using ``bzr export``.
2382 (Michal Junák, #511987)
2383
2384* Allow syscalls to automatically restart when ``TextUIFactory``'s
2385 SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
2386 IO, which are often poorly handled by Python's libraries and parts of
2387 bzrlib. (Andrew Bennetts, #496813)
2388
2389* Avoid infinite recursion when probing for apport.
2390 (Vincent Ladeuil, #516934)
2391
2392* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
2393 (Martin Pool, #331095)
2394
2395* Avoid truncating svn URLs.
2396 (Martin Pool, Martin von Gagern, #545185)
2397
2398* ``bzr add`` will not add conflict related files unless explicitly required.
2399 (Vincent Ladeuil, #322767, #414589)
2400
2401* ``bzr dump-btree`` now works on ``*.cix`` and ``*.six`` files. Those
2402 indices do not have reference lists, so ``dump-btree`` will simply show
2403 ``None`` instead. (Andrew Bennetts, #488607)
2404
2405* ``bzr help`` will no longer trigger the get_missing_command hook when
2406 doing a topic lookup. This avoids prompting (like 'no command plugins/loom,
2407 did you mean log?') when getting help. In future we may trigger the hook
2408 deliberately when no help topics match from any help index.
2409 (Robert Collins, #396261)
2410
2411* ``bzr log -n0 -r..A.B.C`` should not crash but just consider the None
2412 revspec as representing the first revision of the branch.
2413 (Vincent Ladeuil, #519862)
2414
2415* ``bzr remove-tree`` can now remove multiple working trees.
2416 (Jared Hance, Andrew Bennetts, #253137)
2417
2418* ``bzr resolve --take-this`` and ``--take-other`` now correctly renames
2419 the kept file on content conflicts where one side deleted the file.
2420 (Vincent Ladeuil, #529968)
2421
2422* ``bzr upgrade`` now creates the ``backup.bzr`` directory with the same
2423 permissions as ``.bzr`` directory on a POSIX OS.
2424 (Parth Malwankar, #262450)
2425
2426* ``bzr upgrade`` now names backup directory as ``backup.bzr.~N~`` instead
2427 of ``backup.bzr``. This directory is ignored by bzr commands such as
2428 ``add``.
2429 (Parth Malwankar, #335033, #300001)
2430
2431* Cope with non-utf8 characters inside ``.bzrignore``.
2432 (Jason Spashett, #183504)
2433
2434* Correctly interpret "451 Rename/move failure: Directory not empty" from
2435 ftp servers while trying to take a lock.
2436 (Martin Pool, #528722)
2437
2438* DirStateRevisionTree.kind() was returning wrong result when 'kind'
2439 changes occured between the workingtree and one of its parents.
2440 (Vincent Ladeuil, #535547)
2441
2442* Fix ``log`` to better check ancestors even if merged revisions are involved.
2443 (Vincent Ladeuil, #476293)
2444
2445* Loading a plugin from a given path with ``BZR_PLUGINS_AT`` doesn't depend
2446 on os.lisdir() order and is now reliable.
2447 (Vincent Ladeuil, #552922).
2448
2449* Many IO operations that returned ``EINTR`` were retried even if it
2450 wasn't safe to do so via careless use of ``until_no_eintr``. Bazaar now
2451 only retries operations that are safe to retry, and in some cases has
2452 switched to operations that can be retried (e.g. ``sock.send`` rather than
2453 ``sock.sendall``).
2454 (Andrew Bennetts, Martin <gzlist@googlemail.com>, #496813)
2455
2456* Path conflicts now support --take-this and --take-other even when a
2457 deletion is involved.
2458 (Vincent Ladeuil, #531967)
2459
2460* Network transfer amounts and rates are now displayed in SI units according
2461 to the Ubuntu Units Policy <https://wiki.ubuntu.com/UnitsPolicy>.
2462 (Gordon Tyler, #514399)
2463
2464* Support kind markers for socket and fifo filesystem objects. This
2465 prevents ``bzr status --short`` from crashing when those files are
2466 present. (John Arbash Meinel, #303275)
2467
2468* ``bzr mkdir DIR`` will not create DIR unless DIR's parent is a versioned
2469 directory. (Parth Malwankar, #138600)
2470
2471* SSH child processes will now ignore SIGQUIT on nix systems so breaking into
2472 the debugger won't kill the session.
2473 (Martin <gzlist@googlemail.com>, #162502)
2474
2475* Tolerate patches with leading noise in ``bzr-handle-patch``.
2476 (Toshio Kuratomi, Martin Pool, #502076)
2477
2478* ``update -r`` now supports updating to revisions that are not on
2479 mainline (i.e. it supports dotted revisions).
2480 (Parth Malwankar, #517800)
2481
2482* Use first apparent author not committer in GNU Changelog format.
2483 (Martin von Gagern, #513322)
2484
2485API Changes
2486***********
2487
2488* ``bzrlib.merge_directive._BaseMergeDirective`` has been renamed to
2489 ``bzrlib.merge_directive.BaseMergeDirective`` and is now public.
2490 (Jelmer Vernooij)
2491
2492* ``BranchFormat.initialize`` now takes an optional ``name`` of the colocated
2493 branch to create. (Jelmer Vernooij)
2494
2495* ``BzrDir.get_branch_transport`` now takes an optional ``name`` of the
2496 colocated branch to open. (Jelmer Vernooij)
2497
2498* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
2499 can set a signal handler and call ``signal.siginterrupt(signum,
2500 False)`` for it, if the platform and Python version supports it.
2501 (Andrew Bennetts, #496813)
2502
2503* New ``bzrlib.initialize`` is recommended for programs using bzrlib to
2504 run when starting up; it sets up several things that previously needed
2505 to be done separately.
2506 (Martin Pool, #507710)
2507
2508* Exporters now support a ``per_file_timestamps`` argument to write out the
2509 timestamp of the commit in which a file revision was introduced.
2510 (Jelmer Vernooij)
2511
2512* New method ``BzrDir.list_branches()`` that returns a sequence of branches
2513 present in a control directory. (Jelmer Vernooij)
2514
2515* New method ``Repository.get_known_graph_ancestry()``.
2516 (Jelmer Vernooij, #495502)
2517
2518* New transport methods ``readlink``, ``symlink`` and ``hardlink``.
2519 (Neil Santos)
2520
2521* Remove unused ``CommandFailed`` exception.
2522 (Martin Pool)
2523
2524Internals
2525*********
2526
2527* ``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
2528 ``message_callback`` in the same way that commit does. (Robert Collins)
2529
2530* ``bzrlib.builtins.Commit.run`` raises ``bzrlib.errors.BoundBranchOutOfDate``
2531 rather than ``bzrlib.errors.BzrCommandError`` when the bound branch is out
2532 of date. (Gary van der Merwe)
2533
2534* ``bzrlib.commands.run_bzr`` is more extensible: callers can supply the
2535 functions to load or disable plugins if they wish to use a different
2536 plugin mechanism; the --help, --version and no-command name code paths
2537 now use the generic pluggable command lookup infrastructure.
2538 (Robert Collins)
2539
2540* ``bzrlib.errors.BoundBranchOutOfDate`` has a new field ``extra_help``
2541 which can be set to add extra help to the error. (Gary van der Merwe)
2542
2543* New method ``Branch.automatic_tag_name`` that can be used to find the
2544 tag name for a particular revision automatically. (Jelmer Vernooij)
2545
2546* The methods ``BzrDir.create_branch()``, ``BzrDir.destroy_branch()`` and
2547 ``BzrDir.open_branch()`` now take an optional ``name`` argument.
2548 (Jelmer Vernooij)
2549
2550Testing
2551*******
2552
2553* bzr now has a ``.testr.conf`` file in its source tree configured
2554 appropriately for running tests with Testrepository
2555 (``https://launchpad.net/testrepository``). (Robert Collins)
2556
2557* Documentation about testing with ``subunit`` has been tweaked.
2558 (Robert Collins)
2559
2560* Known failures has been added for resolve --take-other on ParentLoop
2561 conflicts. This reflects bug #537956 without fixing it.
2562 (Vincent Ladeuil)
2563
2564* New ``bzrlib.tests.test_import_tariff`` can make assertions about what
2565 Python modules are loaded, to guard against startup time or library
2566 dependency regressions.
2567 (Martin Pool)
2568
2569* PQM will now run with subunit output. To analyze a PQM error use
2570 tribunal, or cat log | subunit-filter | subunit2pyunit. (Robert Collins)
2571
2572* Stop sending apport crash files to ``.cache`` in the directory from
2573 which ``bzr selftest`` was run. (Martin Pool, #422350)
2574
2575* Tests no longer fail if "close() called during concurrent
2576 operation on the same file object" occurs when closing the log file
2577 (which can happen if a thread tries to write to the log file at the
2578 wrong moment). An warning will be written to ``stderr`` when this
2579 happens, and another warning will be written if the log file could not
2580 be closed after retrying 100 times. (Andrew Bennetts, #531746)
2581
2582bzr 2.1.3
2583#########
2584
2585:Codename: Do run run
2586:2.1.3: NOT RELEASED YET
2587
2588Compatibility Breaks
2589********************
2590
2591New Features
2592************
2593
2594Bug Fixes
2595*********
2596
2597* Configuration files in ``${BZR_HOME}`` are now written in an atomic
2598 way which should help avoid problems with concurrent writers.
2599 (Vincent Ladeuil, #525571)
2600
2601* Don't traceback trying to unversion children files of an already
2602 unversioned directory. (Vincent Ladeuil, #494221)
2603
2604* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
2605 which can result in "missing referenced chk root keys" errors when
2606 fetching from repositories with affected revisions.
2607 (Andrew Bennetts, #522637)
2608
2609* Raise ValueError instead of a string exception.
2610 (John Arbash Meinel, #586926)
2611
2612Improvements
2613************
2614
2615Documentation
2616*************
2617
2618API Changes
2619***********
2620
2621Internals
2622*********
2623
2624Testing
2625*******
2626
2627bzr 2.1.2
2628#########
2629
2630:2.1.2: 2010-05-28
2631
2632This release fixes two critical networking issues with older servers and
2633with interrupted system call errors when pushing or pulling. We recommend
2634upgrading to anyone running a 2.1.x version of bzr.
2635
2636Bug Fixes
2637*********
2638
2639* ``bzr clean-tree`` should not delete nested bzrdirs. Required for proper
2640 support of bzr-externals and scmproj plugins.
2641 (Alexander Belchenko, bug #572098)
2642
2643* ``bzr switch`` does not die if a ConfigurableFileMerger is used.
2644 (Aaron Bentley, #559436)
2645
2646* Do not register a SIGWINCH signal handler, instead just poll for the
2647 terminal width as needed. This avoids the "Interrupted System Call"
2648 problems that occur on POSIX with all currently released versions of
2649 Python.
2650 (Andrew Bennetts, #583941)
2651
2652* Fixed ``AssertionError`` when accessing smart servers running Bazaar
2653 versions before 1.6.
2654 (Andrew Bennetts, #528041)
2655
2656* Reset ``siginterrupt`` flag to False every time we handle a signal
2657 installed with ``set_signal_handler(..., restart_syscall=True)`` (from
2658 ``bzrlib.osutils``. Reduces the likelihood of "Interrupted System Call"
2659 errors compared to registering ``signal.signal`` directly.
2660 (Andrew Bennetts)
2661
2662* Reduce peak memory by one copy of compressed text.
2663 (John Arbash Meinel, #566940)
2664
2665* Support Pyrex 0.9.9, required changing how we handle exceptions in Pyrex.
2666 (John Arbash Meinel, #582656)
2667
2668* When passing a file to ``UTF8DirReader`` make sure to close the current
2669 directory file handle after the chdir fails. Otherwise when passing many
2670 filenames into a command line ``bzr status`` we would leak descriptors.
2671 (John Arbash Meinel, #583486)
2672
2673Internals
2674*********
2675
2676* ``_remember_remote_is_before`` no longer raises AssertionError when
2677 suboptimal network behaviour is noticed; instead it just mutters to the
2678 log file (and warns the user if they have set the ``hpss`` debug flag).
2679 This was causing unnecessary aborts for performance bugs that are minor
2680 at worst.
2681 (Andrew Bennetts, #528041)
2682
2683
2684bzr 2.1.1
2685#########
2686
2687:2.1.1: 2010-03-24
2688
2689This is a small bugfix release. Upgrading is recommended for anyone
2690running 2.1.0 or earlier.
2691
2692Bug Fixes
2693*********
2694
2695* Allow syscalls to automatically restart when ``TextUIFactory``'s
2696 SIGWINCH handler is invoked, avoiding ``EINTR`` errors during blocking
2697 IO, which are often poorly handled by Python's libraries and parts of
2698 bzrlib. (Andrew Bennetts, #496813)
2699
2700* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
2701 (Martin Pool, #331095)
2702
2703* Fix plugin packaging on Windows. (Ian Clatworthy, #524162)
2704
2705* Fix stub sftp test server to call os.getcwdu().
2706 (Vincent Ladeuil, #526221, #526353)
2707
2708* Fixed CHM generation by moving the NEWS section template into
2709 a separate file. (Ian Clatworthy, #524184)
2710
2711* Merge correctly when this_tree is not a WorkingTree. (Aaron Bentley)
2712
2713* Register SIGWINCH handler only when creating a ``TextUIFactory``; avoids
2714 problems importing bzrlib from a non-main thread.
2715 (Elliot Murphy, #521989)
2716
2717* Repositories accessed via a smart server now reject being stacked on a
2718 repository in an incompatible format, as is the case when accessing them
2719 via other methods. This was causing fetches from those repositories via
2720 a smart server (e.g. using ``bzr branch``) to receive invalid data.
2721 (Andrew Bennetts, #562380)
2722
2723* Standardize the error handling when creating a new ``StaticTuple``
2724 (problems will raise TypeError). (Matt Nordhoff, #457979)
2725
2726* Warn if pyrex is too old to compile the new ``SimpleSet`` and
2727 ``StaticTuple`` extensions, rather than having the build fail randomly.
2728 (John Arbash Meinel, #449776)
2729
2730Documentation
2731*************
2732
2733* Added a link to the Desktop Guide. (Ian Clatworthy)
2734
2735* Added What's New in Bazaar 2.1 document. (Ian Clatworthy)
2736
2737* Drop Google Analytics from the core docs as they caused problems
2738 in the CHM files. (Ian Clatworthy, #502010)
2739
2740API Changes
2741***********
2742
2743* Added ``bzrlib.osutils.set_signal_handler``, a convenience function that
2744 can set a signal handler and call ``signal.siginterrupt(signum,
2745 False)`` for it, if the platform and Python version supports it.
2746 (Andrew Bennetts, #496813)
2747
2748
2749bzr 2.1.0
2750#########
2751
2752:Codename: Strasbourg
2753:2.1.0: 2010-02-11
2754
2755This release marks our second long-term-stable series. The Bazaar team
2756has decided that we will continue to make bugfix-only 2.0.x and 2.1.x
2757releases, along with 2.2 development releases.
2758
2759This is a fairly incremental update, focusing on polish and bugfixing.
2760There are no changes for supported disk formats. Key updates include
2761reduced memory consumption for many operations, a new per-file merge
2762hook, ignore patterns can now include '!' to exclude files, globbing
2763support for all commands on Windows, and support for addressing home
2764directories via ``bzr+ssh://host/~/`` syntax.
2765
2766Users are encouraged to upgrade from the 2.0 stable series.
2767
2768Bug Fixes
2769*********
2770
2771* Don't require testtools to use sftp.
2772 (Vincent Ladeuil, #516183)
2773
2774* Fix "AttributeError in Inter1and2Helper" during fetch.
2775 (Martin Pool, #513432)
2776
2777* ``bzr update`` performs the two merges in a more logical order and will stop
2778 when it encounters conflicts.
2779 (Gerard Krol, #113809)
2780
2781* Give a better error message when doing ``bzr bind`` in an already bound
2782 branch. (Neil Martinsen-Burrell, #513063)
2783
2784* Ignore ``KeyError`` from ``remove_index`` during ``_abort_write_group``
2785 in a pack repository, which can happen harmlessly if the abort occurs during
2786 finishing the write group. Also use ``bzrlib.cleanup`` so that any
2787 other errors that occur while aborting the individual packs won't be
2788 hidden by secondary failures when removing the corresponding indices.
2789 (Andrew Bennetts, #423015)
2790
2791* Set the mtime of files exported to a directory by ``bzr export`` all to
2792 the same value to avoid confusing ``make`` and other date-based build
2793 systems. (Robert Collins, #515631)
2794
2795Improvements
2796************
2797
2798* Fetching into experimental formats will now print a warning. (Jelmer
2799 Vernooij)
2800
2801API Changes
2802***********
2803
2804* ``Repository.deserialise_inventory`` has been renamed to
2805 ``Repository._deserialise_inventory`` to indicate it is private.
2806 (Jelmer Vernooij)
2807
2808* ``Repository.get_inventory_xml`` has been renamed to
2809 ``Repository._get_inventory_xml`` to indicate it is private.
2810 (Jelmer Vernooij)
2811
2812* ``Repository.serialise_inventory`` has been renamed to
2813 ``Repository._serialise_inventory`` to indicate it is private.
2814
2815* Using the ``bzrlib.chk_map`` module from within multiple threads at the
2816 same time was broken due to race conditions with a module level page
2817 cache. This shows up as a KeyError in the ``bzrlib.lru_cache`` code with
2818 ``bzrlib.chk_map`` in the backtrace, and can be triggered without using
2819 the same high level objects such as ``bzrlib.repository.Repository``
2820 from different threads. chk_map now uses a thread local cache which may
2821 increase memory pressure on processes using threads.
2822 (Robert Collins, John Arbash Meinel, #514090)
2823
2824* The new ``merge_file_content`` should now be ok with tests to avoid
2825 regressions.
2826 (Vincent Ladeuil, #515597)
2827
2828Internals
2829*********
2830
2831* Use ``bzrlib.cleanup`` rather than less robust ``try``/``finally``
2832 blocks in several places in ``bzrlib.merge``. This avoids masking prior
2833 errors when errors like ``ImmortalPendingDeletion`` occur during cleanup
2834 in ``do_merge``.
2835 (Andrew Bennetts, #517275)
2836
2837API Changes
2838***********
2839
2840* The ``remove_index`` method of
2841 ``bzrlib.repofmt.pack_repo.AggregateIndex`` no longer takes a ``pack``
2842 argument. This argument was always ignored.
2843 (Andrew Bennetts, #423015)
2844
2845bzr 2.1.0rc2
2846############
2847
2848:Codename: after the bubbles
2849:2.1.0rc2: 2010-01-29
2850
2851This is a quick-turn-around to update a small issue with our new per-file
2852merge hook. We expect no major changes from this to the final 2.1.0.
2853
2854API Changes
2855***********
2856
2857* The new ``merge_file_content`` hook point has been altered to provide a
2858 better API where state for extensions can be stored rather than the
2859 too-simple function based approach. This fixes a performance regression
2860 where branch configuration would be parsed per-file during merge. As
2861 part of this the included news_merger has been refactored into a base
2862 helper class ``bzrlib.merge.ConfigurableFileMerger``.
2863 (Robert Collins, John Arbash Meinel, #513822)
2864
2865
2866bzr 2.1.0rc1
2867############
2868
2869:Codename: the 'new' stable
2870:2.1.0rc1: 2009-01-21
2871
2872This is the first stable release candidate for Bazaar's 2.1 series. From
2873this point onwards, the 2.1 series will be considered stable (as the 2.0
2874series) and only bugfixes are expected to be incorporated. The dozen or so
2875bugfixes in the 2.0.4 release are also included in this release (along
2876with more than 15 more bugfixes). Some of the interesting features are
2877support for per-file merge hooks, ``bzr unshelve --preview``, support
2878for using ! in ignore files to exclude files from being ignored, a small
2879memory leak was squashed, and many ``ObjectNotLocked`` errors were fixed.
2880This looks to be a very good start for a new stable series.
2881
2882
2883New Features
2884************
2885
2886* Add bug information to log output when available.
2887 (Neil Martinsen-Burrell, Guillermo Gonzalez, #251729)
2888
2889* Added ``merge_file_content`` hook point to ``Merger``, allowing plugins
2890 to register custom merge logic, e.g. to provide smarter merging for
2891 particular files.
2892
2893* Bazaar now includes the ``news_merge`` plugin. It is disabled by
2894 default, to enable it add a ``news_merge_files`` option to your
2895 configuration. Consult ``bzr help news_merge`` for more information.
2896 (Andrew Bennetts)
2897
2898* ``bzr branch`` now takes a ``--bind`` option. This lets you
2899 branch and bind all in one command. (Ian Clatworthy)
2900
2901* ``bzr switch`` now takes a ``--revision`` option, to allow switching to
2902 a specific revision of a branch. (Daniel Watkins, #183559)
2903
2904* ``bzr unshelve --preview`` can now be used to show how a patch on the
2905 shelf would be applied to the working tree.
2906 (Guilherme Salgado, #308122)
2907
2908* ``bzr update`` now takes a ``--revision`` argument. This lets you
2909 change the revision of the working tree to any revision in the
2910 ancestry of the current or master branch. (Matthieu Moy, Mark Hammond,
2911 Martin Pool, #45719)
2912
2913* ``-Dbytes`` can now be used to display the total number of bytes
2914 transferred for the current command. This information is always logged
2915 to ``.bzr.log`` for later inspection. (John Arbash Meinel)
2916
2917* New ignore patterns. Patterns prefixed with '!' are exceptions to
2918 ignore patterns and take precedence over regular ignores. Such
2919 exceptions are used to specify files that should be versioned which
2920 would otherwise be ignored. Patterns prefixed with '!!' act as regular
2921 ignore patterns, but have highest precedence, even over the '!'
2922 exception patterns. (John Whitley, #428031)
2923
2924* The ``supress_warnings`` configuration option has been introduced to disable
2925 various warnings (it currently only supports the ``format_deprecation``
2926 warning). The new option can be set in any of the following locations:
2927 ``bazaar.conf``, ``locations.conf`` and/or ``branch.conf``.
2928 (Ted Gould, Matthew Fuller, Vincent Ladeuil)
2929
2930Bug Fixes
2931*********
2932
2933* Always show a message if an OS error occurs while trying to run a
2934 user-specified commit message editor.
2935 (Martin Pool, #504842)
2936
2937* ``bzr diff`` will now use the epoch when it is unable to determine
2938 the timestamp of a file, if the revision it was introduced in is a
2939 ghost. (Jelmer Vernooij, #295611)
2940
2941* ``bzr switch -b`` can now create branches that are located using directory
2942 services such as ``lp:``, even when the branch name doesn't contain a
2943 '/'. (Neil Martinsen-Burrell, #495263)
2944
2945* ``bzr unshelve`` has improved messages about what it is doing.
2946 (Neil Martinsen-Burrell, #496917)
2947
2948* Concurrent autopacking is more resilient to already-renamed pack files.
2949 If we find that a file we are about to obsolete is already obsoleted, we
2950 do not try to rename it, and we leave the file in ``obsolete_packs``.
2951 The code is also fault tolerant if a file goes missing, assuming that
2952 another process already removed the file.
2953 (John Arbash Meinel, Gareth White, #507557)
2954
2955* Fix "Too many concurrent requests" in reconcile when network connection
2956 fails. (Andrew Bennetts, #503878)
2957
2958* Fixed a side effect mutation of ``RemoteBzrDirFormat._network_name``
2959 that caused some tests to fail when run in a non-default order.
2960 Probably no user impact. (Martin Pool, #504102)
2961
2962* Fixed ``ObjectNotLocked`` error in ``bzr cat -rbranch:../foo FILE``.
2963 (Andrew Bennetts, #506274)
2964
2965* FTP transports support Unicode paths by encoding/decoding them as utf8.
2966 (Vincent Ladeuil, #472161)
2967
2968* Listen to the SIGWINCH signal to update the terminal width.
2969 (Vincent Ladeuil, #316357)
2970
2971* Progress bars are now hidden when ``--quiet`` is given.
2972 (Martin Pool, #320035)
2973
2974* ``SilentUIFactory`` now supports ``make_output_stream`` and discards
2975 whatever is written to it. This un-breaks some plugin tests that
2976 depended on this behaviour.
2977 (Martin Pool, #499757)
2978
2979* When operations update the working tree, all affected files should end
2980 up with the same mtime. (eg. when versioning a generated file, if you
2981 update the source and the generated file together, the generated file
2982 should appear up-to-date.)
2983 (John Arbash Meinel, Martin <gzlist>, #488724)
2984
2985Improvements
2986************
2987
2988* Added ``add_cleanup`` and ``cleanup_now`` to ``bzrlib.command.Command``.
2989 All the builtin commands now use ``add_cleanup`` rather than
2990 ``try``/``finally`` blocks where applicable as it is simpler and more
2991 robust. (Andrew Bennetts)
2992
2993* All except a small number of storage formats are now hidden, making
2994 the help for numerous commands far more digestible. (Ian Clatworthy)
2995
2996* Attempts to open a shared repository as a branch (e.g. ``bzr branch
2997 path/to/repo``) will now include "location is a repository" as a hint in
2998 the error message. (Brian de Alwis, Andrew Bennetts, #440952)
2999
3000* Push will now inform the user when they are trying to push to a foreign
3001 VCS for which roundtripping is not supported, and will suggest them to
3002 use dpush. (Jelmer Vernooij)
3003
3004* The version of bzr being run is now written to the log file.
3005 (__monty__, #257170)
3006
3007* Transport network activity indicator is shown more of the time when
3008 Bazaar is doing network IO.
3009 (Martin Pool)
3010
3011Documentation
3012*************
3013
3014* Add documentation on creating merges with more than one parent.
3015 (Neil Martinsen-Burrell, #481526)
3016
3017* Better explain the --uncommitted option of merge.
3018 (Neil Martinsen-Burrell, #505088)
3019
3020* Improve discussion of pending merges in the documentation for
3021 ``revert``. (Neil Martinsen-Burrell, #505093)
3022
3023* Improved help for ``bzr send``.
3024 (Martin Pool, Bojan Nikolic)
3025
3026* There is a System Administrator's Guide in ``doc/en/admin-guide``,
3027 including discussions of installation, relevant plugins, security and
3028 backup. (Neil Martinsen-Burrell)
3029
3030* The ``conflicts`` help topic has been renamed to ``conflict-types``.
3031 (Ian Clatworthy)
3032
3033* The User Reference is now presented as a series of topics.
3034 Many of the included topics have link and format tweaks applied.
3035 (Ian Clatworthy)
3036
3037API Changes
3038***********
3039
3040* Added ``cachedproperty`` decorator to ``bzrlib.decorators``.
3041 (Andrew Bennetts)
3042
3043* Many test features were renamed from ``FooFeature`` to ``foo_feature``
3044 to be consistent with instances being lower case and classes being
3045 CamelCase. For the features that were more likely to be used, we added a
3046 deprecation thunk, but not all. (John Arbash Meinel)
3047
3048* Merger classes (such as ``Merge3Merger``) now expect a ``this_branch``
3049 parameter in their constructors, and provide ``this_branch`` as an
3050 attribute. (Andrew Bennetts)
3051
3052* The Branch hooks pre_change_branch_tip no longer masks exceptions raised
3053 by plugins - the original exceptions are now preserved. (Robert Collins)
3054
3055* The Transport ``Server.tearDown`` method is now renamed to
3056 ``stop_server`` and ``setUp`` to ``start_server`` for consistency with
3057 our normal naming pattern, and to avoid confusion with Python's
3058 ``TestCase.tearDown``. (Martin Pool)
3059
3060* ``WorkingTree.update`` implementations must now accept a ``revision``
3061 parameter.
3062
3063Internals
3064*********
3065
3066* Added ``BzrDir.open_branchV3`` smart server request, which can receive
3067 a string of details (such as "location is a repository") as part of a
3068 ``nobranch`` response. (Andrew Bennetts, #440952)
3069
3070* New helper osutils.UnicodeOrBytesToBytesWriter which encodes unicode
3071 objects but passes str objects straight through. This is used for
3072 selftest but may be useful for diff and other operations that generate
3073 mixed output. (Robert Collins)
3074
3075* New exception ``NoRoundtrippingSupport``, for use by foreign branch
3076 plugins. (Jelmer Vernooij)
3077
3078Testing
3079*******
3080
3081* ``bzrlib.tests.permute_for_extension`` is a helper that simplifies
3082 running all tests in the current module, once against a pure python
3083 implementation, and once against an extension (pyrex/C) implementation.
3084 It can be used to dramatically simplify the implementation of
3085 ``load_tests``. (John Arbash Meinel)
3086
3087* ``bzrlib.tests.TestCase`` now subclasses ``testtools.testcase.TestCase``.
3088 This permits features in testtools such as getUniqueInteger and
3089 getUniqueString to be used. Because of this, testtools version 0.9.2 or
3090 newer is now a dependency to run bzr selftest. Running with versions of
3091 testtools less than 0.9.2 will cause bzr to error while loading the test
3092 suite. (Robert Collins)
3093
3094* Shell-like tests now support the command "mv" for moving files. The
3095 syntax for ``mv file1 file2``, ``mv dir1 dir2`` and ``mv file dir`` is
3096 supported. (Neil Martinsen-Burrell)
3097
3098* The test progress bar no longer distinguishes tests that 'errored' from
3099 tests that 'failed' - they're all just failures.
3100 (Martin Pool)
3101>>>>>>> MERGE-SOURCE
15673102
1568bzr 2.0.63103bzr 2.0.6
1569#########3104#########
@@ -1589,38 +3124,78 @@
1589 permissions as ``.bzr`` directory on a POSIX OS.3124 permissions as ``.bzr`` directory on a POSIX OS.
1590 (Parth Malwankar, #262450)3125 (Parth Malwankar, #262450)
15913126
1592* Don't traceback trying to unversion children files of an already3127<<<<<<< TREE
1593 unversioned directory. (Vincent Ladeuil, #494221)3128* Don't traceback trying to unversion children files of an already
15943129 unversioned directory. (Vincent Ladeuil, #494221)
1595* Raise ValueError instead of a string exception.3130
1596 (John Arbash Meinel, #586926)3131* Raise ValueError instead of a string exception.
15973132 (John Arbash Meinel, #586926)
1598* Reduce peak memory by one copy of compressed text.3133
1599 (John Arbash Meinel, #566940)3134* Reduce peak memory by one copy of compressed text.
16003135 (John Arbash Meinel, #566940)
1601* Repositories accessed via a smart server now reject being stacked on a3136
1602 repository in an incompatible format, as is the case when accessing them3137* Repositories accessed via a smart server now reject being stacked on a
1603 via other methods. This was causing fetches from those repositories via3138 repository in an incompatible format, as is the case when accessing them
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
1605 (Andrew Bennetts, #562380)3140 a smart server (e.g. using ``bzr branch``) to receive invalid data.
16063141 (Andrew Bennetts, #562380)
1607* Selftest with versions of subunit that support ``stopTestRun`` will no longer3142
1608 error. This error was caused by 2.0 not being updated when upstream3143* Selftest with versions of subunit that support ``stopTestRun`` will no longer
1609 python merged the end of run patch, which chose ``stopTestRun`` rather than3144 error. This error was caused by 2.0 not being updated when upstream
1610 ``done``. (Robert Collins, #571437)3145 python merged the end of run patch, which chose ``stopTestRun`` rather than
16113146 ``done``. (Robert Collins, #571437)
1612* When passing a file to ``UTF8DirReader`` make sure to close the current3147
1613 directory file handle after the chdir fails. Otherwise when passing many3148* When passing a file to ``UTF8DirReader`` make sure to close the current
1614 filenames into a command line ``bzr status`` we would leak descriptors.3149 directory file handle after the chdir fails. Otherwise when passing many
1615 (John Arbash Meinel, #583486)3150 filenames into a command line ``bzr status`` we would leak descriptors.
16163151 (John Arbash Meinel, #583486)
16173152
1618Testing3153
1619*******3154Testing
16203155*******
1621* ``build_tree_contents`` can create symlinks.3156
1622 (Martin Pool, John Arbash Meinel)3157* ``build_tree_contents`` can create symlinks.
16233158 (Martin Pool, John Arbash Meinel)
3159
3160=======
3161* Don't traceback trying to unversion children files of an already
3162 unversioned directory. (Vincent Ladeuil, #494221)
3163
3164* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
3165 which can result in "missing referenced chk root keys" errors when
3166 fetching from repositories with affected revisions.
3167 (Andrew Bennetts, #522637)
3168
3169* Raise ValueError instead of a string exception.
3170 (John Arbash Meinel, #586926)
3171
3172* Reduce peak memory by one copy of compressed text.
3173 (John Arbash Meinel, #566940)
3174
3175* Repositories accessed via a smart server now reject being stacked on a
3176 repository in an incompatible format, as is the case when accessing them
3177 via other methods. This was causing fetches from those repositories via
3178 a smart server (e.g. using ``bzr branch``) to receive invalid data.
3179 (Andrew Bennetts, #562380)
3180
3181* Selftest with versions of subunit that support ``stopTestRun`` will no longer
3182 error. This error was caused by 2.0 not being updated when upstream
3183 python merged the end of run patch, which chose ``stopTestRun`` rather than
3184 ``done``. (Robert Collins, #571437)
3185
3186* When passing a file to ``UTF8DirReader`` make sure to close the current
3187 directory file handle after the chdir fails. Otherwise when passing many
3188 filenames into a command line ``bzr status`` we would leak descriptors.
3189 (John Arbash Meinel, #583486)
3190
3191
3192Testing
3193*******
3194
3195* ``build_tree_contents`` can create symlinks.
3196 (Martin Pool, John Arbash Meinel)
3197
3198>>>>>>> MERGE-SOURCE
16243199
1625bzr 2.0.53200bzr 2.0.5
1626#########3201#########
16273202
=== modified file 'bzr'
--- bzr 2010-07-13 07:44:02 +0000
+++ bzr 2010-07-29 06:48:01 +0000
@@ -23,7 +23,11 @@
23import warnings23import warnings
2424
25# update this on each release25# update this on each release
26<<<<<<< TREE
26_script_version = (2, 3, 0)27_script_version = (2, 3, 0)
28=======
29_script_version = (2, 2, 0)
30>>>>>>> MERGE-SOURCE
2731
28try:32try:
29 version_info = sys.version_info33 version_info = sys.version_info
3034
=== modified file 'bzrlib/__init__.py'
--- bzrlib/__init__.py 2010-07-13 07:44:02 +0000
+++ bzrlib/__init__.py 2010-07-29 06:48:01 +0000
@@ -52,11 +52,19 @@
52# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a52# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
53# releaselevel of 'dev' for unreleased under-development code.53# releaselevel of 'dev' for unreleased under-development code.
5454
55<<<<<<< TREE
55version_info = (2, 3, 0, 'dev', 1)56version_info = (2, 3, 0, 'dev', 1)
5657
57# API compatibility version58# API compatibility version
58api_minimum_version = (2, 2, 0)59api_minimum_version = (2, 2, 0)
5960
61=======
62version_info = (2, 2, 0, 'beta', 4)
63
64# API compatibility version
65api_minimum_version = (2, 2, 0)
66
67>>>>>>> MERGE-SOURCE
6068
61def _format_version_tuple(version_info):69def _format_version_tuple(version_info):
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.
6371
=== removed file 'bzrlib/benchmarks/__init__.py'
--- bzrlib/benchmarks/__init__.py 2009-06-10 03:56:49 +0000
+++ bzrlib/benchmarks/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,206 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Benchmark test suite for bzr."""
18
19from bzrlib import (
20 bzrdir,
21 )
22from bzrlib import plugin as _mod_plugin
23import bzrlib.branch
24from bzrlib.tests.TestUtil import TestLoader
25from bzrlib.tests.blackbox import ExternalBase
26
27
28class Benchmark(ExternalBase):
29 """A Test class which provides helpers for writing benchmark tests."""
30
31 def make_kernel_like_tree(self, url=None, root='.',
32 link_working=False):
33 """Setup a temporary tree roughly like a kernel tree.
34
35 :param url: Creat the kernel like tree as a lightweight checkout
36 of a new branch created at url.
37 :param root: Path where the tree will be created.
38 :param link_working: instead of creating a new copy of all files
39 just hardlink the working tree. Tests must request this, because
40 they must break links if they want to change the files
41 :return: A newly created tree.
42 """
43 from bzrlib.benchmarks.tree_creator.kernel_like import (
44 KernelLikeTreeCreator,
45 )
46 creator = KernelLikeTreeCreator(self, link_working=link_working,
47 url=url)
48 return creator.create(root=root)
49
50 def make_kernel_like_added_tree(self, root='.',
51 link_working=True,
52 hot_cache=True):
53 """Make a kernel like tree, with all files added
54
55 :param root: Where to create the files
56 :param link_working: Instead of copying all of the working tree
57 files, just hardlink them to the cached files. Tests can unlink
58 files that they will change.
59 :param hot_cache: Run through the newly created tree and make sure
60 the stat-cache is correct. The old way of creating a freshly
61 added tree always had a hot cache.
62 """
63 from bzrlib.benchmarks.tree_creator.kernel_like import (
64 KernelLikeAddedTreeCreator,
65 )
66 creator = KernelLikeAddedTreeCreator(self, link_working=link_working,
67 hot_cache=hot_cache)
68 return creator.create(root=root)
69
70 def make_kernel_like_committed_tree(self, root='.',
71 link_working=True,
72 link_bzr=False,
73 hot_cache=True):
74 """Make a kernel like tree, with all files added and committed
75
76 :param root: Where to create the files
77 :param link_working: Instead of copying all of the working tree
78 files, just hardlink them to the cached files. Tests can unlink
79 files that they will change.
80 :param link_bzr: Hardlink the .bzr directory. For readonly
81 operations this is safe, and shaves off a lot of setup time
82 """
83 from bzrlib.benchmarks.tree_creator.kernel_like import (
84 KernelLikeCommittedTreeCreator,
85 )
86 creator = KernelLikeCommittedTreeCreator(self,
87 link_working=link_working,
88 link_bzr=link_bzr,
89 hot_cache=hot_cache)
90 return creator.create(root=root)
91
92 def make_kernel_like_inventory(self):
93 """Create an inventory with the properties of a kernel-like tree
94
95 This should be equivalent to a committed kernel like tree, not
96 just a working tree.
97 """
98 from bzrlib.benchmarks.tree_creator.kernel_like import (
99 KernelLikeInventoryCreator,
100 )
101 creator = KernelLikeInventoryCreator(self)
102 return creator.create()
103
104 def make_many_commit_tree(self, directory_name='.',
105 hardlink=False):
106 """Create a tree with many commits.
107
108 No file changes are included. Not hardlinking the working tree,
109 because there are no working tree files.
110 """
111 from bzrlib.benchmarks.tree_creator.simple_many_commit import (
112 SimpleManyCommitTreeCreator,
113 )
114 creator = SimpleManyCommitTreeCreator(self, link_bzr=hardlink)
115 return creator.create(root=directory_name)
116
117 def make_heavily_merged_tree(self, directory_name='.',
118 hardlink=False):
119 """Create a tree in which almost every commit is a merge.
120
121 No file changes are included. This produces two trees,
122 one of which is returned. Except for the first commit, every
123 commit in its revision-history is a merge another commit in the other
124 tree. Not hardlinking the working tree, because there are no working
125 tree files.
126 """
127 from bzrlib.benchmarks.tree_creator.heavily_merged import (
128 HeavilyMergedTreeCreator,
129 )
130 creator = HeavilyMergedTreeCreator(self, link_bzr=hardlink)
131 return creator.create(root=directory_name)
132
133 def create_with_commits(self, num_files, num_commits, directory_name='.',
134 hardlink=False):
135 """Create a tree with many files and many commits. Every commit changes
136 exactly one file.
137
138 :param num_files: number of files to be created
139 :param num_commits: number of commits in the newly created tree
140 """
141 from bzrlib.benchmarks.tree_creator.many_commit import (
142 ManyCommitTreeCreator,
143 )
144 creator = ManyCommitTreeCreator(self, link_bzr=hardlink,
145 num_files=num_files,
146 num_commits=num_commits)
147 tree = creator.create(root=directory_name)
148 files = ["%s/%s" % (directory_name, fn) for fn in creator.files]
149 return tree, files
150
151 def commit_some_revisions(self, tree, files, num_commits,
152 changes_per_commit):
153 """Commit a specified number of revisions to some files in a tree,
154 makeing a specified number of changes per commit.
155
156 :param tree: The tree in which the changes happen.
157 :param files: The list of files where changes should occur.
158 :param num_commits: The number of commits
159 :param changes_per_commit: The number of files that are touched in
160 each commit.
161 """
162 for j in range(num_commits):
163 for i in range(changes_per_commit):
164 fn = files[(i + j) % changes_per_commit]
165 content = range(i) + [i, i, i, '']
166 f = open(fn, "w")
167 try:
168 f.write("\n".join([str(k) for k in content]))
169 finally:
170 f.close()
171 tree.commit("new revision")
172
173
174def test_suite():
175 """Build and return a TestSuite which contains benchmark tests only."""
176 testmod_names = [ \
177 'bzrlib.benchmarks.bench_add',
178 'bzrlib.benchmarks.bench_bench',
179 'bzrlib.benchmarks.bench_bundle',
180 'bzrlib.benchmarks.bench_cache_utf8',
181 'bzrlib.benchmarks.bench_checkout',
182 'bzrlib.benchmarks.bench_commit',
183 'bzrlib.benchmarks.bench_dirstate',
184 'bzrlib.benchmarks.bench_info',
185 'bzrlib.benchmarks.bench_inventory',
186 'bzrlib.benchmarks.bench_knit',
187 'bzrlib.benchmarks.bench_log',
188 'bzrlib.benchmarks.bench_pack',
189 'bzrlib.benchmarks.bench_osutils',
190 'bzrlib.benchmarks.bench_rocks',
191 'bzrlib.benchmarks.bench_startup',
192 'bzrlib.benchmarks.bench_status',
193 'bzrlib.benchmarks.bench_tags',
194 'bzrlib.benchmarks.bench_transform',
195 'bzrlib.benchmarks.bench_workingtree',
196 'bzrlib.benchmarks.bench_sftp',
197 'bzrlib.benchmarks.bench_xml',
198 ]
199 suite = TestLoader().loadTestsFromModuleNames(testmod_names)
200
201 # Load any benchmarks from plugins
202 for name, plugin in _mod_plugin.plugins().items():
203 if getattr(plugin.module, 'bench_suite', None) is not None:
204 suite.addTest(plugin.module.bench_suite())
205
206 return suite
2070
=== removed file 'bzrlib/benchmarks/bench_add.py'
--- bzrlib/benchmarks/bench_add.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_add.py 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr add performance."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class AddBenchmark(Benchmark):
24 """Benchmarks for 'bzr add'"""
25
26 def test_one_add_kernel_like_tree(self):
27 """Adding a kernel sized tree should be bearable (<5secs) fast."""
28 self.make_kernel_like_tree(link_working=True)
29 # on roberts machine: this originally took: 25936ms/32244ms
30 # after making smart_add use the parent_ie: 5033ms/ 9368ms
31 # plain os.walk takes 213ms on this tree
32 self.time(self.run_bzr, 'add')
330
=== removed file 'bzrlib/benchmarks/bench_bench.py'
--- bzrlib/benchmarks/bench_bench.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_bench.py 1970-01-01 00:00:00 +0000
@@ -1,101 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr benchmark utilities performance."""
18
19from bzrlib import (
20 osutils,
21 )
22from bzrlib.benchmarks import Benchmark
23from bzrlib.benchmarks.tree_creator.kernel_like import (
24 KernelLikeTreeCreator,
25 KernelLikeAddedTreeCreator,
26 KernelLikeCommittedTreeCreator,
27 )
28from bzrlib.tests import TestSkipped
29
30
31class MakeKernelLikeTreeBenchmark(Benchmark):
32 """Benchmark creating benchmark trees."""
33
34 def test_make_kernel_like_tree(self):
35 """Making a kernel sized tree should be ~ 5seconds on modern disk."""
36 # on roberts machine: this originally took: 7372ms/ 7479ms
37 # with the LocalTransport._abspath call: 3730ms/ 3778ms
38 # with AtomicFile tuning: 2888ms/ 2926ms
39 # switching to transport.append_bytes: 1468ms/ 2849ms
40 self.time(self.make_kernel_like_tree)
41
42 def test_02_make_kernel_like_tree(self):
43 """Hardlinking a kernel-like working tree should be ~1s"""
44 # make sure kernel_like_tree is cached
45 creator = KernelLikeTreeCreator(self, link_working=True)
46 if not creator.is_caching_enabled():
47 raise TestSkipped('caching is disabled')
48 creator.ensure_cached()
49 self.time(creator.create, root='bar')
50
51 def test_03_make_kernel_like_added_tree(self):
52 """Time the first creation of a kernel like added tree"""
53 creator = KernelLikeAddedTreeCreator(self)
54 creator.disable_cache()
55 self.time(creator.create, root='foo')
56
57 def test_04_make_kernel_like_added_tree(self):
58 """Time the second creation of a kernel like added tree
59 (this should be a clone)
60 """
61 # make sure kernel_like_added_tree is cached
62 creator = KernelLikeAddedTreeCreator(self, link_working=True)
63 if not creator.is_caching_enabled():
64 # Caching is disabled, this test is meaningless
65 raise TestSkipped('caching is disabled')
66 creator.ensure_cached()
67 self.time(creator.create, root='bar')
68
69 def test_05_make_kernel_like_committed_tree(self):
70 """Time the first creation of a committed kernel like tree"""
71 creator = KernelLikeCommittedTreeCreator(self)
72 creator.disable_cache()
73 self.time(creator.create, root='foo')
74
75 def test_06_make_kernel_like_committed_tree(self):
76 """Time the second creation of a committed kernel like tree
77 (this should be a clone)
78 """
79 creator = KernelLikeCommittedTreeCreator(self,
80 link_working=True,
81 link_bzr=False)
82 if not creator.is_caching_enabled():
83 # Caching is disabled, this test is meaningless
84 raise TestSkipped('caching is disabled')
85 creator.ensure_cached()
86 self.time(creator.create, root='bar')
87
88 def test_07_make_kernel_like_committed_tree_hardlink(self):
89 """Time the creation of a committed kernel like tree
90 (this should also hardlink the .bzr/ directory)
91 """
92 creator = KernelLikeCommittedTreeCreator(self,
93 link_working=True,
94 link_bzr=True)
95 if not creator.is_caching_enabled():
96 # Caching is disabled, this test is meaningless
97 raise TestSkipped('caching is disabled')
98 creator.ensure_cached()
99 self.time(creator.create, root='bar')
100
101
1020
=== removed file 'bzrlib/benchmarks/bench_bundle.py'
--- bzrlib/benchmarks/bench_bundle.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_bundle.py 1970-01-01 00:00:00 +0000
@@ -1,207 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr bundle performance."""
18
19from cStringIO import StringIO
20import os
21import shutil
22
23from bzrlib import bzrdir
24from bzrlib.benchmarks import Benchmark
25from bzrlib.branch import Branch
26from bzrlib.bundle.apply_bundle import install_bundle
27from bzrlib.bundle.serializer import read_bundle, write_bundle
28from bzrlib.revision import NULL_REVISION
29from bzrlib.revisionspec import RevisionSpec
30from bzrlib.workingtree import WorkingTree
31
32
33class BundleBenchmark(Benchmark):
34 """Benchmarks for bzr bundle performance and bzr merge with a bundle."""
35
36 def test_create_bundle_known_kernel_like_tree(self):
37 """Create a bundle for a kernel sized tree with no ignored, unknowns,
38 or added and one commit.
39 """
40 self.make_kernel_like_committed_tree()
41 self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
42
43 def test_create_bundle_many_commit_tree (self):
44 """Create a bundle for a tree with many commits but no changes."""
45 self.make_many_commit_tree()
46 self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
47
48 def test_create_bundle_heavily_merged_tree(self):
49 """Create a bundle for a heavily merged tree."""
50 self.make_heavily_merged_tree()
51 self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
52
53 def test_apply_bundle_known_kernel_like_tree(self):
54 """Create a bundle for a kernel sized tree with no ignored, unknowns,
55 or added and one commit.
56 """
57 tree = self.make_kernel_like_committed_tree('tree')
58
59 f = open('bundle', 'wb')
60 try:
61 write_bundle(tree.branch.repository, tree.last_revision(),
62 NULL_REVISION, f)
63 finally:
64 f.close()
65
66 tree2 = self.make_branch_and_tree('branch_a')
67 os.chdir('branch_a')
68 self.time(self.run_bzr, ['merge', '../bundle'])
69
70
71class BundleLibraryLevelWriteBenchmark(Benchmark):
72 """ Benchmarks for the write_bundle library function. """
73
74 def _time_read_write(self):
75 branch, relpath = Branch.open_containing("a")
76 revision_history = branch.revision_history()
77 bundle_text = StringIO()
78 self.time(write_bundle, branch.repository, revision_history[-1],
79 NULL_REVISION, bundle_text)
80 bundle_text.seek(0)
81 target_tree = self.make_branch_and_tree('b')
82 bundle = self.time(read_bundle, bundle_text)
83 self.time(install_bundle, target_tree.branch.repository, bundle)
84
85 def test_few_files_small_tree_1_revision(self):
86 os.mkdir("a")
87 tree, files = self.create_with_commits(5, 1, directory_name="a")
88 self.commit_some_revisions(tree, files[:5], 1, 1)
89 self._time_read_write()
90
91 def test_few_files_small_tree_100_revision(self):
92 os.mkdir("a")
93 tree, files = self.create_with_commits(5, 1, directory_name="a")
94 self.commit_some_revisions(tree, files[:5], 100, 1)
95 self._time_read_write()
96
97 def test_few_files_moderate_tree_1_revision(self):
98 os.mkdir("a")
99 tree, files = self.create_with_commits(100, 1, directory_name="a")
100 self.commit_some_revisions(tree, files[:5], 1, 1)
101 self._time_read_write()
102
103 def test_few_files_moderate_tree_100_revision(self):
104 os.mkdir("a")
105 tree, files = self.create_with_commits(100, 1, directory_name="a")
106 self.commit_some_revisions(tree, files[:5], 100, 1)
107 self._time_read_write()
108
109 def test_some_files_moderate_tree_1_revision(self):
110 os.mkdir("a")
111 tree, files = self.create_with_commits(100, 1, directory_name="a")
112 self.commit_some_revisions(tree, files[:100], 1, 1)
113 self._time_read_write()
114
115 def test_few_files_big_tree_1_revision(self):
116 os.mkdir("a")
117 tree, files = self.create_with_commits(1000, 1, directory_name="a")
118 self.commit_some_revisions(tree, files[:5], 1, 1)
119 self._time_read_write()
120
121 def test_some_files_big_tree_1_revision(self):
122 os.mkdir("a")
123 tree, files = self.create_with_commits(1000, 1, directory_name="a")
124 self.commit_some_revisions(tree, files[:100], 1, 1)
125 self._time_read_write()
126
127
128class BundleLibraryLevelInstallBenchmark(Benchmark):
129 """ Benchmarks for the install_bundle library function. """
130
131 def _time_read_write(self):
132 branch, relpath = Branch.open_containing("a")
133 revision_history = branch.revision_history()
134 bundle_text = StringIO()
135 write_bundle(branch.repository, revision_history[-1],
136 NULL_REVISION, bundle_text)
137 bundle_text.seek(0)
138 target_tree = self.make_branch_and_tree('b')
139 bundle = self.time(read_bundle, bundle_text)
140 self.time(install_bundle, target_tree.branch.repository, bundle)
141
142 def test_few_files_small_tree_1_revision(self):
143 os.mkdir("a")
144 tree, files = self.create_with_commits(5, 1, directory_name="a")
145 self.commit_some_revisions(tree, files[:5], 1, 1)
146 self._time_read_write()
147
148 def test_few_files_small_tree_100_revision(self):
149 os.mkdir("a")
150 tree, files = self.create_with_commits(5, 1, directory_name="a")
151 self.commit_some_revisions(tree, files[:5], 100, 1)
152 self._time_read_write()
153
154 def test_few_files_moderate_tree_1_revision(self):
155 os.mkdir("a")
156 tree, files = self.create_with_commits(100, 1, directory_name="a")
157 self.commit_some_revisions(tree, files[:5], 1, 1)
158 self._time_read_write()
159
160 def test_few_files_moderate_tree_100_revision(self):
161 os.mkdir("a")
162 tree, files = self.create_with_commits(100, 1, directory_name="a")
163 self.commit_some_revisions(tree, files[:5], 100, 1)
164 self._time_read_write()
165
166 def test_some_files_moderate_tree_1_revision(self):
167 os.mkdir("a")
168 tree, files = self.create_with_commits(100, 1, directory_name="a")
169 self.commit_some_revisions(tree, files[:100], 1, 1)
170 self._time_read_write()
171
172 def test_few_files_big_tree_1_revision(self):
173 os.mkdir("a")
174 tree, files = self.create_with_commits(1000, 1, directory_name="a")
175 self.commit_some_revisions(tree, files[:5], 1, 1)
176 self._time_read_write()
177
178 def test_some_files_big_tree_1_revision(self):
179 os.mkdir("a")
180 tree, files = self.create_with_commits(1000, 1, directory_name="a")
181 self.commit_some_revisions(tree, files[:100], 1, 1)
182 self._time_read_write()
183
184
185if __name__ == '__main__':
186 # USE the following if you want to regenerate the above test functions
187 for treesize, treesize_h in [(5, "small"), (100, "moderate"),
188 (1000, "big")]:
189 for bundlefiles, bundlefiles_h in [(5, "few"), (100, "some")]:
190 if bundlefiles > treesize:
191 continue
192 for num_revisions in [1, 100]:
193 if (num_revisions >= 100 and
194 (bundlefiles >= 100 or treesize >= 1000)):
195 # Skip the 100x100x? tests.
196 # And the 100x?x1000
197 continue
198 code = """\
199 def test_%s_files_%s_tree_%s_revision(self):
200 os.mkdir("a")
201 tree, files = self.create_with_commits(%s, 1, directory_name="a")
202 self.commit_some_revisions(tree, files[:%s], %s, 1)
203 self._time_read_write()
204""" % (bundlefiles_h, treesize_h, num_revisions,
205 treesize, bundlefiles, num_revisions)
206 print code
207
2080
=== removed file 'bzrlib/benchmarks/bench_cache_utf8.py'
--- bzrlib/benchmarks/bench_cache_utf8.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_cache_utf8.py 1970-01-01 00:00:00 +0000
@@ -1,226 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
18"""Tests for encoding performance."""
19
20from bzrlib import (
21 cache_utf8,
22 osutils,
23 )
24
25from bzrlib.benchmarks import Benchmark
26
27
28_normal_revision_id = (u'john@arbash-meinel.com-20060801200018'
29 u'-cafa6272d9b8cac4')
30_unicode_revision_id = (u'\u062c\u0648\u062c\u0648@\xe5rbash-meinel.com-'
31 u'\xb5\xb5\xb5-20060801200018-cafa6272d9b8cac4')
32
33_normal_revision_id_utf8 = _normal_revision_id.encode('utf-8')
34_unicode_revision_id_utf8 = _unicode_revision_id.encode('utf-8')
35
36
37class EncodingBenchmark(Benchmark):
38 """Benchmark the time to encode strings."""
39
40 def setUp(self):
41 super(EncodingBenchmark, self).setUp()
42 # Make sure we start and end with a clean cache
43 cache_utf8.clear_encoding_cache()
44 self.addCleanup(cache_utf8.clear_encoding_cache)
45
46 def encode_1M(self, revision_id):
47 """Encode the given revision id 1 million times"""
48 # In a real kernel tree there are 7.7M lines of code
49 # so the initial import actually has to encode a revision
50 # id to store annotated lines one time for every line.
51 for i in xrange(1000000):
52 revision_id.encode('utf8')
53
54 def encode_cached_1M(self, revision_id):
55 """Encode the given revision id 1 million times using the cache"""
56 encode = cache_utf8.encode
57 for i in xrange(1000000):
58 encode(revision_id)
59
60 def encode_multi(self, revision_list, count):
61 """Encode each entry in the list count times"""
62 for i in xrange(count):
63 for revision_id in revision_list:
64 revision_id.encode('utf-8')
65
66 def encode_cached_multi(self, revision_list, count):
67 """Encode each entry in the list count times"""
68 encode = cache_utf8.encode
69 for i in xrange(count):
70 for revision_id in revision_list:
71 encode(revision_id)
72
73 def test_encode_1_by_1M_ascii(self):
74 """Test encoding a single revision id 1 million times."""
75 self.time(self.encode_1M, _normal_revision_id)
76
77 def test_encode_1_by_1M_ascii_cached(self):
78 """Test encoding a single revision id 1 million times."""
79 self.time(self.encode_cached_1M, _normal_revision_id)
80
81 def test_encode_1_by_1M_ascii_str(self):
82 # We have places that think they have a unicode revision id
83 # but actually, they have a plain string. So .encode(utf8)
84 # actually has to decode from ascii, and then encode into utf8
85 self.time(self.encode_1M, str(_normal_revision_id))
86
87 def test_encode_1_by_1M_ascii_str_cached(self):
88 self.time(self.encode_cached_1M, str(_normal_revision_id))
89
90 def test_encode_1_by_1M_unicode(self):
91 """Test encoding a single revision id 1 million times."""
92 self.time(self.encode_1M, _unicode_revision_id)
93
94 def test_encode_1_by_1M_unicode_cached(self):
95 """Test encoding a single revision id 1 million times."""
96 self.time(self.encode_cached_1M, _unicode_revision_id)
97
98 def test_encode_1k_by_1k_ascii(self):
99 """Test encoding 5 revisions 100k times"""
100 revisions = [unicode(osutils.rand_chars(60)) for x in xrange(1000)]
101 self.time(self.encode_multi, revisions, 1000)
102
103 def test_encode_1k_by_1k_ascii_cached(self):
104 """Test encoding 5 revisions 100k times"""
105 revisions = [unicode(osutils.rand_chars(60)) for x in xrange(1000)]
106 self.time(self.encode_cached_multi, revisions, 1000)
107
108 def test_encode_1k_by_1k_unicode(self):
109 """Test encoding 5 revisions 100k times"""
110 revisions = [u'\u062c\u0648\u062c\u0648' +
111 unicode(osutils.rand_chars(60)) for x in xrange(1000)]
112 self.time(self.encode_multi, revisions, 1000)
113
114 def test_encode_1k_by_1k_unicode_cached(self):
115 """Test encoding 5 revisions 100k times"""
116 revisions = [u'\u062c\u0648\u062c\u0648' +
117 unicode(osutils.rand_chars(60)) for x in xrange(1000)]
118 self.time(self.encode_cached_multi, revisions, 1000)
119
120 def test_encode_500K_by_1_ascii(self):
121 revisions = [unicode("test%07d" % x) for x in xrange(500000)]
122 self.time(self.encode_multi, revisions, 1)
123
124 def test_encode_500K_by_1_ascii_cached(self):
125 revisions = [unicode("test%07d" % x) for x in xrange(500000)]
126 self.time(self.encode_cached_multi, revisions, 1)
127
128 def test_encode_500K_by_1_unicode(self):
129 revisions = [u'\u062c\u0648\u062c\u0648' +
130 unicode("%07d" % x) for x in xrange(500000)]
131 self.time(self.encode_multi, revisions, 1)
132
133 def test_encode_500K_by_1_unicode_cached(self):
134 revisions = [u'\u062c\u0648\u062c\u0648' +
135 unicode("%07d" % x) for x in xrange(500000)]
136 self.time(self.encode_cached_multi, revisions, 1)
137
138
139class DecodingBenchmarks(Benchmark):
140 """Benchmark the time to decode strings."""
141
142 def setUp(self):
143 super(DecodingBenchmarks, self).setUp()
144 # Make sure we start and end with a clean cache
145 cache_utf8.clear_encoding_cache()
146 self.addCleanup(cache_utf8.clear_encoding_cache)
147
148 def decode_1M(self, revision_id):
149 for i in xrange(1000000):
150 revision_id.decode('utf8')
151
152 def decode_cached_1M(self, revision_id):
153 decode = cache_utf8.decode
154 for i in xrange(1000000):
155 decode(revision_id)
156
157 def decode_multi(self, revision_list, count):
158 for i in xrange(count):
159 for revision_id in revision_list:
160 revision_id.decode('utf-8')
161
162 def decode_cached_multi(self, revision_list, count):
163 decode = cache_utf8.decode
164 for i in xrange(count):
165 for revision_id in revision_list:
166 decode(revision_id)
167
168 def test_decode_1_by_1M_ascii(self):
169 """Test decoding a single revision id 1 million times."""
170 self.time(self.decode_1M, _normal_revision_id_utf8)
171
172 def test_decode_1_by_1M_ascii_cached(self):
173 """Test decoding a single revision id 1 million times."""
174 self.time(self.decode_cached_1M, _normal_revision_id_utf8)
175
176 def test_decode_1_by_1M_unicode(self):
177 """Test decoding a single revision id 1 million times."""
178 self.time(self.decode_1M, _unicode_revision_id_utf8)
179
180 def test_decode_1_by_1M_unicode_cached(self):
181 """Test decoding a single revision id 1 million times."""
182 self.time(self.decode_cached_1M, _unicode_revision_id_utf8)
183
184 def test_decode_1k_by_1k_ascii(self):
185 """Test decoding 5 revisions 100k times"""
186 revisions = [osutils.rand_chars(60) for x in xrange(1000)]
187 self.time(self.decode_multi, revisions, 1000)
188
189 def test_decode_1k_by_1k_ascii_cached(self):
190 """Test decoding 5 revisions 100k times"""
191 revisions = [osutils.rand_chars(60) for x in xrange(1000)]
192 self.time(self.decode_cached_multi, revisions, 1000)
193
194 def test_decode_1k_by_1k_unicode(self):
195 """Test decoding 5 revisions 100k times"""
196 revisions = [(u'\u062c\u0648\u062c\u0648' +
197 unicode(osutils.rand_chars(60))).encode('utf8')
198 for x in xrange(1000)]
199 self.time(self.decode_multi, revisions, 1000)
200
201 def test_decode_1k_by_1k_unicode_cached(self):
202 """Test decoding 5 revisions 100k times"""
203 revisions = [(u'\u062c\u0648\u062c\u0648' +
204 unicode(osutils.rand_chars(60))).encode('utf8')
205 for x in xrange(1000)]
206 self.time(self.decode_cached_multi, revisions, 1000)
207
208 def test_decode_500K_by_1_ascii(self):
209 revisions = [("test%07d" % x) for x in xrange(500000)]
210 self.time(self.decode_multi, revisions, 1)
211
212 def test_decode_500K_by_1_ascii_cached(self):
213 revisions = [("test%07d" % x) for x in xrange(500000)]
214 self.time(self.decode_cached_multi, revisions, 1)
215
216 def test_decode_500K_by_1_unicode(self):
217 revisions = [(u'\u062c\u0648\u062c\u0648' +
218 unicode("%07d" % x)).encode('utf-8')
219 for x in xrange(500000)]
220 self.time(self.decode_multi, revisions, 1)
221
222 def test_decode_500K_by_1_unicode_cached(self):
223 revisions = [(u'\u062c\u0648\u062c\u0648' +
224 unicode("%07d" % x)).encode('utf-8')
225 for x in xrange(500000)]
226 self.time(self.decode_cached_multi, revisions, 1)
2270
=== removed file 'bzrlib/benchmarks/bench_checkout.py'
--- bzrlib/benchmarks/bench_checkout.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_checkout.py 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr tree building (checkout) performance."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class CheckoutBenchmark(Benchmark):
24 """Benchmarks for ``'bzr checkout'`` performance."""
25
26 def test_build_kernel_like_tree(self):
27 """Checkout of a clean kernel sized tree should be (<10secs)."""
28 self.make_kernel_like_committed_tree(link_bzr=True)
29 self.time(self.run_bzr, ['checkout', '--lightweight', '.', 'acheckout'])
300
=== renamed file 'bzrlib/benchmarks/bench_commit.py' => 'bzrlib/benchmarks/bench_commit.py.THIS'
=== renamed file 'bzrlib/benchmarks/bench_dirstate.py' => 'bzrlib/benchmarks/bench_dirstate.py.THIS'
=== removed file 'bzrlib/benchmarks/bench_info.py'
--- bzrlib/benchmarks/bench_info.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_info.py 1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr info performance."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class InfoBenchmark(Benchmark):
24 """This is a stub. Use this benchmark with a network transport.
25 Currently "bzr info sftp://..." takes > 4 min"""
26
27 def test_no_ignored_unknown_kernel_like_tree(self):
28 """Info in a kernel sized tree with no ignored or unknowns. """
29 self.make_kernel_like_added_tree()
30 self.time(self.run_bzr, 'info')
31
32 def test_no_changes_known_kernel_like_tree(self):
33 """Info in a kernel sized tree with no ignored, unknowns, or added."""
34 self.make_kernel_like_committed_tree()
35 self.time(self.run_bzr, 'info')
36
37
380
=== removed file 'bzrlib/benchmarks/bench_inventory.py'
--- bzrlib/benchmarks/bench_inventory.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_inventory.py 1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for `bzrlib.inventory.Inventory` performance."""
18
19
20import bzrlib.inventory
21from bzrlib.benchmarks import Benchmark
22
23
24class InvBenchmark(Benchmark):
25 """Benchmarks for building large inventories."""
26
27 def test_make_10824_inv_entries(self):
28 """Making 10824 inv entries should be quick."""
29 entries = []
30 def make_10824_entries():
31 for counter in xrange(10000):
32 bzrlib.inventory.make_entry('file', 'foo',
33 "a_parent_id")
34 for counter in xrange(824):
35 bzrlib.inventory.make_entry('directory', 'foo',
36 "a_parent_id")
37 # on roberts machine: this originally took: 533ms/ 600ms
38 # fixing slots to be vaguely accurate : 365ms/ 419ms
39 self.time(make_10824_entries)
400
=== renamed file 'bzrlib/benchmarks/bench_knit.py' => 'bzrlib/benchmarks/bench_knit.py.THIS'
=== removed file 'bzrlib/benchmarks/bench_log.py'
--- bzrlib/benchmarks/bench_log.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_log.py 1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for tree transform performance"""
18
19import os
20import sys
21
22from bzrlib.benchmarks import Benchmark
23from bzrlib.log import log_formatter, show_log
24from bzrlib.osutils import pathjoin
25from cStringIO import StringIO
26from bzrlib.transform import TreeTransform
27from bzrlib.workingtree import WorkingTree
28
29
30class LinesDone(Exception):
31 """Raised when `LineConsumer` reaches the required number of lines."""
32 pass
33
34
35class LineConsumer(object):
36 """Count lines that are produced.
37
38 When the required number of lines have been reached, raise `LinesDone`.
39 """
40
41 def __init__(self, required_lines):
42 """Create a new consumer.
43
44 :param required_lines: How many lines must be produced.
45 :type required_lines: integer
46 """
47 self.required_lines = required_lines
48
49 def write(self, text):
50 """Write some text to the black hole.
51
52 But count how many lines have been written.
53
54 :param text: A string that would be written.
55 :raise LinesDone: when the required number of lines has been reached.
56 :return: None
57 """
58 self.required_lines -= text.count('\n')
59 if self.required_lines < 0:
60 raise LinesDone()
61
62
63class LogBenchmark(Benchmark):
64 """Benchmarks for ``'bzr log'`` performance."""
65
66 def test_log(self):
67 """Run log in a many-commit tree."""
68 tree = self.make_many_commit_tree(hardlink=True)
69 lf = log_formatter('long', to_file=StringIO())
70 self.time(show_log, tree.branch, lf, direction='reverse')
71
72 def test_merge_log(self):
73 """Run log in a tree with many merges"""
74 tree = self.make_heavily_merged_tree(hardlink=True)
75 lf = log_formatter('short', to_file=StringIO())
76 self.time(show_log, tree.branch, lf, direction='reverse')
77
78 def test_log_screenful(self):
79 """Simulate log --long|less"""
80 self.screenful_tester('long')
81
82 def test_log_screenful_line(self):
83 """Simulate log --line|less"""
84 self.screenful_tester('line')
85
86 def test_log_screenful_short(self):
87 """Simulate log --short|less"""
88 self.screenful_tester('short')
89
90 def screenful_tester(self, formatter):
91 """Run show_log, but stop after 25 lines are generated"""
92 tree = self.make_many_commit_tree(hardlink=True)
93 def log_screenful():
94 lf = log_formatter(formatter, to_file=LineConsumer(25))
95 try:
96 show_log(tree.branch, lf, direction='reverse')
97 except LinesDone:
98 pass
99 else:
100 raise Exception, "LinesDone not raised"
101 self.time(log_screenful)
102
103 def test_cmd_log(self):
104 """Test execution of the log command."""
105 tree = self.make_many_commit_tree(hardlink=True)
106 self.time(self.run_bzr, ['log', '-r', '-4..'])
107
108 def test_cmd_log_subprocess(self):
109 """Text startup and execution of the log command."""
110 tree = self.make_many_commit_tree(hardlink=True)
111 self.time(self.run_bzr_subprocess, 'log', '-r', '-4..')
112
113 def test_log_verbose(self):
114 """'verbose' log -- shows file changes"""
115 tree = self.make_many_commit_tree(hardlink=True)
116 lf = log_formatter('long', to_file=StringIO())
117 self.time(show_log, tree.branch, lf, direction='reverse', verbose=True)
1180
=== removed file 'bzrlib/benchmarks/bench_osutils.py'
--- bzrlib/benchmarks/bench_osutils.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_osutils.py 1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr osutils functions performance."""
18
19
20from bzrlib.benchmarks import Benchmark
21import bzrlib.osutils as osutils
22
23
24class WalkDirsBenchmark(Benchmark):
25 """Benchmarks for `bzrlib.osutils.walkdirs`"""
26
27 def test_walkdirs_kernel_like_tree(self):
28 """Walking a kernel sized tree is fast!(150ms)."""
29 self.make_kernel_like_tree(link_working=True)
30 # on roberts machine: this originally took: 157ms/4177ms
31 # plain os.walk takes 213ms on this tree
32 # with the pyrex readdir module: 77ms/5423ms
33 def dowalk():
34 for dirblock in osutils.walkdirs('.'):
35 if dirblock[0][1] == '.bzr':
36 del dirblock[0]
37 self.time(dowalk)
380
=== removed file 'bzrlib/benchmarks/bench_pack.py'
--- bzrlib/benchmarks/bench_pack.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_pack.py 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
1# Copyright (C) 2007 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Benchmarks for pack performance"""
18
19import os
20
21from bzrlib import (
22 pack,
23 )
24from bzrlib.benchmarks import Benchmark
25
26
27class BenchPack(Benchmark):
28 """Benchmark pack performance."""
29
30 def test_insert_one_gig_1k_chunks_no_names_disk(self):
31 # test real disk writing of many small chunks.
32 # useful for testing whether buffer sizes are right
33 transport = self.get_transport()
34 stream = transport.open_write_stream('pack.pack')
35 writer = pack.ContainerWriter(stream.write)
36 self.write_1_gig(writer)
37 stream.close()
38
39 def test_insert_one_gig_1k_chunks_no_names_null(self):
40 # write to dev/null so we test the pack processing.
41 transport = self.get_transport()
42 dev_null = open('/dev/null', 'wb')
43 writer = pack.ContainerWriter(dev_null.write)
44 self.write_1_gig(writer)
45 dev_null.close()
46
47 def write_1_gig(self, writer):
48 one_k = "A" * 1024
49 writer.begin()
50 def write_1g():
51 for hunk in xrange(1024 * 1024):
52 writer.add_bytes_record(one_k, [])
53 self.time(write_1g)
54 writer.end()
550
=== removed file 'bzrlib/benchmarks/bench_rocks.py'
--- bzrlib/benchmarks/bench_rocks.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_rocks.py 1970-01-01 00:00:00 +0000
@@ -1,28 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Benchmarks of bzr rocks."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class RocksBenchmark(Benchmark):
24 """Benchmarks for ``'bzr rocks'``"""
25
26 def test_rocks(self):
27 """Test the startup overhead by running a do-nothing command"""
28 self.time(self.run_bzr_subprocess, 'rocks')
290
=== removed file 'bzrlib/benchmarks/bench_sftp.py'
--- bzrlib/benchmarks/bench_sftp.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_sftp.py 1970-01-01 00:00:00 +0000
@@ -1,101 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr performance over SFTP"""
18
19import os
20
21from bzrlib import (
22 bzrdir,
23 )
24from bzrlib.benchmarks import Benchmark
25from bzrlib.tests import test_sftp_transport, TestSkipped
26
27try:
28 import paramiko
29 paramiko_loaded = True
30except ImportError:
31 paramiko_loaded = False
32
33
34class SFTPBenchmark(Benchmark):
35 """Benchmark branch, push and pull across a local sftp connection."""
36
37 def setUp(self):
38 super(SFTPBenchmark, self).setUp()
39 if not paramiko_loaded:
40 raise TestSkipped('you must have paramiko to run this test')
41 test_sftp_transport.set_test_transport_to_sftp(self)
42
43 def test_branch(self):
44 os.mkdir("a")
45 tree, files = self.create_with_commits(100, 100, "a")
46 self.time(bzrdir.BzrDir.open(self.get_url('a')).sprout, "b")
47
48 def create_commit_and_pull(self, num_pull_revisions):
49 os.mkdir("a")
50 tree, files = self.create_with_commits(100, 100, "a")
51 rbzrdir = bzrdir.BzrDir.open(self.get_url('a'))
52 b2 = tree.bzrdir.sprout("b") # branch
53 # change a few files and commit
54 self.commit_some_revisions(tree, files, num_pull_revisions, 20)
55 self.time(b2.open_branch().pull, rbzrdir.open_branch())
56
57 def test_pull_1(self):
58 self.create_commit_and_pull(1)
59
60 def test_pull_10(self):
61 self.create_commit_and_pull(10)
62
63 def test_pull_100(self):
64 self.create_commit_and_pull(100)
65
66 def create_commit_and_push(self, num_push_revisions):
67 os.mkdir("a")
68 tree, files = self.create_with_commits(100, 100, "a")
69 rbzrdir = bzrdir.BzrDir.open(self.get_url('a'))
70 b2 = tree.bzrdir.sprout("b") # branch
71 wtree = b2.open_workingtree()
72 # change a few files and commit
73 self.commit_some_revisions(
74 wtree, ["b/%i" for i in range(100)],
75 num_commits=num_push_revisions,
76 changes_per_commit=20)
77 self.time(rbzrdir.open_branch().pull, wtree.branch)
78
79 def test_initial_push(self):
80 os.mkdir('a')
81 tree, files = self.create_with_commits(100, 100, "a")
82 self.time(tree.bzrdir.clone, self.get_url('b'),
83 revision_id=tree.last_revision())
84
85 def test_push_1(self):
86 self.create_commit_and_push(1)
87
88 def test_push_10(self):
89 self.create_commit_and_push(10)
90
91 def test_push_100(self):
92 self.create_commit_and_push(100)
93
94
95class SFTPSlowSocketBenchmark(SFTPBenchmark):
96 """Benchmarks of SFTP performance with a 30ms delay per roundtrip."""
97
98 def setUp(self):
99 super(SFTPSlowSocketBenchmark, self).setUp()
100 self.get_server().add_latency = 0.03
101
1020
=== removed file 'bzrlib/benchmarks/bench_startup.py'
--- bzrlib/benchmarks/bench_startup.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_startup.py 1970-01-01 00:00:00 +0000
@@ -1,91 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Benchmarks of bzr startup time, for some simple operations."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class StartupBenchmark(Benchmark):
24 """Benchmark startup costs for certain bzr commands."""
25
26 def make_simple_tree(self):
27 """A small, simple tree. No caching needed"""
28 tree = self.make_branch_and_tree('.')
29 self.build_tree(['a', 'b/', 'b/c'])
30 tree.add(['a', 'b', 'b/c'])
31 return tree
32
33 def make_simple_committed_tree(self):
34 tree = self.make_simple_tree()
35 tree.commit('simple commit')
36 return tree
37
38 def test___version(self):
39 """Test the startup overhead of plain bzr --version"""
40 self.time(self.run_bzr_subprocess, '--version')
41
42 def test_branch(self):
43 """Test the time to branch this into other"""
44 tree = self.make_simple_committed_tree()
45 self.time(self.run_bzr_subprocess, 'branch', '.', 'other')
46
47 def test_commit(self):
48 """Test execution of simple commit"""
49 tree = self.make_simple_tree()
50 self.time(self.run_bzr_subprocess, 'commit', '-m', 'init simple tree')
51
52 def test_diff(self):
53 """Test simple diff time"""
54 tree = self.make_simple_committed_tree()
55 self.time(self.run_bzr_subprocess, 'diff')
56
57 def test_help(self):
58 """Test the startup overhead of plain bzr help"""
59 self.time(self.run_bzr_subprocess, 'help')
60
61 def test_help_commands(self):
62 """startup time for bzr help commands, which has to load more"""
63 self.time(self.run_bzr_subprocess, 'help', 'commands')
64
65 def test_log(self):
66 """Test simple log time"""
67 tree = self.make_simple_committed_tree()
68 self.time(self.run_bzr_subprocess, 'log')
69
70 def test_missing(self):
71 """Test simple missing time"""
72 tree = self.make_simple_committed_tree()
73 other = tree.bzrdir.sprout('other')
74 self.time(self.run_bzr_subprocess, 'missing', working_dir='other')
75
76 def test_pull(self):
77 """Test simple pull time"""
78 tree = self.make_simple_committed_tree()
79 other = tree.bzrdir.sprout('other')
80 # There should be nothing to pull, and this should be determined
81 # quickly
82 self.time(self.run_bzr_subprocess, 'pull', working_dir='other')
83
84 def test_rocks(self):
85 """Test the startup overhead by running a do-nothing command"""
86 self.time(self.run_bzr_subprocess, 'rocks')
87
88 def test_status(self):
89 """Test simple status time"""
90 tree = self.make_simple_committed_tree()
91 self.time(self.run_bzr_subprocess, 'status')
920
=== removed file 'bzrlib/benchmarks/bench_status.py'
--- bzrlib/benchmarks/bench_status.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_status.py 1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
1# Copyright (C) 2006, 2007 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr status performance."""
18
19
20from bzrlib.benchmarks import Benchmark
21
22
23class StatusBenchmark(Benchmark):
24 """Benchmarks for ``'bzr status'``."""
25
26 def test_no_ignored_unknown_kernel_like_tree(self):
27 """Status in a kernel sized tree with no ignored or unknowns.
28
29 This should be bearable (<2secs) fast.
30 """
31 self.make_kernel_like_added_tree()
32 # on robertc's machine the first sample of this took 1687ms/15994ms
33 self.time(self.run_bzr, 'status')
34
35 def test_no_changes_known_kernel_like_tree(self):
36 """Status in a kernel sized tree with no ignored, unknowns, or added."""
37 self.make_kernel_like_committed_tree(link_bzr=True)
38 self.time(self.run_bzr, 'status')
39
40 def test_single_file_no_changes_known_kernel_like_tree(self):
41 """Status in a kernel sized tree with no ignored, unknowns, or added
42 of a single file."""
43 self.make_kernel_like_committed_tree()
44 #XXX depends on the filenames generated by make_kernel_like_tree
45 self.time(self.run_bzr, ['status', '7/4/0/16'])
46
47 def test_status_one_added_file_kernel_like_tree(self):
48 """Status of a single added file in our stock large tree."""
49 self.make_kernel_like_tree()
50 self.run_bzr('add')
51 self.run_bzr(['commit', '-m', 'initial import'])
52 self.time(self.run_bzr, ['status', '3/3/3/10'])
530
=== removed file 'bzrlib/benchmarks/bench_tags.py'
--- bzrlib/benchmarks/bench_tags.py 2009-05-27 08:33:37 +0000
+++ bzrlib/benchmarks/bench_tags.py 1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
1# Copyright (C) 2007 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Test for tags serialization (indirect testing for bencode)"""
18
19
20import time
21
22from bzrlib.benchmarks import Benchmark
23import bzrlib.bencode
24import bzrlib.tag
25
26
27class TagsBencodeBenchmark(Benchmark):
28 """Benchmark for serialization/deserialization of tags"""
29
30 def setUp(self):
31 super(TagsBencodeBenchmark, self).setUp()
32 self.tobj = bzrlib.tag.BasicTags(None)
33 tags = {}
34 revid = 'j.random@example.com-20070812132500-%016d'
35 for i in xrange(100):
36 tags[str(i)] = revid % i
37 self.tags = tags
38 self.bencoded_tags = bzrlib.bencode.bencode(tags)
39
40 def time_N(self, N, kallable, *args, **kwargs):
41 def _func(N, kallable, *args, **kwargs):
42 for i in xrange(N):
43 kallable(*args, **kwargs)
44 self.time(_func, N, kallable, *args, **kwargs)
45
46 def test_serialize_empty_tags(self):
47 # Measure overhead of operation
48 self.time_N(10000, self.tobj._serialize_tag_dict, {})
49
50 def test_deserialize_empty_tags(self):
51 # Measure overhead of operation
52 self.time_N(10000, self.tobj._deserialize_tag_dict, 'de')
53
54 def test_serialize_tags(self):
55 self.time_N(1000, self.tobj._serialize_tag_dict, self.tags)
56
57 def test_deserialize_tags(self):
58 self.time_N(1000, self.tobj._deserialize_tag_dict, self.bencoded_tags)
590
=== removed file 'bzrlib/benchmarks/bench_transform.py'
--- bzrlib/benchmarks/bench_transform.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_transform.py 1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for tree transform performance"""
18
19import os
20
21from bzrlib.benchmarks import Benchmark
22from bzrlib.osutils import pathjoin
23from bzrlib.transform import TreeTransform
24from bzrlib.workingtree import WorkingTree
25
26
27class TransformBenchmark(Benchmark):
28 """Benchmarks for `bzrlib.transform`"""
29
30 def test_canonicalize_path(self):
31 """Canonicalizing paths should be fast."""
32 wt = self.make_kernel_like_tree(link_working=True)
33 paths = []
34 for dirpath, dirnames, filenames in os.walk('.'):
35 paths.extend(pathjoin(dirpath, d) for d in dirnames)
36 paths.extend(pathjoin(dirpath, f) for f in filenames)
37 tt = TreeTransform(wt)
38 self.time(self.canonicalize_paths, tt, paths)
39 tt.finalize()
40
41 def canonicalize_paths(self, tt, paths):
42 for path in paths:
43 tt.canonical_path(path)
440
=== removed file 'bzrlib/benchmarks/bench_workingtree.py'
--- bzrlib/benchmarks/bench_workingtree.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_workingtree.py 1970-01-01 00:00:00 +0000
@@ -1,111 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr working tree performance."""
18
19import os
20
21from bzrlib import ignores
22from bzrlib.benchmarks import Benchmark
23from bzrlib.workingtree import WorkingTree
24
25
26class WorkingTreeBenchmark(Benchmark):
27 """Benchmarks for `bzrlib.workingtree` performance."""
28
29 def test_list_files_kernel_like_tree(self):
30 tree = self.make_kernel_like_added_tree()
31 tree.lock_read()
32 try:
33 self.time(list, tree.list_files())
34 finally:
35 tree.unlock()
36
37 def test_list_files_unknown_kernel_like_tree(self):
38 tree = self.make_kernel_like_tree(link_working=True)
39 tree = WorkingTree.open('.')
40 # Bzr only traverses directories if they are versioned
41 # So add all the directories, but not the files, yielding
42 # lots of unknown files.
43 for root, dirs, files in os.walk('.'):
44 if '.bzr' in dirs:
45 dirs.remove('.bzr')
46 if root == '.':
47 continue
48 tree.add(root)
49 tree.lock_read()
50 try:
51 self.time(list, tree.list_files())
52 finally:
53 tree.unlock()
54
55 def test_is_ignored_single_call(self):
56 """How long does is_ignored take to initialise and check one file."""
57 t = self.make_branch_and_tree('.')
58 self.time(t.is_ignored, "CVS")
59
60 def test_is_ignored_10824_calls(self):
61 """How long does is_ignored take to initialise and check one file."""
62 t = self.make_branch_and_tree('.')
63 def call_is_ignored_10824_not_ignored():
64 for x in xrange(10824):
65 t.is_ignored(str(x))
66 self.time(call_is_ignored_10824_not_ignored)
67
68 def test_is_ignored_10_patterns(self):
69 t = self.make_branch_and_tree('.')
70 ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 9)])
71 ignores.add_runtime_ignores(['./foo', 'foo/bar'])
72 self.time(t.is_ignored,'bar')
73 ignores._runtime_ignores = set()
74
75 def test_is_ignored_50_patterns(self):
76 t = self.make_branch_and_tree('.')
77 ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 49)])
78 ignores.add_runtime_ignores(['./foo', 'foo/bar'])
79 self.time(t.is_ignored,'bar')
80 ignores._runtime_ignores = set()
81
82 def test_is_ignored_100_patterns(self):
83 t = self.make_branch_and_tree('.')
84 ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 99)])
85 ignores.add_runtime_ignores(['./foo', 'foo/bar'])
86 self.time(t.is_ignored,'bar')
87 ignores._runtime_ignores = set()
88
89 def test_is_ignored_1000_patterns(self):
90 t = self.make_branch_and_tree('.')
91 ignores.add_runtime_ignores([u'*.%i' % i for i in range(1, 999)])
92 ignores.add_runtime_ignores(['./foo', 'foo/bar'])
93 self.time(t.is_ignored,'bar')
94 ignores._runtime_ignores = set()
95
96 def test_walkdirs_kernel_like_tree(self):
97 """Walking a kernel sized tree is fast!(150ms)."""
98 self.make_kernel_like_tree()
99 self.run_bzr('add')
100 tree = WorkingTree.open('.')
101 # on roberts machine: this originally took: 157ms/4177ms
102 # plain os.walk takes 213ms on this tree
103 self.time(list, tree.walkdirs())
104
105 def test_walkdirs_kernel_like_tree_unknown(self):
106 """Walking a kernel sized tree is fast!(150ms)."""
107 self.make_kernel_like_tree()
108 tree = WorkingTree.open('.')
109 # on roberts machine: this originally took: 157ms/4177ms
110 # plain os.walk takes 213ms on this tree
111 self.time(list, tree.walkdirs())
1120
=== removed file 'bzrlib/benchmarks/bench_xml.py'
--- bzrlib/benchmarks/bench_xml.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/bench_xml.py 1970-01-01 00:00:00 +0000
@@ -1,87 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tests for bzr xml serialization performance."""
18
19from bzrlib import (
20 cache_utf8,
21 xml5,
22 )
23from bzrlib.benchmarks import Benchmark
24
25
26class BenchXMLSerializer(Benchmark):
27 """Benchmarks for serializing to/from XML."""
28
29 def test_write_to_string_kernel_like_inventory(self):
30 # On jam's machine, ElementTree serializer took: 2161ms/13487ms
31 # with Robert's serializer: 631ms/10770ms
32 # with Entity escaper: 487ms/11636ms
33 # caching Entity escaper, empty cache: 448ms/ 9489ms
34 # caching Entity escaper, full cache: 375ms/ 9489ms
35 # passing around function: 406ms/ 8942ms
36 # cached, passing around function: 328ms/11248ms
37 # removing extra function: 354ms/ 8942ms
38 # cached, removing extra function: 275ms/11248ms
39 # no cache, real utf8: 363ms/11697ms
40 # cached, real utf8: 272ms/12827ms
41 # Really all we want is a real inventory
42 inv = self.make_kernel_like_inventory()
43
44 xml5._clear_cache()
45 # We want a real tree with lots of file ids and sha strings, etc.
46 self.time(xml5.serializer_v5.write_inventory_to_string, inv)
47
48 def test_write_kernel_like_inventory(self):
49 # Really all we want is a real inventory
50 inv = self.make_kernel_like_inventory()
51
52 xml5._clear_cache()
53 f = open('kernel-like-inventory', 'wb')
54 try:
55 # We want a real tree with lots of file ids and sha strings, etc.
56 self.time(xml5.serializer_v5.write_inventory, inv, f)
57 finally:
58 f.close()
59
60 def test_write_to_string_cached_kernel_like_inventory(self):
61 inv = self.make_kernel_like_inventory()
62
63 xml5._clear_cache()
64 # We want a real tree with lots of file ids and sha strings, etc.
65 xml5.serializer_v5.write_inventory_to_string(inv)
66
67 self.time(xml5.serializer_v5.write_inventory_to_string, inv)
68
69 def test_read_from_string_kernel_like_inventory(self):
70 inv = self.make_kernel_like_inventory()
71 as_str = xml5.serializer_v5.write_inventory_to_string(inv)
72
73 cache_utf8.clear_encoding_cache()
74 read_inv = self.time(xml5.serializer_v5.read_inventory_from_string,
75 as_str)
76 # TODO: make sure the final inventory is equal as a sanity check
77
78 def test_read_from_string_cached_kernel_like_inventory(self):
79 cache_utf8.clear_encoding_cache()
80 inv = self.make_kernel_like_inventory()
81 as_str = xml5.serializer_v5.write_inventory_to_string(inv)
82
83 xml5.serializer_v5.read_inventory_from_string(as_str)
84
85 read_inv = self.time(xml5.serializer_v5.read_inventory_from_string,
86 as_str)
87 # TODO: make sure the final inventory is equal as a sanity check
880
=== removed file 'bzrlib/benchmarks/tree_creator/__init__.py'
--- bzrlib/benchmarks/tree_creator/__init__.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/tree_creator/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,175 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Base implementation of TreeCreator classes
18
19These are classes that are used to easily create test trees.
20"""
21
22import os
23import shutil
24
25from bzrlib import (
26 osutils,
27 workingtree,
28 )
29
30
31class TreeCreator(object):
32 """Just a basic class which is used to create various test trees"""
33
34 CACHE_ROOT = None
35
36 def __init__(self, test, tree_name,
37 link_bzr=False,
38 link_working=False,
39 hot_cache=True):
40 """Instantiate a new creator object, supply the id of the tree
41
42 :param test: A TestCaseWithTransport object (most creators need
43 we need the build_tree functionality)
44 """
45
46 self._cache_root = TreeCreator.CACHE_ROOT
47 self._test = test
48 self._tree_name = tree_name
49 self._link_bzr = link_bzr
50 self._link_working = link_working
51 self._hot_cache = hot_cache
52 if not osutils.hardlinks_good():
53 self._link_working = self._link_bzr = False
54
55 def is_caching_enabled(self):
56 """Will we try to cache the tree we create?"""
57 return self._cache_root is not None
58
59 def is_cached(self):
60 """Is this tree already cached?"""
61 cache_dir = self._get_cache_dir()
62 if cache_dir is None:
63 return False
64 return os.path.exists(cache_dir)
65
66 def disable_cache(self):
67 """Do not use the cache"""
68 self._cache_root = None
69
70 def ensure_cached(self):
71 """If caching, make sure the cached copy exists"""
72 cache_dir = self._get_cache_dir()
73 if cache_dir is None:
74 return
75
76 if not self.is_cached():
77 self._create_tree(root=cache_dir, in_cache=True)
78
79 def create(self, root):
80 """Create a new tree at 'root'.
81
82 :return: A WorkingTree object.
83 """
84 cache_dir = self._get_cache_dir()
85 if cache_dir is None:
86 # Not caching
87 return self._create_tree(root, in_cache=False)
88
89 self.ensure_cached()
90
91 return self._clone_cached_tree(root)
92
93 def _get_cache_dir(self):
94 """Get the directory to use for caching this tree
95
96 :return: The path to use for caching. If None, caching is disabled
97 """
98 if self._cache_root is None:
99 return None
100 return osutils.pathjoin(self._cache_root, self._tree_name)
101
102 def _create_tree(self, root, in_cache=False):
103 """Create the desired tree in the given location.
104
105 Children should override this function to provide the actual creation
106 of the desired tree. This will be called by 'create()'. If it is
107 building a tree in the cache, before copying it to the real target,
108 it will pass in_cache=True
109 """
110 raise NotImplemented(self._create_tree)
111
112 def _clone_cached_tree(self, dest):
113 """Copy the contents of the cached dir into the destination
114 Optionally hardlink certain pieces of the tree.
115
116 This is just meant as a helper function for child classes
117
118 :param dest: The destination to copy things to
119 """
120 # We use shutil.copyfile so that we don't copy permissions
121 # because most of our source trees are marked readonly to
122 # prevent modifying in the case of hardlinks
123 handlers = {'file':shutil.copyfile}
124 if osutils.hardlinks_good():
125 if self._link_working:
126 if self._link_bzr:
127 handlers = {'file':os.link}
128 else:
129 # Don't hardlink files inside bzr
130 def file_handler(source, dest):
131 if '.bzr/' in source:
132 shutil.copyfile(source, dest)
133 else:
134 os.link(source, dest)
135 handlers = {'file':file_handler}
136 elif self._link_bzr:
137 # Only link files inside .bzr/
138 def file_handler(source, dest):
139 if '.bzr/' in source:
140 os.link(source, dest)
141 else:
142 shutil.copyfile(source, dest)
143 handlers = {'file':file_handler}
144
145 source = self._get_cache_dir()
146 osutils.copy_tree(source, dest, handlers=handlers)
147 tree = workingtree.WorkingTree.open(dest)
148 if self._hot_cache:
149 tree.lock_write()
150 try:
151 # tree._hashcache.scan() just checks and removes
152 # entries that are out of date
153 # we need to actually store new ones
154 for path, ie in tree.inventory.iter_entries_by_dir():
155 tree.get_file_sha1(ie.file_id, path)
156 finally:
157 tree.unlock()
158 # If we didn't iterate the tree, the hash cache is technically
159 # invalid, and it would be better to remove it, but there is
160 # no public api for that.
161 return tree
162
163 def _protect_files(self, root):
164 """Chmod all files underneath 'root' to prevent writing
165
166 This is a helper function for child classes.
167
168 :param root: The base directory to modify
169 """
170 for dirinfo, entries in osutils.walkdirs(root):
171 for relpath, name, kind, st, abspath in entries:
172 if kind == 'file':
173 os.chmod(abspath, 0440)
174
175
1760
=== removed file 'bzrlib/benchmarks/tree_creator/heavily_merged.py'
--- bzrlib/benchmarks/tree_creator/heavily_merged.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/tree_creator/heavily_merged.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tree creator for many commits, but no changes"""
18
19import errno
20import os
21
22from bzrlib import (
23 bzrdir,
24 )
25
26from bzrlib.benchmarks.tree_creator import TreeCreator
27
28
29class HeavilyMergedTreeCreator(TreeCreator):
30 """Create a tree in which almost every commit is a merge.
31
32 No file changes are included. This produces two trees,
33 one of which is returned. Except for the first commit, every
34 commit in its revision-history is a merge of another commit in the other
35 tree.
36 Not hardlinking the working tree, because there are no working tree files.
37 """
38
39 def __init__(self, test, link_bzr=True):
40 super(HeavilyMergedTreeCreator, self).__init__(test,
41 tree_name='heavily_merged_tree',
42 link_bzr=link_bzr,
43 link_working=False,
44 hot_cache=True)
45
46 def _create_tree(self, root, in_cache=False):
47 try:
48 os.mkdir(root)
49 except (IOError, OSError), e:
50 if e.errno not in (errno.EEXIST,):
51 raise
52
53 tree = bzrdir.BzrDir.create_standalone_workingtree(root)
54 tree.lock_write()
55 try:
56 tree2 = tree.bzrdir.sprout(root + '/tree2').open_workingtree()
57 tree2.lock_write()
58 try:
59 for i in xrange(250):
60 revision_id = tree.commit('no-changes commit %d-a' % i)
61 tree2.branch.fetch(tree.branch, revision_id)
62 tree2.add_parent_tree_id(revision_id)
63 revision_id = tree2.commit('no-changes commit %d-b' % i)
64 tree.branch.fetch(tree2.branch, revision_id)
65 tree.add_parent_tree_id(revision_id)
66 tree.set_parent_ids(tree.get_parent_ids()[:1])
67 finally:
68 tree2.unlock()
69 finally:
70 tree.unlock()
71 if in_cache:
72 self._protect_files(root+'/.bzr')
73 return tree
74
75
760
=== renamed file 'bzrlib/benchmarks/tree_creator/kernel_like.py' => 'bzrlib/benchmarks/tree_creator/kernel_like.py.THIS'
=== removed file 'bzrlib/benchmarks/tree_creator/many_commit.py'
--- bzrlib/benchmarks/tree_creator/many_commit.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/tree_creator/many_commit.py 1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tree creator for many commits, including file changes."""
18
19from bzrlib import (
20 bzrdir,
21 )
22
23from bzrlib.benchmarks.tree_creator import TreeCreator
24
25
26class ManyCommitTreeCreator(TreeCreator):
27 """Create an tree many files and many commits."""
28
29 def __init__(self, test, link_bzr=False, num_files=10, num_commits=10):
30 tree_name = 'many_files_many_commit_tree_%d_%d' % (
31 num_files, num_commits)
32 super(ManyCommitTreeCreator, self).__init__(test,
33 tree_name=tree_name,
34 link_bzr=link_bzr,
35 link_working=False,
36 hot_cache=True)
37 self.files = ["%s" % (i, ) for i in range(num_files)]
38 self.num_files = num_files
39 self.num_commits = num_commits
40
41 def _create_tree(self, root, in_cache=False):
42 num_files = self.num_files
43 num_commits = self.num_commits
44 files = ["%s/%s" % (root, fn) for fn in self.files]
45 for fn in files:
46 f = open(fn, "wb")
47 try:
48 f.write("some content\n")
49 finally:
50 f.close()
51 tree = bzrdir.BzrDir.create_standalone_workingtree(root)
52 tree.add(self.files)
53 tree.lock_write()
54 try:
55 tree.commit('initial commit')
56 for i in range(num_commits):
57 fn = files[i % len(files)]
58 content = range(i) + [i, i, i, ""]
59 f = open(fn, "wb")
60 try:
61 f.write("\n".join([str(i) for i in content]))
62 finally:
63 f.close()
64 tree.commit("changing file %s" % fn)
65 finally:
66 tree.unlock()
67 return tree
68
690
=== removed file 'bzrlib/benchmarks/tree_creator/simple_many_commit.py'
--- bzrlib/benchmarks/tree_creator/simple_many_commit.py 2009-03-23 14:59:43 +0000
+++ bzrlib/benchmarks/tree_creator/simple_many_commit.py 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
1# Copyright (C) 2006 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Tree creator for many commits, but no changes"""
18
19from bzrlib import (
20 bzrdir,
21 )
22
23from bzrlib.benchmarks.tree_creator import TreeCreator
24
25
26class SimpleManyCommitTreeCreator(TreeCreator):
27 """Create an empty tree with lots of commits"""
28
29 def __init__(self, test, link_bzr=False):
30 super(SimpleManyCommitTreeCreator, self).__init__(test,
31 tree_name='many_commit_tree',
32 link_bzr=link_bzr,
33 link_working=False,
34 hot_cache=True)
35
36 def _create_tree(self, root, in_cache=False):
37 tree = bzrdir.BzrDir.create_standalone_workingtree(root)
38 tree.lock_write()
39 try:
40 for i in xrange(1000):
41 tree.commit('no-changes commit %d' % i)
42 finally:
43 tree.unlock()
44 if in_cache:
45 self._protect_files(root+'/.bzr')
46
47 return tree
480
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py 2010-07-22 23:01:51 +0000
+++ bzrlib/branch.py 2010-07-29 06:48:01 +0000
@@ -246,9 +246,13 @@
246 if not local and not config.has_explicit_nickname():246 if not local and not config.has_explicit_nickname():
247 try:247 try:
248 master = self.get_master_branch(possible_transports)248 master = self.get_master_branch(possible_transports)
249 if master and self.user_url == master.user_url:
250 raise errors.RecursiveBind(self.user_url)
249 if master is not None:251 if master is not None:
250 # return the master branch value252 # return the master branch value
251 return master.nick253 return master.nick
254 except errors.RecursiveBind, e:
255 raise e
252 except errors.BzrError, e:256 except errors.BzrError, e:
253 # Silently fall back to local implicit nick if the master is257 # Silently fall back to local implicit nick if the master is
254 # unavailable258 # unavailable
255259
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py 2010-07-20 10:18:05 +0000
+++ bzrlib/builtins.py 2010-07-29 06:48:01 +0000
@@ -171,10 +171,60 @@
171171
172 :return: workingtree, [relative_paths]172 :return: workingtree, [relative_paths]
173 """173 """
174<<<<<<< TREE
174 return WorkingTree.open_containing_paths(175 return WorkingTree.open_containing_paths(
175 file_list, default_directory='.',176 file_list, default_directory='.',
176 canonicalize=True,177 canonicalize=True,
177 apply_view=True)178 apply_view=True)
179=======
180 if file_list is None or len(file_list) == 0:
181 tree = WorkingTree.open_containing(default_branch)[0]
182 if tree.supports_views() and apply_view:
183 view_files = tree.views.lookup_view()
184 if view_files:
185 file_list = view_files
186 view_str = views.view_display_str(view_files)
187 note("Ignoring files outside view. View is %s" % view_str)
188 return tree, file_list
189 tree = WorkingTree.open_containing(file_list[0])[0]
190 return tree, safe_relpath_files(tree, file_list, canonicalize,
191 apply_view=apply_view)
192
193
194def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
195 """Convert file_list into a list of relpaths in tree.
196
197 :param tree: A tree to operate on.
198 :param file_list: A list of user provided paths or None.
199 :param apply_view: if True and a view is set, apply it or check that
200 specified files are within it
201 :return: A list of relative paths.
202 :raises errors.PathNotChild: When a provided path is in a different tree
203 than tree.
204 """
205 if file_list is None:
206 return None
207 if tree.supports_views() and apply_view:
208 view_files = tree.views.lookup_view()
209 else:
210 view_files = []
211 new_list = []
212 # tree.relpath exists as a "thunk" to osutils, but canonical_relpath
213 # doesn't - fix that up here before we enter the loop.
214 if canonicalize:
215 fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
216 else:
217 fixer = tree.relpath
218 for filename in file_list:
219 try:
220 relpath = fixer(osutils.dereference_path(filename))
221 if view_files and not osutils.is_inside_any(view_files, relpath):
222 raise errors.FileOutsideView(filename, view_files)
223 new_list.append(relpath)
224 except errors.PathNotChild:
225 raise errors.FileInWrongBranch(tree.branch, filename)
226 return new_list
227>>>>>>> MERGE-SOURCE
178228
179229
180def _get_view_info_for_change_reporter(tree):230def _get_view_info_for_change_reporter(tree):
@@ -718,6 +768,7 @@
718 raise errors.BzrCommandError('invalid kind %r specified' % (kind,))768 raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
719769
720 revision = _get_one_revision('inventory', revision)770 revision = _get_one_revision('inventory', revision)
771<<<<<<< TREE
721 work_tree, file_list = WorkingTree.open_containing_paths(file_list)772 work_tree, file_list = WorkingTree.open_containing_paths(file_list)
722 self.add_cleanup(work_tree.lock_read().unlock)773 self.add_cleanup(work_tree.lock_read().unlock)
723 if revision is not None:774 if revision is not None:
@@ -740,6 +791,30 @@
740 entries = tree.inventory.entries()791 entries = tree.inventory.entries()
741792
742 self.cleanup_now()793 self.cleanup_now()
794=======
795 work_tree, file_list = tree_files(file_list)
796 self.add_cleanup(work_tree.lock_read().unlock)
797 if revision is not None:
798 tree = revision.as_tree(work_tree.branch)
799
800 extra_trees = [work_tree]
801 self.add_cleanup(tree.lock_read().unlock)
802 else:
803 tree = work_tree
804 extra_trees = []
805
806 if file_list is not None:
807 file_ids = tree.paths2ids(file_list, trees=extra_trees,
808 require_versioned=True)
809 # find_ids_across_trees may include some paths that don't
810 # exist in 'tree'.
811 entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
812 for file_id in file_ids if file_id in tree)
813 else:
814 entries = tree.inventory.entries()
815
816 self.cleanup_now()
817>>>>>>> MERGE-SOURCE
743 for path, entry in entries:818 for path, entry in entries:
744 if kind and kind != entry.kind:819 if kind and kind != entry.kind:
745 continue820 continue
@@ -789,9 +864,15 @@
789 names_list = []864 names_list = []
790 if len(names_list) < 2:865 if len(names_list) < 2:
791 raise errors.BzrCommandError("missing file argument")866 raise errors.BzrCommandError("missing file argument")
867<<<<<<< TREE
792 tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)868 tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
793 self.add_cleanup(tree.lock_tree_write().unlock)869 self.add_cleanup(tree.lock_tree_write().unlock)
794 self._run(tree, names_list, rel_names, after)870 self._run(tree, names_list, rel_names, after)
871=======
872 tree, rel_names = tree_files(names_list, canonicalize=False)
873 self.add_cleanup(tree.lock_tree_write().unlock)
874 self._run(tree, names_list, rel_names, after)
875>>>>>>> MERGE-SOURCE
795876
796 def run_auto(self, names_list, after, dry_run):877 def run_auto(self, names_list, after, dry_run):
797 if names_list is not None and len(names_list) > 1:878 if names_list is not None and len(names_list) > 1:
@@ -800,10 +881,16 @@
800 if after:881 if after:
801 raise errors.BzrCommandError('--after cannot be specified with'882 raise errors.BzrCommandError('--after cannot be specified with'
802 ' --auto.')883 ' --auto.')
884<<<<<<< TREE
803 work_tree, file_list = WorkingTree.open_containing_paths(885 work_tree, file_list = WorkingTree.open_containing_paths(
804 names_list, default_directory='.')886 names_list, default_directory='.')
805 self.add_cleanup(work_tree.lock_tree_write().unlock)887 self.add_cleanup(work_tree.lock_tree_write().unlock)
806 rename_map.RenameMap.guess_renames(work_tree, dry_run)888 rename_map.RenameMap.guess_renames(work_tree, dry_run)
889=======
890 work_tree, file_list = tree_files(names_list, default_branch='.')
891 self.add_cleanup(work_tree.lock_tree_write().unlock)
892 rename_map.RenameMap.guess_renames(work_tree, dry_run)
893>>>>>>> MERGE-SOURCE
807894
808 def _run(self, tree, names_list, rel_names, after):895 def _run(self, tree, names_list, rel_names, after):
809 into_existing = osutils.isdir(names_list[-1])896 into_existing = osutils.isdir(names_list[-1])
@@ -1162,12 +1249,17 @@
11621249
1163 def run(self, from_location, to_location=None, revision=None,1250 def run(self, from_location, to_location=None, revision=None,
1164 hardlink=False, stacked=False, standalone=False, no_tree=False,1251 hardlink=False, stacked=False, standalone=False, no_tree=False,
1252<<<<<<< TREE
1165 use_existing_dir=False, switch=False, bind=False,1253 use_existing_dir=False, switch=False, bind=False,
1166 files_from=None):1254 files_from=None):
1255=======
1256 use_existing_dir=False, switch=False, bind=False):
1257>>>>>>> MERGE-SOURCE
1167 from bzrlib import switch as _mod_switch1258 from bzrlib import switch as _mod_switch
1168 from bzrlib.tag import _merge_tags_if_possible1259 from bzrlib.tag import _merge_tags_if_possible
1169 accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(1260 accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1170 from_location)1261 from_location)
1262<<<<<<< TREE
1171 if not (hardlink or files_from):1263 if not (hardlink or files_from):
1172 # accelerator_tree is usually slower because you have to read N1264 # accelerator_tree is usually slower because you have to read N
1173 # files (no readahead, lots of seeks, etc), but allow the user to1265 # files (no readahead, lots of seeks, etc), but allow the user to
@@ -1175,6 +1267,8 @@
1175 accelerator_tree = None1267 accelerator_tree = None
1176 if files_from is not None and files_from != from_location:1268 if files_from is not None and files_from != from_location:
1177 accelerator_tree = WorkingTree.open(files_from)1269 accelerator_tree = WorkingTree.open(files_from)
1270=======
1271>>>>>>> MERGE-SOURCE
1178 revision = _get_one_revision('branch', revision)1272 revision = _get_one_revision('branch', revision)
1179 self.add_cleanup(br_from.lock_read().unlock)1273 self.add_cleanup(br_from.lock_read().unlock)
1180 if revision is not None:1274 if revision is not None:
@@ -2689,6 +2783,14 @@
2689 "NAME_PATTERN or --default-rules.")2783 "NAME_PATTERN or --default-rules.")
2690 name_pattern_list = [globbing.normalize_pattern(p)2784 name_pattern_list = [globbing.normalize_pattern(p)
2691 for p in name_pattern_list]2785 for p in name_pattern_list]
2786 bad_patterns = ''
2787 for p in name_pattern_list:
2788 if not globbing.Globster.is_pattern_valid(p):
2789 bad_patterns += ('\n %s' % p)
2790 if bad_patterns:
2791 msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2792 ui.ui_factory.show_error(msg)
2793 raise errors.InvalidPattern('')
2692 for name_pattern in name_pattern_list:2794 for name_pattern in name_pattern_list:
2693 if (name_pattern[0] == '/' or2795 if (name_pattern[0] == '/' or
2694 (len(name_pattern) > 1 and name_pattern[1] == ':')):2796 (len(name_pattern) > 1 and name_pattern[1] == ':')):
@@ -3164,9 +3266,15 @@
3164 specific_files=selected_list,3266 specific_files=selected_list,
3165 allow_pointless=unchanged, strict=strict, local=local,3267 allow_pointless=unchanged, strict=strict, local=local,
3166 reporter=None, verbose=verbose, revprops=properties,3268 reporter=None, verbose=verbose, revprops=properties,
3269<<<<<<< TREE
3167 authors=author, timestamp=commit_stamp,3270 authors=author, timestamp=commit_stamp,
3168 timezone=offset,3271 timezone=offset,
3169 exclude=tree.safe_relpath_files(exclude))3272 exclude=tree.safe_relpath_files(exclude))
3273=======
3274 authors=author, timestamp=commit_stamp,
3275 timezone=offset,
3276 exclude=safe_relpath_files(tree, exclude))
3277>>>>>>> MERGE-SOURCE
3170 except PointlessCommit:3278 except PointlessCommit:
3171 raise errors.BzrCommandError("No changes to commit."3279 raise errors.BzrCommandError("No changes to commit."
3172 " Use --unchanged to commit anyhow.")3280 " Use --unchanged to commit anyhow.")
@@ -3506,15 +3614,21 @@
3506 'throughout the test suite.',3614 'throughout the test suite.',
3507 type=get_transport_type),3615 type=get_transport_type),
3508 Option('benchmark',3616 Option('benchmark',
3509 help='Run the benchmarks rather than selftests.'),3617 help='Run the benchmarks rather than selftests.',
3618 hidden=True),
3510 Option('lsprof-timed',3619 Option('lsprof-timed',
3511 help='Generate lsprof output for benchmarked'3620 help='Generate lsprof output for benchmarked'
3512 ' sections of code.'),3621 ' sections of code.'),
3622<<<<<<< TREE
3513 Option('lsprof-tests',3623 Option('lsprof-tests',
3514 help='Generate lsprof output for each test.'),3624 help='Generate lsprof output for each test.'),
3515 Option('cache-dir', type=str,3625 Option('cache-dir', type=str,
3516 help='Cache intermediate benchmark output in this '3626 help='Cache intermediate benchmark output in this '
3517 'directory.'),3627 'directory.'),
3628=======
3629 Option('lsprof-tests',
3630 help='Generate lsprof output for each test.'),
3631>>>>>>> MERGE-SOURCE
3518 Option('first',3632 Option('first',
3519 help='Run all tests, but run specified tests first.',3633 help='Run all tests, but run specified tests first.',
3520 short_name='f',3634 short_name='f',
@@ -3554,20 +3668,16 @@
35543668
3555 def run(self, testspecs_list=None, verbose=False, one=False,3669 def run(self, testspecs_list=None, verbose=False, one=False,
3556 transport=None, benchmark=None,3670 transport=None, benchmark=None,
3557 lsprof_timed=None, cache_dir=None,3671 lsprof_timed=None,
3558 first=False, list_only=False,3672 first=False, list_only=False,
3559 randomize=None, exclude=None, strict=False,3673 randomize=None, exclude=None, strict=False,
3560 load_list=None, debugflag=None, starting_with=None, subunit=False,3674 load_list=None, debugflag=None, starting_with=None, subunit=False,
3561 parallel=None, lsprof_tests=False):3675 parallel=None, lsprof_tests=False):
3562 from bzrlib.tests import selftest3676 from bzrlib.tests import selftest
3563 import bzrlib.benchmarks as benchmarks
3564 from bzrlib.benchmarks import tree_creator
35653677
3566 # Make deprecation warnings visible, unless -Werror is set3678 # Make deprecation warnings visible, unless -Werror is set
3567 symbol_versioning.activate_deprecation_warnings(override=False)3679 symbol_versioning.activate_deprecation_warnings(override=False)
35683680
3569 if cache_dir is not None:
3570 tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3571 if testspecs_list is not None:3681 if testspecs_list is not None:
3572 pattern = '|'.join(testspecs_list)3682 pattern = '|'.join(testspecs_list)
3573 else:3683 else:
@@ -3592,6 +3702,7 @@
3592 self.additional_selftest_args.setdefault(3702 self.additional_selftest_args.setdefault(
3593 'suite_decorators', []).append(parallel)3703 'suite_decorators', []).append(parallel)
3594 if benchmark:3704 if benchmark:
3705<<<<<<< TREE
3595 test_suite_factory = benchmarks.test_suite3706 test_suite_factory = benchmarks.test_suite
3596 # Unless user explicitly asks for quiet, be verbose in benchmarks3707 # Unless user explicitly asks for quiet, be verbose in benchmarks
3597 verbose = not is_quiet()3708 verbose = not is_quiet()
@@ -3620,6 +3731,30 @@
3620 }3731 }
3621 selftest_kwargs.update(self.additional_selftest_args)3732 selftest_kwargs.update(self.additional_selftest_args)
3622 result = selftest(**selftest_kwargs)3733 result = selftest(**selftest_kwargs)
3734=======
3735 raise errors.BzrCommandError(
3736 "--benchmark is no longer supported from bzr 2.2; "
3737 "use bzr-usertest instead")
3738 test_suite_factory = None
3739 selftest_kwargs = {"verbose": verbose,
3740 "pattern": pattern,
3741 "stop_on_failure": one,
3742 "transport": transport,
3743 "test_suite_factory": test_suite_factory,
3744 "lsprof_timed": lsprof_timed,
3745 "lsprof_tests": lsprof_tests,
3746 "matching_tests_first": first,
3747 "list_only": list_only,
3748 "random_seed": randomize,
3749 "exclude_pattern": exclude,
3750 "strict": strict,
3751 "load_list": load_list,
3752 "debug_flags": debugflag,
3753 "starting_with": starting_with
3754 }
3755 selftest_kwargs.update(self.additional_selftest_args)
3756 result = selftest(**selftest_kwargs)
3757>>>>>>> MERGE-SOURCE
3623 return int(not result)3758 return int(not result)
36243759
36253760
@@ -4068,6 +4203,7 @@
4068 from bzrlib.conflicts import restore4203 from bzrlib.conflicts import restore
4069 if merge_type is None:4204 if merge_type is None:
4070 merge_type = _mod_merge.Merge3Merger4205 merge_type = _mod_merge.Merge3Merger
4206<<<<<<< TREE
4071 tree, file_list = WorkingTree.open_containing_paths(file_list)4207 tree, file_list = WorkingTree.open_containing_paths(file_list)
4072 self.add_cleanup(tree.lock_write().unlock)4208 self.add_cleanup(tree.lock_write().unlock)
4073 parents = tree.get_parent_ids()4209 parents = tree.get_parent_ids()
@@ -4088,6 +4224,28 @@
4088 interesting_ids.add(file_id)4224 interesting_ids.add(file_id)
4089 if tree.kind(file_id) != "directory":4225 if tree.kind(file_id) != "directory":
4090 continue4226 continue
4227=======
4228 tree, file_list = tree_files(file_list)
4229 self.add_cleanup(tree.lock_write().unlock)
4230 parents = tree.get_parent_ids()
4231 if len(parents) != 2:
4232 raise errors.BzrCommandError("Sorry, remerge only works after normal"
4233 " merges. Not cherrypicking or"
4234 " multi-merges.")
4235 repository = tree.branch.repository
4236 interesting_ids = None
4237 new_conflicts = []
4238 conflicts = tree.conflicts()
4239 if file_list is not None:
4240 interesting_ids = set()
4241 for filename in file_list:
4242 file_id = tree.path2id(filename)
4243 if file_id is None:
4244 raise errors.NotVersionedError(filename)
4245 interesting_ids.add(file_id)
4246 if tree.kind(file_id) != "directory":
4247 continue
4248>>>>>>> MERGE-SOURCE
40914249
4092 for name, ie in tree.inventory.iter_entries(file_id):4250 for name, ie in tree.inventory.iter_entries(file_id):
4093 interesting_ids.add(ie.file_id)4251 interesting_ids.add(ie.file_id)
@@ -4184,12 +4342,21 @@
41844342
4185 def run(self, revision=None, no_backup=False, file_list=None,4343 def run(self, revision=None, no_backup=False, file_list=None,
4186 forget_merges=None):4344 forget_merges=None):
4345<<<<<<< TREE
4187 tree, file_list = WorkingTree.open_containing_paths(file_list)4346 tree, file_list = WorkingTree.open_containing_paths(file_list)
4188 self.add_cleanup(tree.lock_tree_write().unlock)4347 self.add_cleanup(tree.lock_tree_write().unlock)
4189 if forget_merges:4348 if forget_merges:
4190 tree.set_parent_ids(tree.get_parent_ids()[:1])4349 tree.set_parent_ids(tree.get_parent_ids()[:1])
4191 else:4350 else:
4192 self._revert_tree_to_revision(tree, revision, file_list, no_backup)4351 self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4352=======
4353 tree, file_list = tree_files(file_list)
4354 self.add_cleanup(tree.lock_tree_write().unlock)
4355 if forget_merges:
4356 tree.set_parent_ids(tree.get_parent_ids()[:1])
4357 else:
4358 self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4359>>>>>>> MERGE-SOURCE
41934360
4194 @staticmethod4361 @staticmethod
4195 def _revert_tree_to_revision(tree, revision, file_list, no_backup):4362 def _revert_tree_to_revision(tree, revision, file_list, no_backup):
41964363
=== modified file 'bzrlib/bundle/__init__.py'
--- bzrlib/bundle/__init__.py 2010-07-15 12:53:44 +0000
+++ bzrlib/bundle/__init__.py 2010-07-29 06:48:01 +0000
@@ -14,8 +14,14 @@
14# along with this program; if not, write to the Free Software14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1616
17from cStringIO import StringIO17<<<<<<< TREE
1818from cStringIO import StringIO
19
20=======
21from cStringIO import StringIO
22
23from bzrlib.symbol_versioning import deprecated_function, deprecated_in
24>>>>>>> MERGE-SOURCE
19from bzrlib.lazy_import import lazy_import25from bzrlib.lazy_import import lazy_import
20lazy_import(globals(), """26lazy_import(globals(), """
21from bzrlib import (27from bzrlib import (
2228
=== modified file 'bzrlib/chk_map.py'
--- bzrlib/chk_map.py 2010-05-11 10:45:26 +0000
+++ bzrlib/chk_map.py 2010-07-29 06:48:01 +0000
@@ -90,8 +90,6 @@
90_INTERESTING_NEW_SIZE = 5090_INTERESTING_NEW_SIZE = 50
91# If a ChildNode shrinks by more than this amount, we check for a remap91# If a ChildNode shrinks by more than this amount, we check for a remap
92_INTERESTING_SHRINKAGE_LIMIT = 2092_INTERESTING_SHRINKAGE_LIMIT = 20
93# If we delete more than this many nodes applying a delta, we check for a remap
94_INTERESTING_DELETES_LIMIT = 5
9593
9694
97def _search_key_plain(key):95def _search_key_plain(key):
@@ -135,7 +133,7 @@
135 into the map; if old_key is not None, then the old mapping133 into the map; if old_key is not None, then the old mapping
136 of old_key is removed.134 of old_key is removed.
137 """135 """
138 delete_count = 0136 has_deletes = False
139 # Check preconditions first.137 # Check preconditions first.
140 as_st = StaticTuple.from_sequence138 as_st = StaticTuple.from_sequence
141 new_items = set([as_st(key) for (old, key, value) in delta139 new_items = set([as_st(key) for (old, key, value) in delta
@@ -148,12 +146,11 @@
148 for old, new, value in delta:146 for old, new, value in delta:
149 if old is not None and old != new:147 if old is not None and old != new:
150 self.unmap(old, check_remap=False)148 self.unmap(old, check_remap=False)
151 delete_count += 1149 has_deletes = True
152 for old, new, value in delta:150 for old, new, value in delta:
153 if new is not None:151 if new is not None:
154 self.map(new, value)152 self.map(new, value)
155 if delete_count > _INTERESTING_DELETES_LIMIT:153 if has_deletes:
156 trace.mutter("checking remap as %d deletions", delete_count)
157 self._check_remap()154 self._check_remap()
158 return self._save()155 return self._save()
159156
@@ -573,7 +570,7 @@
573 """Check if nodes can be collapsed."""570 """Check if nodes can be collapsed."""
574 self._ensure_root()571 self._ensure_root()
575 if type(self._root_node) is InternalNode:572 if type(self._root_node) is InternalNode:
576 self._root_node._check_remap(self._store)573 self._root_node = self._root_node._check_remap(self._store)
577574
578 def _save(self):575 def _save(self):
579 """Save the map completely.576 """Save the map completely.
580577
=== modified file 'bzrlib/config.py'
--- bzrlib/config.py 2010-07-13 16:10:20 +0000
+++ bzrlib/config.py 2010-07-29 06:48:01 +0000
@@ -478,12 +478,23 @@
478 def _get_nickname(self):478 def _get_nickname(self):
479 return self.get_user_option('nickname')479 return self.get_user_option('nickname')
480480
481<<<<<<< TREE
481 def _write_config_file(self):482 def _write_config_file(self):
482 atomic_file = atomicfile.AtomicFile(self._get_filename())483 atomic_file = atomicfile.AtomicFile(self._get_filename())
483 self._get_parser().write(atomic_file)484 self._get_parser().write(atomic_file)
484 atomic_file.commit()485 atomic_file.commit()
485 atomic_file.close()486 atomic_file.close()
486487
488=======
489 def _write_config_file(self):
490 filename = self._get_filename()
491 atomic_file = atomicfile.AtomicFile(filename)
492 self._get_parser().write(atomic_file)
493 atomic_file.commit()
494 atomic_file.close()
495 osutils.copy_ownership_from_path(filename)
496
497>>>>>>> MERGE-SOURCE
487498
488class GlobalConfig(IniBasedConfig):499class GlobalConfig(IniBasedConfig):
489 """The configuration that should be used for a specific location."""500 """The configuration that should be used for a specific location."""
490501
=== modified file 'bzrlib/conflicts.py'
--- bzrlib/conflicts.py 2010-07-16 15:35:43 +0000
+++ bzrlib/conflicts.py 2010-07-29 06:48:01 +0000
@@ -24,7 +24,12 @@
24import errno24import errno
2525
26from bzrlib import (26from bzrlib import (
27 cleanup,27<<<<<<< TREE
28 cleanup,
29=======
30 builtins,
31 cleanup,
32>>>>>>> MERGE-SOURCE
28 commands,33 commands,
29 errors,34 errors,
30 osutils,35 osutils,
@@ -141,6 +146,18 @@
141 action = 'done'146 action = 'done'
142 if action == 'auto':147 if action == 'auto':
143 if file_list is None:148 if file_list is None:
149 if action is None:
150 # FIXME: There is a special case here related to the option
151 # handling that could be clearer and easier to discover by
152 # providing an --auto action (bug #344013 and #383396) and
153 # make it mandatory instead of implicit and active only
154 # when no file_list is provided -- vila 091229
155 action = 'auto'
156 else:
157 if action is None:
158 action = 'done'
159 if action == 'auto':
160 if file_list is None:
144 un_resolved, resolved = tree.auto_resolve()161 un_resolved, resolved = tree.auto_resolve()
145 if len(un_resolved) > 0:162 if len(un_resolved) > 0:
146 trace.note('%d conflict(s) auto-resolved.', len(resolved))163 trace.note('%d conflict(s) auto-resolved.', len(resolved))
147164
=== modified file 'bzrlib/diff.py'
=== modified file 'bzrlib/errors.py'
--- bzrlib/errors.py 2010-07-20 10:50:44 +0000
+++ bzrlib/errors.py 2010-07-29 06:48:01 +0000
@@ -949,11 +949,8 @@
949 # original exception is available as e.original_error949 # original exception is available as e.original_error
950 #950 #
951 # New code should prefer to raise specific subclasses951 # New code should prefer to raise specific subclasses
952 def __init__(self, message):952 def __init__(self, msg):
953 # Python 2.5 uses a slot for StandardError.message,953 self.msg = msg
954 # so use a different variable name. We now work around this in
955 # BzrError.__str__, but this member name is kept for compatability.
956 self.msg = message
957954
958955
959class LockActive(LockError):956class LockActive(LockError):
@@ -1179,8 +1176,13 @@
11791176
1180class InvalidRevisionSpec(BzrError):1177class InvalidRevisionSpec(BzrError):
11811178
1179<<<<<<< TREE
1182 _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"1180 _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
1183 " %(branch_url)s%(extra)s")1181 " %(branch_url)s%(extra)s")
1182=======
1183 _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
1184 " %(branch)s%(extra)s")
1185>>>>>>> MERGE-SOURCE
11841186
1185 def __init__(self, spec, branch, extra=None):1187 def __init__(self, spec, branch, extra=None):
1186 BzrError.__init__(self, branch=branch, spec=spec)1188 BzrError.__init__(self, branch=branch, spec=spec)
@@ -1381,12 +1383,12 @@
13811383
1382class WeaveParentMismatch(WeaveError):1384class WeaveParentMismatch(WeaveError):
13831385
1384 _fmt = "Parents are mismatched between two revisions. %(message)s"1386 _fmt = "Parents are mismatched between two revisions. %(msg)s"
13851387
13861388
1387class WeaveInvalidChecksum(WeaveError):1389class WeaveInvalidChecksum(WeaveError):
13881390
1389 _fmt = "Text did not match it's checksum: %(message)s"1391 _fmt = "Text did not match it's checksum: %(msg)s"
13901392
13911393
1392class WeaveTextDiffers(WeaveError):1394class WeaveTextDiffers(WeaveError):
@@ -1440,7 +1442,7 @@
14401442
1441class VersionedFileInvalidChecksum(VersionedFileError):1443class VersionedFileInvalidChecksum(VersionedFileError):
14421444
1443 _fmt = "Text did not match its checksum: %(message)s"1445 _fmt = "Text did not match its checksum: %(msg)s"
14441446
14451447
1446class KnitError(InternalBzrError):1448class KnitError(InternalBzrError):
@@ -3121,47 +3123,105 @@
3121 def __init__(self, source_branch, target_branch):3123 def __init__(self, source_branch, target_branch):
3122 self.source_branch = source_branch3124 self.source_branch = source_branch
3123 self.target_branch = target_branch3125 self.target_branch = target_branch
31243126<<<<<<< TREE
31253127
3126class NoRoundtrippingSupport(BzrError):3128
31273129class NoRoundtrippingSupport(BzrError):
3128 _fmt = ("Roundtripping is not supported between %(source_branch)r and "3130
3129 "%(target_branch)r.")3131 _fmt = ("Roundtripping is not supported between %(source_branch)r and "
31303132 "%(target_branch)r.")
3131 internal_error = True3133
31323134 internal_error = True
3133 def __init__(self, source_branch, target_branch):3135
3134 self.source_branch = source_branch3136 def __init__(self, source_branch, target_branch):
3135 self.target_branch = target_branch3137 self.source_branch = source_branch
31363138 self.target_branch = target_branch
31373139
3138class FileTimestampUnavailable(BzrError):3140
31393141class FileTimestampUnavailable(BzrError):
3140 _fmt = "The filestamp for %(path)s is not available."3142
31413143 _fmt = "The filestamp for %(path)s is not available."
3142 internal_error = True3144
31433145 internal_error = True
3144 def __init__(self, path):3146
3145 self.path = path3147 def __init__(self, path):
31463148 self.path = path
31473149
3148class NoColocatedBranchSupport(BzrError):3150
31493151class NoColocatedBranchSupport(BzrError):
3150 _fmt = ("%(bzrdir)r does not support co-located branches.")3152
31513153 _fmt = ("%(bzrdir)r does not support co-located branches.")
3152 def __init__(self, bzrdir):3154
3153 self.bzrdir = bzrdir3155 def __init__(self, bzrdir):
31543156 self.bzrdir = bzrdir
3155class NoWhoami(BzrError):3157
31563158class NoWhoami(BzrError):
3157 _fmt = ('Unable to determine your name.\n'3159
3158 "Please, set your name with the 'whoami' command.\n"3160 _fmt = ('Unable to determine your name.\n'
3159 'E.g. bzr whoami "Your Name <name@example.com>"')3161 "Please, set your name with the 'whoami' command.\n"
31603162 'E.g. bzr whoami "Your Name <name@example.com>"')
3161class InvalidPattern(BzrError):3163
31623164class InvalidPattern(BzrError):
3163 _fmt = ('Invalid pattern(s) found. %(msg)s')3165
31643166 _fmt = ('Invalid pattern(s) found. %(msg)s')
3165 def __init__(self, msg):3167
3166 self.msg = msg3168 def __init__(self, msg):
31673169 self.msg = msg
3170
3171=======
3172
3173
3174class NoRoundtrippingSupport(BzrError):
3175
3176 _fmt = ("Roundtripping is not supported between %(source_branch)r and "
3177 "%(target_branch)r.")
3178
3179 internal_error = True
3180
3181 def __init__(self, source_branch, target_branch):
3182 self.source_branch = source_branch
3183 self.target_branch = target_branch
3184
3185
3186class FileTimestampUnavailable(BzrError):
3187
3188 _fmt = "The filestamp for %(path)s is not available."
3189
3190 internal_error = True
3191
3192 def __init__(self, path):
3193 self.path = path
3194
3195
3196class NoColocatedBranchSupport(BzrError):
3197
3198 _fmt = ("%(bzrdir)r does not support co-located branches.")
3199
3200 def __init__(self, bzrdir):
3201 self.bzrdir = bzrdir
3202
3203
3204class NoWhoami(BzrError):
3205
3206 _fmt = ('Unable to determine your name.\n'
3207 "Please, set your name with the 'whoami' command.\n"
3208 'E.g. bzr whoami "Your Name <name@example.com>"')
3209
3210
3211class InvalidPattern(BzrError):
3212
3213 _fmt = ('Invalid pattern(s) found. %(msg)s')
3214
3215 def __init__(self, msg):
3216 self.msg = msg
3217
3218
3219class RecursiveBind(BzrError):
3220
3221 _fmt = ('Branch "%(branch_url)s" appears to be bound to itself. '
3222 'Please use `bzr unbind` to fix.')
3223
3224 def __init__(self, branch_url):
3225 self.branch_url = branch_url
3226
3227>>>>>>> MERGE-SOURCE
31683228
=== modified file 'bzrlib/globbing.py'
--- bzrlib/globbing.py 2010-07-09 16:16:11 +0000
+++ bzrlib/globbing.py 2010-07-29 06:48:01 +0000
@@ -179,24 +179,41 @@
179 so are matched first, then the basename patterns, then the fullpath179 so are matched first, then the basename patterns, then the fullpath
180 patterns.180 patterns.
181 """181 """
182 # We want to _add_patterns in a specific order (as per type_list below)
183 # starting with the shortest and going to the longest.
184 # As some Python version don't support ordered dicts the list below is
185 # used to select inputs for _add_pattern in a specific order.
186 pattern_types = [ "extension", "basename", "fullpath" ]
187
188 pattern_info = {
189 "extension" : {
190 "translator" : _sub_extension,
191 "prefix" : r'(?:.*/)?(?!.*/)(?:.*\.)'
192 },
193 "basename" : {
194 "translator" : _sub_basename,
195 "prefix" : r'(?:.*/)?(?!.*/)'
196 },
197 "fullpath" : {
198 "translator" : _sub_fullpath,
199 "prefix" : r''
200 },
201 }
202
182 def __init__(self, patterns):203 def __init__(self, patterns):
183 self._regex_patterns = []204 self._regex_patterns = []
184 path_patterns = []205 pattern_lists = {
185 base_patterns = []206 "extension" : [],
186 ext_patterns = []207 "basename" : [],
208 "fullpath" : [],
209 }
187 for pat in patterns:210 for pat in patterns:
188 pat = normalize_pattern(pat)211 pat = normalize_pattern(pat)
189 if pat.startswith(u'RE:') or u'/' in pat:212 pattern_lists[Globster.identify(pat)].append(pat)
190 path_patterns.append(pat)213 pi = Globster.pattern_info
191 elif pat.startswith(u'*.'):214 for t in Globster.pattern_types:
192 ext_patterns.append(pat)215 self._add_patterns(pattern_lists[t], pi[t]["translator"],
193 else:216 pi[t]["prefix"])
194 base_patterns.append(pat)
195 self._add_patterns(ext_patterns,_sub_extension,
196 prefix=r'(?:.*/)?(?!.*/)(?:.*\.)')
197 self._add_patterns(base_patterns,_sub_basename,
198 prefix=r'(?:.*/)?(?!.*/)')
199 self._add_patterns(path_patterns,_sub_fullpath)
200217
201 def _add_patterns(self, patterns, translator, prefix=''):218 def _add_patterns(self, patterns, translator, prefix=''):
202 while patterns:219 while patterns:
@@ -211,6 +228,7 @@
211228
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.
213 """230 """
231<<<<<<< TREE
214 try:232 try:
215 for regex, patterns in self._regex_patterns:233 for regex, patterns in self._regex_patterns:
216 match = regex.match(filename)234 match = regex.match(filename)
@@ -223,42 +241,133 @@
223 mutter('Invalid pattern found in regex: %s.', e.msg)241 mutter('Invalid pattern found in regex: %s.', e.msg)
224 e.msg = "File ~/.bazaar/ignore or .bzrignore contains errors."242 e.msg = "File ~/.bazaar/ignore or .bzrignore contains errors."
225 raise e243 raise e
244=======
245 try:
246 for regex, patterns in self._regex_patterns:
247 match = regex.match(filename)
248 if match:
249 return patterns[match.lastindex -1]
250 except errors.InvalidPattern, e:
251 # We can't show the default e.msg to the user as thats for
252 # the combined pattern we sent to regex. Instead we indicate to
253 # the user that an ignore file needs fixing.
254 mutter('Invalid pattern found in regex: %s.', e.msg)
255 e.msg = "File ~/.bazaar/ignore or .bzrignore contains error(s)."
256 bad_patterns = ''
257 for _, patterns in self._regex_patterns:
258 for p in patterns:
259 if not Globster.is_pattern_valid(p):
260 bad_patterns += ('\n %s' % p)
261 e.msg += bad_patterns
262 raise e
263>>>>>>> MERGE-SOURCE
226 return None264 return None
227265
228class ExceptionGlobster(object):266<<<<<<< TREE
229 """A Globster that supports exception patterns.267class ExceptionGlobster(object):
230 268 """A Globster that supports exception patterns.
231 Exceptions are ignore patterns prefixed with '!'. Exception269
232 patterns take precedence over regular patterns and cause a 270 Exceptions are ignore patterns prefixed with '!'. Exception
233 matching filename to return None from the match() function. 271 patterns take precedence over regular patterns and cause a
234 Patterns using a '!!' prefix are highest precedence, and act 272 matching filename to return None from the match() function.
235 as regular ignores. '!!' patterns are useful to establish ignores273 Patterns using a '!!' prefix are highest precedence, and act
236 that apply under paths specified by '!' exception patterns.274 as regular ignores. '!!' patterns are useful to establish ignores
237 """275 that apply under paths specified by '!' exception patterns.
238 276 """
239 def __init__(self,patterns):277
240 ignores = [[], [], []]278 def __init__(self,patterns):
241 for p in patterns:279 ignores = [[], [], []]
242 if p.startswith(u'!!'):280 for p in patterns:
243 ignores[2].append(p[2:])281 if p.startswith(u'!!'):
244 elif p.startswith(u'!'):282 ignores[2].append(p[2:])
245 ignores[1].append(p[1:])283 elif p.startswith(u'!'):
246 else:284 ignores[1].append(p[1:])
247 ignores[0].append(p)285 else:
248 self._ignores = [Globster(i) for i in ignores]286 ignores[0].append(p)
249 287 self._ignores = [Globster(i) for i in ignores]
250 def match(self, filename):288
251 """Searches for a pattern that matches the given filename.289 def match(self, filename):
252290 """Searches for a pattern that matches the given filename.
253 :return A matching pattern or None if there is no matching pattern.291
254 """292 :return A matching pattern or None if there is no matching pattern.
255 double_neg = self._ignores[2].match(filename)293 """
256 if double_neg:294 double_neg = self._ignores[2].match(filename)
257 return "!!%s" % double_neg295 if double_neg:
258 elif self._ignores[1].match(filename):296 return "!!%s" % double_neg
259 return None297 elif self._ignores[1].match(filename):
260 else:298 return None
261 return self._ignores[0].match(filename)299 else:
300 return self._ignores[0].match(filename)
301=======
302 @staticmethod
303 def identify(pattern):
304 """Returns pattern category.
305
306 :param pattern: normalized pattern.
307 Identify if a pattern is fullpath, basename or extension
308 and returns the appropriate type.
309 """
310 if pattern.startswith(u'RE:') or u'/' in pattern:
311 return "fullpath"
312 elif pattern.startswith(u'*.'):
313 return "extension"
314 else:
315 return "basename"
316
317 @staticmethod
318 def is_pattern_valid(pattern):
319 """Returns True if pattern is valid.
320
321 :param pattern: Normalized pattern.
322 is_pattern_valid() assumes pattern to be normalized.
323 see: globbing.normalize_pattern
324 """
325 result = True
326 translator = Globster.pattern_info[Globster.identify(pattern)]["translator"]
327 tpattern = '(%s)' % translator(pattern)
328 try:
329 re_obj = re.compile(tpattern, re.UNICODE)
330 re_obj.search("") # force compile
331 except errors.InvalidPattern, e:
332 result = False
333 return result
334
335
336class ExceptionGlobster(object):
337 """A Globster that supports exception patterns.
338
339 Exceptions are ignore patterns prefixed with '!'. Exception
340 patterns take precedence over regular patterns and cause a
341 matching filename to return None from the match() function.
342 Patterns using a '!!' prefix are highest precedence, and act
343 as regular ignores. '!!' patterns are useful to establish ignores
344 that apply under paths specified by '!' exception patterns.
345 """
346
347 def __init__(self,patterns):
348 ignores = [[], [], []]
349 for p in patterns:
350 if p.startswith(u'!!'):
351 ignores[2].append(p[2:])
352 elif p.startswith(u'!'):
353 ignores[1].append(p[1:])
354 else:
355 ignores[0].append(p)
356 self._ignores = [Globster(i) for i in ignores]
357
358 def match(self, filename):
359 """Searches for a pattern that matches the given filename.
360
361 :return A matching pattern or None if there is no matching pattern.
362 """
363 double_neg = self._ignores[2].match(filename)
364 if double_neg:
365 return "!!%s" % double_neg
366 elif self._ignores[1].match(filename):
367 return None
368 else:
369 return self._ignores[0].match(filename)
370>>>>>>> MERGE-SOURCE
262371
263class _OrderedGlobster(Globster):372class _OrderedGlobster(Globster):
264 """A Globster that keeps pattern order."""373 """A Globster that keeps pattern order."""
@@ -272,6 +381,7 @@
272 self._regex_patterns = []381 self._regex_patterns = []
273 for pat in patterns:382 for pat in patterns:
274 pat = normalize_pattern(pat)383 pat = normalize_pattern(pat)
384<<<<<<< TREE
275 if pat.startswith(u'RE:') or u'/' in pat:385 if pat.startswith(u'RE:') or u'/' in pat:
276 self._add_patterns([pat], _sub_fullpath)386 self._add_patterns([pat], _sub_fullpath)
277 elif pat.startswith(u'*.'):387 elif pat.startswith(u'*.'):
@@ -283,6 +393,14 @@
283393
284394
285_slashes = re.compile(r'[\\/]+')395_slashes = re.compile(r'[\\/]+')
396=======
397 t = Globster.identify(pat)
398 self._add_patterns([pat], Globster.pattern_info[t]["translator"],
399 Globster.pattern_info[t]["prefix"])
400
401
402_slashes = re.compile(r'[\\/]+')
403>>>>>>> MERGE-SOURCE
286def normalize_pattern(pattern):404def normalize_pattern(pattern):
287 """Converts backslashes in path patterns to forward slashes.405 """Converts backslashes in path patterns to forward slashes.
288406
289407
=== modified file 'bzrlib/help_topics/en/conflict-types.txt'
--- bzrlib/help_topics/en/conflict-types.txt 2010-04-28 13:15:14 +0000
+++ bzrlib/help_topics/en/conflict-types.txt 2010-07-29 06:48:01 +0000
@@ -3,6 +3,7 @@
33
4Some operations, like merge, revert and pull, modify the contents of your4Some operations, like merge, revert and pull, modify the contents of your
5working tree. These modifications are programmatically generated, and so they5working tree. These modifications are programmatically generated, and so they
6<<<<<<< TREE
6may conflict with the current state of your working tree. 7may conflict with the current state of your working tree.
78
8When conflicts are present in your working tree (as shown by ``bzr9When conflicts are present in your working tree (as shown by ``bzr
@@ -40,6 +41,45 @@
4041
41Yet, whether Bazaar makes a choice or not, there are some other simple but42Yet, whether Bazaar makes a choice or not, there are some other simple but
42different ways to resolve the conflict.43different ways to resolve the conflict.
44=======
45may conflict with the current state of your working tree.
46
47When conflicts are present in your working tree (as shown by ``bzr
48conflicts``), you should resolve them and then inform bzr that the conflicts
49have been resolved.
50
51Resolving conflicts is sometimes not obvious. Either because the user that
52should resolve them is not the one responsible for their occurrence, as is the
53case when merging other people's work or because some conflicts are presented
54in a way that is not easy to understand.
55
56Bazaar tries to avoid conflicts ; its aim is to ask you to resolve the
57conflict if and only if there's an actual conceptual conflict in the source
58tree. Because Bazaar doesn't understand the real meaning of the files being
59versioned, it can, when faced with ambiguities, fall short in either direction
60trying to resolve the conflict itself. Many kinds of changes can be combined
61programmatically, but sometimes only a human can determine the right thing to
62do.
63
64When Bazaar generates a conflict, it adds information into the working tree to
65present the conflicting versions, and it's up to you to find the correct
66resolution.
67
68Whatever the conflict is, resolving it is roughly done in two steps::
69
70- modify the working tree content so that the conflicted item is now in the
71 state you want to keep,
72
73- inform Bazaar that the conflict is now solved and ask to cleanup any
74 remaining generated information (``bzr resolve <item>``).
75
76For most conflict types, there are some obvious ways to modify the working
77tree and put it into the desired state. For some types of conflicts, Bazaar
78itself already made a choice, when possible.
79
80Yet, whether Bazaar makes a choice or not, there are some other simple but
81different ways to resolve the conflict.
82>>>>>>> MERGE-SOURCE
4383
44Each type of conflict is explained below, and the action which must be done to84Each type of conflict is explained below, and the action which must be done to
45resolve the conflict is outlined.85resolve the conflict is outlined.
@@ -121,6 +161,7 @@
121of the file with herringbone conflict markers. It will appear that the "main161of the file with herringbone conflict markers. It will appear that the "main
122copy" has been renamed to THIS or OTHER.162copy" has been renamed to THIS or OTHER.
123163
164<<<<<<< TREE
124To resolve that kind of conflict, you should rebuild FILE from either version165To resolve that kind of conflict, you should rebuild FILE from either version
125or a combination of both.166or a combination of both.
126167
@@ -158,6 +199,45 @@
158favor of the target branch, you need to similarly use ``tag --force`` in the199favor of the target branch, you need to similarly use ``tag --force`` in the
159source branch. (Note that pulling or pushing using --overwrite will overwrite200source branch. (Note that pulling or pushing using --overwrite will overwrite
160all tags as well.)201all tags as well.)
202=======
203To resolve that kind of conflict, you should rebuild FILE from either version
204or a combination of both.
205
206``bzr resolve`` recognizes the following actions:
207
208- ``--action=take-this`` will issue ``bzr mv FILE.THIS FILE``,
209- ``--action=take-other`` will issue ``bzr mv FILE.OTHER FILE``,
210- ``--action=done`` will just mark the conflict as resolved.
211
212Any action will also delete the previously generated ``.BASE``, ``.THIS`` and
213``.OTHER`` files if they are still present in the working tree.
214
215Bazaar cannot auto-detect when conflicts of this kind have been resolved.
216
217Tag conflicts
218-------------
219
220Typical message::
221
222 Conflicting tags:
223 version-0.1
224
225When pulling from or pushing to another branch, Bazaar informs you about tags
226that conflict between the two branches; that is the same tag points to two
227different revisions. You need not resolve these conflicts, but subsequent
228uses of pull or push will result in the same message.
229
230To resolve the conflict, you must apply the correct tags to either the target
231branch or the source branch as appropriate. Use "bzr tags --show-ids -d
232SOURCE_URL" to see the tags in the source branch. If you want to make the
233target branch's tags match the source branch, then in the target branch do
234``bzr tag --force -r revid:REVISION_ID CONFLICTING_TAG`` for each of the
235CONFLICTING_TAGs, where REVISION_ID comes from the list of tags in the source
236branch. You need not call "bzr resolve" after doing this. To resolve in
237favor of the target branch, you need to similarly use ``tag --force`` in the
238source branch. (Note that pulling or pushing using --overwrite will overwrite
239all tags as well.)
240>>>>>>> MERGE-SOURCE
161241
162Duplicate paths242Duplicate paths
163---------------243---------------
@@ -167,6 +247,7 @@
167 Conflict adding file FILE. Moved existing file to FILE.moved.247 Conflict adding file FILE. Moved existing file to FILE.moved.
168248
169Sometimes Bazaar will attempt to create a file using a pathname that has249Sometimes Bazaar will attempt to create a file using a pathname that has
250<<<<<<< TREE
170already been used. The existing file will be renamed to "FILE.moved". 251already been used. The existing file will be renamed to "FILE.moved".
171252
172To resolve that kind of conflict, you should rebuild FILE from either version253To resolve that kind of conflict, you should rebuild FILE from either version
@@ -181,6 +262,22 @@
181Note that you must get rid of FILE.moved before using ``--action=done``.262Note that you must get rid of FILE.moved before using ``--action=done``.
182263
183Bazaar cannot auto-detect when conflicts of this kind have been resolved.264Bazaar cannot auto-detect when conflicts of this kind have been resolved.
265=======
266already been used. The existing file will be renamed to "FILE.moved".
267
268To resolve that kind of conflict, you should rebuild FILE from either version
269or a combination of both.
270
271``bzr resolve`` recognizes the following actions::
272
273- ``--action=take-this`` will issue ``bzr rm FILE ; bzr mv FILE.moved FILE``,
274- ``--action=take-other`` will issue ``bzr rm FILE.moved``,
275- ``--action=done`` will just mark the conflict as resolved.
276
277Note that you must get rid of FILE.moved before using ``--action=done``.
278
279Bazaar cannot auto-detect when conflicts of this kind have been resolved.
280>>>>>>> MERGE-SOURCE
184281
185Unversioned parent282Unversioned parent
186------------------283------------------
@@ -204,6 +301,7 @@
204301
205 Conflict adding files to FILE. Created directory.302 Conflict adding files to FILE. Created directory.
206303
304<<<<<<< TREE
207This happens when a directory has been deleted in the target, but has new305This happens when a directory has been deleted in the target, but has new
208children in the source. This is similar to the "unversioned parent" conflict,306children in the source. This is similar to the "unversioned parent" conflict,
209except that the parent directory does not *exist*, instead of just being307except that the parent directory does not *exist*, instead of just being
@@ -222,6 +320,25 @@
222 - ``--action=done`` will just mark the conflict as resolved.320 - ``--action=done`` will just mark the conflict as resolved.
223321
224Bazaar cannot auto-detect when conflicts of this kind have been resolved.322Bazaar cannot auto-detect when conflicts of this kind have been resolved.
323=======
324This happens when a directory has been deleted in the target, but has new
325children in the source. This is similar to the "unversioned parent" conflict,
326except that the parent directory does not *exist*, instead of just being
327unversioned. In this situation, Bazaar will create the missing parent.
328Resolving this issue depends very much on the particular scenario.
329
330To resolve that kind of conflict, you should either remove or rename the
331children or the directory or a combination of both.
332
333``bzr resolve`` recognizes the following actions::
334
335- ``--action=take-this`` will issue ``bzr rm directory`` including the children,
336- ``--action=take-other`` will acknowledge Bazaar choice to keep the children
337 and restoring the directory,
338- ``--action=done`` will just mark the conflict as resolved.
339
340Bazaar cannot auto-detect when conflicts of this kind have been resolved.
341>>>>>>> MERGE-SOURCE
225342
226Deleting parent343Deleting parent
227---------------344---------------
@@ -232,6 +349,7 @@
232349
233This is the opposite of "missing parent". A directory is deleted in the350This is the opposite of "missing parent". A directory is deleted in the
234source, but has new children in the target. Bazaar will retain the directory.351source, but has new children in the target. Bazaar will retain the directory.
352<<<<<<< TREE
235Resolving this issue depends very much on the particular scenario.353Resolving this issue depends very much on the particular scenario.
236354
237To resolve that kind of conflict, you should either remove or rename the355To resolve that kind of conflict, you should either remove or rename the
@@ -245,6 +363,21 @@
245 - ``--action=done`` will just mark the conflict as resolved.363 - ``--action=done`` will just mark the conflict as resolved.
246364
247Bazaar cannot auto-detect when conflicts of this kind have been resolved.365Bazaar cannot auto-detect when conflicts of this kind have been resolved.
366=======
367Resolving this issue depends very much on the particular scenario.
368
369To resolve that kind of conflict, you should either remove or rename the
370children or the directory or a combination of both.
371
372``bzr resolve`` recognizes the following actions::
373
374- ``--action=take-this`` will acknowledge Bazaar choice to keep the directory,
375- ``--action=take-other`` will issue ``bzr rm directory`` including the
376 children,
377- ``--action=done`` will just mark the conflict as resolved.
378
379Bazaar cannot auto-detect when conflicts of this kind have been resolved.
The diff has been truncated for viewing.