29
29
from bzrlib import (
39
40
merge as _mod_merge,
43
45
revision as _mod_revision,
50
52
from bzrlib.branch import Branch
51
53
from bzrlib.conflicts import ConflictList
52
from bzrlib.revisionspec import RevisionSpec
54
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
53
55
from bzrlib.smtp_connection import SMTPConnection
54
56
from bzrlib.workingtree import WorkingTree
57
59
from bzrlib.commands import Command, display_command
58
from bzrlib.option import ListOption, Option, RegistryOption, custom_help
59
from bzrlib.trace import mutter, note, warning, is_quiet, info
62
def tree_files(file_list, default_branch=u'.'):
60
from bzrlib.option import (
67
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
70
def tree_files(file_list, default_branch=u'.', canonicalize=True,
64
return internal_tree_files(file_list, default_branch)
73
return internal_tree_files(file_list, default_branch, canonicalize,
65
75
except errors.FileInWrongBranch, e:
66
76
raise errors.BzrCommandError("%s is not in the same branch as %s" %
67
77
(e.path, file_list[0]))
80
def tree_files_for_add(file_list):
82
Return a tree and list of absolute paths from a file list.
84
Similar to tree_files, but add handles files a bit differently, so it a
85
custom implementation. In particular, MutableTreeTree.smart_add expects
86
absolute paths, which it immediately converts to relative paths.
88
# FIXME Would be nice to just return the relative paths like
89
# internal_tree_files does, but there are a large number of unit tests
90
# that assume the current interface to mutabletree.smart_add
92
tree, relpath = WorkingTree.open_containing(file_list[0])
93
if tree.supports_views():
94
view_files = tree.views.lookup_view()
96
for filename in file_list:
97
if not osutils.is_inside_any(view_files, filename):
98
raise errors.FileOutsideView(filename, view_files)
99
file_list = file_list[:]
100
file_list[0] = tree.abspath(relpath)
102
tree = WorkingTree.open_containing(u'.')[0]
103
if tree.supports_views():
104
view_files = tree.views.lookup_view()
106
file_list = view_files
107
view_str = views.view_display_str(view_files)
108
note("Ignoring files outside view. View is %s" % view_str)
109
return tree, file_list
112
def _get_one_revision(command_name, revisions):
113
if revisions is None:
115
if len(revisions) != 1:
116
raise errors.BzrCommandError(
117
'bzr %s --revision takes exactly one revision identifier' % (
122
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
123
"""Get a revision tree. Not suitable for commands that change the tree.
125
Specifically, the basis tree in dirstate trees is coupled to the dirstate
126
and doing a commit/uncommit/pull will at best fail due to changing the
129
If tree is passed in, it should be already locked, for lifetime management
130
of the trees internal cached state.
134
if revisions is None:
136
rev_tree = tree.basis_tree()
138
rev_tree = branch.basis_tree()
140
revision = _get_one_revision(command_name, revisions)
141
rev_tree = revision.as_tree(branch)
70
145
# XXX: Bad function name; should possibly also be a class method of
71
146
# WorkingTree rather than a function.
72
def internal_tree_files(file_list, default_branch=u'.'):
147
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
73
149
"""Convert command-line paths to a WorkingTree and relative paths.
75
151
This is typically used for command-line processors that take one or
240
359
rev_id = rev.as_revision_id(b)
241
360
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
363
class cmd_dump_btree(Command):
364
"""Dump the contents of a btree index file to stdout.
366
PATH is a btree index file, it can be any URL. This includes things like
367
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
369
By default, the tuples stored in the index file will be displayed. With
370
--raw, we will uncompress the pages, but otherwise display the raw bytes
374
# TODO: Do we want to dump the internal nodes as well?
375
# TODO: It would be nice to be able to dump the un-parsed information,
376
# rather than only going through iter_all_entries. However, this is
377
# good enough for a start
379
encoding_type = 'exact'
380
takes_args = ['path']
381
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
382
' rather than the parsed tuples.'),
385
def run(self, path, raw=False):
386
dirname, basename = osutils.split(path)
387
t = transport.get_transport(dirname)
389
self._dump_raw_bytes(t, basename)
391
self._dump_entries(t, basename)
393
def _get_index_and_bytes(self, trans, basename):
394
"""Create a BTreeGraphIndex and raw bytes."""
395
bt = btree_index.BTreeGraphIndex(trans, basename, None)
396
bytes = trans.get_bytes(basename)
397
bt._file = cStringIO.StringIO(bytes)
398
bt._size = len(bytes)
401
def _dump_raw_bytes(self, trans, basename):
404
# We need to parse at least the root node.
405
# This is because the first page of every row starts with an
406
# uncompressed header.
407
bt, bytes = self._get_index_and_bytes(trans, basename)
408
for page_idx, page_start in enumerate(xrange(0, len(bytes),
409
btree_index._PAGE_SIZE)):
410
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
411
page_bytes = bytes[page_start:page_end]
413
self.outf.write('Root node:\n')
414
header_end, data = bt._parse_header_from_bytes(page_bytes)
415
self.outf.write(page_bytes[:header_end])
417
self.outf.write('\nPage %d\n' % (page_idx,))
418
decomp_bytes = zlib.decompress(page_bytes)
419
self.outf.write(decomp_bytes)
420
self.outf.write('\n')
422
def _dump_entries(self, trans, basename):
424
st = trans.stat(basename)
425
except errors.TransportNotPossible:
426
# We can't stat, so we'll fake it because we have to do the 'get()'
428
bt, _ = self._get_index_and_bytes(trans, basename)
430
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
431
for node in bt.iter_all_entries():
432
# Node is made up of:
433
# (index, key, value, [references])
434
self.outf.write('%s\n' % (node[1:],))
244
437
class cmd_remove_tree(Command):
245
438
"""Remove the working tree from a given branch/checkout.
1628
2035
raise errors.BzrCommandError(msg)
2038
def _parse_levels(s):
2042
msg = "The levels argument must be an integer."
2043
raise errors.BzrCommandError(msg)
1631
2046
class cmd_log(Command):
1632
"""Show log of a branch, file, or directory.
1634
By default show the log of the branch containing the working directory.
1636
To request a range of logs, you can use the command -r begin..end
1637
-r revision requests a specific revision, -r ..end or -r begin.. are
1641
Log the current branch::
1649
Log the last 10 revisions of a branch::
1651
bzr log -r -10.. http://server/branch
2047
"""Show historical log for a branch or subset of a branch.
2049
log is bzr's default tool for exploring the history of a branch.
2050
The branch to use is taken from the first parameter. If no parameters
2051
are given, the branch containing the working directory is logged.
2052
Here are some simple examples::
2054
bzr log log the current branch
2055
bzr log foo.py log a file in its branch
2056
bzr log http://server/branch log a branch on a server
2058
The filtering, ordering and information shown for each revision can
2059
be controlled as explained below. By default, all revisions are
2060
shown sorted (topologically) so that newer revisions appear before
2061
older ones and descendants always appear before ancestors. If displayed,
2062
merged revisions are shown indented under the revision in which they
2067
The log format controls how information about each revision is
2068
displayed. The standard log formats are called ``long``, ``short``
2069
and ``line``. The default is long. See ``bzr help log-formats``
2070
for more details on log formats.
2072
The following options can be used to control what information is
2075
-l N display a maximum of N revisions
2076
-n N display N levels of revisions (0 for all, 1 for collapsed)
2077
-v display a status summary (delta) for each revision
2078
-p display a diff (patch) for each revision
2079
--show-ids display revision-ids (and file-ids), not just revnos
2081
Note that the default number of levels to display is a function of the
2082
log format. If the -n option is not used, the standard log formats show
2083
just the top level (mainline).
2085
Status summaries are shown using status flags like A, M, etc. To see
2086
the changes explained using words like ``added`` and ``modified``
2087
instead, use the -vv option.
2091
To display revisions from oldest to newest, use the --forward option.
2092
In most cases, using this option will have little impact on the total
2093
time taken to produce a log, though --forward does not incrementally
2094
display revisions like --reverse does when it can.
2096
:Revision filtering:
2098
The -r option can be used to specify what revision or range of revisions
2099
to filter against. The various forms are shown below::
2101
-rX display revision X
2102
-rX.. display revision X and later
2103
-r..Y display up to and including revision Y
2104
-rX..Y display from X to Y inclusive
2106
See ``bzr help revisionspec`` for details on how to specify X and Y.
2107
Some common examples are given below::
2109
-r-1 show just the tip
2110
-r-10.. show the last 10 mainline revisions
2111
-rsubmit:.. show what's new on this branch
2112
-rancestor:path.. show changes since the common ancestor of this
2113
branch and the one at location path
2114
-rdate:yesterday.. show changes since yesterday
2116
When logging a range of revisions using -rX..Y, log starts at
2117
revision Y and searches back in history through the primary
2118
("left-hand") parents until it finds X. When logging just the
2119
top level (using -n1), an error is reported if X is not found
2120
along the way. If multi-level logging is used (-n0), X may be
2121
a nested merge revision and the log will be truncated accordingly.
2125
If parameters are given and the first one is not a branch, the log
2126
will be filtered to show only those revisions that changed the
2127
nominated files or directories.
2129
Filenames are interpreted within their historical context. To log a
2130
deleted file, specify a revision range so that the file existed at
2131
the end or start of the range.
2133
Historical context is also important when interpreting pathnames of
2134
renamed files/directories. Consider the following example:
2136
* revision 1: add tutorial.txt
2137
* revision 2: modify tutorial.txt
2138
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2142
* ``bzr log guide.txt`` will log the file added in revision 1
2144
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2146
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2147
the original file in revision 2.
2149
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2150
was no file called guide.txt in revision 2.
2152
Renames are always followed by log. By design, there is no need to
2153
explicitly ask for this (and no way to stop logging a file back
2154
until it was last renamed).
2158
The --message option can be used for finding revisions that match a
2159
regular expression in a commit message.
2163
GUI tools and IDEs are often better at exploring history than command
2164
line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2165
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2166
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2168
Web interfaces are often better at exploring history than command line
2169
tools, particularly for branches on servers. You may prefer Loggerhead
2170
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2172
You may find it useful to add the aliases below to ``bazaar.conf``::
2176
top = log -l10 --line
2179
``bzr tip`` will then show the latest revision while ``bzr top``
2180
will show the last 10 mainline revisions. To see the details of a
2181
particular revision X, ``bzr show -rX``.
2183
If you are interested in looking deeper into a particular merge X,
2184
use ``bzr log -n0 -rX``.
2186
``bzr log -v`` on a branch with lots of history is currently
2187
very slow. A fix for this issue is currently under development.
2188
With or without that fix, it is recommended that a revision range
2189
be given when using the -v option.
2191
bzr has a generic full-text matching plugin, bzr-search, that can be
2192
used to find revisions matching user names, commit messages, etc.
2193
Among other features, this plugin can find all revisions containing
2194
a list of words but not others.
2196
When exploring non-mainline history on large projects with deep
2197
history, the performance of log can be greatly improved by installing
2198
the historycache plugin. This plugin buffers historical information
2199
trading disk space for faster speed.
1654
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1656
takes_args = ['location?']
2201
takes_args = ['file*']
2202
_see_also = ['log-formats', 'revisionspec']
1657
2203
takes_options = [
1658
2204
Option('forward',
1659
2205
help='Show from oldest to newest.'),
1662
help='Display timezone as local, original, or utc.'),
1663
2207
custom_help('verbose',
1664
2208
help='Show files changed in each revision.'),
2212
type=bzrlib.option._parse_revision_str,
2214
help='Show just the specified revision.'
2215
' See also "help revisionspec".'),
2219
help='Number of levels to display - 0 for all, 1 for flat.',
2221
type=_parse_levels),
1668
2222
Option('message',
1669
2223
short_name='m',
1670
2224
help='Show revisions whose message matches this '
1716
2302
dir, relpath = bzrdir.BzrDir.open_containing(location)
1717
2303
b = dir.open_branch()
2304
rev1, rev2 = _get_revision_range(revision, b, self.name())
2306
# Decide on the type of delta & diff filtering to use
2307
# TODO: add an --all-files option to make this configurable & consistent
2315
diff_type = 'partial'
1721
if revision is None:
1724
elif len(revision) == 1:
1725
rev1 = rev2 = revision[0].in_history(b)
1726
elif len(revision) == 2:
1727
if revision[1].get_branch() != revision[0].get_branch():
1728
# b is taken from revision[0].get_branch(), and
1729
# show_log will use its revision_history. Having
1730
# different branches will lead to weird behaviors.
1731
raise errors.BzrCommandError(
1732
"Log doesn't accept two revisions in different"
1734
rev1 = revision[0].in_history(b)
1735
rev2 = revision[1].in_history(b)
1737
raise errors.BzrCommandError(
1738
'bzr log --revision takes one or two values.')
2321
# Build the log formatter
1740
2322
if log_format is None:
1741
2323
log_format = log.log_formatter_registry.get_default(b)
1743
2324
lf = log_format(show_ids=show_ids, to_file=self.outf,
1744
show_timezone=timezone)
1750
direction=direction,
1751
start_revision=rev1,
2325
show_timezone=timezone,
2326
delta_format=get_verbosity_level(),
2328
show_advice=levels is None)
2330
# Choose the algorithm for doing the logging. It's annoying
2331
# having multiple code paths like this but necessary until
2332
# the underlying repository format is faster at generating
2333
# deltas or can provide everything we need from the indices.
2334
# The default algorithm - match-using-deltas - works for
2335
# multiple files and directories and is faster for small
2336
# amounts of history (200 revisions say). However, it's too
2337
# slow for logging a single file in a repository with deep
2338
# history, i.e. > 10K revisions. In the spirit of "do no
2339
# evil when adding features", we continue to use the
2340
# original algorithm - per-file-graph - for the "single
2341
# file that isn't a directory without showing a delta" case.
2342
partial_history = revision and b.repository._format.supports_chks
2343
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2344
or delta_type or partial_history)
2346
# Build the LogRequest and execute it
2347
if len(file_ids) == 0:
2349
rqst = make_log_request_dict(
2350
direction=direction, specific_fileids=file_ids,
2351
start_revision=rev1, end_revision=rev2, limit=limit,
2352
message_search=message, delta_type=delta_type,
2353
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2354
Logger(b, rqst).show(lf)
2359
def _get_revision_range(revisionspec_list, branch, command_name):
2360
"""Take the input of a revision option and turn it into a revision range.
2362
It returns RevisionInfo objects which can be used to obtain the rev_id's
2363
of the desired revisions. It does some user input validations.
2365
if revisionspec_list is None:
2368
elif len(revisionspec_list) == 1:
2369
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2370
elif len(revisionspec_list) == 2:
2371
start_spec = revisionspec_list[0]
2372
end_spec = revisionspec_list[1]
2373
if end_spec.get_branch() != start_spec.get_branch():
2374
# b is taken from revision[0].get_branch(), and
2375
# show_log will use its revision_history. Having
2376
# different branches will lead to weird behaviors.
2377
raise errors.BzrCommandError(
2378
"bzr %s doesn't accept two revisions in different"
2379
" branches." % command_name)
2380
rev1 = start_spec.in_history(branch)
2381
# Avoid loading all of history when we know a missing
2382
# end of range means the last revision ...
2383
if end_spec.spec is None:
2384
last_revno, last_revision_id = branch.last_revision_info()
2385
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2387
rev2 = end_spec.in_history(branch)
2389
raise errors.BzrCommandError(
2390
'bzr %s --revision takes one or two values.' % command_name)
2394
def _revision_range_to_revid_range(revision_range):
2397
if revision_range[0] is not None:
2398
rev_id1 = revision_range[0].rev_id
2399
if revision_range[1] is not None:
2400
rev_id2 = revision_range[1].rev_id
2401
return rev_id1, rev_id2
1759
2403
def get_log_format(long=False, short=False, line=False, default='long'):
1760
2404
log_format = default
2155
2842
class cmd_commit(Command):
2156
2843
"""Commit changes into a new revision.
2158
If no arguments are given, the entire tree is committed.
2160
If selected files are specified, only changes to those files are
2161
committed. If a directory is specified then the directory and everything
2162
within it is committed.
2164
When excludes are given, they take precedence over selected files.
2165
For example, too commit only changes within foo, but not changes within
2168
bzr commit foo -x foo/bar
2170
If author of the change is not the same person as the committer, you can
2171
specify the author's name using the --author option. The name should be
2172
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2174
A selected-file commit may fail in some cases where the committed
2175
tree would be invalid. Consider::
2180
bzr commit foo -m "committing foo"
2181
bzr mv foo/bar foo/baz
2184
bzr commit foo/bar -m "committing bar but not baz"
2186
In the example above, the last commit will fail by design. This gives
2187
the user the opportunity to decide whether they want to commit the
2188
rename at the same time, separately first, or not at all. (As a general
2189
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2191
Note: A selected-file commit after a merge is not yet supported.
2845
An explanatory message needs to be given for each commit. This is
2846
often done by using the --message option (getting the message from the
2847
command line) or by using the --file option (getting the message from
2848
a file). If neither of these options is given, an editor is opened for
2849
the user to enter the message. To see the changed files in the
2850
boilerplate text loaded into the editor, use the --show-diff option.
2852
By default, the entire tree is committed and the person doing the
2853
commit is assumed to be the author. These defaults can be overridden
2858
If selected files are specified, only changes to those files are
2859
committed. If a directory is specified then the directory and
2860
everything within it is committed.
2862
When excludes are given, they take precedence over selected files.
2863
For example, to commit only changes within foo, but not changes
2866
bzr commit foo -x foo/bar
2868
A selective commit after a merge is not yet supported.
2872
If the author of the change is not the same person as the committer,
2873
you can specify the author's name using the --author option. The
2874
name should be in the same format as a committer-id, e.g.
2875
"John Doe <jdoe@example.com>". If there is more than one author of
2876
the change you can specify the option multiple times, once for each
2881
A common mistake is to forget to add a new file or directory before
2882
running the commit command. The --strict option checks for unknown
2883
files and aborts the commit if any are found. More advanced pre-commit
2884
checks can be implemented by defining hooks. See ``bzr help hooks``
2889
If you accidentially commit the wrong changes or make a spelling
2890
mistake in the commit message say, you can use the uncommit command
2891
to undo it. See ``bzr help uncommit`` for details.
2893
Hooks can also be configured to run after a commit. This allows you
2894
to trigger updates to external systems like bug trackers. The --fixes
2895
option can be used to record the association between a revision and
2896
one or more bugs. See ``bzr help bugs`` for details.
2898
A selective commit may fail in some cases where the committed
2899
tree would be invalid. Consider::
2904
bzr commit foo -m "committing foo"
2905
bzr mv foo/bar foo/baz
2908
bzr commit foo/bar -m "committing bar but not baz"
2910
In the example above, the last commit will fail by design. This gives
2911
the user the opportunity to decide whether they want to commit the
2912
rename at the same time, separately first, or not at all. (As a general
2913
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2193
2915
# TODO: Run hooks on tree to-be-committed, and after commit.
3869
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3870
from bzrlib import lockdir
3871
from bzrlib.smart import medium, server
3872
from bzrlib.transport import get_transport
3873
from bzrlib.transport.chroot import ChrootServer
4727
def get_host_and_port(self, port):
4728
"""Return the host and port to run the smart server on.
4730
If 'port' is None, None will be returned for the host and port.
4732
If 'port' has a colon in it, the string before the colon will be
4733
interpreted as the host.
4735
:param port: A string of the port to run the server on.
4736
:return: A tuple of (host, port), where 'host' is a host name or IP,
4737
and port is an integer TCP/IP port.
4740
if port is not None:
4742
host, port = port.split(':')
4746
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4748
from bzrlib.transport import get_transport, transport_server_registry
3874
4749
if directory is None:
3875
4750
directory = os.getcwd()
4751
if protocol is None:
4752
protocol = transport_server_registry.get()
4753
host, port = self.get_host_and_port(port)
3876
4754
url = urlutils.local_path_to_url(directory)
3877
4755
if not allow_writes:
3878
4756
url = 'readonly+' + url
3879
chroot_server = ChrootServer(get_transport(url))
3880
chroot_server.setUp()
3881
t = get_transport(chroot_server.get_url())
3883
smart_server = medium.SmartServerPipeStreamMedium(
3884
sys.stdin, sys.stdout, t)
3886
host = medium.BZR_DEFAULT_INTERFACE
3888
port = medium.BZR_DEFAULT_PORT
3891
host, port = port.split(':')
3893
smart_server = server.SmartTCPServer(t, host=host, port=port)
3894
print 'listening on port: ', smart_server.port
3896
# for the duration of this server, no UI output is permitted.
3897
# note that this may cause problems with blackbox tests. This should
3898
# be changed with care though, as we dont want to use bandwidth sending
3899
# progress over stderr to smart server clients!
3900
old_factory = ui.ui_factory
3901
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
3903
ui.ui_factory = ui.SilentUIFactory()
3904
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
3905
smart_server.serve()
3907
ui.ui_factory = old_factory
3908
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4757
transport = get_transport(url)
4758
protocol(transport, host, port, inet)
3911
4761
class cmd_join(Command):
3912
"""Combine a subtree into its containing tree.
3914
This command is for experimental use only. It requires the target tree
3915
to be in dirstate-with-subtree format, which cannot be converted into
4762
"""Combine a tree into its containing tree.
4764
This command requires the target tree to be in a rich-root format.
3918
4766
The TREE argument should be an independent tree, inside another tree, but
3919
4767
not part of it. (Such trees can be produced by "bzr split", but also by
4160
5002
help='Write merge directive to this file; '
4161
5003
'use - for stdout.',
5006
help='Refuse to send if there are uncommitted changes in'
5007
' the working tree, --no-strict disables the check.'),
4163
5008
Option('mail-to', help='Mail the request to this address.',
4167
RegistryOption.from_kwargs('format',
4168
'Use the specified output format.',
4169
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4170
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5012
Option('body', help='Body for the email.', type=unicode),
5013
RegistryOption('format',
5014
help='Use the specified output format.',
5015
lazy_registry=('bzrlib.send', 'format_registry')),
4173
5018
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4174
5019
no_patch=False, revision=None, remember=False, output=None,
4175
format='4', mail_to=None, message=None, **kwargs):
4176
return self._run(submit_branch, revision, public_branch, remember,
4177
format, no_bundle, no_patch, output,
4178
kwargs.get('from', '.'), mail_to, message)
4180
def _run(self, submit_branch, revision, public_branch, remember, format,
4181
no_bundle, no_patch, output, from_, mail_to, message):
4182
from bzrlib.revision import NULL_REVISION
4183
branch = Branch.open_containing(from_)[0]
4185
outfile = StringIO()
4189
outfile = open(output, 'wb')
4190
# we may need to write data into branch's repository to calculate
4195
config = branch.get_config()
4197
mail_to = config.get_user_option('submit_to')
4198
mail_client = config.get_mail_client()
4199
if remember and submit_branch is None:
4200
raise errors.BzrCommandError(
4201
'--remember requires a branch to be specified.')
4202
stored_submit_branch = branch.get_submit_branch()
4203
remembered_submit_branch = None
4204
if submit_branch is None:
4205
submit_branch = stored_submit_branch
4206
remembered_submit_branch = "submit"
4208
if stored_submit_branch is None or remember:
4209
branch.set_submit_branch(submit_branch)
4210
if submit_branch is None:
4211
submit_branch = branch.get_parent()
4212
remembered_submit_branch = "parent"
4213
if submit_branch is None:
4214
raise errors.BzrCommandError('No submit branch known or'
4216
if remembered_submit_branch is not None:
4217
note('Using saved %s location "%s" to determine what '
4218
'changes to submit.', remembered_submit_branch,
4222
submit_config = Branch.open(submit_branch).get_config()
4223
mail_to = submit_config.get_user_option("child_submit_to")
4225
stored_public_branch = branch.get_public_branch()
4226
if public_branch is None:
4227
public_branch = stored_public_branch
4228
elif stored_public_branch is None or remember:
4229
branch.set_public_branch(public_branch)
4230
if no_bundle and public_branch is None:
4231
raise errors.BzrCommandError('No public branch specified or'
4233
base_revision_id = None
4235
if revision is not None:
4236
if len(revision) > 2:
4237
raise errors.BzrCommandError('bzr send takes '
4238
'at most two one revision identifiers')
4239
revision_id = revision[-1].as_revision_id(branch)
4240
if len(revision) == 2:
4241
base_revision_id = revision[0].as_revision_id(branch)
4242
if revision_id is None:
4243
revision_id = branch.last_revision()
4244
if revision_id == NULL_REVISION:
4245
raise errors.BzrCommandError('No revisions to submit.')
4247
directive = merge_directive.MergeDirective2.from_objects(
4248
branch.repository, revision_id, time.time(),
4249
osutils.local_time_offset(), submit_branch,
4250
public_branch=public_branch, include_patch=not no_patch,
4251
include_bundle=not no_bundle, message=message,
4252
base_revision_id=base_revision_id)
4253
elif format == '0.9':
4256
patch_type = 'bundle'
4258
raise errors.BzrCommandError('Format 0.9 does not'
4259
' permit bundle with no patch')
4265
directive = merge_directive.MergeDirective.from_objects(
4266
branch.repository, revision_id, time.time(),
4267
osutils.local_time_offset(), submit_branch,
4268
public_branch=public_branch, patch_type=patch_type,
4271
outfile.writelines(directive.to_lines())
4273
subject = '[MERGE] '
4274
if message is not None:
4277
revision = branch.repository.get_revision(revision_id)
4278
subject += revision.get_summary()
4279
basename = directive.get_disk_name(branch)
4280
mail_client.compose_merge_request(mail_to, subject,
4281
outfile.getvalue(), basename)
5020
format=None, mail_to=None, message=None, body=None,
5021
strict=None, **kwargs):
5022
from bzrlib.send import send
5023
return send(submit_branch, revision, public_branch, remember,
5024
format, no_bundle, no_patch, output,
5025
kwargs.get('from', '.'), mail_to, message, body,
4288
5030
class cmd_bundle_revisions(cmd_send):
4290
"""Create a merge-directive for submiting changes.
5031
"""Create a merge-directive for submitting changes.
4292
5033
A merge directive provides many things needed for requesting merges:
4488
5255
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
4489
5256
takes_args = ['location?']
4490
takes_options = [RegistryOption.from_kwargs('target_type',
4491
title='Target type',
4492
help='The type to reconfigure the directory to.',
4493
value_switches=True, enum_switch=False,
4494
branch='Reconfigure to be an unbound branch '
4495
'with no working tree.',
4496
tree='Reconfigure to be an unbound branch '
4497
'with a working tree.',
4498
checkout='Reconfigure to be a bound branch '
4499
'with a working tree.',
4500
lightweight_checkout='Reconfigure to be a lightweight'
4501
' checkout (with no local history).',
4502
standalone='Reconfigure to be a standalone branch '
4503
'(i.e. stop using shared repository).',
4504
use_shared='Reconfigure to use a shared repository.'),
4505
Option('bind-to', help='Branch to bind checkout to.',
4508
help='Perform reconfiguration even if local changes'
5258
RegistryOption.from_kwargs(
5260
title='Target type',
5261
help='The type to reconfigure the directory to.',
5262
value_switches=True, enum_switch=False,
5263
branch='Reconfigure to be an unbound branch with no working tree.',
5264
tree='Reconfigure to be an unbound branch with a working tree.',
5265
checkout='Reconfigure to be a bound branch with a working tree.',
5266
lightweight_checkout='Reconfigure to be a lightweight'
5267
' checkout (with no local history).',
5268
standalone='Reconfigure to be a standalone branch '
5269
'(i.e. stop using shared repository).',
5270
use_shared='Reconfigure to use a shared repository.',
5271
with_trees='Reconfigure repository to create '
5272
'working trees on branches by default.',
5273
with_no_trees='Reconfigure repository to not create '
5274
'working trees on branches by default.'
5276
Option('bind-to', help='Branch to bind checkout to.', type=str),
5278
help='Perform reconfiguration even if local changes'
5280
Option('stacked-on',
5281
help='Reconfigure a branch to be stacked on another branch.',
5285
help='Reconfigure a branch to be unstacked. This '
5286
'may require copying substantial data into it.',
4512
def run(self, location=None, target_type=None, bind_to=None, force=False):
5290
def run(self, location=None, target_type=None, bind_to=None, force=False,
4513
5293
directory = bzrdir.BzrDir.open(location)
5294
if stacked_on and unstacked:
5295
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5296
elif stacked_on is not None:
5297
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5299
reconfigure.ReconfigureUnstacked().apply(directory)
5300
# At the moment you can use --stacked-on and a different
5301
# reconfiguration shape at the same time; there seems no good reason
4514
5303
if target_type is None:
4515
raise errors.BzrCommandError('No target configuration specified')
5304
if stacked_on or unstacked:
5307
raise errors.BzrCommandError('No target configuration '
4516
5309
elif target_type == 'branch':
4517
5310
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4518
5311
elif target_type == 'tree':
4519
5312
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4520
5313
elif target_type == 'checkout':
4521
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
5314
reconfiguration = reconfigure.Reconfigure.to_checkout(
4523
5316
elif target_type == 'lightweight-checkout':
4524
5317
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4525
5318
directory, bind_to)
4547
5346
directory of the current branch. For example, if you are currently in a
4548
5347
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4549
5348
/path/to/newbranch.
5350
Bound branches use the nickname of its master branch unless it is set
5351
locally, in which case switching will update the the local nickname to be
4552
5355
takes_args = ['to_location']
4553
5356
takes_options = [Option('force',
4554
help='Switch even if local commits will be lost.')
5357
help='Switch even if local commits will be lost.'),
5358
Option('create-branch', short_name='b',
5359
help='Create the target branch from this one before'
5360
' switching to it.'),
4557
def run(self, to_location, force=False):
5363
def run(self, to_location, force=False, create_branch=False):
4558
5364
from bzrlib import switch
4559
5365
tree_location = '.'
4560
5366
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4562
to_branch = Branch.open(to_location)
5368
branch = control_dir.open_branch()
5369
had_explicit_nick = branch.get_config().has_explicit_nickname()
4563
5370
except errors.NotBranchError:
4564
to_branch = Branch.open(
4565
control_dir.open_branch().base + '../' + to_location)
5372
had_explicit_nick = False
5375
raise errors.BzrCommandError('cannot create branch without'
5377
if '/' not in to_location and '\\' not in to_location:
5378
# This path is meant to be relative to the existing branch
5379
this_url = self._get_branch_location(control_dir)
5380
to_location = urlutils.join(this_url, '..', to_location)
5381
to_branch = branch.bzrdir.sprout(to_location,
5382
possible_transports=[branch.bzrdir.root_transport],
5383
source_branch=branch).open_branch()
5385
# from_branch = control_dir.open_branch()
5386
# except errors.NotBranchError:
5387
# raise BzrCommandError('Cannot create a branch from this'
5388
# ' location when we cannot open this branch')
5389
# from_branch.bzrdir.sprout(
5393
to_branch = Branch.open(to_location)
5394
except errors.NotBranchError:
5395
this_url = self._get_branch_location(control_dir)
5396
to_branch = Branch.open(
5397
urlutils.join(this_url, '..', to_location))
4566
5398
switch.switch(control_dir, to_branch, force)
5399
if had_explicit_nick:
5400
branch = control_dir.open_branch() #get the new branch!
5401
branch.nick = to_branch.nick
4567
5402
note('Switched to branch: %s',
4568
5403
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5405
def _get_branch_location(self, control_dir):
5406
"""Return location of branch for this control dir."""
5408
this_branch = control_dir.open_branch()
5409
# This may be a heavy checkout, where we want the master branch
5410
master_location = this_branch.get_bound_location()
5411
if master_location is not None:
5412
return master_location
5413
# If not, use a local sibling
5414
return this_branch.base
5415
except errors.NotBranchError:
5416
format = control_dir.find_branch_format()
5417
if getattr(format, 'get_reference', None) is not None:
5418
return format.get_reference(control_dir)
5420
return control_dir.root_transport.base
5423
class cmd_view(Command):
5424
"""Manage filtered views.
5426
Views provide a mask over the tree so that users can focus on
5427
a subset of a tree when doing their work. After creating a view,
5428
commands that support a list of files - status, diff, commit, etc -
5429
effectively have that list of files implicitly given each time.
5430
An explicit list of files can still be given but those files
5431
must be within the current view.
5433
In most cases, a view has a short life-span: it is created to make
5434
a selected change and is deleted once that change is committed.
5435
At other times, you may wish to create one or more named views
5436
and switch between them.
5438
To disable the current view without deleting it, you can switch to
5439
the pseudo view called ``off``. This can be useful when you need
5440
to see the whole tree for an operation or two (e.g. merge) but
5441
want to switch back to your view after that.
5444
To define the current view::
5446
bzr view file1 dir1 ...
5448
To list the current view::
5452
To delete the current view::
5456
To disable the current view without deleting it::
5458
bzr view --switch off
5460
To define a named view and switch to it::
5462
bzr view --name view-name file1 dir1 ...
5464
To list a named view::
5466
bzr view --name view-name
5468
To delete a named view::
5470
bzr view --name view-name --delete
5472
To switch to a named view::
5474
bzr view --switch view-name
5476
To list all views defined::
5480
To delete all views::
5482
bzr view --delete --all
5486
takes_args = ['file*']
5489
help='Apply list or delete action to all views.',
5492
help='Delete the view.',
5495
help='Name of the view to define, list or delete.',
5499
help='Name of the view to switch to.',
5504
def run(self, file_list,
5510
tree, file_list = tree_files(file_list, apply_view=False)
5511
current_view, view_dict = tree.views.get_view_info()
5516
raise errors.BzrCommandError(
5517
"Both --delete and a file list specified")
5519
raise errors.BzrCommandError(
5520
"Both --delete and --switch specified")
5522
tree.views.set_view_info(None, {})
5523
self.outf.write("Deleted all views.\n")
5525
raise errors.BzrCommandError("No current view to delete")
5527
tree.views.delete_view(name)
5528
self.outf.write("Deleted '%s' view.\n" % name)
5531
raise errors.BzrCommandError(
5532
"Both --switch and a file list specified")
5534
raise errors.BzrCommandError(
5535
"Both --switch and --all specified")
5536
elif switch == 'off':
5537
if current_view is None:
5538
raise errors.BzrCommandError("No current view to disable")
5539
tree.views.set_view_info(None, view_dict)
5540
self.outf.write("Disabled '%s' view.\n" % (current_view))
5542
tree.views.set_view_info(switch, view_dict)
5543
view_str = views.view_display_str(tree.views.lookup_view())
5544
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5547
self.outf.write('Views defined:\n')
5548
for view in sorted(view_dict):
5549
if view == current_view:
5553
view_str = views.view_display_str(view_dict[view])
5554
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5556
self.outf.write('No views defined.\n')
5559
# No name given and no current view set
5562
raise errors.BzrCommandError(
5563
"Cannot change the 'off' pseudo view")
5564
tree.views.set_view(name, sorted(file_list))
5565
view_str = views.view_display_str(tree.views.lookup_view())
5566
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5570
# No name given and no current view set
5571
self.outf.write('No current view.\n')
5573
view_str = views.view_display_str(tree.views.lookup_view(name))
5574
self.outf.write("'%s' view is: %s\n" % (name, view_str))
4571
5577
class cmd_hooks(Command):
4572
"""Show a branch's currently registered hooks.
4576
takes_args = ['path?']
4578
def run(self, path=None):
5583
for hook_key in sorted(hooks.known_hooks.keys()):
5584
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5585
self.outf.write("%s:\n" % type(some_hooks).__name__)
5586
for hook_name, hook_point in sorted(some_hooks.items()):
5587
self.outf.write(" %s:\n" % (hook_name,))
5588
found_hooks = list(hook_point)
5590
for hook in found_hooks:
5591
self.outf.write(" %s\n" %
5592
(some_hooks.get_hook_name(hook),))
5594
self.outf.write(" <no hooks installed>\n")
5597
class cmd_shelve(Command):
5598
"""Temporarily set aside some changes from the current tree.
5600
Shelve allows you to temporarily put changes you've made "on the shelf",
5601
ie. out of the way, until a later time when you can bring them back from
5602
the shelf with the 'unshelve' command. The changes are stored alongside
5603
your working tree, and so they aren't propagated along with your branch nor
5604
will they survive its deletion.
5606
If shelve --list is specified, previously-shelved changes are listed.
5608
Shelve is intended to help separate several sets of changes that have
5609
been inappropriately mingled. If you just want to get rid of all changes
5610
and you don't need to restore them later, use revert. If you want to
5611
shelve all text changes at once, use shelve --all.
5613
If filenames are specified, only the changes to those files will be
5614
shelved. Other files will be left untouched.
5616
If a revision is specified, changes since that revision will be shelved.
5618
You can put multiple items on the shelf, and by default, 'unshelve' will
5619
restore the most recently shelved changes.
5622
takes_args = ['file*']
5626
Option('all', help='Shelve all changes.'),
5628
RegistryOption('writer', 'Method to use for writing diffs.',
5629
bzrlib.option.diff_writer_registry,
5630
value_switches=True, enum_switch=False),
5632
Option('list', help='List shelved changes.'),
5634
help='Destroy removed changes instead of shelving them.'),
5636
_see_also = ['unshelve']
5638
def run(self, revision=None, all=False, file_list=None, message=None,
5639
writer=None, list=False, destroy=False):
5641
return self.run_for_list()
5642
from bzrlib.shelf_ui import Shelver
5644
writer = bzrlib.option.diff_writer_registry.get()
5646
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5647
file_list, message, destroy=destroy)
5651
shelver.work_tree.unlock()
5652
except errors.UserAbort:
5655
def run_for_list(self):
5656
tree = WorkingTree.open_containing('.')[0]
5659
manager = tree.get_shelf_manager()
5660
shelves = manager.active_shelves()
5661
if len(shelves) == 0:
5662
note('No shelved changes.')
5664
for shelf_id in reversed(shelves):
5665
message = manager.get_metadata(shelf_id).get('message')
5667
message = '<no message>'
5668
self.outf.write('%3d: %s\n' % (shelf_id, message))
5674
class cmd_unshelve(Command):
5675
"""Restore shelved changes.
5677
By default, the most recently shelved changes are restored. However if you
5678
specify a shelf by id those changes will be restored instead. This works
5679
best when the changes don't depend on each other.
5682
takes_args = ['shelf_id?']
5684
RegistryOption.from_kwargs(
5685
'action', help="The action to perform.",
5686
enum_switch=False, value_switches=True,
5687
apply="Apply changes and remove from the shelf.",
5688
dry_run="Show changes, but do not apply or remove them.",
5689
delete_only="Delete changes without applying them."
5692
_see_also = ['shelve']
5694
def run(self, shelf_id=None, action='apply'):
5695
from bzrlib.shelf_ui import Unshelver
5696
unshelver = Unshelver.from_args(shelf_id, action)
5700
unshelver.tree.unlock()
5703
class cmd_clean_tree(Command):
5704
"""Remove unwanted files from working tree.
5706
By default, only unknown files, not ignored files, are deleted. Versioned
5707
files are never deleted.
5709
Another class is 'detritus', which includes files emitted by bzr during
5710
normal operations and selftests. (The value of these files decreases with
5713
If no options are specified, unknown files are deleted. Otherwise, option
5714
flags are respected, and may be combined.
5716
To check what clean-tree will do, use --dry-run.
5718
takes_options = [Option('ignored', help='Delete all ignored files.'),
5719
Option('detritus', help='Delete conflict files, merge'
5720
' backups, and failed selftest dirs.'),
5722
help='Delete files unknown to bzr (default).'),
5723
Option('dry-run', help='Show files to delete instead of'
5725
Option('force', help='Do not prompt before deleting.')]
5726
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5728
from bzrlib.clean_tree import clean_tree
5729
if not (unknown or ignored or detritus):
5733
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5734
dry_run=dry_run, no_prompt=force)
5737
class cmd_reference(Command):
5738
"""list, view and set branch locations for nested trees.
5740
If no arguments are provided, lists the branch locations for nested trees.
5741
If one argument is provided, display the branch location for that tree.
5742
If two arguments are provided, set the branch location for that tree.
5747
takes_args = ['path?', 'location?']
5749
def run(self, path=None, location=None):
5751
if path is not None:
5753
tree, branch, relpath =(
5754
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5755
if path is not None:
5758
tree = branch.basis_tree()
4579
5759
if path is None:
4581
branch_hooks = Branch.open(path).hooks
4582
for hook_type in branch_hooks:
4583
hooks = branch_hooks[hook_type]
4584
self.outf.write("%s:\n" % (hook_type,))
4587
self.outf.write(" %s\n" %
4588
(branch_hooks.get_hook_name(hook),))
5760
info = branch._get_all_reference_info().iteritems()
5761
self._display_reference_info(tree, branch, info)
5763
file_id = tree.path2id(path)
5765
raise errors.NotVersionedError(path)
5766
if location is None:
5767
info = [(file_id, branch.get_reference_info(file_id))]
5768
self._display_reference_info(tree, branch, info)
4590
self.outf.write(" <no hooks installed>\n")
4593
def _create_prefix(cur_transport):
4594
needed = [cur_transport]
4595
# Recurse upwards until we can create a directory successfully
4597
new_transport = cur_transport.clone('..')
4598
if new_transport.base == cur_transport.base:
4599
raise errors.BzrCommandError(
4600
"Failed to create path prefix for %s."
4601
% cur_transport.base)
4603
new_transport.mkdir('.')
4604
except errors.NoSuchFile:
4605
needed.append(new_transport)
4606
cur_transport = new_transport
4609
# Now we only need to create child directories
4611
cur_transport = needed.pop()
4612
cur_transport.ensure_base()
5770
branch.set_reference_info(file_id, path, location)
5772
def _display_reference_info(self, tree, branch, info):
5774
for file_id, (path, location) in info:
5776
path = tree.id2path(file_id)
5777
except errors.NoSuchId:
5779
ref_list.append((path, location))
5780
for path, location in sorted(ref_list):
5781
self.outf.write('%s %s\n' % (path, location))
4615
5784
# these get imported and then picked up by the scan for cmd_*
4616
5785
# TODO: Some more consistent way to split command definitions across files;
4617
# we do need to load at least some information about them to know of
5786
# we do need to load at least some information about them to know of
4618
5787
# aliases. ideally we would avoid loading the implementation until the
4619
5788
# details were needed.
4620
5789
from bzrlib.cmd_version_info import cmd_version_info