326
215
# TODO: jam 20060112 should cat-revision always output utf-8?
327
216
if revision_id is not None:
328
revision_id = osutils.safe_revision_id(revision_id, warn=False)
330
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
331
except errors.NoSuchRevision:
332
msg = "The repository %s contains no revision %s." % (b.repository.base,
334
raise errors.BzrCommandError(msg)
217
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
335
218
elif revision is not None:
336
219
for rev in revision:
338
221
raise errors.BzrCommandError('You cannot specify a NULL'
340
rev_id = rev.as_revision_id(b)
223
revno, rev_id = rev.in_history(b)
341
224
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
344
class cmd_dump_btree(Command):
345
"""Dump the contents of a btree index file to stdout.
347
PATH is a btree index file, it can be any URL. This includes things like
348
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
350
By default, the tuples stored in the index file will be displayed. With
351
--raw, we will uncompress the pages, but otherwise display the raw bytes
355
# TODO: Do we want to dump the internal nodes as well?
356
# TODO: It would be nice to be able to dump the un-parsed information,
357
# rather than only going through iter_all_entries. However, this is
358
# good enough for a start
360
encoding_type = 'exact'
361
takes_args = ['path']
362
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
363
' rather than the parsed tuples.'),
366
def run(self, path, raw=False):
367
dirname, basename = osutils.split(path)
368
t = transport.get_transport(dirname)
370
self._dump_raw_bytes(t, basename)
372
self._dump_entries(t, basename)
374
def _get_index_and_bytes(self, trans, basename):
375
"""Create a BTreeGraphIndex and raw bytes."""
376
bt = btree_index.BTreeGraphIndex(trans, basename, None)
377
bytes = trans.get_bytes(basename)
378
bt._file = cStringIO.StringIO(bytes)
379
bt._size = len(bytes)
382
def _dump_raw_bytes(self, trans, basename):
385
# We need to parse at least the root node.
386
# This is because the first page of every row starts with an
387
# uncompressed header.
388
bt, bytes = self._get_index_and_bytes(trans, basename)
389
for page_idx, page_start in enumerate(xrange(0, len(bytes),
390
btree_index._PAGE_SIZE)):
391
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
392
page_bytes = bytes[page_start:page_end]
394
self.outf.write('Root node:\n')
395
header_end, data = bt._parse_header_from_bytes(page_bytes)
396
self.outf.write(page_bytes[:header_end])
398
self.outf.write('\nPage %d\n' % (page_idx,))
399
decomp_bytes = zlib.decompress(page_bytes)
400
self.outf.write(decomp_bytes)
401
self.outf.write('\n')
403
def _dump_entries(self, trans, basename):
405
st = trans.stat(basename)
406
except errors.TransportNotPossible:
407
# We can't stat, so we'll fake it because we have to do the 'get()'
409
bt, _ = self._get_index_and_bytes(trans, basename)
411
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
412
for node in bt.iter_all_entries():
413
# Node is made up of:
414
# (index, key, value, [references])
415
self.outf.write('%s\n' % (node[1:],))
418
227
class cmd_remove_tree(Command):
419
228
"""Remove the working tree from a given branch/checkout.
978
663
_see_also = ['pull', 'update', 'working-trees']
979
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
664
takes_options = ['remember', 'overwrite', 'verbose',
980
665
Option('create-prefix',
981
666
help='Create the path leading up to the branch '
982
'if it does not already exist.'),
667
'if it does not already exist'),
983
668
Option('directory',
984
help='Branch to push from, '
985
'rather than the one containing the working directory.',
669
help='branch to push from, '
670
'rather than the one containing the working directory',
989
674
Option('use-existing-dir',
990
675
help='By default push will fail if the target'
991
676
' directory exists, but does not already'
992
' have a control directory. This flag will'
677
' have a control directory. This flag will'
993
678
' allow push to proceed.'),
995
help='Create a stacked branch that references the public location '
996
'of the parent branch.'),
998
help='Create a stacked branch that refers to another branch '
999
'for the commit history. Only the work not present in the '
1000
'referenced branch is included in the branch created.',
1003
680
takes_args = ['location?']
1004
681
encoding_type = 'replace'
1006
683
def run(self, location=None, remember=False, overwrite=False,
1007
create_prefix=False, verbose=False, revision=None,
1008
use_existing_dir=False, directory=None, stacked_on=None,
1010
from bzrlib.push import _show_push_branch
1012
# Get the source branch and revision_id
684
create_prefix=False, verbose=False,
685
use_existing_dir=False,
687
# FIXME: Way too big! Put this into a function called from the
1013
689
if directory is None:
1015
691
br_from = Branch.open_containing(directory)[0]
1016
revision = _get_one_revision('push', revision)
1017
if revision is not None:
1018
revision_id = revision.in_history(br_from).rev_id
1020
revision_id = br_from.last_revision()
1022
# Get the stacked_on branch, if any
1023
if stacked_on is not None:
1024
stacked_on = urlutils.normalize_url(stacked_on)
1026
parent_url = br_from.get_parent()
1028
parent = Branch.open(parent_url)
1029
stacked_on = parent.get_public_branch()
1031
# I considered excluding non-http url's here, thus forcing
1032
# 'public' branches only, but that only works for some
1033
# users, so it's best to just depend on the user spotting an
1034
# error by the feedback given to them. RBC 20080227.
1035
stacked_on = parent_url
1037
raise errors.BzrCommandError(
1038
"Could not determine branch to refer to.")
1040
# Get the destination location
692
stored_loc = br_from.get_push_location()
1041
693
if location is None:
1042
stored_loc = br_from.get_push_location()
1043
694
if stored_loc is None:
1044
raise errors.BzrCommandError(
1045
"No push location known or specified.")
695
raise errors.BzrCommandError("No push location known or specified.")
1047
697
display_url = urlutils.unescape_for_display(stored_loc,
1048
698
self.outf.encoding)
1049
self.outf.write("Using saved push location: %s\n" % display_url)
699
self.outf.write("Using saved location: %s\n" % display_url)
1050
700
location = stored_loc
1052
_show_push_branch(br_from, revision_id, location, self.outf,
1053
verbose=verbose, overwrite=overwrite, remember=remember,
1054
stacked_on=stacked_on, create_prefix=create_prefix,
1055
use_existing_dir=use_existing_dir)
702
to_transport = transport.get_transport(location)
704
br_to = repository_to = dir_to = None
706
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
707
except errors.NotBranchError:
708
pass # Didn't find anything
710
# If we can open a branch, use its direct repository, otherwise see
711
# if there is a repository without a branch.
713
br_to = dir_to.open_branch()
714
except errors.NotBranchError:
715
# Didn't find a branch, can we find a repository?
717
repository_to = dir_to.find_repository()
718
except errors.NoRepositoryPresent:
721
# Found a branch, so we must have found a repository
722
repository_to = br_to.repository
726
# The destination doesn't exist; create it.
727
# XXX: Refactor the create_prefix/no_create_prefix code into a
728
# common helper function
730
to_transport.mkdir('.')
731
except errors.FileExists:
732
if not use_existing_dir:
733
raise errors.BzrCommandError("Target directory %s"
734
" already exists, but does not have a valid .bzr"
735
" directory. Supply --use-existing-dir to push"
736
" there anyway." % location)
737
except errors.NoSuchFile:
738
if not create_prefix:
739
raise errors.BzrCommandError("Parent directory of %s"
741
"\nYou may supply --create-prefix to create all"
742
" leading parent directories."
745
_create_prefix(to_transport)
747
# Now the target directory exists, but doesn't have a .bzr
748
# directory. So we need to create it, along with any work to create
749
# all of the dependent branches, etc.
750
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
751
revision_id=br_from.last_revision())
752
br_to = dir_to.open_branch()
753
# TODO: Some more useful message about what was copied
754
note('Created new branch.')
755
# We successfully created the target, remember it
756
if br_from.get_push_location() is None or remember:
757
br_from.set_push_location(br_to.base)
758
elif repository_to is None:
759
# we have a bzrdir but no branch or repository
760
# XXX: Figure out what to do other than complain.
761
raise errors.BzrCommandError("At %s you have a valid .bzr control"
762
" directory, but not a branch or repository. This is an"
763
" unsupported configuration. Please move the target directory"
764
" out of the way and try again."
767
# We have a repository but no branch, copy the revisions, and then
769
last_revision_id = br_from.last_revision()
770
repository_to.fetch(br_from.repository,
771
revision_id=last_revision_id)
772
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
773
note('Created new branch.')
774
if br_from.get_push_location() is None or remember:
775
br_from.set_push_location(br_to.base)
776
else: # We have a valid to branch
777
# We were able to connect to the remote location, so remember it
778
# we don't need to successfully push because of possible divergence.
779
if br_from.get_push_location() is None or remember:
780
br_from.set_push_location(br_to.base)
781
old_rh = br_to.revision_history()
784
tree_to = dir_to.open_workingtree()
785
except errors.NotLocalUrl:
786
warning("This transport does not update the working "
787
"tree of: %s. See 'bzr help working-trees' for "
788
"more information." % br_to.base)
789
push_result = br_from.push(br_to, overwrite)
790
except errors.NoWorkingTree:
791
push_result = br_from.push(br_to, overwrite)
795
push_result = br_from.push(tree_to.branch, overwrite)
799
except errors.DivergedBranches:
800
raise errors.BzrCommandError('These branches have diverged.'
801
' Try using "merge" and then "push".')
802
if push_result is not None:
803
push_result.report(self.outf)
805
new_rh = br_to.revision_history()
808
from bzrlib.log import show_changed_revisions
809
show_changed_revisions(br_to, old_rh, new_rh,
812
# we probably did a clone rather than a push, so a message was
1058
817
class cmd_branch(Command):
1908
1563
raise errors.BzrCommandError(msg)
1911
def _parse_levels(s):
1915
msg = "The levels argument must be an integer."
1916
raise errors.BzrCommandError(msg)
1919
1566
class cmd_log(Command):
1920
"""Show historical log for a branch or subset of a branch.
1922
log is bzr's default tool for exploring the history of a branch.
1923
The branch to use is taken from the first parameter. If no parameters
1924
are given, the branch containing the working directory is logged.
1925
Here are some simple examples::
1927
bzr log log the current branch
1928
bzr log foo.py log a file in its branch
1929
bzr log http://server/branch log a branch on a server
1931
The filtering, ordering and information shown for each revision can
1932
be controlled as explained below. By default, all revisions are
1933
shown sorted (topologically) so that newer revisions appear before
1934
older ones and descendants always appear before ancestors. If displayed,
1935
merged revisions are shown indented under the revision in which they
1940
The log format controls how information about each revision is
1941
displayed. The standard log formats are called ``long``, ``short``
1942
and ``line``. The default is long. See ``bzr help log-formats``
1943
for more details on log formats.
1945
The following options can be used to control what information is
1948
-l N display a maximum of N revisions
1949
-n N display N levels of revisions (0 for all, 1 for collapsed)
1950
-v display a status summary (delta) for each revision
1951
-p display a diff (patch) for each revision
1952
--show-ids display revision-ids (and file-ids), not just revnos
1954
Note that the default number of levels to display is a function of the
1955
log format. If the -n option is not used, the standard log formats show
1956
just the top level (mainline).
1958
Status summaries are shown using status flags like A, M, etc. To see
1959
the changes explained using words like ``added`` and ``modified``
1960
instead, use the -vv option.
1964
To display revisions from oldest to newest, use the --forward option.
1965
In most cases, using this option will have little impact on the total
1966
time taken to produce a log, though --forward does not incrementally
1967
display revisions like --reverse does when it can.
1969
:Revision filtering:
1971
The -r option can be used to specify what revision or range of revisions
1972
to filter against. The various forms are shown below::
1974
-rX display revision X
1975
-rX.. display revision X and later
1976
-r..Y display up to and including revision Y
1977
-rX..Y display from X to Y inclusive
1979
See ``bzr help revisionspec`` for details on how to specify X and Y.
1980
Some common examples are given below::
1982
-r-1 show just the tip
1983
-r-10.. show the last 10 mainline revisions
1984
-rsubmit:.. show what's new on this branch
1985
-rancestor:path.. show changes since the common ancestor of this
1986
branch and the one at location path
1987
-rdate:yesterday.. show changes since yesterday
1989
When logging a range of revisions using -rX..Y, log starts at
1990
revision Y and searches back in history through the primary
1991
("left-hand") parents until it finds X. When logging just the
1992
top level (using -n1), an error is reported if X is not found
1993
along the way. If multi-level logging is used (-n0), X may be
1994
a nested merge revision and the log will be truncated accordingly.
1998
If parameters are given and the first one is not a branch, the log
1999
will be filtered to show only those revisions that changed the
2000
nominated files or directories.
2002
Filenames are interpreted within their historical context. To log a
2003
deleted file, specify a revision range so that the file existed at
2004
the end or start of the range.
2006
Historical context is also important when interpreting pathnames of
2007
renamed files/directories. Consider the following example:
2009
* revision 1: add tutorial.txt
2010
* revision 2: modify tutorial.txt
2011
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2015
* ``bzr log guide.txt`` will log the file added in revision 1
2017
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2019
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2020
the original file in revision 2.
2022
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2023
was no file called guide.txt in revision 2.
2025
Renames are always followed by log. By design, there is no need to
2026
explicitly ask for this (and no way to stop logging a file back
2027
until it was last renamed).
2031
The --message option can be used for finding revisions that match a
2032
regular expression in a commit message.
2036
GUI tools and IDEs are often better at exploring history than command
2037
line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2038
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2039
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2041
Web interfaces are often better at exploring history than command line
2042
tools, particularly for branches on servers. You may prefer Loggerhead
2043
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2045
You may find it useful to add the aliases below to ``bazaar.conf``::
2049
top = log -l10 --line
2052
``bzr tip`` will then show the latest revision while ``bzr top``
2053
will show the last 10 mainline revisions. To see the details of a
2054
particular revision X, ``bzr show -rX``.
2056
If you are interested in looking deeper into a particular merge X,
2057
use ``bzr log -n0 -rX``.
2059
``bzr log -v`` on a branch with lots of history is currently
2060
very slow. A fix for this issue is currently under development.
2061
With or without that fix, it is recommended that a revision range
2062
be given when using the -v option.
2064
bzr has a generic full-text matching plugin, bzr-search, that can be
2065
used to find revisions matching user names, commit messages, etc.
2066
Among other features, this plugin can find all revisions containing
2067
a list of words but not others.
2069
When exploring non-mainline history on large projects with deep
2070
history, the performance of log can be greatly improved by installing
2071
the revnocache plugin. This plugin buffers historical information
2072
trading disk space for faster speed.
1567
"""Show log of a branch, file, or directory.
1569
By default show the log of the branch containing the working directory.
1571
To request a range of logs, you can use the command -r begin..end
1572
-r revision requests a specific revision, -r ..end or -r begin.. are
1578
bzr log -r -10.. http://server/branch
2074
takes_args = ['file*']
2075
_see_also = ['log-formats', 'revisionspec']
2078
help='Show from oldest to newest.'),
2080
custom_help('verbose',
2081
help='Show files changed in each revision.'),
2085
type=bzrlib.option._parse_revision_str,
2087
help='Show just the specified revision.'
2088
' See also "help revisionspec".'),
2092
help='Number of levels to display - 0 for all, 1 for flat.',
2094
type=_parse_levels),
2097
help='Show revisions whose message matches this '
2098
'regular expression.',
2102
help='Limit the output to the first N revisions.',
2107
help='Show changes made in each revision as a patch.'),
1581
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1583
takes_args = ['location?']
1584
takes_options = [Option('forward',
1585
help='show from oldest to newest'),
1589
help='show files changed in each revision'),
1590
'show-ids', 'revision',
1594
help='show revisions whose message matches this regexp',
1597
help='limit the output to the first N revisions',
2109
1600
encoding_type = 'replace'
2111
1602
@display_command
2112
def run(self, file_list=None, timezone='original',
1603
def run(self, location=None, timezone='original',
2114
1605
show_ids=False,
2118
1608
log_format=None,
2123
from bzrlib.log import (
2125
make_log_request_dict,
2126
_get_info_for_log_files,
1611
from bzrlib.log import show_log
1612
assert message is None or isinstance(message, basestring), \
1613
"invalid message argument %r" % message
2128
1614
direction = (forward and 'forward') or 'reverse'
2130
if change is not None:
2132
raise errors.RangeInChangeOption()
2133
if revision is not None:
2134
raise errors.BzrCommandError(
2135
'--revision and --change are mutually exclusive')
2140
filter_by_dir = False
2142
# find the file ids to log and check for directory filtering
2143
b, file_info_list, rev1, rev2 = _get_info_for_log_files(revision,
2145
for relpath, file_id, kind in file_info_list:
1619
# find the file id to log:
1621
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1625
tree = b.basis_tree()
1626
file_id = tree.path2id(fp)
2146
1627
if file_id is None:
2147
1628
raise errors.BzrCommandError(
2148
"Path unknown at end or start of revision range: %s" %
2150
# If the relpath is the top of the tree, we log everything
2155
file_ids.append(file_id)
2156
filter_by_dir = filter_by_dir or (
2157
kind in ['directory', 'tree-reference'])
1629
"Path does not have any revision history: %s" %
2160
# FIXME ? log the current subdir only RBC 20060203
1633
# FIXME ? log the current subdir only RBC 20060203
2161
1634
if revision is not None \
2162
1635
and len(revision) > 0 and revision[0].get_branch():
2163
1636
location = revision[0].get_branch()
2166
1639
dir, relpath = bzrdir.BzrDir.open_containing(location)
2167
1640
b = dir.open_branch()
2168
rev1, rev2 = _get_revision_range(revision, b, self.name())
2170
# Decide on the type of delta & diff filtering to use
2171
# TODO: add an --all-files option to make this configurable & consistent
2179
diff_type = 'partial'
2185
# Build the log formatter
1644
if revision is None:
1647
elif len(revision) == 1:
1648
rev1 = rev2 = revision[0].in_history(b)
1649
elif len(revision) == 2:
1650
if revision[1].get_branch() != revision[0].get_branch():
1651
# b is taken from revision[0].get_branch(), and
1652
# show_log will use its revision_history. Having
1653
# different branches will lead to weird behaviors.
1654
raise errors.BzrCommandError(
1655
"Log doesn't accept two revisions in different"
1657
rev1 = revision[0].in_history(b)
1658
rev2 = revision[1].in_history(b)
1660
raise errors.BzrCommandError(
1661
'bzr log --revision takes one or two values.')
2186
1663
if log_format is None:
2187
1664
log_format = log.log_formatter_registry.get_default(b)
2188
1666
lf = log_format(show_ids=show_ids, to_file=self.outf,
2189
show_timezone=timezone,
2190
delta_format=get_verbosity_level(),
2193
# Choose the algorithm for doing the logging. It's annoying
2194
# having multiple code paths like this but necessary until
2195
# the underlying repository format is faster at generating
2196
# deltas or can provide everything we need from the indices.
2197
# The default algorithm - match-using-deltas - works for
2198
# multiple files and directories and is faster for small
2199
# amounts of history (200 revisions say). However, it's too
2200
# slow for logging a single file in a repository with deep
2201
# history, i.e. > 10K revisions. In the spirit of "do no
2202
# evil when adding features", we continue to use the
2203
# original algorithm - per-file-graph - for the "single
2204
# file that isn't a directory without showing a delta" case.
2205
partial_history = revision and b.repository._format.supports_chks
2206
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2207
or delta_type or partial_history)
2209
# Build the LogRequest and execute it
2210
if len(file_ids) == 0:
2212
rqst = make_log_request_dict(
2213
direction=direction, specific_fileids=file_ids,
2214
start_revision=rev1, end_revision=rev2, limit=limit,
2215
message_search=message, delta_type=delta_type,
2216
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2217
Logger(b, rqst).show(lf)
1667
show_timezone=timezone)
1673
direction=direction,
1674
start_revision=rev1,
2222
def _get_revision_range(revisionspec_list, branch, command_name):
2223
"""Take the input of a revision option and turn it into a revision range.
2225
It returns RevisionInfo objects which can be used to obtain the rev_id's
2226
of the desired revisions. It does some user input validations.
2228
if revisionspec_list is None:
2231
elif len(revisionspec_list) == 1:
2232
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2233
elif len(revisionspec_list) == 2:
2234
start_spec = revisionspec_list[0]
2235
end_spec = revisionspec_list[1]
2236
if end_spec.get_branch() != start_spec.get_branch():
2237
# b is taken from revision[0].get_branch(), and
2238
# show_log will use its revision_history. Having
2239
# different branches will lead to weird behaviors.
2240
raise errors.BzrCommandError(
2241
"bzr %s doesn't accept two revisions in different"
2242
" branches." % command_name)
2243
rev1 = start_spec.in_history(branch)
2244
# Avoid loading all of history when we know a missing
2245
# end of range means the last revision ...
2246
if end_spec.spec is None:
2247
last_revno, last_revision_id = branch.last_revision_info()
2248
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2250
rev2 = end_spec.in_history(branch)
2252
raise errors.BzrCommandError(
2253
'bzr %s --revision takes one or two values.' % command_name)
2257
def _revision_range_to_revid_range(revision_range):
2260
if revision_range[0] is not None:
2261
rev_id1 = revision_range[0].rev_id
2262
if revision_range[1] is not None:
2263
rev_id2 = revision_range[1].rev_id
2264
return rev_id1, rev_id2
2266
1682
def get_log_format(long=False, short=False, line=False, default='long'):
2267
1683
log_format = default
2745
2095
_see_also = ['bugs', 'uncommit']
2746
2096
takes_args = ['selected*']
2748
ListOption('exclude', type=str, short_name='x',
2749
help="Do not consider changes made to a given path."),
2750
Option('message', type=unicode,
2752
help="Description of the new revision."),
2755
help='Commit even if nothing has changed.'),
2756
Option('file', type=str,
2759
help='Take commit message from this file.'),
2761
help="Refuse to commit if there are unknown "
2762
"files in the working tree."),
2763
ListOption('fixes', type=str,
2764
help="Mark a bug as being fixed by this revision "
2765
"(see \"bzr help bugs\")."),
2766
ListOption('author', type=unicode,
2767
help="Set the author's name, if it's different "
2768
"from the committer."),
2770
help="Perform a local commit in a bound "
2771
"branch. Local commits are not pushed to "
2772
"the master branch until a normal commit "
2776
help='When no message is supplied, show the diff along'
2777
' with the status summary in the message editor.'),
2097
takes_options = ['message', 'verbose',
2099
help='commit even if nothing has changed'),
2100
Option('file', type=str,
2103
help='file containing commit message'),
2105
help="refuse to commit if there are unknown "
2106
"files in the working tree."),
2107
ListOption('fixes', type=str,
2108
help="mark a bug as being fixed by this "
2111
help="perform a local only commit in a bound "
2112
"branch. Such commits are not pushed to "
2113
"the master branch until a normal commit "
2779
2117
aliases = ['ci', 'checkin']
2781
def _iter_bug_fix_urls(self, fixes, branch):
2119
def _get_bug_fix_properties(self, fixes, branch):
2782
2121
# Configure the properties for bug fixing attributes.
2783
2122
for fixed_bug in fixes:
2784
2123
tokens = fixed_bug.split(':')
2785
2124
if len(tokens) != 2:
2786
2125
raise errors.BzrCommandError(
2787
"Invalid bug %s. Must be in the form of 'tracker:id'. "
2788
"See \"bzr help bugs\" for more information on this "
2789
"feature.\nCommit refused." % fixed_bug)
2126
"Invalid bug %s. Must be in the form of 'tag:id'. "
2127
"Commit refused." % fixed_bug)
2790
2128
tag, bug_id = tokens
2792
yield bugtracker.get_bug_url(tag, branch, bug_id)
2130
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2793
2131
except errors.UnknownBugTrackerAbbreviation:
2794
2132
raise errors.BzrCommandError(
2795
2133
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2796
except errors.MalformedBugIdentifier, e:
2134
except errors.MalformedBugIdentifier:
2797
2135
raise errors.BzrCommandError(
2798
"%s\nCommit refused." % (str(e),))
2136
"Invalid bug identifier for %s. Commit refused."
2138
properties.append('%s fixed' % bug_url)
2139
return '\n'.join(properties)
2800
def run(self, message=None, file=None, verbose=False, selected_list=None,
2801
unchanged=False, strict=False, local=False, fixes=None,
2802
author=None, show_diff=False, exclude=None):
2803
from bzrlib.errors import (
2808
from bzrlib.msgeditor import (
2809
edit_commit_message_encoded,
2810
generate_commit_message_template,
2811
make_commit_message_template_encoded
2141
def run(self, message=None, file=None, verbose=True, selected_list=None,
2142
unchanged=False, strict=False, local=False, fixes=None):
2143
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2144
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2146
from bzrlib.msgeditor import edit_commit_message, \
2147
make_commit_message_template
2814
2149
# TODO: Need a blackbox test for invoking the external editor; may be
2815
2150
# slightly problematic to run this cross-platform.
2817
# TODO: do more checks that the commit will succeed before
2152
# TODO: do more checks that the commit will succeed before
2818
2153
# spending the user's valuable time typing a commit message.
2820
2155
properties = {}
3178
2394
takes_args = ['testspecs*']
3179
2395
takes_options = ['verbose',
3181
help='Stop when one test fails.',
2397
help='stop when one test fails',
3182
2398
short_name='1',
2400
Option('keep-output',
2401
help='keep output directories when tests fail'),
3184
2402
Option('transport',
3185
2403
help='Use a different transport by default '
3186
2404
'throughout the test suite.',
3187
2405
type=get_transport_type),
3189
help='Run the benchmarks rather than selftests.'),
2406
Option('benchmark', help='run the bzr benchmarks.'),
3190
2407
Option('lsprof-timed',
3191
help='Generate lsprof output for benchmarked'
2408
help='generate lsprof output for benchmarked'
3192
2409
' sections of code.'),
3193
2410
Option('cache-dir', type=str,
3194
help='Cache intermediate benchmark output in this '
2411
help='a directory to cache intermediate'
2412
' benchmark steps'),
2413
Option('clean-output',
2414
help='clean temporary tests directories'
2415
' without running tests'),
3196
2416
Option('first',
3197
help='Run all tests, but run specified tests first.',
2417
help='run all tests, but run specified tests first',
3198
2418
short_name='f',
2420
Option('numbered-dirs',
2421
help='use numbered dirs for TestCaseInTempDir'),
3200
2422
Option('list-only',
3201
help='List the tests instead of running them.'),
3202
RegistryOption('parallel',
3203
help="Run the test suite in parallel.",
3204
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3205
value_switches=False,
2423
help='list the tests instead of running them'),
3207
2424
Option('randomize', type=str, argname="SEED",
3208
help='Randomize the order of tests using the given'
3209
' seed or "now" for the current time.'),
2425
help='randomize the order of tests using the given'
2426
' seed or "now" for the current time'),
3210
2427
Option('exclude', type=str, argname="PATTERN",
3211
2428
short_name='x',
3212
help='Exclude tests that match this regular'
3215
help='Output test progress via subunit.'),
3216
Option('strict', help='Fail on missing dependencies or '
3218
Option('load-list', type=str, argname='TESTLISTFILE',
3219
help='Load a test id list from a text file.'),
3220
ListOption('debugflag', type=str, short_name='E',
3221
help='Turn on a selftest debug flag.'),
3222
ListOption('starting-with', type=str, argname='TESTID',
3223
param_name='starting_with', short_name='s',
3225
'Load only the tests starting with TESTID.'),
2429
help='exclude tests that match this regular'
3227
2432
encoding_type = 'replace'
3230
Command.__init__(self)
3231
self.additional_selftest_args = {}
3233
def run(self, testspecs_list=None, verbose=False, one=False,
3234
transport=None, benchmark=None,
3235
lsprof_timed=None, cache_dir=None,
3236
first=False, list_only=False,
3237
randomize=None, exclude=None, strict=False,
3238
load_list=None, debugflag=None, starting_with=None, subunit=False,
2434
def run(self, testspecs_list=None, verbose=None, one=False,
2435
keep_output=False, transport=None, benchmark=None,
2436
lsprof_timed=None, cache_dir=None, clean_output=False,
2437
first=False, numbered_dirs=None, list_only=False,
2438
randomize=None, exclude=None):
3240
2440
from bzrlib.tests import selftest
3241
2441
import bzrlib.benchmarks as benchmarks
3242
2442
from bzrlib.benchmarks import tree_creator
3244
# Make deprecation warnings visible, unless -Werror is set
3245
symbol_versioning.activate_deprecation_warnings(override=False)
2445
from bzrlib.tests import clean_selftest_output
2446
clean_selftest_output()
2449
warning("notice: selftest --keep-output "
2450
"is no longer supported; "
2451
"test output is always removed")
2453
if numbered_dirs is None and sys.platform == 'win32':
2454
numbered_dirs = True
3247
2456
if cache_dir is not None:
3248
2457
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3250
print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
3251
print ' %s (%s python%s)' % (
3253
bzrlib.version_string,
3254
bzrlib._format_version_tuple(sys.version_info),
2458
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2459
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
3257
2461
if testspecs_list is not None:
3258
2462
pattern = '|'.join(testspecs_list)
3263
from bzrlib.tests import SubUnitBzrRunner
3265
raise errors.BzrCommandError("subunit not available. subunit "
3266
"needs to be installed to use --subunit.")
3267
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3269
self.additional_selftest_args.setdefault(
3270
'suite_decorators', []).append(parallel)
3272
2466
test_suite_factory = benchmarks.test_suite
3273
# Unless user explicitly asks for quiet, be verbose in benchmarks
3274
verbose = not is_quiet()
3275
2469
# TODO: should possibly lock the history file...
3276
2470
benchfile = open(".perf_history", "at", buffering=1)
3278
2472
test_suite_factory = None
3279
2475
benchfile = None
3281
selftest_kwargs = {"verbose": verbose,
3283
"stop_on_failure": one,
3284
"transport": transport,
3285
"test_suite_factory": test_suite_factory,
3286
"lsprof_timed": lsprof_timed,
3287
"bench_history": benchfile,
3288
"matching_tests_first": first,
3289
"list_only": list_only,
3290
"random_seed": randomize,
3291
"exclude_pattern": exclude,
3293
"load_list": load_list,
3294
"debug_flags": debugflag,
3295
"starting_with": starting_with
3297
selftest_kwargs.update(self.additional_selftest_args)
3298
result = selftest(**selftest_kwargs)
2477
result = selftest(verbose=verbose,
2479
stop_on_failure=one,
2480
transport=transport,
2481
test_suite_factory=test_suite_factory,
2482
lsprof_timed=lsprof_timed,
2483
bench_history=benchfile,
2484
matching_tests_first=first,
2485
numbered_dirs=numbered_dirs,
2486
list_only=list_only,
2487
random_seed=randomize,
2488
exclude_pattern=exclude
3300
2491
if benchfile is not None:
3301
2492
benchfile.close()
3303
note('tests passed')
2494
info('tests passed')
3305
note('tests failed')
2496
info('tests failed')
3306
2497
return int(not result)
3309
2500
class cmd_version(Command):
3310
2501
"""Show version of bzr."""
3312
encoding_type = 'replace'
3314
Option("short", help="Print just the version number."),
3317
2503
@display_command
3318
def run(self, short=False):
3319
2505
from bzrlib.version import show_version
3321
self.outf.write(bzrlib.version_string + '\n')
3323
show_version(to_file=self.outf)
3326
2509
class cmd_rocks(Command):
3398
2568
directory, where they can be reviewed (with bzr diff), tested, and then
3399
2569
committed to record the result of the merge.
2573
To merge the latest revision from bzr.dev:
2574
bzr merge ../bzr.dev
2576
To merge changes up to and including revision 82 from bzr.dev:
2577
bzr merge -r 82 ../bzr.dev
2579
To merge the changes introduced by 82, without previous changes:
2580
bzr merge -r 81..82 ../bzr.dev
3401
2582
merge refuses to run if there are any uncommitted changes, unless
3402
2583
--force is given.
3405
To merge the latest revision from bzr.dev::
3407
bzr merge ../bzr.dev
3409
To merge changes up to and including revision 82 from bzr.dev::
3411
bzr merge -r 82 ../bzr.dev
3413
To merge the changes introduced by 82, without previous changes::
3415
bzr merge -r 81..82 ../bzr.dev
3417
To apply a merge directive contained in /tmp/merge:
3419
bzr merge /tmp/merge
3422
encoding_type = 'exact'
3423
_see_also = ['update', 'remerge', 'status-flags', 'send']
3424
takes_args = ['location?']
3429
help='Merge even if the destination tree has uncommitted changes.'),
2586
_see_also = ['update', 'remerge', 'status-flags']
2587
takes_args = ['branch?']
2588
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
3433
2589
Option('show-base', help="Show base revision text in "
3435
2591
Option('uncommitted', help='Apply uncommitted changes'
3436
' from a working copy, instead of branch changes.'),
2592
' from a working copy, instead of branch changes'),
3437
2593
Option('pull', help='If the destination is already'
3438
2594
' completely merged into the source, pull from the'
3439
' source rather than merging. When this happens,'
2595
' source rather than merging. When this happens,'
3440
2596
' you do not need to commit the result.'),
3441
2597
Option('directory',
3442
help='Branch to merge into, '
3443
'rather than the one containing the working directory.',
3447
Option('preview', help='Instead of merging, show a diff of the merge.')
2598
help='Branch to merge into, '
2599
'rather than the one containing the working directory',
3450
def run(self, location=None, revision=None, force=False,
3451
merge_type=None, show_base=False, reprocess=None, remember=False,
2605
def run(self, branch=None, revision=None, force=False, merge_type=None,
2606
show_base=False, reprocess=False, remember=False,
3452
2607
uncommitted=False, pull=False,
3453
2608
directory=None,
2610
from bzrlib.tag import _merge_tags_if_possible
2611
other_revision_id = None
3456
2612
if merge_type is None:
3457
2613
merge_type = _mod_merge.Merge3Merger
3459
2615
if directory is None: directory = u'.'
3460
possible_transports = []
3462
allow_pending = True
3463
verified = 'inapplicable'
2616
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2617
# inventory. Because merge is a mutating operation, it really
2618
# should be a lock_write() for the whole cmd_merge operation.
2619
# However, cmd_merge open's its own tree in _merge_helper, which
2620
# means if we lock here, the later lock_write() will always block.
2621
# Either the merge helper code should be updated to take a tree,
2622
# (What about tree.merge_from_branch?)
3464
2623
tree = WorkingTree.open_containing(directory)[0]
3466
# die as quickly as possible if there are uncommitted changes
3468
basis_tree = tree.revision_tree(tree.last_revision())
3469
except errors.NoSuchRevision:
3470
basis_tree = tree.basis_tree()
3472
changes = tree.changes_from(basis_tree)
3473
if changes.has_changed():
3474
raise errors.UncommittedChanges(tree)
3476
view_info = _get_view_info_for_change_reporter(tree)
3477
2624
change_reporter = delta._ChangeReporter(
3478
unversioned_filter=tree.is_ignored, view_info=view_info)
3481
pb = ui.ui_factory.nested_progress_bar()
3482
cleanups.append(pb.finished)
3484
cleanups.append(tree.unlock)
3485
if location is not None:
3487
mergeable = bundle.read_mergeable_from_url(location,
3488
possible_transports=possible_transports)
3489
except errors.NotABundle:
2625
unversioned_filter=tree.is_ignored)
2627
if branch is not None:
2629
mergeable = bundle.read_mergeable_from_url(
2631
except errors.NotABundle:
2632
pass # Continue on considering this url a Branch
2634
if revision is not None:
2635
raise errors.BzrCommandError(
2636
'Cannot use -r with merge directives or bundles')
2637
other_revision_id = mergeable.install_revisions(
2638
tree.branch.repository)
2639
revision = [RevisionSpec.from_string(
2640
'revid:' + other_revision_id)]
2642
if revision is None \
2643
or len(revision) < 1 or revision[0].needs_branch():
2644
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2646
if revision is None or len(revision) < 1:
2649
other = [branch, None]
2652
other = [branch, -1]
2653
other_branch, path = Branch.open_containing(branch)
2656
raise errors.BzrCommandError('Cannot use --uncommitted and'
2657
' --revision at the same time.')
2658
branch = revision[0].get_branch() or branch
2659
if len(revision) == 1:
2661
if other_revision_id is not None:
3493
raise errors.BzrCommandError('Cannot use --uncommitted'
3494
' with bundles or merge directives.')
3496
if revision is not None:
3497
raise errors.BzrCommandError(
3498
'Cannot use -r with merge directives or bundles')
3499
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3502
if merger is None and uncommitted:
3503
if revision is not None and len(revision) > 0:
3504
raise errors.BzrCommandError('Cannot use --uncommitted and'
3505
' --revision at the same time.')
3506
location = self._select_branch_location(tree, location)[0]
3507
other_tree, other_path = WorkingTree.open_containing(location)
3508
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3510
allow_pending = False
3511
if other_path != '':
3512
merger.interesting_files = [other_path]
3515
merger, allow_pending = self._get_merger_from_branch(tree,
3516
location, revision, remember, possible_transports, pb)
3518
merger.merge_type = merge_type
3519
merger.reprocess = reprocess
3520
merger.show_base = show_base
3521
self.sanity_check_merger(merger)
3522
if (merger.base_rev_id == merger.other_rev_id and
3523
merger.other_rev_id is not None):
3524
note('Nothing to do.')
2666
other_branch, path = Branch.open_containing(branch)
2667
revno = revision[0].in_history(other_branch).revno
2668
other = [branch, revno]
2670
assert len(revision) == 2
2671
if None in revision:
2672
raise errors.BzrCommandError(
2673
"Merge doesn't permit empty revision specifier.")
2674
base_branch, path = Branch.open_containing(branch)
2675
branch1 = revision[1].get_branch() or branch
2676
other_branch, path1 = Branch.open_containing(branch1)
2677
if revision[0].get_branch() is not None:
2678
# then path was obtained from it, and is None.
2681
base = [branch, revision[0].in_history(base_branch).revno]
2682
other = [branch1, revision[1].in_history(other_branch).revno]
2684
if ((tree.branch.get_parent() is None or remember) and
2685
other_branch is not None):
2686
tree.branch.set_parent(other_branch.base)
2688
# pull tags now... it's a bit inconsistent to do it ahead of copying
2689
# the history but that's done inside the merge code
2690
if other_branch is not None:
2691
_merge_tags_if_possible(other_branch, tree.branch)
2694
interesting_files = [path]
2696
interesting_files = None
2697
pb = ui.ui_factory.nested_progress_bar()
2700
conflict_count = _merge_helper(
2701
other, base, other_rev_id=other_revision_id,
2702
check_clean=(not force),
2703
merge_type=merge_type,
2704
reprocess=reprocess,
2705
show_base=show_base,
2708
pb=pb, file_list=interesting_files,
2709
change_reporter=change_reporter)
2712
if conflict_count != 0:
3527
if merger.interesting_files is not None:
3528
raise errors.BzrCommandError('Cannot pull individual files')
3529
if (merger.base_rev_id == tree.last_revision()):
3530
result = tree.pull(merger.other_branch, False,
3531
merger.other_rev_id)
3532
result.report(self.outf)
3534
merger.check_basis(False)
3536
return self._do_preview(merger)
3538
return self._do_merge(merger, change_reporter, allow_pending,
3541
for cleanup in reversed(cleanups):
3544
def _do_preview(self, merger):
3545
from bzrlib.diff import show_diff_trees
3546
tree_merger = merger.make_merger()
3547
tt = tree_merger.make_preview_transform()
3549
result_tree = tt.get_preview_tree()
3550
show_diff_trees(merger.this_tree, result_tree, self.outf,
3551
old_label='', new_label='')
3555
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3556
merger.change_reporter = change_reporter
3557
conflict_count = merger.do_merge()
3559
merger.set_pending()
3560
if verified == 'failed':
3561
warning('Preview patch does not match changes')
3562
if conflict_count != 0:
3567
def sanity_check_merger(self, merger):
3568
if (merger.show_base and
3569
not merger.merge_type is _mod_merge.Merge3Merger):
3570
raise errors.BzrCommandError("Show-base is not supported for this"
3571
" merge type. %s" % merger.merge_type)
3572
if merger.reprocess is None:
3573
if merger.show_base:
3574
merger.reprocess = False
3576
# Use reprocess if the merger supports it
3577
merger.reprocess = merger.merge_type.supports_reprocess
3578
if merger.reprocess and not merger.merge_type.supports_reprocess:
3579
raise errors.BzrCommandError("Conflict reduction is not supported"
3580
" for merge type %s." %
3582
if merger.reprocess and merger.show_base:
3583
raise errors.BzrCommandError("Cannot do conflict reduction and"
3586
def _get_merger_from_branch(self, tree, location, revision, remember,
3587
possible_transports, pb):
3588
"""Produce a merger from a location, assuming it refers to a branch."""
3589
from bzrlib.tag import _merge_tags_if_possible
3590
# find the branch locations
3591
other_loc, user_location = self._select_branch_location(tree, location,
3593
if revision is not None and len(revision) == 2:
3594
base_loc, _unused = self._select_branch_location(tree,
3595
location, revision, 0)
3597
base_loc = other_loc
3599
other_branch, other_path = Branch.open_containing(other_loc,
3600
possible_transports)
3601
if base_loc == other_loc:
3602
base_branch = other_branch
3604
base_branch, base_path = Branch.open_containing(base_loc,
3605
possible_transports)
3606
# Find the revision ids
3607
if revision is None or len(revision) < 1 or revision[-1] is None:
3608
other_revision_id = _mod_revision.ensure_null(
3609
other_branch.last_revision())
3611
other_revision_id = revision[-1].as_revision_id(other_branch)
3612
if (revision is not None and len(revision) == 2
3613
and revision[0] is not None):
3614
base_revision_id = revision[0].as_revision_id(base_branch)
3616
base_revision_id = None
3617
# Remember where we merge from
3618
if ((remember or tree.branch.get_submit_branch() is None) and
3619
user_location is not None):
3620
tree.branch.set_submit_branch(other_branch.base)
3621
_merge_tags_if_possible(other_branch, tree.branch)
3622
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3623
other_revision_id, base_revision_id, other_branch, base_branch)
3624
if other_path != '':
3625
allow_pending = False
3626
merger.interesting_files = [other_path]
3628
allow_pending = True
3629
return merger, allow_pending
3631
def _select_branch_location(self, tree, user_location, revision=None,
3633
"""Select a branch location, according to possible inputs.
3635
If provided, branches from ``revision`` are preferred. (Both
3636
``revision`` and ``index`` must be supplied.)
3638
Otherwise, the ``location`` parameter is used. If it is None, then the
3639
``submit`` or ``parent`` location is used, and a note is printed.
3641
:param tree: The working tree to select a branch for merging into
3642
:param location: The location entered by the user
3643
:param revision: The revision parameter to the command
3644
:param index: The index to use for the revision parameter. Negative
3645
indices are permitted.
3646
:return: (selected_location, user_location). The default location
3647
will be the user-entered location.
3649
if (revision is not None and index is not None
3650
and revision[index] is not None):
3651
branch = revision[index].get_branch()
3652
if branch is not None:
3653
return branch, branch
3654
if user_location is None:
3655
location = self._get_remembered(tree, 'Merging from')
3657
location = user_location
3658
return location, user_location
3660
def _get_remembered(self, tree, verb_string):
2716
except errors.AmbiguousBase, e:
2717
m = ("sorry, bzr can't determine the right merge base yet\n"
2718
"candidates are:\n "
2719
+ "\n ".join(e.bases)
2721
"please specify an explicit base with -r,\n"
2722
"and (if you want) report this to the bzr developers\n")
2725
# TODO: move up to common parent; this isn't merge-specific anymore.
2726
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3661
2727
"""Use tree.branch's parent if none was supplied.
3663
2729
Report if the remembered location was used.
3665
stored_location = tree.branch.get_submit_branch()
3666
stored_location_type = "submit"
3667
if stored_location is None:
3668
stored_location = tree.branch.get_parent()
3669
stored_location_type = "parent"
2731
if supplied_location is not None:
2732
return supplied_location
2733
stored_location = tree.branch.get_parent()
3670
2734
mutter("%s", stored_location)
3671
2735
if stored_location is None:
3672
2736
raise errors.BzrCommandError("No location specified or remembered")
3673
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3674
note(u"%s remembered %s location %s", verb_string,
3675
stored_location_type, display_url)
2737
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2738
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3676
2739
return stored_location
3878
2913
takes_args = ['context?']
3879
2914
aliases = ['s-c']
3882
2917
@display_command
3883
2918
def run(self, context=None):
3884
2919
import shellcomplete
3885
2920
shellcomplete.shellcomplete(context)
2923
class cmd_fetch(Command):
2924
"""Copy in history from another branch but don't merge it.
2926
This is an internal method used for pull and merge.
2929
takes_args = ['from_branch', 'to_branch']
2930
def run(self, from_branch, to_branch):
2931
from bzrlib.fetch import Fetcher
2932
from_b = Branch.open(from_branch)
2933
to_b = Branch.open(to_branch)
2934
Fetcher(to_b, from_b)
3888
2937
class cmd_missing(Command):
3889
2938
"""Show unmerged/unpulled revisions between two branches.
3891
2940
OTHER_BRANCH may be local or remote.
3893
To filter on a range of revisions, you can use the command -r begin..end
3894
-r revision requests a specific revision, -r ..end or -r begin.. are
3899
Determine the missing revisions between this and the branch at the
3900
remembered pull location::
3904
Determine the missing revisions between this and another branch::
3906
bzr missing http://server/branch
3908
Determine the missing revisions up to a specific revision on the other
3911
bzr missing -r ..-10
3913
Determine the missing revisions up to a specific revision on this
3916
bzr missing --my-revision ..-10
3919
2943
_see_also = ['merge', 'pull']
3920
2944
takes_args = ['other_branch?']
3922
Option('reverse', 'Reverse the order of revisions.'),
3924
'Display changes in the local branch only.'),
3925
Option('this' , 'Same as --mine-only.'),
3926
Option('theirs-only',
3927
'Display changes in the remote branch only.'),
3928
Option('other', 'Same as --theirs-only.'),
3932
custom_help('revision',
3933
help='Filter on other branch revisions (inclusive). '
3934
'See "help revisionspec" for details.'),
3935
Option('my-revision',
3936
type=_parse_revision_str,
3937
help='Filter on local branch revisions (inclusive). '
3938
'See "help revisionspec" for details.'),
3939
Option('include-merges',
3940
'Show all revisions in addition to the mainline ones.'),
2945
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2947
'Display changes in the local branch only'),
2948
Option('this' , 'same as --mine-only'),
2949
Option('theirs-only',
2950
'Display changes in the remote branch only'),
2951
Option('other', 'same as --theirs-only'),
3942
2956
encoding_type = 'replace'
3944
2958
@display_command
3945
2959
def run(self, other_branch=None, reverse=False, mine_only=False,
3947
log_format=None, long=False, short=False, line=False,
3948
show_ids=False, verbose=False, this=False, other=False,
3949
include_merges=False, revision=None, my_revision=None):
2960
theirs_only=False, log_format=None, long=False, short=False, line=False,
2961
show_ids=False, verbose=False, this=False, other=False):
3950
2962
from bzrlib.missing import find_unmerged, iter_log_revisions
2963
from bzrlib.log import log_formatter
3959
# TODO: We should probably check that we don't have mine-only and
3960
# theirs-only set, but it gets complicated because we also have
3961
# this and other which could be used.
3968
2970
local_branch = Branch.open_containing(u".")[0]
3969
2971
parent = local_branch.get_parent()
3970
2972
if other_branch is None:
3971
2973
other_branch = parent
3972
2974
if other_branch is None:
3973
raise errors.BzrCommandError("No peer location known"
2975
raise errors.BzrCommandError("No peer location known or specified.")
3975
2976
display_url = urlutils.unescape_for_display(parent,
3976
2977
self.outf.encoding)
3977
message("Using saved parent location: "
3978
+ display_url + "\n")
2978
print "Using last location: " + display_url
3980
2980
remote_branch = Branch.open(other_branch)
3981
2981
if remote_branch.base == local_branch.base:
3982
2982
remote_branch = local_branch
3984
local_revid_range = _revision_range_to_revid_range(
3985
_get_revision_range(my_revision, local_branch,
3988
remote_revid_range = _revision_range_to_revid_range(
3989
_get_revision_range(revision,
3990
remote_branch, self.name()))
3992
2983
local_branch.lock_read()
3994
2985
remote_branch.lock_read()
3996
local_extra, remote_extra = find_unmerged(
3997
local_branch, remote_branch, restrict,
3998
backward=not reverse,
3999
include_merges=include_merges,
4000
local_revid_range=local_revid_range,
4001
remote_revid_range=remote_revid_range)
4003
if log_format is None:
4004
registry = log.log_formatter_registry
4005
log_format = registry.get_default(local_branch)
2987
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2988
if (log_format is None):
2989
log_format = log.log_formatter_registry.get_default(
4006
2991
lf = log_format(to_file=self.outf,
4007
2992
show_ids=show_ids,
4008
2993
show_timezone='original')
2994
if reverse is False:
2995
local_extra.reverse()
2996
remote_extra.reverse()
4011
2997
if local_extra and not theirs_only:
4012
message("You have %d extra revision(s):\n" %
4014
for revision in iter_log_revisions(local_extra,
2998
print "You have %d extra revision(s):" % len(local_extra)
2999
for revision in iter_log_revisions(local_extra,
4015
3000
local_branch.repository,
4017
3002
lf.log_revision(revision)
4018
3003
printed_local = True
4021
3005
printed_local = False
4023
3006
if remote_extra and not mine_only:
4024
3007
if printed_local is True:
4026
message("You are missing %d revision(s):\n" %
4028
for revision in iter_log_revisions(remote_extra,
4029
remote_branch.repository,
3009
print "You are missing %d revision(s):" % len(remote_extra)
3010
for revision in iter_log_revisions(remote_extra,
3011
remote_branch.repository,
4031
3013
lf.log_revision(revision)
3014
if not remote_extra and not local_extra:
3016
print "Branches are up to date."
4032
3018
status_code = 1
4034
if mine_only and not local_extra:
4035
# We checked local, and found nothing extra
4036
message('This branch is up to date.\n')
4037
elif theirs_only and not remote_extra:
4038
# We checked remote, and found nothing extra
4039
message('Other branch is up to date.\n')
4040
elif not (mine_only or theirs_only or local_extra or
4042
# We checked both branches, and neither one had extra
4044
message("Branches are up to date.\n")
4046
3020
remote_branch.unlock()
4762
3567
s.send_email(message)
4765
class cmd_send(Command):
4766
"""Mail or create a merge-directive for submitting changes.
4768
A merge directive provides many things needed for requesting merges:
4770
* A machine-readable description of the merge to perform
4772
* An optional patch that is a preview of the changes requested
4774
* An optional bundle of revision data, so that the changes can be applied
4775
directly from the merge directive, without retrieving data from a
4778
If --no-bundle is specified, then public_branch is needed (and must be
4779
up-to-date), so that the receiver can perform the merge using the
4780
public_branch. The public_branch is always included if known, so that
4781
people can check it later.
4783
The submit branch defaults to the parent, but can be overridden. Both
4784
submit branch and public branch will be remembered if supplied.
4786
If a public_branch is known for the submit_branch, that public submit
4787
branch is used in the merge instructions. This means that a local mirror
4788
can be used as your actual submit branch, once you have set public_branch
4791
Mail is sent using your preferred mail program. This should be transparent
4792
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4793
If the preferred client can't be found (or used), your editor will be used.
4795
To use a specific mail program, set the mail_client configuration option.
4796
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4797
specific clients are "claws", "evolution", "kmail", "mutt", and
4798
"thunderbird"; generic options are "default", "editor", "emacsclient",
4799
"mapi", and "xdg-email". Plugins may also add supported clients.
4801
If mail is being sent, a to address is required. This can be supplied
4802
either on the commandline, by setting the submit_to configuration
4803
option in the branch itself or the child_submit_to configuration option
4804
in the submit branch.
4806
Two formats are currently supported: "4" uses revision bundle format 4 and
4807
merge directive format 2. It is significantly faster and smaller than
4808
older formats. It is compatible with Bazaar 0.19 and later. It is the
4809
default. "0.9" uses revision bundle format 0.9 and merge directive
4810
format 1. It is compatible with Bazaar 0.12 - 0.18.
4812
The merge directives created by bzr send may be applied using bzr merge or
4813
bzr pull by specifying a file containing a merge directive as the location.
4816
encoding_type = 'exact'
4818
_see_also = ['merge', 'pull']
4820
takes_args = ['submit_branch?', 'public_branch?']
4824
help='Do not include a bundle in the merge directive.'),
4825
Option('no-patch', help='Do not include a preview patch in the merge'
4828
help='Remember submit and public branch.'),
4830
help='Branch to generate the submission from, '
4831
'rather than the one containing the working directory.',
4834
Option('output', short_name='o',
4835
help='Write merge directive to this file; '
4836
'use - for stdout.',
4838
Option('mail-to', help='Mail the request to this address.',
4842
Option('body', help='Body for the email.', type=unicode),
4843
RegistryOption.from_kwargs('format',
4844
'Use the specified output format.',
4845
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4846
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4849
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4850
no_patch=False, revision=None, remember=False, output=None,
4851
format='4', mail_to=None, message=None, body=None, **kwargs):
4852
return self._run(submit_branch, revision, public_branch, remember,
4853
format, no_bundle, no_patch, output,
4854
kwargs.get('from', '.'), mail_to, message, body)
4856
def _run(self, submit_branch, revision, public_branch, remember, format,
4857
no_bundle, no_patch, output, from_, mail_to, message, body):
4858
from bzrlib.revision import NULL_REVISION
4859
branch = Branch.open_containing(from_)[0]
4861
outfile = cStringIO.StringIO()
4865
outfile = open(output, 'wb')
4866
# we may need to write data into branch's repository to calculate
4871
config = branch.get_config()
4873
mail_to = config.get_user_option('submit_to')
4874
mail_client = config.get_mail_client()
4875
if (not getattr(mail_client, 'supports_body', False)
4876
and body is not None):
4877
raise errors.BzrCommandError(
4878
'Mail client "%s" does not support specifying body' %
4879
mail_client.__class__.__name__)
4880
if remember and submit_branch is None:
4881
raise errors.BzrCommandError(
4882
'--remember requires a branch to be specified.')
4883
stored_submit_branch = branch.get_submit_branch()
4884
remembered_submit_branch = None
4885
if submit_branch is None:
4886
submit_branch = stored_submit_branch
4887
remembered_submit_branch = "submit"
4889
if stored_submit_branch is None or remember:
4890
branch.set_submit_branch(submit_branch)
4891
if submit_branch is None:
4892
submit_branch = branch.get_parent()
4893
remembered_submit_branch = "parent"
4894
if submit_branch is None:
4895
raise errors.BzrCommandError('No submit branch known or'
4897
if remembered_submit_branch is not None:
4898
note('Using saved %s location "%s" to determine what '
4899
'changes to submit.', remembered_submit_branch,
4903
submit_config = Branch.open(submit_branch).get_config()
4904
mail_to = submit_config.get_user_option("child_submit_to")
4906
stored_public_branch = branch.get_public_branch()
4907
if public_branch is None:
4908
public_branch = stored_public_branch
4909
elif stored_public_branch is None or remember:
4910
branch.set_public_branch(public_branch)
4911
if no_bundle and public_branch is None:
4912
raise errors.BzrCommandError('No public branch specified or'
4914
base_revision_id = None
4916
if revision is not None:
4917
if len(revision) > 2:
4918
raise errors.BzrCommandError('bzr send takes '
4919
'at most two one revision identifiers')
4920
revision_id = revision[-1].as_revision_id(branch)
4921
if len(revision) == 2:
4922
base_revision_id = revision[0].as_revision_id(branch)
4923
if revision_id is None:
4924
revision_id = branch.last_revision()
4925
if revision_id == NULL_REVISION:
4926
raise errors.BzrCommandError('No revisions to submit.')
4928
directive = merge_directive.MergeDirective2.from_objects(
4929
branch.repository, revision_id, time.time(),
4930
osutils.local_time_offset(), submit_branch,
4931
public_branch=public_branch, include_patch=not no_patch,
4932
include_bundle=not no_bundle, message=message,
4933
base_revision_id=base_revision_id)
4934
elif format == '0.9':
4937
patch_type = 'bundle'
4939
raise errors.BzrCommandError('Format 0.9 does not'
4940
' permit bundle with no patch')
4946
directive = merge_directive.MergeDirective.from_objects(
4947
branch.repository, revision_id, time.time(),
4948
osutils.local_time_offset(), submit_branch,
4949
public_branch=public_branch, patch_type=patch_type,
4952
outfile.writelines(directive.to_lines())
4954
subject = '[MERGE] '
4955
if message is not None:
4958
revision = branch.repository.get_revision(revision_id)
4959
subject += revision.get_summary()
4960
basename = directive.get_disk_name(branch)
4961
mail_client.compose_merge_request(mail_to, subject,
4970
class cmd_bundle_revisions(cmd_send):
4972
"""Create a merge-directive for submitting changes.
4974
A merge directive provides many things needed for requesting merges:
4976
* A machine-readable description of the merge to perform
4978
* An optional patch that is a preview of the changes requested
4980
* An optional bundle of revision data, so that the changes can be applied
4981
directly from the merge directive, without retrieving data from a
4984
If --no-bundle is specified, then public_branch is needed (and must be
4985
up-to-date), so that the receiver can perform the merge using the
4986
public_branch. The public_branch is always included if known, so that
4987
people can check it later.
4989
The submit branch defaults to the parent, but can be overridden. Both
4990
submit branch and public branch will be remembered if supplied.
4992
If a public_branch is known for the submit_branch, that public submit
4993
branch is used in the merge instructions. This means that a local mirror
4994
can be used as your actual submit branch, once you have set public_branch
4997
Two formats are currently supported: "4" uses revision bundle format 4 and
4998
merge directive format 2. It is significantly faster and smaller than
4999
older formats. It is compatible with Bazaar 0.19 and later. It is the
5000
default. "0.9" uses revision bundle format 0.9 and merge directive
5001
format 1. It is compatible with Bazaar 0.12 - 0.18.
5006
help='Do not include a bundle in the merge directive.'),
5007
Option('no-patch', help='Do not include a preview patch in the merge'
5010
help='Remember submit and public branch.'),
5012
help='Branch to generate the submission from, '
5013
'rather than the one containing the working directory.',
5016
Option('output', short_name='o', help='Write directive to this file.',
5019
RegistryOption.from_kwargs('format',
5020
'Use the specified output format.',
5021
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
5022
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5024
aliases = ['bundle']
5026
_see_also = ['send', 'merge']
5030
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5031
no_patch=False, revision=None, remember=False, output=None,
5032
format='4', **kwargs):
5035
return self._run(submit_branch, revision, public_branch, remember,
5036
format, no_bundle, no_patch, output,
5037
kwargs.get('from', '.'), None, None, None)
5040
3570
class cmd_tag(Command):
5041
"""Create, remove or modify a tag naming a revision.
3571
"""Create a tag naming a revision.
5043
3573
Tags give human-meaningful names to revisions. Commands that take a -r
5044
3574
(--revision) option can be given -rtag:X, where X is any previously
5103
3630
class cmd_tags(Command):
5106
This command shows a table of tag names and the revisions they reference.
3633
This tag shows a table of tag names and the revisions they reference.
5109
3636
_see_also = ['tag']
5110
3637
takes_options = [
5111
3638
Option('directory',
5112
help='Branch whose tags should be displayed.',
3639
help='Branch whose tags should be displayed',
5113
3640
short_name='d',
5116
RegistryOption.from_kwargs('sort',
5117
'Sort tags by different criteria.', title='Sorting',
5118
alpha='Sort tags lexicographically (default).',
5119
time='Sort tags chronologically.',
5125
3645
@display_command
5132
3649
branch, relpath = Branch.open_containing(directory)
5134
tags = branch.tags.get_tag_dict().items()
5141
graph = branch.repository.get_graph()
5142
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5143
revid1, revid2 = rev1.rev_id, rev2.rev_id
5144
# only show revisions between revid1 and revid2 (inclusive)
5145
tags = [(tag, revid) for tag, revid in tags if
5146
graph.is_between(revid, revid1, revid2)]
5151
elif sort == 'time':
5153
for tag, revid in tags:
5155
revobj = branch.repository.get_revision(revid)
5156
except errors.NoSuchRevision:
5157
timestamp = sys.maxint # place them at the end
5159
timestamp = revobj.timestamp
5160
timestamps[revid] = timestamp
5161
tags.sort(key=lambda x: timestamps[x[1]])
5163
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5164
revno_map = branch.get_revision_id_to_revno_map()
5165
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
5166
for tag, revid in tags ]
5167
for tag, revspec in tags:
5168
self.outf.write('%-20s %s\n' % (tag, revspec))
5171
class cmd_reconfigure(Command):
5172
"""Reconfigure the type of a bzr directory.
5174
A target configuration must be specified.
5176
For checkouts, the bind-to location will be auto-detected if not specified.
5177
The order of preference is
5178
1. For a lightweight checkout, the current bound location.
5179
2. For branches that used to be checkouts, the previously-bound location.
5180
3. The push location.
5181
4. The parent location.
5182
If none of these is available, --bind-to must be specified.
5185
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5186
takes_args = ['location?']
5188
RegistryOption.from_kwargs(
5190
title='Target type',
5191
help='The type to reconfigure the directory to.',
5192
value_switches=True, enum_switch=False,
5193
branch='Reconfigure to be an unbound branch with no working tree.',
5194
tree='Reconfigure to be an unbound branch with a working tree.',
5195
checkout='Reconfigure to be a bound branch with a working tree.',
5196
lightweight_checkout='Reconfigure to be a lightweight'
5197
' checkout (with no local history).',
5198
standalone='Reconfigure to be a standalone branch '
5199
'(i.e. stop using shared repository).',
5200
use_shared='Reconfigure to use a shared repository.',
5201
with_trees='Reconfigure repository to create '
5202
'working trees on branches by default.',
5203
with_no_trees='Reconfigure repository to not create '
5204
'working trees on branches by default.'
5206
Option('bind-to', help='Branch to bind checkout to.', type=str),
5208
help='Perform reconfiguration even if local changes'
5212
def run(self, location=None, target_type=None, bind_to=None, force=False):
5213
directory = bzrdir.BzrDir.open(location)
5214
if target_type is None:
5215
raise errors.BzrCommandError('No target configuration specified')
5216
elif target_type == 'branch':
5217
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5218
elif target_type == 'tree':
5219
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5220
elif target_type == 'checkout':
5221
reconfiguration = reconfigure.Reconfigure.to_checkout(
5223
elif target_type == 'lightweight-checkout':
5224
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5226
elif target_type == 'use-shared':
5227
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5228
elif target_type == 'standalone':
5229
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5230
elif target_type == 'with-trees':
5231
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5233
elif target_type == 'with-no-trees':
5234
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5236
reconfiguration.apply(force)
5239
class cmd_switch(Command):
5240
"""Set the branch of a checkout and update.
5242
For lightweight checkouts, this changes the branch being referenced.
5243
For heavyweight checkouts, this checks that there are no local commits
5244
versus the current bound branch, then it makes the local branch a mirror
5245
of the new location and binds to it.
5247
In both cases, the working tree is updated and uncommitted changes
5248
are merged. The user can commit or revert these as they desire.
5250
Pending merges need to be committed or reverted before using switch.
5252
The path to the branch to switch to can be specified relative to the parent
5253
directory of the current branch. For example, if you are currently in a
5254
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5257
Bound branches use the nickname of its master branch unless it is set
5258
locally, in which case switching will update the the local nickname to be
5262
takes_args = ['to_location']
5263
takes_options = [Option('force',
5264
help='Switch even if local commits will be lost.')
5267
def run(self, to_location, force=False):
5268
from bzrlib import switch
5270
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5271
branch = control_dir.open_branch()
5273
to_branch = Branch.open(to_location)
5274
except errors.NotBranchError:
5275
this_branch = control_dir.open_branch()
5276
# This may be a heavy checkout, where we want the master branch
5277
this_url = this_branch.get_bound_location()
5278
# If not, use a local sibling
5279
if this_url is None:
5280
this_url = this_branch.base
5281
to_branch = Branch.open(
5282
urlutils.join(this_url, '..', to_location))
5283
switch.switch(control_dir, to_branch, force)
5284
if branch.get_config().has_explicit_nickname():
5285
branch = control_dir.open_branch() #get the new branch!
5286
branch.nick = to_branch.nick
5287
note('Switched to branch: %s',
5288
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5291
class cmd_view(Command):
5292
"""Manage filtered views.
5294
Views provide a mask over the tree so that users can focus on
5295
a subset of a tree when doing their work. After creating a view,
5296
commands that support a list of files - status, diff, commit, etc -
5297
effectively have that list of files implicitly given each time.
5298
An explicit list of files can still be given but those files
5299
must be within the current view.
5301
In most cases, a view has a short life-span: it is created to make
5302
a selected change and is deleted once that change is committed.
5303
At other times, you may wish to create one or more named views
5304
and switch between them.
5306
To disable the current view without deleting it, you can switch to
5307
the pseudo view called ``off``. This can be useful when you need
5308
to see the whole tree for an operation or two (e.g. merge) but
5309
want to switch back to your view after that.
5312
To define the current view::
5314
bzr view file1 dir1 ...
5316
To list the current view::
5320
To delete the current view::
5324
To disable the current view without deleting it::
5326
bzr view --switch off
5328
To define a named view and switch to it::
5330
bzr view --name view-name file1 dir1 ...
5332
To list a named view::
5334
bzr view --name view-name
5336
To delete a named view::
5338
bzr view --name view-name --delete
5340
To switch to a named view::
5342
bzr view --switch view-name
5344
To list all views defined::
5348
To delete all views::
5350
bzr view --delete --all
5354
takes_args = ['file*']
5357
help='Apply list or delete action to all views.',
5360
help='Delete the view.',
5363
help='Name of the view to define, list or delete.',
5367
help='Name of the view to switch to.',
5372
def run(self, file_list,
5378
tree, file_list = tree_files(file_list, apply_view=False)
5379
current_view, view_dict = tree.views.get_view_info()
5384
raise errors.BzrCommandError(
5385
"Both --delete and a file list specified")
5387
raise errors.BzrCommandError(
5388
"Both --delete and --switch specified")
5390
tree.views.set_view_info(None, {})
5391
self.outf.write("Deleted all views.\n")
5393
raise errors.BzrCommandError("No current view to delete")
5395
tree.views.delete_view(name)
5396
self.outf.write("Deleted '%s' view.\n" % name)
5399
raise errors.BzrCommandError(
5400
"Both --switch and a file list specified")
5402
raise errors.BzrCommandError(
5403
"Both --switch and --all specified")
5404
elif switch == 'off':
5405
if current_view is None:
5406
raise errors.BzrCommandError("No current view to disable")
5407
tree.views.set_view_info(None, view_dict)
5408
self.outf.write("Disabled '%s' view.\n" % (current_view))
5410
tree.views.set_view_info(switch, view_dict)
5411
view_str = views.view_display_str(tree.views.lookup_view())
5412
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5415
self.outf.write('Views defined:\n')
5416
for view in sorted(view_dict):
5417
if view == current_view:
5421
view_str = views.view_display_str(view_dict[view])
5422
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5424
self.outf.write('No views defined.\n')
5427
# No name given and no current view set
5430
raise errors.BzrCommandError(
5431
"Cannot change the 'off' pseudo view")
5432
tree.views.set_view(name, sorted(file_list))
5433
view_str = views.view_display_str(tree.views.lookup_view())
5434
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
3650
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3651
self.outf.write('%-20s %s\n' % (tag_name, target))
3654
# command-line interpretation helper for merge-related commands
3655
def _merge_helper(other_revision, base_revision,
3656
check_clean=True, ignore_zero=False,
3657
this_dir=None, backup_files=False,
3659
file_list=None, show_base=False, reprocess=False,
3662
change_reporter=None,
3664
"""Merge changes into a tree.
3667
list(path, revno) Base for three-way merge.
3668
If [None, None] then a base will be automatically determined.
3670
list(path, revno) Other revision for three-way merge.
3672
Directory to merge changes into; '.' by default.
3674
If true, this_dir must have no uncommitted changes before the
3676
ignore_zero - If true, suppress the "zero conflicts" message when
3677
there are no conflicts; should be set when doing something we expect
3678
to complete perfectly.
3679
file_list - If supplied, merge only changes to selected files.
3681
All available ancestors of other_revision and base_revision are
3682
automatically pulled into the branch.
3684
The revno may be -1 to indicate the last revision on the branch, which is
3687
This function is intended for use from the command line; programmatic
3688
clients might prefer to call merge.merge_inner(), which has less magic
3691
# Loading it late, so that we don't always have to import bzrlib.merge
3692
if merge_type is None:
3693
merge_type = _mod_merge.Merge3Merger
3694
if this_dir is None:
3696
this_tree = WorkingTree.open_containing(this_dir)[0]
3697
if show_base and not merge_type is _mod_merge.Merge3Merger:
3698
raise errors.BzrCommandError("Show-base is not supported for this merge"
3699
" type. %s" % merge_type)
3700
if reprocess and not merge_type.supports_reprocess:
3701
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3702
" type %s." % merge_type)
3703
if reprocess and show_base:
3704
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3705
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3706
# only want to take out a lock_tree_write() if we don't have to pull
3707
# any ancestry. But merge might fetch ancestry in the middle, in
3708
# which case we would need a lock_write().
3709
# Because we cannot upgrade locks, for now we live with the fact that
3710
# the tree will be locked multiple times during a merge. (Maybe
3711
# read-only some of the time, but it means things will get read
3714
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3715
pb=pb, change_reporter=change_reporter)
3716
merger.pp = ProgressPhase("Merge phase", 5, pb)
3717
merger.pp.next_phase()
3718
merger.check_basis(check_clean)
3719
if other_rev_id is not None:
3720
merger.set_other_revision(other_rev_id, this_tree.branch)
5438
# No name given and no current view set
5439
self.outf.write('No current view.\n')
5441
view_str = views.view_display_str(tree.views.lookup_view(name))
5442
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5445
class cmd_hooks(Command):
5451
for hook_key in sorted(hooks.known_hooks.keys()):
5452
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5453
self.outf.write("%s:\n" % type(some_hooks).__name__)
5454
for hook_name, hook_point in sorted(some_hooks.items()):
5455
self.outf.write(" %s:\n" % (hook_name,))
5456
found_hooks = list(hook_point)
5458
for hook in found_hooks:
5459
self.outf.write(" %s\n" %
5460
(some_hooks.get_hook_name(hook),))
5462
self.outf.write(" <no hooks installed>\n")
5465
class cmd_shelve(Command):
5466
"""Temporarily set aside some changes from the current tree.
5468
Shelve allows you to temporarily put changes you've made "on the shelf",
5469
ie. out of the way, until a later time when you can bring them back from
5470
the shelf with the 'unshelve' command. The changes are stored alongside
5471
your working tree, and so they aren't propagated along with your branch nor
5472
will they survive its deletion.
5474
If shelve --list is specified, previously-shelved changes are listed.
5476
Shelve is intended to help separate several sets of changes that have
5477
been inappropriately mingled. If you just want to get rid of all changes
5478
and you don't need to restore them later, use revert. If you want to
5479
shelve all text changes at once, use shelve --all.
5481
If filenames are specified, only the changes to those files will be
5482
shelved. Other files will be left untouched.
5484
If a revision is specified, changes since that revision will be shelved.
5486
You can put multiple items on the shelf, and by default, 'unshelve' will
5487
restore the most recently shelved changes.
5490
takes_args = ['file*']
5494
Option('all', help='Shelve all changes.'),
5496
RegistryOption('writer', 'Method to use for writing diffs.',
5497
bzrlib.option.diff_writer_registry,
5498
value_switches=True, enum_switch=False),
5500
Option('list', help='List shelved changes.'),
5502
help='Destroy removed changes instead of shelving them.'),
5504
_see_also = ['unshelve']
5506
def run(self, revision=None, all=False, file_list=None, message=None,
5507
writer=None, list=False, destroy=False):
5509
return self.run_for_list()
5510
from bzrlib.shelf_ui import Shelver
5512
writer = bzrlib.option.diff_writer_registry.get()
5514
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5515
message, destroy=destroy).run()
5516
except errors.UserAbort:
3722
merger.set_other(other_revision)
3723
merger.pp.next_phase()
3724
merger.set_base(base_revision)
3725
if merger.base_rev_id == merger.other_rev_id:
3726
note('Nothing to do.')
5519
def run_for_list(self):
5520
tree = WorkingTree.open_containing('.')[0]
5523
manager = tree.get_shelf_manager()
5524
shelves = manager.active_shelves()
5525
if len(shelves) == 0:
5526
note('No shelved changes.')
3728
if file_list is None:
3729
if pull and merger.base_rev_id == merger.this_rev_id:
3730
# FIXME: deduplicate with pull
3731
result = merger.this_tree.pull(merger.this_branch,
3732
False, merger.other_rev_id)
3733
if result.old_revid == result.new_revid:
3734
note('No revisions to pull.')
3736
note('Now on revision %d.' % result.new_revno)
5528
for shelf_id in reversed(shelves):
5529
message = manager.get_metadata(shelf_id).get('message')
5531
message = '<no message>'
5532
self.outf.write('%3d: %s\n' % (shelf_id, message))
5538
class cmd_unshelve(Command):
5539
"""Restore shelved changes.
5541
By default, the most recently shelved changes are restored. However if you
5542
specify a shelf by id those changes will be restored instead. This works
5543
best when the changes don't depend on each other.
5546
takes_args = ['shelf_id?']
5548
RegistryOption.from_kwargs(
5549
'action', help="The action to perform.",
5550
enum_switch=False, value_switches=True,
5551
apply="Apply changes and remove from the shelf.",
5552
dry_run="Show changes, but do not apply or remove them.",
5553
delete_only="Delete changes without applying them."
5556
_see_also = ['shelve']
5558
def run(self, shelf_id=None, action='apply'):
5559
from bzrlib.shelf_ui import Unshelver
5560
Unshelver.from_args(shelf_id, action).run()
5563
class cmd_clean_tree(Command):
5564
"""Remove unwanted files from working tree.
5566
By default, only unknown files, not ignored files, are deleted. Versioned
5567
files are never deleted.
5569
Another class is 'detritus', which includes files emitted by bzr during
5570
normal operations and selftests. (The value of these files decreases with
5573
If no options are specified, unknown files are deleted. Otherwise, option
5574
flags are respected, and may be combined.
5576
To check what clean-tree will do, use --dry-run.
5578
takes_options = [Option('ignored', help='Delete all ignored files.'),
5579
Option('detritus', help='Delete conflict files, merge'
5580
' backups, and failed selftest dirs.'),
5582
help='Delete files unknown to bzr (default).'),
5583
Option('dry-run', help='Show files to delete instead of'
5585
Option('force', help='Do not prompt before deleting.')]
5586
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5588
from bzrlib.clean_tree import clean_tree
5589
if not (unknown or ignored or detritus):
5593
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5594
dry_run=dry_run, no_prompt=force)
3738
merger.backup_files = backup_files
3739
merger.merge_type = merge_type
3740
merger.set_interesting_files(file_list)
3741
merger.show_base = show_base
3742
merger.reprocess = reprocess
3743
conflicts = merger.do_merge()
3744
if file_list is None:
3745
merger.set_pending()
5597
3751
def _create_prefix(cur_transport):