1
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""builtin bzr commands"""
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
43
revision as _mod_revision,
50
from bzrlib.branch import Branch
51
from bzrlib.conflicts import ConflictList
52
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
53
from bzrlib.smtp_connection import SMTPConnection
54
from bzrlib.workingtree import WorkingTree
57
from bzrlib.commands import Command, display_command
58
from bzrlib.option import (
65
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
68
def tree_files(file_list, default_branch=u'.', canonicalize=True):
70
return internal_tree_files(file_list, default_branch, canonicalize)
71
except errors.FileInWrongBranch, e:
72
raise errors.BzrCommandError("%s is not in the same branch as %s" %
73
(e.path, file_list[0]))
76
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
81
rev_tree = tree.basis_tree()
83
rev_tree = branch.basis_tree()
85
if len(revisions) != 1:
86
raise errors.BzrCommandError(
87
'bzr %s --revision takes exactly one revision identifier' % (
89
rev_tree = revisions[0].as_tree(branch)
93
# XXX: Bad function name; should possibly also be a class method of
94
# WorkingTree rather than a function.
95
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True):
96
"""Convert command-line paths to a WorkingTree and relative paths.
98
This is typically used for command-line processors that take one or
99
more filenames, and infer the workingtree that contains them.
101
The filenames given are not required to exist.
103
:param file_list: Filenames to convert.
105
:param default_branch: Fallback tree path to use if file_list is empty or
108
:return: workingtree, [relative_paths]
110
if file_list is None or len(file_list) == 0:
111
return WorkingTree.open_containing(default_branch)[0], file_list
112
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
113
return tree, safe_relpath_files(tree, file_list, canonicalize)
116
def safe_relpath_files(tree, file_list, canonicalize=True):
117
"""Convert file_list into a list of relpaths in tree.
119
:param tree: A tree to operate on.
120
:param file_list: A list of user provided paths or None.
121
:return: A list of relative paths.
122
:raises errors.PathNotChild: When a provided path is in a different tree
125
if file_list is None:
128
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
129
# doesn't - fix that up here before we enter the loop.
131
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
134
for filename in file_list:
136
new_list.append(fixer(osutils.dereference_path(filename)))
137
except errors.PathNotChild:
138
raise errors.FileInWrongBranch(tree.branch, filename)
142
# TODO: Make sure no commands unconditionally use the working directory as a
143
# branch. If a filename argument is used, the first of them should be used to
144
# specify the branch. (Perhaps this can be factored out into some kind of
145
# Argument class, representing a file in a branch, where the first occurrence
148
class cmd_status(Command):
149
"""Display status summary.
151
This reports on versioned and unknown files, reporting them
152
grouped by state. Possible states are:
155
Versioned in the working copy but not in the previous revision.
158
Versioned in the previous revision but removed or deleted
162
Path of this file changed from the previous revision;
163
the text may also have changed. This includes files whose
164
parent directory was renamed.
167
Text has changed since the previous revision.
170
File kind has been changed (e.g. from file to directory).
173
Not versioned and not matching an ignore pattern.
175
To see ignored files use 'bzr ignored'. For details on the
176
changes to file texts, use 'bzr diff'.
178
Note that --short or -S gives status flags for each item, similar
179
to Subversion's status command. To get output similar to svn -q,
182
If no arguments are specified, the status of the entire working
183
directory is shown. Otherwise, only the status of the specified
184
files or directories is reported. If a directory is given, status
185
is reported for everything inside that directory.
187
Before merges are committed, the pending merge tip revisions are
188
shown. To see all pending merge revisions, use the -v option.
189
To skip the display of pending merge information altogether, use
190
the no-pending option or specify a file/directory.
192
If a revision argument is given, the status is calculated against
193
that revision, or between two revisions if two are provided.
196
# TODO: --no-recurse, --recurse options
198
takes_args = ['file*']
199
takes_options = ['show-ids', 'revision', 'change', 'verbose',
200
Option('short', help='Use short status indicators.',
202
Option('versioned', help='Only show versioned files.',
204
Option('no-pending', help='Don\'t show pending merges.',
207
aliases = ['st', 'stat']
209
encoding_type = 'replace'
210
_see_also = ['diff', 'revert', 'status-flags']
213
def run(self, show_ids=False, file_list=None, revision=None, short=False,
214
versioned=False, no_pending=False, verbose=False):
215
from bzrlib.status import show_tree_status
217
if revision and len(revision) > 2:
218
raise errors.BzrCommandError('bzr status --revision takes exactly'
219
' one or two revision specifiers')
221
tree, relfile_list = tree_files(file_list)
222
# Avoid asking for specific files when that is not needed.
223
if relfile_list == ['']:
225
# Don't disable pending merges for full trees other than '.'.
226
if file_list == ['.']:
228
# A specific path within a tree was given.
229
elif relfile_list is not None:
231
show_tree_status(tree, show_ids=show_ids,
232
specific_files=relfile_list, revision=revision,
233
to_file=self.outf, short=short, versioned=versioned,
234
show_pending=(not no_pending), verbose=verbose)
237
class cmd_cat_revision(Command):
238
"""Write out metadata for a revision.
240
The revision to print can either be specified by a specific
241
revision identifier, or you can use --revision.
245
takes_args = ['revision_id?']
246
takes_options = ['revision']
247
# cat-revision is more for frontends so should be exact
251
def run(self, revision_id=None, revision=None):
252
if revision_id is not None and revision is not None:
253
raise errors.BzrCommandError('You can only supply one of'
254
' revision_id or --revision')
255
if revision_id is None and revision is None:
256
raise errors.BzrCommandError('You must supply either'
257
' --revision or a revision_id')
258
b = WorkingTree.open_containing(u'.')[0].branch
260
# TODO: jam 20060112 should cat-revision always output utf-8?
261
if revision_id is not None:
262
revision_id = osutils.safe_revision_id(revision_id, warn=False)
264
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
265
except errors.NoSuchRevision:
266
msg = "The repository %s contains no revision %s." % (b.repository.base,
268
raise errors.BzrCommandError(msg)
269
elif revision is not None:
272
raise errors.BzrCommandError('You cannot specify a NULL'
274
rev_id = rev.as_revision_id(b)
275
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
278
class cmd_dump_btree(Command):
279
"""Dump the contents of a btree index file to stdout.
281
PATH is a btree index file, it can be any URL. This includes things like
282
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
284
By default, the tuples stored in the index file will be displayed. With
285
--raw, we will uncompress the pages, but otherwise display the raw bytes
289
# TODO: Do we want to dump the internal nodes as well?
290
# TODO: It would be nice to be able to dump the un-parsed information,
291
# rather than only going through iter_all_entries. However, this is
292
# good enough for a start
294
encoding_type = 'exact'
295
takes_args = ['path']
296
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
297
' rather than the parsed tuples.'),
300
def run(self, path, raw=False):
301
dirname, basename = osutils.split(path)
302
t = transport.get_transport(dirname)
304
self._dump_raw_bytes(t, basename)
306
self._dump_entries(t, basename)
308
def _get_index_and_bytes(self, trans, basename):
309
"""Create a BTreeGraphIndex and raw bytes."""
310
bt = btree_index.BTreeGraphIndex(trans, basename, None)
311
bytes = trans.get_bytes(basename)
312
bt._file = cStringIO.StringIO(bytes)
313
bt._size = len(bytes)
316
def _dump_raw_bytes(self, trans, basename):
319
# We need to parse at least the root node.
320
# This is because the first page of every row starts with an
321
# uncompressed header.
322
bt, bytes = self._get_index_and_bytes(trans, basename)
323
for page_idx, page_start in enumerate(xrange(0, len(bytes),
324
btree_index._PAGE_SIZE)):
325
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
326
page_bytes = bytes[page_start:page_end]
328
self.outf.write('Root node:\n')
329
header_end, data = bt._parse_header_from_bytes(page_bytes)
330
self.outf.write(page_bytes[:header_end])
332
self.outf.write('\nPage %d\n' % (page_idx,))
333
decomp_bytes = zlib.decompress(page_bytes)
334
self.outf.write(decomp_bytes)
335
self.outf.write('\n')
337
def _dump_entries(self, trans, basename):
339
st = trans.stat(basename)
340
except errors.TransportNotPossible:
341
# We can't stat, so we'll fake it because we have to do the 'get()'
343
bt, _ = self._get_index_and_bytes(trans, basename)
345
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
346
for node in bt.iter_all_entries():
347
# Node is made up of:
348
# (index, key, value, [references])
349
self.outf.write('%s\n' % (node[1:],))
352
class cmd_remove_tree(Command):
353
"""Remove the working tree from a given branch/checkout.
355
Since a lightweight checkout is little more than a working tree
356
this will refuse to run against one.
358
To re-create the working tree, use "bzr checkout".
360
_see_also = ['checkout', 'working-trees']
361
takes_args = ['location?']
364
help='Remove the working tree even if it has '
365
'uncommitted changes.'),
368
def run(self, location='.', force=False):
369
d = bzrdir.BzrDir.open(location)
372
working = d.open_workingtree()
373
except errors.NoWorkingTree:
374
raise errors.BzrCommandError("No working tree to remove")
375
except errors.NotLocalUrl:
376
raise errors.BzrCommandError("You cannot remove the working tree of a "
379
changes = working.changes_from(working.basis_tree())
380
if changes.has_changed():
381
raise errors.UncommittedChanges(working)
383
working_path = working.bzrdir.root_transport.base
384
branch_path = working.branch.bzrdir.root_transport.base
385
if working_path != branch_path:
386
raise errors.BzrCommandError("You cannot remove the working tree from "
387
"a lightweight checkout")
389
d.destroy_workingtree()
392
class cmd_revno(Command):
393
"""Show current revision number.
395
This is equal to the number of revisions on this branch.
399
takes_args = ['location?']
402
def run(self, location=u'.'):
403
self.outf.write(str(Branch.open_containing(location)[0].revno()))
404
self.outf.write('\n')
407
class cmd_revision_info(Command):
408
"""Show revision number and revision id for a given revision identifier.
411
takes_args = ['revision_info*']
415
help='Branch to examine, '
416
'rather than the one containing the working directory.',
423
def run(self, revision=None, directory=u'.', revision_info_list=[]):
426
if revision is not None:
427
revs.extend(revision)
428
if revision_info_list is not None:
429
for rev in revision_info_list:
430
revs.append(RevisionSpec.from_string(rev))
432
b = Branch.open_containing(directory)[0]
435
revs.append(RevisionSpec.from_string('-1'))
438
revision_id = rev.as_revision_id(b)
440
revno = '%4d' % (b.revision_id_to_revno(revision_id))
441
except errors.NoSuchRevision:
442
dotted_map = b.get_revision_id_to_revno_map()
443
revno = '.'.join(str(i) for i in dotted_map[revision_id])
444
print '%s %s' % (revno, revision_id)
447
class cmd_add(Command):
448
"""Add specified files or directories.
450
In non-recursive mode, all the named items are added, regardless
451
of whether they were previously ignored. A warning is given if
452
any of the named files are already versioned.
454
In recursive mode (the default), files are treated the same way
455
but the behaviour for directories is different. Directories that
456
are already versioned do not give a warning. All directories,
457
whether already versioned or not, are searched for files or
458
subdirectories that are neither versioned or ignored, and these
459
are added. This search proceeds recursively into versioned
460
directories. If no names are given '.' is assumed.
462
Therefore simply saying 'bzr add' will version all files that
463
are currently unknown.
465
Adding a file whose parent directory is not versioned will
466
implicitly add the parent, and so on up to the root. This means
467
you should never need to explicitly add a directory, they'll just
468
get added when you add a file in the directory.
470
--dry-run will show which files would be added, but not actually
473
--file-ids-from will try to use the file ids from the supplied path.
474
It looks up ids trying to find a matching parent directory with the
475
same filename, and then by pure path. This option is rarely needed
476
but can be useful when adding the same logical file into two
477
branches that will be merged later (without showing the two different
478
adds as a conflict). It is also useful when merging another project
479
into a subdirectory of this one.
481
takes_args = ['file*']
484
help="Don't recursively add the contents of directories."),
486
help="Show what would be done, but don't actually do anything."),
488
Option('file-ids-from',
490
help='Lookup file ids from this tree.'),
492
encoding_type = 'replace'
493
_see_also = ['remove']
495
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
500
if file_ids_from is not None:
502
base_tree, base_path = WorkingTree.open_containing(
504
except errors.NoWorkingTree:
505
base_branch, base_path = Branch.open_containing(
507
base_tree = base_branch.basis_tree()
509
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
510
to_file=self.outf, should_print=(not is_quiet()))
512
action = bzrlib.add.AddAction(to_file=self.outf,
513
should_print=(not is_quiet()))
516
base_tree.lock_read()
518
file_list = self._maybe_expand_globs(file_list)
520
tree = WorkingTree.open_containing(file_list[0])[0]
522
tree = WorkingTree.open_containing(u'.')[0]
523
added, ignored = tree.smart_add(file_list, not
524
no_recurse, action=action, save=not dry_run)
526
if base_tree is not None:
528
if not is_quiet() and len(added) > 0:
529
self.outf.write('add completed\n')
532
for glob in sorted(ignored.keys()):
533
for path in ignored[glob]:
534
self.outf.write("ignored %s matching \"%s\"\n"
538
for glob, paths in ignored.items():
539
match_len += len(paths)
540
self.outf.write("ignored %d file(s).\n" % match_len)
541
self.outf.write("If you wish to add some of these files,"
542
" please add them by name.\n")
545
class cmd_mkdir(Command):
546
"""Create a new versioned directory.
548
This is equivalent to creating the directory and then adding it.
551
takes_args = ['dir+']
552
encoding_type = 'replace'
554
def run(self, dir_list):
557
wt, dd = WorkingTree.open_containing(d)
559
self.outf.write('added %s\n' % d)
562
class cmd_relpath(Command):
563
"""Show path of a file relative to root"""
565
takes_args = ['filename']
569
def run(self, filename):
570
# TODO: jam 20050106 Can relpath return a munged path if
571
# sys.stdout encoding cannot represent it?
572
tree, relpath = WorkingTree.open_containing(filename)
573
self.outf.write(relpath)
574
self.outf.write('\n')
577
class cmd_inventory(Command):
578
"""Show inventory of the current working copy or a revision.
580
It is possible to limit the output to a particular entry
581
type using the --kind option. For example: --kind file.
583
It is also possible to restrict the list of files to a specific
584
set. For example: bzr inventory --show-ids this/file
593
help='List entries of a particular kind: file, directory, symlink.',
596
takes_args = ['file*']
599
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
600
if kind and kind not in ['file', 'directory', 'symlink']:
601
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
603
work_tree, file_list = tree_files(file_list)
604
work_tree.lock_read()
606
if revision is not None:
607
if len(revision) > 1:
608
raise errors.BzrCommandError(
609
'bzr inventory --revision takes exactly one revision'
611
tree = revision[0].as_tree(work_tree.branch)
613
extra_trees = [work_tree]
619
if file_list is not None:
620
file_ids = tree.paths2ids(file_list, trees=extra_trees,
621
require_versioned=True)
622
# find_ids_across_trees may include some paths that don't
624
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
625
for file_id in file_ids if file_id in tree)
627
entries = tree.inventory.entries()
630
if tree is not work_tree:
633
for path, entry in entries:
634
if kind and kind != entry.kind:
637
self.outf.write('%-50s %s\n' % (path, entry.file_id))
639
self.outf.write(path)
640
self.outf.write('\n')
643
class cmd_mv(Command):
644
"""Move or rename a file.
647
bzr mv OLDNAME NEWNAME
649
bzr mv SOURCE... DESTINATION
651
If the last argument is a versioned directory, all the other names
652
are moved into it. Otherwise, there must be exactly two arguments
653
and the file is changed to a new name.
655
If OLDNAME does not exist on the filesystem but is versioned and
656
NEWNAME does exist on the filesystem but is not versioned, mv
657
assumes that the file has been manually moved and only updates
658
its internal inventory to reflect that change.
659
The same is valid when moving many SOURCE files to a DESTINATION.
661
Files cannot be moved between branches.
664
takes_args = ['names*']
665
takes_options = [Option("after", help="Move only the bzr identifier"
666
" of the file, because the file has already been moved."),
668
aliases = ['move', 'rename']
669
encoding_type = 'replace'
671
def run(self, names_list, after=False):
672
if names_list is None:
675
if len(names_list) < 2:
676
raise errors.BzrCommandError("missing file argument")
677
tree, rel_names = tree_files(names_list, canonicalize=False)
680
self._run(tree, names_list, rel_names, after)
684
def _run(self, tree, names_list, rel_names, after):
685
into_existing = osutils.isdir(names_list[-1])
686
if into_existing and len(names_list) == 2:
688
# a. case-insensitive filesystem and change case of dir
689
# b. move directory after the fact (if the source used to be
690
# a directory, but now doesn't exist in the working tree
691
# and the target is an existing directory, just rename it)
692
if (not tree.case_sensitive
693
and rel_names[0].lower() == rel_names[1].lower()):
694
into_existing = False
697
# 'fix' the case of a potential 'from'
698
from_id = tree.path2id(
699
tree.get_canonical_inventory_path(rel_names[0]))
700
if (not osutils.lexists(names_list[0]) and
701
from_id and inv.get_file_kind(from_id) == "directory"):
702
into_existing = False
705
# move into existing directory
706
# All entries reference existing inventory items, so fix them up
707
# for cicp file-systems.
708
rel_names = tree.get_canonical_inventory_paths(rel_names)
709
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
710
self.outf.write("%s => %s\n" % pair)
712
if len(names_list) != 2:
713
raise errors.BzrCommandError('to mv multiple files the'
714
' destination must be a versioned'
717
# for cicp file-systems: the src references an existing inventory
719
src = tree.get_canonical_inventory_path(rel_names[0])
720
# Find the canonical version of the destination: In all cases, the
721
# parent of the target must be in the inventory, so we fetch the
722
# canonical version from there (we do not always *use* the
723
# canonicalized tail portion - we may be attempting to rename the
725
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
726
dest_parent = osutils.dirname(canon_dest)
727
spec_tail = osutils.basename(rel_names[1])
728
# For a CICP file-system, we need to avoid creating 2 inventory
729
# entries that differ only by case. So regardless of the case
730
# we *want* to use (ie, specified by the user or the file-system),
731
# we must always choose to use the case of any existing inventory
732
# items. The only exception to this is when we are attempting a
733
# case-only rename (ie, canonical versions of src and dest are
735
dest_id = tree.path2id(canon_dest)
736
if dest_id is None or tree.path2id(src) == dest_id:
737
# No existing item we care about, so work out what case we
738
# are actually going to use.
740
# If 'after' is specified, the tail must refer to a file on disk.
742
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
744
# pathjoin with an empty tail adds a slash, which breaks
746
dest_parent_fq = tree.basedir
748
dest_tail = osutils.canonical_relpath(
750
osutils.pathjoin(dest_parent_fq, spec_tail))
752
# not 'after', so case as specified is used
753
dest_tail = spec_tail
755
# Use the existing item so 'mv' fails with AlreadyVersioned.
756
dest_tail = os.path.basename(canon_dest)
757
dest = osutils.pathjoin(dest_parent, dest_tail)
758
mutter("attempting to move %s => %s", src, dest)
759
tree.rename_one(src, dest, after=after)
760
self.outf.write("%s => %s\n" % (src, dest))
763
class cmd_pull(Command):
764
"""Turn this branch into a mirror of another branch.
766
This command only works on branches that have not diverged. Branches are
767
considered diverged if the destination branch's most recent commit is one
768
that has not been merged (directly or indirectly) into the parent.
770
If branches have diverged, you can use 'bzr merge' to integrate the changes
771
from one into the other. Once one branch has merged, the other should
772
be able to pull it again.
774
If you want to forget your local changes and just update your branch to
775
match the remote one, use pull --overwrite.
777
If there is no default location set, the first pull will set it. After
778
that, you can omit the location to use the default. To change the
779
default, use --remember. The value will only be saved if the remote
780
location can be accessed.
782
Note: The location can be specified either in the form of a branch,
783
or in the form of a path to a file containing a merge directive generated
787
_see_also = ['push', 'update', 'status-flags']
788
takes_options = ['remember', 'overwrite', 'revision',
789
custom_help('verbose',
790
help='Show logs of pulled revisions.'),
792
help='Branch to pull into, '
793
'rather than the one containing the working directory.',
798
takes_args = ['location?']
799
encoding_type = 'replace'
801
def run(self, location=None, remember=False, overwrite=False,
802
revision=None, verbose=False,
804
# FIXME: too much stuff is in the command class
807
if directory is None:
810
tree_to = WorkingTree.open_containing(directory)[0]
811
branch_to = tree_to.branch
812
except errors.NoWorkingTree:
814
branch_to = Branch.open_containing(directory)[0]
816
possible_transports = []
817
if location is not None:
819
mergeable = bundle.read_mergeable_from_url(location,
820
possible_transports=possible_transports)
821
except errors.NotABundle:
824
stored_loc = branch_to.get_parent()
826
if stored_loc is None:
827
raise errors.BzrCommandError("No pull location known or"
830
display_url = urlutils.unescape_for_display(stored_loc,
833
self.outf.write("Using saved parent location: %s\n" % display_url)
834
location = stored_loc
836
if mergeable is not None:
837
if revision is not None:
838
raise errors.BzrCommandError(
839
'Cannot use -r with merge directives or bundles')
840
mergeable.install_revisions(branch_to.repository)
841
base_revision_id, revision_id, verified = \
842
mergeable.get_merge_request(branch_to.repository)
843
branch_from = branch_to
845
branch_from = Branch.open(location,
846
possible_transports=possible_transports)
848
if branch_to.get_parent() is None or remember:
849
branch_to.set_parent(branch_from.base)
851
if revision is not None:
852
if len(revision) == 1:
853
revision_id = revision[0].as_revision_id(branch_from)
855
raise errors.BzrCommandError(
856
'bzr pull --revision takes one value.')
858
branch_to.lock_write()
860
if tree_to is not None:
861
change_reporter = delta._ChangeReporter(
862
unversioned_filter=tree_to.is_ignored)
863
result = tree_to.pull(branch_from, overwrite, revision_id,
865
possible_transports=possible_transports)
867
result = branch_to.pull(branch_from, overwrite, revision_id)
869
result.report(self.outf)
870
if verbose and result.old_revid != result.new_revid:
871
log.show_branch_change(branch_to, self.outf, result.old_revno,
877
class cmd_push(Command):
878
"""Update a mirror of this branch.
880
The target branch will not have its working tree populated because this
881
is both expensive, and is not supported on remote file systems.
883
Some smart servers or protocols *may* put the working tree in place in
886
This command only works on branches that have not diverged. Branches are
887
considered diverged if the destination branch's most recent commit is one
888
that has not been merged (directly or indirectly) by the source branch.
890
If branches have diverged, you can use 'bzr push --overwrite' to replace
891
the other branch completely, discarding its unmerged changes.
893
If you want to ensure you have the different changes in the other branch,
894
do a merge (see bzr help merge) from the other branch, and commit that.
895
After that you will be able to do a push without '--overwrite'.
897
If there is no default push location set, the first push will set it.
898
After that, you can omit the location to use the default. To change the
899
default, use --remember. The value will only be saved if the remote
900
location can be accessed.
903
_see_also = ['pull', 'update', 'working-trees']
904
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
905
Option('create-prefix',
906
help='Create the path leading up to the branch '
907
'if it does not already exist.'),
909
help='Branch to push from, '
910
'rather than the one containing the working directory.',
914
Option('use-existing-dir',
915
help='By default push will fail if the target'
916
' directory exists, but does not already'
917
' have a control directory. This flag will'
918
' allow push to proceed.'),
920
help='Create a stacked branch that references the public location '
921
'of the parent branch.'),
923
help='Create a stacked branch that refers to another branch '
924
'for the commit history. Only the work not present in the '
925
'referenced branch is included in the branch created.',
928
takes_args = ['location?']
929
encoding_type = 'replace'
931
def run(self, location=None, remember=False, overwrite=False,
932
create_prefix=False, verbose=False, revision=None,
933
use_existing_dir=False, directory=None, stacked_on=None,
935
from bzrlib.push import _show_push_branch
937
# Get the source branch and revision_id
938
if directory is None:
940
br_from = Branch.open_containing(directory)[0]
941
if revision is not None:
942
if len(revision) == 1:
943
revision_id = revision[0].in_history(br_from).rev_id
945
raise errors.BzrCommandError(
946
'bzr push --revision takes one value.')
948
revision_id = br_from.last_revision()
950
# Get the stacked_on branch, if any
951
if stacked_on is not None:
952
stacked_on = urlutils.normalize_url(stacked_on)
954
parent_url = br_from.get_parent()
956
parent = Branch.open(parent_url)
957
stacked_on = parent.get_public_branch()
959
# I considered excluding non-http url's here, thus forcing
960
# 'public' branches only, but that only works for some
961
# users, so it's best to just depend on the user spotting an
962
# error by the feedback given to them. RBC 20080227.
963
stacked_on = parent_url
965
raise errors.BzrCommandError(
966
"Could not determine branch to refer to.")
968
# Get the destination location
970
stored_loc = br_from.get_push_location()
971
if stored_loc is None:
972
raise errors.BzrCommandError(
973
"No push location known or specified.")
975
display_url = urlutils.unescape_for_display(stored_loc,
977
self.outf.write("Using saved push location: %s\n" % display_url)
978
location = stored_loc
980
_show_push_branch(br_from, revision_id, location, self.outf,
981
verbose=verbose, overwrite=overwrite, remember=remember,
982
stacked_on=stacked_on, create_prefix=create_prefix,
983
use_existing_dir=use_existing_dir)
986
class cmd_branch(Command):
987
"""Create a new copy of a branch.
989
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
990
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
991
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
992
is derived from the FROM_LOCATION by stripping a leading scheme or drive
993
identifier, if any. For example, "branch lp:foo-bar" will attempt to
996
To retrieve the branch as of a particular revision, supply the --revision
997
parameter, as in "branch foo/bar -r 5".
1000
_see_also = ['checkout']
1001
takes_args = ['from_location', 'to_location?']
1002
takes_options = ['revision', Option('hardlink',
1003
help='Hard-link working tree files where possible.'),
1005
help='Create a stacked branch referring to the source branch. '
1006
'The new branch will depend on the availability of the source '
1007
'branch for all operations.'),
1008
Option('standalone',
1009
help='Do not use a shared repository, even if available.'),
1011
aliases = ['get', 'clone']
1013
def run(self, from_location, to_location=None, revision=None,
1014
hardlink=False, stacked=False, standalone=False):
1015
from bzrlib.tag import _merge_tags_if_possible
1016
if revision is None:
1018
elif len(revision) > 1:
1019
raise errors.BzrCommandError(
1020
'bzr branch --revision takes exactly 1 revision value')
1022
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1026
if len(revision) == 1 and revision[0] is not None:
1027
revision_id = revision[0].as_revision_id(br_from)
1029
# FIXME - wt.last_revision, fallback to branch, fall back to
1030
# None or perhaps NULL_REVISION to mean copy nothing
1032
revision_id = br_from.last_revision()
1033
if to_location is None:
1034
to_location = urlutils.derive_to_location(from_location)
1035
to_transport = transport.get_transport(to_location)
1037
to_transport.mkdir('.')
1038
except errors.FileExists:
1039
raise errors.BzrCommandError('Target directory "%s" already'
1040
' exists.' % to_location)
1041
except errors.NoSuchFile:
1042
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1045
# preserve whatever source format we have.
1046
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1047
possible_transports=[to_transport],
1048
accelerator_tree=accelerator_tree,
1049
hardlink=hardlink, stacked=stacked,
1050
force_new_repo=standalone,
1051
source_branch=br_from)
1052
branch = dir.open_branch()
1053
except errors.NoSuchRevision:
1054
to_transport.delete_tree('.')
1055
msg = "The branch %s has no revision %s." % (from_location,
1057
raise errors.BzrCommandError(msg)
1058
_merge_tags_if_possible(br_from, branch)
1059
# If the source branch is stacked, the new branch may
1060
# be stacked whether we asked for that explicitly or not.
1061
# We therefore need a try/except here and not just 'if stacked:'
1063
note('Created new stacked branch referring to %s.' %
1064
branch.get_stacked_on_url())
1065
except (errors.NotStacked, errors.UnstackableBranchFormat,
1066
errors.UnstackableRepositoryFormat), e:
1067
note('Branched %d revision(s).' % branch.revno())
1072
class cmd_checkout(Command):
1073
"""Create a new checkout of an existing branch.
1075
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1076
the branch found in '.'. This is useful if you have removed the working tree
1077
or if it was never created - i.e. if you pushed the branch to its current
1078
location using SFTP.
1080
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
1081
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
1082
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1083
is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
1084
identifier, if any. For example, "checkout lp:foo-bar" will attempt to
1087
To retrieve the branch as of a particular revision, supply the --revision
1088
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
1089
out of date [so you cannot commit] but it may be useful (i.e. to examine old
1093
_see_also = ['checkouts', 'branch']
1094
takes_args = ['branch_location?', 'to_location?']
1095
takes_options = ['revision',
1096
Option('lightweight',
1097
help="Perform a lightweight checkout. Lightweight "
1098
"checkouts depend on access to the branch for "
1099
"every operation. Normal checkouts can perform "
1100
"common operations like diff and status without "
1101
"such access, and also support local commits."
1103
Option('files-from', type=str,
1104
help="Get file contents from this tree."),
1106
help='Hard-link working tree files where possible.'
1111
def run(self, branch_location=None, to_location=None, revision=None,
1112
lightweight=False, files_from=None, hardlink=False):
1113
if revision is None:
1115
elif len(revision) > 1:
1116
raise errors.BzrCommandError(
1117
'bzr checkout --revision takes exactly 1 revision value')
1118
if branch_location is None:
1119
branch_location = osutils.getcwd()
1120
to_location = branch_location
1121
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1123
if files_from is not None:
1124
accelerator_tree = WorkingTree.open(files_from)
1125
if len(revision) == 1 and revision[0] is not None:
1126
revision_id = revision[0].as_revision_id(source)
1129
if to_location is None:
1130
to_location = urlutils.derive_to_location(branch_location)
1131
# if the source and to_location are the same,
1132
# and there is no working tree,
1133
# then reconstitute a branch
1134
if (osutils.abspath(to_location) ==
1135
osutils.abspath(branch_location)):
1137
source.bzrdir.open_workingtree()
1138
except errors.NoWorkingTree:
1139
source.bzrdir.create_workingtree(revision_id)
1141
source.create_checkout(to_location, revision_id, lightweight,
1142
accelerator_tree, hardlink)
1145
class cmd_renames(Command):
1146
"""Show list of renamed files.
1148
# TODO: Option to show renames between two historical versions.
1150
# TODO: Only show renames under dir, rather than in the whole branch.
1151
_see_also = ['status']
1152
takes_args = ['dir?']
1155
def run(self, dir=u'.'):
1156
tree = WorkingTree.open_containing(dir)[0]
1159
new_inv = tree.inventory
1160
old_tree = tree.basis_tree()
1161
old_tree.lock_read()
1163
old_inv = old_tree.inventory
1165
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1166
for f, paths, c, v, p, n, k, e in iterator:
1167
if paths[0] == paths[1]:
1171
renames.append(paths)
1173
for old_name, new_name in renames:
1174
self.outf.write("%s => %s\n" % (old_name, new_name))
1181
class cmd_update(Command):
1182
"""Update a tree to have the latest code committed to its branch.
1184
This will perform a merge into the working tree, and may generate
1185
conflicts. If you have any local changes, you will still
1186
need to commit them after the update for the update to be complete.
1188
If you want to discard your local changes, you can just do a
1189
'bzr revert' instead of 'bzr commit' after the update.
1192
_see_also = ['pull', 'working-trees', 'status-flags']
1193
takes_args = ['dir?']
1196
def run(self, dir='.'):
1197
tree = WorkingTree.open_containing(dir)[0]
1198
possible_transports = []
1199
master = tree.branch.get_master_branch(
1200
possible_transports=possible_transports)
1201
if master is not None:
1204
tree.lock_tree_write()
1206
existing_pending_merges = tree.get_parent_ids()[1:]
1207
last_rev = _mod_revision.ensure_null(tree.last_revision())
1208
if last_rev == _mod_revision.ensure_null(
1209
tree.branch.last_revision()):
1210
# may be up to date, check master too.
1211
if master is None or last_rev == _mod_revision.ensure_null(
1212
master.last_revision()):
1213
revno = tree.branch.revision_id_to_revno(last_rev)
1214
note("Tree is up to date at revision %d." % (revno,))
1216
conflicts = tree.update(
1217
delta._ChangeReporter(unversioned_filter=tree.is_ignored),
1218
possible_transports=possible_transports)
1219
revno = tree.branch.revision_id_to_revno(
1220
_mod_revision.ensure_null(tree.last_revision()))
1221
note('Updated to revision %d.' % (revno,))
1222
if tree.get_parent_ids()[1:] != existing_pending_merges:
1223
note('Your local commits will now show as pending merges with '
1224
"'bzr status', and can be committed with 'bzr commit'.")
1233
class cmd_info(Command):
1234
"""Show information about a working tree, branch or repository.
1236
This command will show all known locations and formats associated to the
1237
tree, branch or repository. Statistical information is included with
1240
Branches and working trees will also report any missing revisions.
1242
_see_also = ['revno', 'working-trees', 'repositories']
1243
takes_args = ['location?']
1244
takes_options = ['verbose']
1245
encoding_type = 'replace'
1248
def run(self, location=None, verbose=False):
1253
from bzrlib.info import show_bzrdir_info
1254
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1255
verbose=noise_level, outfile=self.outf)
1258
class cmd_remove(Command):
1259
"""Remove files or directories.
1261
This makes bzr stop tracking changes to the specified files. bzr will delete
1262
them if they can easily be recovered using revert. If no options or
1263
parameters are given bzr will scan for files that are being tracked by bzr
1264
but missing in your tree and stop tracking them for you.
1266
takes_args = ['file*']
1267
takes_options = ['verbose',
1268
Option('new', help='Only remove files that have never been committed.'),
1269
RegistryOption.from_kwargs('file-deletion-strategy',
1270
'The file deletion mode to be used.',
1271
title='Deletion Strategy', value_switches=True, enum_switch=False,
1272
safe='Only delete files if they can be'
1273
' safely recovered (default).',
1274
keep="Don't delete any files.",
1275
force='Delete all the specified files, even if they can not be '
1276
'recovered and even if they are non-empty directories.')]
1277
aliases = ['rm', 'del']
1278
encoding_type = 'replace'
1280
def run(self, file_list, verbose=False, new=False,
1281
file_deletion_strategy='safe'):
1282
tree, file_list = tree_files(file_list)
1284
if file_list is not None:
1285
file_list = [f for f in file_list]
1289
# Heuristics should probably all move into tree.remove_smart or
1292
added = tree.changes_from(tree.basis_tree(),
1293
specific_files=file_list).added
1294
file_list = sorted([f[0] for f in added], reverse=True)
1295
if len(file_list) == 0:
1296
raise errors.BzrCommandError('No matching files.')
1297
elif file_list is None:
1298
# missing files show up in iter_changes(basis) as
1299
# versioned-with-no-kind.
1301
for change in tree.iter_changes(tree.basis_tree()):
1302
# Find paths in the working tree that have no kind:
1303
if change[1][1] is not None and change[6][1] is None:
1304
missing.append(change[1][1])
1305
file_list = sorted(missing, reverse=True)
1306
file_deletion_strategy = 'keep'
1307
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1308
keep_files=file_deletion_strategy=='keep',
1309
force=file_deletion_strategy=='force')
1314
class cmd_file_id(Command):
1315
"""Print file_id of a particular file or directory.
1317
The file_id is assigned when the file is first added and remains the
1318
same through all revisions where the file exists, even when it is
1323
_see_also = ['inventory', 'ls']
1324
takes_args = ['filename']
1327
def run(self, filename):
1328
tree, relpath = WorkingTree.open_containing(filename)
1329
i = tree.path2id(relpath)
1331
raise errors.NotVersionedError(filename)
1333
self.outf.write(i + '\n')
1336
class cmd_file_path(Command):
1337
"""Print path of file_ids to a file or directory.
1339
This prints one line for each directory down to the target,
1340
starting at the branch root.
1344
takes_args = ['filename']
1347
def run(self, filename):
1348
tree, relpath = WorkingTree.open_containing(filename)
1349
fid = tree.path2id(relpath)
1351
raise errors.NotVersionedError(filename)
1352
segments = osutils.splitpath(relpath)
1353
for pos in range(1, len(segments) + 1):
1354
path = osutils.joinpath(segments[:pos])
1355
self.outf.write("%s\n" % tree.path2id(path))
1358
class cmd_reconcile(Command):
1359
"""Reconcile bzr metadata in a branch.
1361
This can correct data mismatches that may have been caused by
1362
previous ghost operations or bzr upgrades. You should only
1363
need to run this command if 'bzr check' or a bzr developer
1364
advises you to run it.
1366
If a second branch is provided, cross-branch reconciliation is
1367
also attempted, which will check that data like the tree root
1368
id which was not present in very early bzr versions is represented
1369
correctly in both branches.
1371
At the same time it is run it may recompress data resulting in
1372
a potential saving in disk space or performance gain.
1374
The branch *MUST* be on a listable system such as local disk or sftp.
1377
_see_also = ['check']
1378
takes_args = ['branch?']
1380
def run(self, branch="."):
1381
from bzrlib.reconcile import reconcile
1382
dir = bzrdir.BzrDir.open(branch)
1386
class cmd_revision_history(Command):
1387
"""Display the list of revision ids on a branch."""
1390
takes_args = ['location?']
1395
def run(self, location="."):
1396
branch = Branch.open_containing(location)[0]
1397
for revid in branch.revision_history():
1398
self.outf.write(revid)
1399
self.outf.write('\n')
1402
class cmd_ancestry(Command):
1403
"""List all revisions merged into this branch."""
1405
_see_also = ['log', 'revision-history']
1406
takes_args = ['location?']
1411
def run(self, location="."):
1413
wt = WorkingTree.open_containing(location)[0]
1414
except errors.NoWorkingTree:
1415
b = Branch.open(location)
1416
last_revision = b.last_revision()
1419
last_revision = wt.last_revision()
1421
revision_ids = b.repository.get_ancestry(last_revision)
1423
for revision_id in revision_ids:
1424
self.outf.write(revision_id + '\n')
1427
class cmd_init(Command):
1428
"""Make a directory into a versioned branch.
1430
Use this to create an empty branch, or before importing an
1433
If there is a repository in a parent directory of the location, then
1434
the history of the branch will be stored in the repository. Otherwise
1435
init creates a standalone branch which carries its own history
1436
in the .bzr directory.
1438
If there is already a branch at the location but it has no working tree,
1439
the tree can be populated with 'bzr checkout'.
1441
Recipe for importing a tree of files::
1447
bzr commit -m "imported project"
1450
_see_also = ['init-repository', 'branch', 'checkout']
1451
takes_args = ['location?']
1453
Option('create-prefix',
1454
help='Create the path leading up to the branch '
1455
'if it does not already exist.'),
1456
RegistryOption('format',
1457
help='Specify a format for this branch. '
1458
'See "help formats".',
1459
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1460
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1461
value_switches=True,
1462
title="Branch Format",
1464
Option('append-revisions-only',
1465
help='Never change revnos or the existing log.'
1466
' Append revisions to it only.')
1468
def run(self, location=None, format=None, append_revisions_only=False,
1469
create_prefix=False):
1471
format = bzrdir.format_registry.make_bzrdir('default')
1472
if location is None:
1475
to_transport = transport.get_transport(location)
1477
# The path has to exist to initialize a
1478
# branch inside of it.
1479
# Just using os.mkdir, since I don't
1480
# believe that we want to create a bunch of
1481
# locations if the user supplies an extended path
1483
to_transport.ensure_base()
1484
except errors.NoSuchFile:
1485
if not create_prefix:
1486
raise errors.BzrCommandError("Parent directory of %s"
1488
"\nYou may supply --create-prefix to create all"
1489
" leading parent directories."
1491
_create_prefix(to_transport)
1494
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1495
except errors.NotBranchError:
1496
# really a NotBzrDir error...
1497
create_branch = bzrdir.BzrDir.create_branch_convenience
1498
branch = create_branch(to_transport.base, format=format,
1499
possible_transports=[to_transport])
1500
a_bzrdir = branch.bzrdir
1502
from bzrlib.transport.local import LocalTransport
1503
if a_bzrdir.has_branch():
1504
if (isinstance(to_transport, LocalTransport)
1505
and not a_bzrdir.has_workingtree()):
1506
raise errors.BranchExistsWithoutWorkingTree(location)
1507
raise errors.AlreadyBranchError(location)
1508
branch = a_bzrdir.create_branch()
1509
a_bzrdir.create_workingtree()
1510
if append_revisions_only:
1512
branch.set_append_revisions_only(True)
1513
except errors.UpgradeRequired:
1514
raise errors.BzrCommandError('This branch format cannot be set'
1515
' to append-revisions-only. Try --experimental-branch6')
1517
from bzrlib.info import describe_layout, describe_format
1519
tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
1520
except (errors.NoWorkingTree, errors.NotLocalUrl):
1522
repository = branch.repository
1523
layout = describe_layout(repository, branch, tree).lower()
1524
format = describe_format(a_bzrdir, repository, branch, tree)
1525
self.outf.write("Created a %s (format: %s)\n" % (layout, format))
1526
if repository.is_shared():
1527
#XXX: maybe this can be refactored into transport.path_or_url()
1528
url = repository.bzrdir.root_transport.external_url()
1530
url = urlutils.local_path_from_url(url)
1531
except errors.InvalidURL:
1533
self.outf.write("Using shared repository: %s\n" % url)
1536
class cmd_init_repository(Command):
1537
"""Create a shared repository to hold branches.
1539
New branches created under the repository directory will store their
1540
revisions in the repository, not in the branch directory.
1542
If the --no-trees option is used then the branches in the repository
1543
will not have working trees by default.
1546
Create a shared repositories holding just branches::
1548
bzr init-repo --no-trees repo
1551
Make a lightweight checkout elsewhere::
1553
bzr checkout --lightweight repo/trunk trunk-checkout
1558
_see_also = ['init', 'branch', 'checkout', 'repositories']
1559
takes_args = ["location"]
1560
takes_options = [RegistryOption('format',
1561
help='Specify a format for this repository. See'
1562
' "bzr help formats" for details.',
1563
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1564
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1565
value_switches=True, title='Repository format'),
1567
help='Branches in the repository will default to'
1568
' not having a working tree.'),
1570
aliases = ["init-repo"]
1572
def run(self, location, format=None, no_trees=False):
1574
format = bzrdir.format_registry.make_bzrdir('default')
1576
if location is None:
1579
to_transport = transport.get_transport(location)
1580
to_transport.ensure_base()
1582
newdir = format.initialize_on_transport(to_transport)
1583
repo = newdir.create_repository(shared=True)
1584
repo.set_make_working_trees(not no_trees)
1586
from bzrlib.info import show_bzrdir_info
1587
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
1590
class cmd_diff(Command):
1591
"""Show differences in the working tree, between revisions or branches.
1593
If no arguments are given, all changes for the current tree are listed.
1594
If files are given, only the changes in those files are listed.
1595
Remote and multiple branches can be compared by using the --old and
1596
--new options. If not provided, the default for both is derived from
1597
the first argument, if any, or the current tree if no arguments are
1600
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1601
produces patches suitable for "patch -p1".
1605
2 - unrepresentable changes
1610
Shows the difference in the working tree versus the last commit::
1614
Difference between the working tree and revision 1::
1618
Difference between revision 2 and revision 1::
1622
Difference between revision 2 and revision 1 for branch xxx::
1626
Show just the differences for file NEWS::
1630
Show the differences in working tree xxx for file NEWS::
1634
Show the differences from branch xxx to this working tree:
1638
Show the differences between two branches for file NEWS::
1640
bzr diff --old xxx --new yyy NEWS
1642
Same as 'bzr diff' but prefix paths with old/ and new/::
1644
bzr diff --prefix old/:new/
1646
_see_also = ['status']
1647
takes_args = ['file*']
1649
Option('diff-options', type=str,
1650
help='Pass these options to the external diff program.'),
1651
Option('prefix', type=str,
1653
help='Set prefixes added to old and new filenames, as '
1654
'two values separated by a colon. (eg "old/:new/").'),
1656
help='Branch/tree to compare from.',
1660
help='Branch/tree to compare to.',
1666
help='Use this command to compare files.',
1670
aliases = ['di', 'dif']
1671
encoding_type = 'exact'
1674
def run(self, revision=None, file_list=None, diff_options=None,
1675
prefix=None, old=None, new=None, using=None):
1676
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1678
if (prefix is None) or (prefix == '0'):
1686
old_label, new_label = prefix.split(":")
1688
raise errors.BzrCommandError(
1689
'--prefix expects two values separated by a colon'
1690
' (eg "old/:new/")')
1692
if revision and len(revision) > 2:
1693
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1694
' one or two revision specifiers')
1696
old_tree, new_tree, specific_files, extra_trees = \
1697
_get_trees_to_diff(file_list, revision, old, new)
1698
return show_diff_trees(old_tree, new_tree, sys.stdout,
1699
specific_files=specific_files,
1700
external_diff_options=diff_options,
1701
old_label=old_label, new_label=new_label,
1702
extra_trees=extra_trees, using=using)
1705
class cmd_deleted(Command):
1706
"""List files deleted in the working tree.
1708
# TODO: Show files deleted since a previous revision, or
1709
# between two revisions.
1710
# TODO: Much more efficient way to do this: read in new
1711
# directories with readdir, rather than stating each one. Same
1712
# level of effort but possibly much less IO. (Or possibly not,
1713
# if the directories are very large...)
1714
_see_also = ['status', 'ls']
1715
takes_options = ['show-ids']
1718
def run(self, show_ids=False):
1719
tree = WorkingTree.open_containing(u'.')[0]
1722
old = tree.basis_tree()
1725
for path, ie in old.inventory.iter_entries():
1726
if not tree.has_id(ie.file_id):
1727
self.outf.write(path)
1729
self.outf.write(' ')
1730
self.outf.write(ie.file_id)
1731
self.outf.write('\n')
1738
class cmd_modified(Command):
1739
"""List files modified in working tree.
1743
_see_also = ['status', 'ls']
1746
help='Write an ascii NUL (\\0) separator '
1747
'between files rather than a newline.')
1751
def run(self, null=False):
1752
tree = WorkingTree.open_containing(u'.')[0]
1753
td = tree.changes_from(tree.basis_tree())
1754
for path, id, kind, text_modified, meta_modified in td.modified:
1756
self.outf.write(path + '\0')
1758
self.outf.write(osutils.quotefn(path) + '\n')
1761
class cmd_added(Command):
1762
"""List files added in working tree.
1766
_see_also = ['status', 'ls']
1769
help='Write an ascii NUL (\\0) separator '
1770
'between files rather than a newline.')
1774
def run(self, null=False):
1775
wt = WorkingTree.open_containing(u'.')[0]
1778
basis = wt.basis_tree()
1781
basis_inv = basis.inventory
1784
if file_id in basis_inv:
1786
if inv.is_root(file_id) and len(basis_inv) == 0:
1788
path = inv.id2path(file_id)
1789
if not os.access(osutils.abspath(path), os.F_OK):
1792
self.outf.write(path + '\0')
1794
self.outf.write(osutils.quotefn(path) + '\n')
1801
class cmd_root(Command):
1802
"""Show the tree root directory.
1804
The root is the nearest enclosing directory with a .bzr control
1807
takes_args = ['filename?']
1809
def run(self, filename=None):
1810
"""Print the branch root."""
1811
tree = WorkingTree.open_containing(filename)[0]
1812
self.outf.write(tree.basedir + '\n')
1815
def _parse_limit(limitstring):
1817
return int(limitstring)
1819
msg = "The limit argument must be an integer."
1820
raise errors.BzrCommandError(msg)
1823
def _parse_levels(s):
1827
msg = "The levels argument must be an integer."
1828
raise errors.BzrCommandError(msg)
1831
class cmd_log(Command):
1832
"""Show log of a branch, file, or directory.
1834
By default show the log of the branch containing the working directory.
1836
To request a range of logs, you can use the command -r begin..end
1837
-r revision requests a specific revision, -r ..end or -r begin.. are
1841
Log the current branch::
1849
Log the last 10 revisions of a branch::
1851
bzr log -r -10.. http://server/branch
1854
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1856
takes_args = ['location?']
1859
help='Show from oldest to newest.'),
1861
custom_help('verbose',
1862
help='Show files changed in each revision.'),
1866
type=bzrlib.option._parse_revision_str,
1868
help='Show just the specified revision.'
1869
' See also "help revisionspec".'),
1873
help='Number of levels to display - 0 for all, 1 for flat.',
1875
type=_parse_levels),
1878
help='Show revisions whose message matches this '
1879
'regular expression.',
1883
help='Limit the output to the first N revisions.',
1888
help='Show changes made in each revision as a patch.'),
1890
encoding_type = 'replace'
1893
def run(self, location=None, timezone='original',
1904
from bzrlib.log import show_log, _get_fileid_to_log
1905
direction = (forward and 'forward') or 'reverse'
1907
if change is not None:
1909
raise errors.RangeInChangeOption()
1910
if revision is not None:
1911
raise errors.BzrCommandError(
1912
'--revision and --change are mutually exclusive')
1919
# find the file id to log:
1921
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1924
file_id = _get_fileid_to_log(revision, tree, b, fp)
1926
raise errors.BzrCommandError(
1927
"Path unknown at end or start of revision range: %s" %
1931
# FIXME ? log the current subdir only RBC 20060203
1932
if revision is not None \
1933
and len(revision) > 0 and revision[0].get_branch():
1934
location = revision[0].get_branch()
1937
dir, relpath = bzrdir.BzrDir.open_containing(location)
1938
b = dir.open_branch()
1942
rev1, rev2 = _get_revision_range(revision, b, self.name())
1943
if log_format is None:
1944
log_format = log.log_formatter_registry.get_default(b)
1946
lf = log_format(show_ids=show_ids, to_file=self.outf,
1947
show_timezone=timezone,
1948
delta_format=get_verbosity_level(),
1955
direction=direction,
1956
start_revision=rev1,
1960
show_diff=show_diff)
1965
def _get_revision_range(revisionspec_list, branch, command_name):
1966
"""Take the input of a revision option and turn it into a revision range.
1968
It returns RevisionInfo objects which can be used to obtain the rev_id's
1969
of the desired revisons. It does some user input validations.
1971
if revisionspec_list is None:
1974
elif len(revisionspec_list) == 1:
1975
rev1 = rev2 = revisionspec_list[0].in_history(branch)
1976
elif len(revisionspec_list) == 2:
1977
start_spec = revisionspec_list[0]
1978
end_spec = revisionspec_list[1]
1979
if end_spec.get_branch() != start_spec.get_branch():
1980
# b is taken from revision[0].get_branch(), and
1981
# show_log will use its revision_history. Having
1982
# different branches will lead to weird behaviors.
1983
raise errors.BzrCommandError(
1984
"bzr %s doesn't accept two revisions in different"
1985
" branches." % command_name)
1986
rev1 = start_spec.in_history(branch)
1987
# Avoid loading all of history when we know a missing
1988
# end of range means the last revision ...
1989
if end_spec.spec is None:
1990
last_revno, last_revision_id = branch.last_revision_info()
1991
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
1993
rev2 = end_spec.in_history(branch)
1995
raise errors.BzrCommandError(
1996
'bzr %s --revision takes one or two values.' % command_name)
2000
def _revision_range_to_revid_range(revision_range):
2003
if revision_range[0] is not None:
2004
rev_id1 = revision_range[0].rev_id
2005
if revision_range[1] is not None:
2006
rev_id2 = revision_range[1].rev_id
2007
return rev_id1, rev_id2
2009
def get_log_format(long=False, short=False, line=False, default='long'):
2010
log_format = default
2014
log_format = 'short'
2020
class cmd_touching_revisions(Command):
2021
"""Return revision-ids which affected a particular file.
2023
A more user-friendly interface is "bzr log FILE".
2027
takes_args = ["filename"]
2030
def run(self, filename):
2031
tree, relpath = WorkingTree.open_containing(filename)
2033
file_id = tree.path2id(relpath)
2034
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
2035
self.outf.write("%6d %s\n" % (revno, what))
2038
class cmd_ls(Command):
2039
"""List files in a tree.
2042
_see_also = ['status', 'cat']
2043
takes_args = ['path?']
2044
# TODO: Take a revision or remote path and list that tree instead.
2048
Option('non-recursive',
2049
help='Don\'t recurse into subdirectories.'),
2051
help='Print paths relative to the root of the branch.'),
2052
Option('unknown', help='Print unknown files.'),
2053
Option('versioned', help='Print versioned files.',
2055
Option('ignored', help='Print ignored files.'),
2057
help='Write an ascii NUL (\\0) separator '
2058
'between files rather than a newline.'),
2060
help='List entries of a particular kind: file, directory, symlink.',
2065
def run(self, revision=None, verbose=False,
2066
non_recursive=False, from_root=False,
2067
unknown=False, versioned=False, ignored=False,
2068
null=False, kind=None, show_ids=False, path=None):
2070
if kind and kind not in ('file', 'directory', 'symlink'):
2071
raise errors.BzrCommandError('invalid kind specified')
2073
if verbose and null:
2074
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2075
all = not (unknown or versioned or ignored)
2077
selection = {'I':ignored, '?':unknown, 'V':versioned}
2084
raise errors.BzrCommandError('cannot specify both --from-root'
2088
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2094
if revision is not None or tree is None:
2095
tree = _get_one_revision_tree('ls', revision, branch=branch)
2099
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2100
if fp.startswith(relpath):
2101
fp = osutils.pathjoin(prefix, fp[len(relpath):])
2102
if non_recursive and '/' in fp:
2104
if not all and not selection[fc]:
2106
if kind is not None and fkind != kind:
2108
kindch = entry.kind_character()
2109
outstring = fp + kindch
2111
outstring = '%-8s %s' % (fc, outstring)
2112
if show_ids and fid is not None:
2113
outstring = "%-50s %s" % (outstring, fid)
2114
self.outf.write(outstring + '\n')
2116
self.outf.write(fp + '\0')
2119
self.outf.write(fid)
2120
self.outf.write('\0')
2128
self.outf.write('%-50s %s\n' % (outstring, my_id))
2130
self.outf.write(outstring + '\n')
2135
class cmd_unknowns(Command):
2136
"""List unknown files.
2144
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2145
self.outf.write(osutils.quotefn(f) + '\n')
2148
class cmd_ignore(Command):
2149
"""Ignore specified files or patterns.
2151
See ``bzr help patterns`` for details on the syntax of patterns.
2153
To remove patterns from the ignore list, edit the .bzrignore file.
2154
After adding, editing or deleting that file either indirectly by
2155
using this command or directly by using an editor, be sure to commit
2158
Note: ignore patterns containing shell wildcards must be quoted from
2162
Ignore the top level Makefile::
2164
bzr ignore ./Makefile
2166
Ignore class files in all directories::
2168
bzr ignore "*.class"
2170
Ignore .o files under the lib directory::
2172
bzr ignore "lib/**/*.o"
2174
Ignore .o files under the lib directory::
2176
bzr ignore "RE:lib/.*\.o"
2178
Ignore everything but the "debian" toplevel directory::
2180
bzr ignore "RE:(?!debian/).*"
2183
_see_also = ['status', 'ignored', 'patterns']
2184
takes_args = ['name_pattern*']
2186
Option('old-default-rules',
2187
help='Write out the ignore rules bzr < 0.9 always used.')
2190
def run(self, name_pattern_list=None, old_default_rules=None):
2191
from bzrlib import ignores
2192
if old_default_rules is not None:
2193
# dump the rules and exit
2194
for pattern in ignores.OLD_DEFAULTS:
2197
if not name_pattern_list:
2198
raise errors.BzrCommandError("ignore requires at least one "
2199
"NAME_PATTERN or --old-default-rules")
2200
name_pattern_list = [globbing.normalize_pattern(p)
2201
for p in name_pattern_list]
2202
for name_pattern in name_pattern_list:
2203
if (name_pattern[0] == '/' or
2204
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2205
raise errors.BzrCommandError(
2206
"NAME_PATTERN should not be an absolute path")
2207
tree, relpath = WorkingTree.open_containing(u'.')
2208
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2209
ignored = globbing.Globster(name_pattern_list)
2212
for entry in tree.list_files():
2216
if ignored.match(filename):
2217
matches.append(filename.encode('utf-8'))
2219
if len(matches) > 0:
2220
print "Warning: the following files are version controlled and" \
2221
" match your ignore pattern:\n%s" % ("\n".join(matches),)
2224
class cmd_ignored(Command):
2225
"""List ignored files and the patterns that matched them.
2227
List all the ignored files and the ignore pattern that caused the file to
2230
Alternatively, to list just the files::
2235
encoding_type = 'replace'
2236
_see_also = ['ignore', 'ls']
2240
tree = WorkingTree.open_containing(u'.')[0]
2243
for path, file_class, kind, file_id, entry in tree.list_files():
2244
if file_class != 'I':
2246
## XXX: Slightly inefficient since this was already calculated
2247
pat = tree.is_ignored(path)
2248
self.outf.write('%-50s %s\n' % (path, pat))
2253
class cmd_lookup_revision(Command):
2254
"""Lookup the revision-id from a revision-number
2257
bzr lookup-revision 33
2260
takes_args = ['revno']
2263
def run(self, revno):
2267
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2269
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2272
class cmd_export(Command):
2273
"""Export current or past revision to a destination directory or archive.
2275
If no revision is specified this exports the last committed revision.
2277
Format may be an "exporter" name, such as tar, tgz, tbz2. If none is
2278
given, try to find the format with the extension. If no extension
2279
is found exports to a directory (equivalent to --format=dir).
2281
If root is supplied, it will be used as the root directory inside
2282
container formats (tar, zip, etc). If it is not supplied it will default
2283
to the exported filename. The root option has no effect for 'dir' format.
2285
If branch is omitted then the branch containing the current working
2286
directory will be used.
2288
Note: Export of tree with non-ASCII filenames to zip is not supported.
2290
================= =========================
2291
Supported formats Autodetected by extension
2292
================= =========================
2295
tbz2 .tar.bz2, .tbz2
2298
================= =========================
2300
takes_args = ['dest', 'branch_or_subdir?']
2303
help="Type of file to export to.",
2308
help="Name of the root directory inside the exported file."),
2310
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2312
from bzrlib.export import export
2314
if branch_or_subdir is None:
2315
tree = WorkingTree.open_containing(u'.')[0]
2319
b, subdir = Branch.open_containing(branch_or_subdir)
2322
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2324
export(rev_tree, dest, format, root, subdir)
2325
except errors.NoSuchExportFormat, e:
2326
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2329
class cmd_cat(Command):
2330
"""Write the contents of a file as of a given revision to standard output.
2332
If no revision is nominated, the last revision is used.
2334
Note: Take care to redirect standard output when using this command on a
2340
Option('name-from-revision', help='The path name in the old tree.'),
2343
takes_args = ['filename']
2344
encoding_type = 'exact'
2347
def run(self, filename, revision=None, name_from_revision=False):
2348
if revision is not None and len(revision) != 1:
2349
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2350
" one revision specifier")
2351
tree, branch, relpath = \
2352
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2355
return self._run(tree, branch, relpath, filename, revision,
2360
def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2362
tree = b.basis_tree()
2363
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2365
cur_file_id = tree.path2id(relpath)
2366
old_file_id = rev_tree.path2id(relpath)
2368
if name_from_revision:
2369
if old_file_id is None:
2370
raise errors.BzrCommandError(
2371
"%r is not present in revision %s" % (
2372
filename, rev_tree.get_revision_id()))
2374
content = rev_tree.get_file_text(old_file_id)
2375
elif cur_file_id is not None:
2376
content = rev_tree.get_file_text(cur_file_id)
2377
elif old_file_id is not None:
2378
content = rev_tree.get_file_text(old_file_id)
2380
raise errors.BzrCommandError(
2381
"%r is not present in revision %s" % (
2382
filename, rev_tree.get_revision_id()))
2383
self.outf.write(content)
2386
class cmd_local_time_offset(Command):
2387
"""Show the offset in seconds from GMT to local time."""
2391
print osutils.local_time_offset()
2395
class cmd_commit(Command):
2396
"""Commit changes into a new revision.
2398
If no arguments are given, the entire tree is committed.
2400
If selected files are specified, only changes to those files are
2401
committed. If a directory is specified then the directory and everything
2402
within it is committed.
2404
When excludes are given, they take precedence over selected files.
2405
For example, too commit only changes within foo, but not changes within
2408
bzr commit foo -x foo/bar
2410
If author of the change is not the same person as the committer, you can
2411
specify the author's name using the --author option. The name should be
2412
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2414
A selected-file commit may fail in some cases where the committed
2415
tree would be invalid. Consider::
2420
bzr commit foo -m "committing foo"
2421
bzr mv foo/bar foo/baz
2424
bzr commit foo/bar -m "committing bar but not baz"
2426
In the example above, the last commit will fail by design. This gives
2427
the user the opportunity to decide whether they want to commit the
2428
rename at the same time, separately first, or not at all. (As a general
2429
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2431
Note: A selected-file commit after a merge is not yet supported.
2433
# TODO: Run hooks on tree to-be-committed, and after commit.
2435
# TODO: Strict commit that fails if there are deleted files.
2436
# (what does "deleted files" mean ??)
2438
# TODO: Give better message for -s, --summary, used by tla people
2440
# XXX: verbose currently does nothing
2442
_see_also = ['bugs', 'uncommit']
2443
takes_args = ['selected*']
2445
ListOption('exclude', type=str, short_name='x',
2446
help="Do not consider changes made to a given path."),
2447
Option('message', type=unicode,
2449
help="Description of the new revision."),
2452
help='Commit even if nothing has changed.'),
2453
Option('file', type=str,
2456
help='Take commit message from this file.'),
2458
help="Refuse to commit if there are unknown "
2459
"files in the working tree."),
2460
ListOption('fixes', type=str,
2461
help="Mark a bug as being fixed by this revision."),
2462
Option('author', type=unicode,
2463
help="Set the author's name, if it's different "
2464
"from the committer."),
2466
help="Perform a local commit in a bound "
2467
"branch. Local commits are not pushed to "
2468
"the master branch until a normal commit "
2472
help='When no message is supplied, show the diff along'
2473
' with the status summary in the message editor.'),
2475
aliases = ['ci', 'checkin']
2477
def _get_bug_fix_properties(self, fixes, branch):
2479
# Configure the properties for bug fixing attributes.
2480
for fixed_bug in fixes:
2481
tokens = fixed_bug.split(':')
2482
if len(tokens) != 2:
2483
raise errors.BzrCommandError(
2484
"Invalid bug %s. Must be in the form of 'tag:id'. "
2485
"Commit refused." % fixed_bug)
2486
tag, bug_id = tokens
2488
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2489
except errors.UnknownBugTrackerAbbreviation:
2490
raise errors.BzrCommandError(
2491
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2492
except errors.MalformedBugIdentifier:
2493
raise errors.BzrCommandError(
2494
"Invalid bug identifier for %s. Commit refused."
2496
properties.append('%s fixed' % bug_url)
2497
return '\n'.join(properties)
2499
def run(self, message=None, file=None, verbose=False, selected_list=None,
2500
unchanged=False, strict=False, local=False, fixes=None,
2501
author=None, show_diff=False, exclude=None):
2502
from bzrlib.errors import (
2507
from bzrlib.msgeditor import (
2508
edit_commit_message_encoded,
2509
generate_commit_message_template,
2510
make_commit_message_template_encoded
2513
# TODO: Need a blackbox test for invoking the external editor; may be
2514
# slightly problematic to run this cross-platform.
2516
# TODO: do more checks that the commit will succeed before
2517
# spending the user's valuable time typing a commit message.
2521
tree, selected_list = tree_files(selected_list)
2522
if selected_list == ['']:
2523
# workaround - commit of root of tree should be exactly the same
2524
# as just default commit in that tree, and succeed even though
2525
# selected-file merge commit is not done yet
2530
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2532
properties['bugs'] = bug_property
2534
if local and not tree.branch.get_bound_location():
2535
raise errors.LocalRequiresBoundBranch()
2537
def get_message(commit_obj):
2538
"""Callback to get commit message"""
2539
my_message = message
2540
if my_message is None and not file:
2541
t = make_commit_message_template_encoded(tree,
2542
selected_list, diff=show_diff,
2543
output_encoding=osutils.get_user_encoding())
2544
start_message = generate_commit_message_template(commit_obj)
2545
my_message = edit_commit_message_encoded(t,
2546
start_message=start_message)
2547
if my_message is None:
2548
raise errors.BzrCommandError("please specify a commit"
2549
" message with either --message or --file")
2550
elif my_message and file:
2551
raise errors.BzrCommandError(
2552
"please specify either --message or --file")
2554
my_message = codecs.open(file, 'rt',
2555
osutils.get_user_encoding()).read()
2556
if my_message == "":
2557
raise errors.BzrCommandError("empty commit message specified")
2561
tree.commit(message_callback=get_message,
2562
specific_files=selected_list,
2563
allow_pointless=unchanged, strict=strict, local=local,
2564
reporter=None, verbose=verbose, revprops=properties,
2566
exclude=safe_relpath_files(tree, exclude))
2567
except PointlessCommit:
2568
# FIXME: This should really happen before the file is read in;
2569
# perhaps prepare the commit; get the message; then actually commit
2570
raise errors.BzrCommandError("no changes to commit."
2571
" use --unchanged to commit anyhow")
2572
except ConflictsInTree:
2573
raise errors.BzrCommandError('Conflicts detected in working '
2574
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
2576
except StrictCommitFailed:
2577
raise errors.BzrCommandError("Commit refused because there are"
2578
" unknown files in the working tree.")
2579
except errors.BoundBranchOutOfDate, e:
2580
raise errors.BzrCommandError(str(e) + "\n"
2581
'To commit to master branch, run update and then commit.\n'
2582
'You can also pass --local to commit to continue working '
2586
class cmd_check(Command):
2587
"""Validate working tree structure, branch consistency and repository history.
2589
This command checks various invariants about branch and repository storage
2590
to detect data corruption or bzr bugs.
2592
The working tree and branch checks will only give output if a problem is
2593
detected. The output fields of the repository check are:
2595
revisions: This is just the number of revisions checked. It doesn't
2597
versionedfiles: This is just the number of versionedfiles checked. It
2598
doesn't indicate a problem.
2599
unreferenced ancestors: Texts that are ancestors of other texts, but
2600
are not properly referenced by the revision ancestry. This is a
2601
subtle problem that Bazaar can work around.
2602
unique file texts: This is the total number of unique file contents
2603
seen in the checked revisions. It does not indicate a problem.
2604
repeated file texts: This is the total number of repeated texts seen
2605
in the checked revisions. Texts can be repeated when their file
2606
entries are modified, but the file contents are not. It does not
2609
If no restrictions are specified, all Bazaar data that is found at the given
2610
location will be checked.
2614
Check the tree and branch at 'foo'::
2616
bzr check --tree --branch foo
2618
Check only the repository at 'bar'::
2620
bzr check --repo bar
2622
Check everything at 'baz'::
2627
_see_also = ['reconcile']
2628
takes_args = ['path?']
2629
takes_options = ['verbose',
2630
Option('branch', help="Check the branch related to the"
2631
" current directory."),
2632
Option('repo', help="Check the repository related to the"
2633
" current directory."),
2634
Option('tree', help="Check the working tree related to"
2635
" the current directory.")]
2637
def run(self, path=None, verbose=False, branch=False, repo=False,
2639
from bzrlib.check import check_dwim
2642
if not branch and not repo and not tree:
2643
branch = repo = tree = True
2644
check_dwim(path, verbose, do_branch=branch, do_repo=repo, do_tree=tree)
2647
class cmd_upgrade(Command):
2648
"""Upgrade branch storage to current format.
2650
The check command or bzr developers may sometimes advise you to run
2651
this command. When the default format has changed you may also be warned
2652
during other operations to upgrade.
2655
_see_also = ['check']
2656
takes_args = ['url?']
2658
RegistryOption('format',
2659
help='Upgrade to a specific format. See "bzr help'
2660
' formats" for details.',
2661
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
2662
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
2663
value_switches=True, title='Branch format'),
2666
def run(self, url='.', format=None):
2667
from bzrlib.upgrade import upgrade
2669
format = bzrdir.format_registry.make_bzrdir('default')
2670
upgrade(url, format)
2673
class cmd_whoami(Command):
2674
"""Show or set bzr user id.
2677
Show the email of the current user::
2681
Set the current user::
2683
bzr whoami "Frank Chu <fchu@example.com>"
2685
takes_options = [ Option('email',
2686
help='Display email address only.'),
2688
help='Set identity for the current branch instead of '
2691
takes_args = ['name?']
2692
encoding_type = 'replace'
2695
def run(self, email=False, branch=False, name=None):
2697
# use branch if we're inside one; otherwise global config
2699
c = Branch.open_containing('.')[0].get_config()
2700
except errors.NotBranchError:
2701
c = config.GlobalConfig()
2703
self.outf.write(c.user_email() + '\n')
2705
self.outf.write(c.username() + '\n')
2708
# display a warning if an email address isn't included in the given name.
2710
config.extract_email_address(name)
2711
except errors.NoEmailInUsername, e:
2712
warning('"%s" does not seem to contain an email address. '
2713
'This is allowed, but not recommended.', name)
2715
# use global config unless --branch given
2717
c = Branch.open_containing('.')[0].get_config()
2719
c = config.GlobalConfig()
2720
c.set_user_option('email', name)
2723
class cmd_nick(Command):
2724
"""Print or set the branch nickname.
2726
If unset, the tree root directory name is used as the nickname.
2727
To print the current nickname, execute with no argument.
2729
Bound branches use the nickname of its master branch unless it is set
2733
_see_also = ['info']
2734
takes_args = ['nickname?']
2735
def run(self, nickname=None):
2736
branch = Branch.open_containing(u'.')[0]
2737
if nickname is None:
2738
self.printme(branch)
2740
branch.nick = nickname
2743
def printme(self, branch):
2747
class cmd_alias(Command):
2748
"""Set/unset and display aliases.
2751
Show the current aliases::
2755
Show the alias specified for 'll'::
2759
Set an alias for 'll'::
2761
bzr alias ll="log --line -r-10..-1"
2763
To remove an alias for 'll'::
2765
bzr alias --remove ll
2768
takes_args = ['name?']
2770
Option('remove', help='Remove the alias.'),
2773
def run(self, name=None, remove=False):
2775
self.remove_alias(name)
2777
self.print_aliases()
2779
equal_pos = name.find('=')
2781
self.print_alias(name)
2783
self.set_alias(name[:equal_pos], name[equal_pos+1:])
2785
def remove_alias(self, alias_name):
2786
if alias_name is None:
2787
raise errors.BzrCommandError(
2788
'bzr alias --remove expects an alias to remove.')
2789
# If alias is not found, print something like:
2790
# unalias: foo: not found
2791
c = config.GlobalConfig()
2792
c.unset_alias(alias_name)
2795
def print_aliases(self):
2796
"""Print out the defined aliases in a similar format to bash."""
2797
aliases = config.GlobalConfig().get_aliases()
2798
for key, value in sorted(aliases.iteritems()):
2799
self.outf.write('bzr alias %s="%s"\n' % (key, value))
2802
def print_alias(self, alias_name):
2803
from bzrlib.commands import get_alias
2804
alias = get_alias(alias_name)
2806
self.outf.write("bzr alias: %s: not found\n" % alias_name)
2809
'bzr alias %s="%s"\n' % (alias_name, ' '.join(alias)))
2811
def set_alias(self, alias_name, alias_command):
2812
"""Save the alias in the global config."""
2813
c = config.GlobalConfig()
2814
c.set_alias(alias_name, alias_command)
2817
class cmd_selftest(Command):
2818
"""Run internal test suite.
2820
If arguments are given, they are regular expressions that say which tests
2821
should run. Tests matching any expression are run, and other tests are
2824
Alternatively if --first is given, matching tests are run first and then
2825
all other tests are run. This is useful if you have been working in a
2826
particular area, but want to make sure nothing else was broken.
2828
If --exclude is given, tests that match that regular expression are
2829
excluded, regardless of whether they match --first or not.
2831
To help catch accidential dependencies between tests, the --randomize
2832
option is useful. In most cases, the argument used is the word 'now'.
2833
Note that the seed used for the random number generator is displayed
2834
when this option is used. The seed can be explicitly passed as the
2835
argument to this option if required. This enables reproduction of the
2836
actual ordering used if and when an order sensitive problem is encountered.
2838
If --list-only is given, the tests that would be run are listed. This is
2839
useful when combined with --first, --exclude and/or --randomize to
2840
understand their impact. The test harness reports "Listed nn tests in ..."
2841
instead of "Ran nn tests in ..." when list mode is enabled.
2843
If the global option '--no-plugins' is given, plugins are not loaded
2844
before running the selftests. This has two effects: features provided or
2845
modified by plugins will not be tested, and tests provided by plugins will
2848
Tests that need working space on disk use a common temporary directory,
2849
typically inside $TMPDIR or /tmp.
2852
Run only tests relating to 'ignore'::
2856
Disable plugins and list tests as they're run::
2858
bzr --no-plugins selftest -v
2860
# NB: this is used from the class without creating an instance, which is
2861
# why it does not have a self parameter.
2862
def get_transport_type(typestring):
2863
"""Parse and return a transport specifier."""
2864
if typestring == "sftp":
2865
from bzrlib.transport.sftp import SFTPAbsoluteServer
2866
return SFTPAbsoluteServer
2867
if typestring == "memory":
2868
from bzrlib.transport.memory import MemoryServer
2870
if typestring == "fakenfs":
2871
from bzrlib.transport.fakenfs import FakeNFSServer
2872
return FakeNFSServer
2873
msg = "No known transport type %s. Supported types are: sftp\n" %\
2875
raise errors.BzrCommandError(msg)
2878
takes_args = ['testspecs*']
2879
takes_options = ['verbose',
2881
help='Stop when one test fails.',
2885
help='Use a different transport by default '
2886
'throughout the test suite.',
2887
type=get_transport_type),
2889
help='Run the benchmarks rather than selftests.'),
2890
Option('lsprof-timed',
2891
help='Generate lsprof output for benchmarked'
2892
' sections of code.'),
2893
Option('cache-dir', type=str,
2894
help='Cache intermediate benchmark output in this '
2897
help='Run all tests, but run specified tests first.',
2901
help='List the tests instead of running them.'),
2902
Option('randomize', type=str, argname="SEED",
2903
help='Randomize the order of tests using the given'
2904
' seed or "now" for the current time.'),
2905
Option('exclude', type=str, argname="PATTERN",
2907
help='Exclude tests that match this regular'
2909
Option('strict', help='Fail on missing dependencies or '
2911
Option('load-list', type=str, argname='TESTLISTFILE',
2912
help='Load a test id list from a text file.'),
2913
ListOption('debugflag', type=str, short_name='E',
2914
help='Turn on a selftest debug flag.'),
2915
ListOption('starting-with', type=str, argname='TESTID',
2916
param_name='starting_with', short_name='s',
2918
'Load only the tests starting with TESTID.'),
2920
encoding_type = 'replace'
2922
def run(self, testspecs_list=None, verbose=False, one=False,
2923
transport=None, benchmark=None,
2924
lsprof_timed=None, cache_dir=None,
2925
first=False, list_only=False,
2926
randomize=None, exclude=None, strict=False,
2927
load_list=None, debugflag=None, starting_with=None):
2928
from bzrlib.tests import selftest
2929
import bzrlib.benchmarks as benchmarks
2930
from bzrlib.benchmarks import tree_creator
2932
# Make deprecation warnings visible, unless -Werror is set
2933
symbol_versioning.activate_deprecation_warnings(override=False)
2935
if cache_dir is not None:
2936
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2938
print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
2939
print ' %s (%s python%s)' % (
2941
bzrlib.version_string,
2942
bzrlib._format_version_tuple(sys.version_info),
2945
if testspecs_list is not None:
2946
pattern = '|'.join(testspecs_list)
2950
test_suite_factory = benchmarks.test_suite
2951
# Unless user explicitly asks for quiet, be verbose in benchmarks
2952
verbose = not is_quiet()
2953
# TODO: should possibly lock the history file...
2954
benchfile = open(".perf_history", "at", buffering=1)
2956
test_suite_factory = None
2959
result = selftest(verbose=verbose,
2961
stop_on_failure=one,
2962
transport=transport,
2963
test_suite_factory=test_suite_factory,
2964
lsprof_timed=lsprof_timed,
2965
bench_history=benchfile,
2966
matching_tests_first=first,
2967
list_only=list_only,
2968
random_seed=randomize,
2969
exclude_pattern=exclude,
2971
load_list=load_list,
2972
debug_flags=debugflag,
2973
starting_with=starting_with,
2976
if benchfile is not None:
2979
note('tests passed')
2981
note('tests failed')
2982
return int(not result)
2985
class cmd_version(Command):
2986
"""Show version of bzr."""
2988
encoding_type = 'replace'
2990
Option("short", help="Print just the version number."),
2994
def run(self, short=False):
2995
from bzrlib.version import show_version
2997
self.outf.write(bzrlib.version_string + '\n')
2999
show_version(to_file=self.outf)
3002
class cmd_rocks(Command):
3003
"""Statement of optimism."""
3009
print "It sure does!"
3012
class cmd_find_merge_base(Command):
3013
"""Find and print a base revision for merging two branches."""
3014
# TODO: Options to specify revisions on either side, as if
3015
# merging only part of the history.
3016
takes_args = ['branch', 'other']
3020
def run(self, branch, other):
3021
from bzrlib.revision import ensure_null
3023
branch1 = Branch.open_containing(branch)[0]
3024
branch2 = Branch.open_containing(other)[0]
3029
last1 = ensure_null(branch1.last_revision())
3030
last2 = ensure_null(branch2.last_revision())
3032
graph = branch1.repository.get_graph(branch2.repository)
3033
base_rev_id = graph.find_unique_lca(last1, last2)
3035
print 'merge base is revision %s' % base_rev_id
3042
class cmd_merge(Command):
3043
"""Perform a three-way merge.
3045
The source of the merge can be specified either in the form of a branch,
3046
or in the form of a path to a file containing a merge directive generated
3047
with bzr send. If neither is specified, the default is the upstream branch
3048
or the branch most recently merged using --remember.
3050
When merging a branch, by default the tip will be merged. To pick a different
3051
revision, pass --revision. If you specify two values, the first will be used as
3052
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3053
available revisions, like this is commonly referred to as "cherrypicking".
3055
Revision numbers are always relative to the branch being merged.
3057
By default, bzr will try to merge in all new work from the other
3058
branch, automatically determining an appropriate base. If this
3059
fails, you may need to give an explicit base.
3061
Merge will do its best to combine the changes in two branches, but there
3062
are some kinds of problems only a human can fix. When it encounters those,
3063
it will mark a conflict. A conflict means that you need to fix something,
3064
before you should commit.
3066
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
3068
If there is no default branch set, the first merge will set it. After
3069
that, you can omit the branch to use the default. To change the
3070
default, use --remember. The value will only be saved if the remote
3071
location can be accessed.
3073
The results of the merge are placed into the destination working
3074
directory, where they can be reviewed (with bzr diff), tested, and then
3075
committed to record the result of the merge.
3077
merge refuses to run if there are any uncommitted changes, unless
3081
To merge the latest revision from bzr.dev::
3083
bzr merge ../bzr.dev
3085
To merge changes up to and including revision 82 from bzr.dev::
3087
bzr merge -r 82 ../bzr.dev
3089
To merge the changes introduced by 82, without previous changes::
3091
bzr merge -r 81..82 ../bzr.dev
3093
To apply a merge directive contained in in /tmp/merge:
3095
bzr merge /tmp/merge
3098
encoding_type = 'exact'
3099
_see_also = ['update', 'remerge', 'status-flags']
3100
takes_args = ['location?']
3105
help='Merge even if the destination tree has uncommitted changes.'),
3109
Option('show-base', help="Show base revision text in "
3111
Option('uncommitted', help='Apply uncommitted changes'
3112
' from a working copy, instead of branch changes.'),
3113
Option('pull', help='If the destination is already'
3114
' completely merged into the source, pull from the'
3115
' source rather than merging. When this happens,'
3116
' you do not need to commit the result.'),
3118
help='Branch to merge into, '
3119
'rather than the one containing the working directory.',
3123
Option('preview', help='Instead of merging, show a diff of the merge.')
3126
def run(self, location=None, revision=None, force=False,
3127
merge_type=None, show_base=False, reprocess=None, remember=False,
3128
uncommitted=False, pull=False,
3132
if merge_type is None:
3133
merge_type = _mod_merge.Merge3Merger
3135
if directory is None: directory = u'.'
3136
possible_transports = []
3138
allow_pending = True
3139
verified = 'inapplicable'
3140
tree = WorkingTree.open_containing(directory)[0]
3141
change_reporter = delta._ChangeReporter(
3142
unversioned_filter=tree.is_ignored)
3145
pb = ui.ui_factory.nested_progress_bar()
3146
cleanups.append(pb.finished)
3148
cleanups.append(tree.unlock)
3149
if location is not None:
3151
mergeable = bundle.read_mergeable_from_url(location,
3152
possible_transports=possible_transports)
3153
except errors.NotABundle:
3157
raise errors.BzrCommandError('Cannot use --uncommitted'
3158
' with bundles or merge directives.')
3160
if revision is not None:
3161
raise errors.BzrCommandError(
3162
'Cannot use -r with merge directives or bundles')
3163
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3166
if merger is None and uncommitted:
3167
if revision is not None and len(revision) > 0:
3168
raise errors.BzrCommandError('Cannot use --uncommitted and'
3169
' --revision at the same time.')
3170
location = self._select_branch_location(tree, location)[0]
3171
other_tree, other_path = WorkingTree.open_containing(location)
3172
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3174
allow_pending = False
3175
if other_path != '':
3176
merger.interesting_files = [other_path]
3179
merger, allow_pending = self._get_merger_from_branch(tree,
3180
location, revision, remember, possible_transports, pb)
3182
merger.merge_type = merge_type
3183
merger.reprocess = reprocess
3184
merger.show_base = show_base
3185
self.sanity_check_merger(merger)
3186
if (merger.base_rev_id == merger.other_rev_id and
3187
merger.other_rev_id is not None):
3188
note('Nothing to do.')
3191
if merger.interesting_files is not None:
3192
raise errors.BzrCommandError('Cannot pull individual files')
3193
if (merger.base_rev_id == tree.last_revision()):
3194
result = tree.pull(merger.other_branch, False,
3195
merger.other_rev_id)
3196
result.report(self.outf)
3198
merger.check_basis(not force)
3200
return self._do_preview(merger)
3202
return self._do_merge(merger, change_reporter, allow_pending,
3205
for cleanup in reversed(cleanups):
3208
def _do_preview(self, merger):
3209
from bzrlib.diff import show_diff_trees
3210
tree_merger = merger.make_merger()
3211
tt = tree_merger.make_preview_transform()
3213
result_tree = tt.get_preview_tree()
3214
show_diff_trees(merger.this_tree, result_tree, self.outf,
3215
old_label='', new_label='')
3219
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3220
merger.change_reporter = change_reporter
3221
conflict_count = merger.do_merge()
3223
merger.set_pending()
3224
if verified == 'failed':
3225
warning('Preview patch does not match changes')
3226
if conflict_count != 0:
3231
def sanity_check_merger(self, merger):
3232
if (merger.show_base and
3233
not merger.merge_type is _mod_merge.Merge3Merger):
3234
raise errors.BzrCommandError("Show-base is not supported for this"
3235
" merge type. %s" % merger.merge_type)
3236
if merger.reprocess is None:
3237
if merger.show_base:
3238
merger.reprocess = False
3240
# Use reprocess if the merger supports it
3241
merger.reprocess = merger.merge_type.supports_reprocess
3242
if merger.reprocess and not merger.merge_type.supports_reprocess:
3243
raise errors.BzrCommandError("Conflict reduction is not supported"
3244
" for merge type %s." %
3246
if merger.reprocess and merger.show_base:
3247
raise errors.BzrCommandError("Cannot do conflict reduction and"
3250
def _get_merger_from_branch(self, tree, location, revision, remember,
3251
possible_transports, pb):
3252
"""Produce a merger from a location, assuming it refers to a branch."""
3253
from bzrlib.tag import _merge_tags_if_possible
3254
# find the branch locations
3255
other_loc, user_location = self._select_branch_location(tree, location,
3257
if revision is not None and len(revision) == 2:
3258
base_loc, _unused = self._select_branch_location(tree,
3259
location, revision, 0)
3261
base_loc = other_loc
3263
other_branch, other_path = Branch.open_containing(other_loc,
3264
possible_transports)
3265
if base_loc == other_loc:
3266
base_branch = other_branch
3268
base_branch, base_path = Branch.open_containing(base_loc,
3269
possible_transports)
3270
# Find the revision ids
3271
if revision is None or len(revision) < 1 or revision[-1] is None:
3272
other_revision_id = _mod_revision.ensure_null(
3273
other_branch.last_revision())
3275
other_revision_id = revision[-1].as_revision_id(other_branch)
3276
if (revision is not None and len(revision) == 2
3277
and revision[0] is not None):
3278
base_revision_id = revision[0].as_revision_id(base_branch)
3280
base_revision_id = None
3281
# Remember where we merge from
3282
if ((remember or tree.branch.get_submit_branch() is None) and
3283
user_location is not None):
3284
tree.branch.set_submit_branch(other_branch.base)
3285
_merge_tags_if_possible(other_branch, tree.branch)
3286
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3287
other_revision_id, base_revision_id, other_branch, base_branch)
3288
if other_path != '':
3289
allow_pending = False
3290
merger.interesting_files = [other_path]
3292
allow_pending = True
3293
return merger, allow_pending
3295
def _select_branch_location(self, tree, user_location, revision=None,
3297
"""Select a branch location, according to possible inputs.
3299
If provided, branches from ``revision`` are preferred. (Both
3300
``revision`` and ``index`` must be supplied.)
3302
Otherwise, the ``location`` parameter is used. If it is None, then the
3303
``submit`` or ``parent`` location is used, and a note is printed.
3305
:param tree: The working tree to select a branch for merging into
3306
:param location: The location entered by the user
3307
:param revision: The revision parameter to the command
3308
:param index: The index to use for the revision parameter. Negative
3309
indices are permitted.
3310
:return: (selected_location, user_location). The default location
3311
will be the user-entered location.
3313
if (revision is not None and index is not None
3314
and revision[index] is not None):
3315
branch = revision[index].get_branch()
3316
if branch is not None:
3317
return branch, branch
3318
if user_location is None:
3319
location = self._get_remembered(tree, 'Merging from')
3321
location = user_location
3322
return location, user_location
3324
def _get_remembered(self, tree, verb_string):
3325
"""Use tree.branch's parent if none was supplied.
3327
Report if the remembered location was used.
3329
stored_location = tree.branch.get_submit_branch()
3330
stored_location_type = "submit"
3331
if stored_location is None:
3332
stored_location = tree.branch.get_parent()
3333
stored_location_type = "parent"
3334
mutter("%s", stored_location)
3335
if stored_location is None:
3336
raise errors.BzrCommandError("No location specified or remembered")
3337
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3338
note(u"%s remembered %s location %s", verb_string,
3339
stored_location_type, display_url)
3340
return stored_location
3343
class cmd_remerge(Command):
3346
Use this if you want to try a different merge technique while resolving
3347
conflicts. Some merge techniques are better than others, and remerge
3348
lets you try different ones on different files.
3350
The options for remerge have the same meaning and defaults as the ones for
3351
merge. The difference is that remerge can (only) be run when there is a
3352
pending merge, and it lets you specify particular files.
3355
Re-do the merge of all conflicted files, and show the base text in
3356
conflict regions, in addition to the usual THIS and OTHER texts::
3358
bzr remerge --show-base
3360
Re-do the merge of "foobar", using the weave merge algorithm, with
3361
additional processing to reduce the size of conflict regions::
3363
bzr remerge --merge-type weave --reprocess foobar
3365
takes_args = ['file*']
3370
help="Show base revision text in conflicts."),
3373
def run(self, file_list=None, merge_type=None, show_base=False,
3375
if merge_type is None:
3376
merge_type = _mod_merge.Merge3Merger
3377
tree, file_list = tree_files(file_list)
3380
parents = tree.get_parent_ids()
3381
if len(parents) != 2:
3382
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3383
" merges. Not cherrypicking or"
3385
repository = tree.branch.repository
3386
interesting_ids = None
3388
conflicts = tree.conflicts()
3389
if file_list is not None:
3390
interesting_ids = set()
3391
for filename in file_list:
3392
file_id = tree.path2id(filename)
3394
raise errors.NotVersionedError(filename)
3395
interesting_ids.add(file_id)
3396
if tree.kind(file_id) != "directory":
3399
for name, ie in tree.inventory.iter_entries(file_id):
3400
interesting_ids.add(ie.file_id)
3401
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3403
# Remerge only supports resolving contents conflicts
3404
allowed_conflicts = ('text conflict', 'contents conflict')
3405
restore_files = [c.path for c in conflicts
3406
if c.typestring in allowed_conflicts]
3407
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3408
tree.set_conflicts(ConflictList(new_conflicts))
3409
if file_list is not None:
3410
restore_files = file_list
3411
for filename in restore_files:
3413
restore(tree.abspath(filename))
3414
except errors.NotConflicted:
3416
# Disable pending merges, because the file texts we are remerging
3417
# have not had those merges performed. If we use the wrong parents
3418
# list, we imply that the working tree text has seen and rejected
3419
# all the changes from the other tree, when in fact those changes
3420
# have not yet been seen.
3421
pb = ui.ui_factory.nested_progress_bar()
3422
tree.set_parent_ids(parents[:1])
3424
merger = _mod_merge.Merger.from_revision_ids(pb,
3426
merger.interesting_ids = interesting_ids
3427
merger.merge_type = merge_type
3428
merger.show_base = show_base
3429
merger.reprocess = reprocess
3430
conflicts = merger.do_merge()
3432
tree.set_parent_ids(parents)
3442
class cmd_revert(Command):
3443
"""Revert files to a previous revision.
3445
Giving a list of files will revert only those files. Otherwise, all files
3446
will be reverted. If the revision is not specified with '--revision', the
3447
last committed revision is used.
3449
To remove only some changes, without reverting to a prior version, use
3450
merge instead. For example, "merge . --revision -2..-3" will remove the
3451
changes introduced by -2, without affecting the changes introduced by -1.
3452
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3454
By default, any files that have been manually changed will be backed up
3455
first. (Files changed only by merge are not backed up.) Backup files have
3456
'.~#~' appended to their name, where # is a number.
3458
When you provide files, you can use their current pathname or the pathname
3459
from the target revision. So you can use revert to "undelete" a file by
3460
name. If you name a directory, all the contents of that directory will be
3463
Any files that have been newly added since that revision will be deleted,
3464
with a backup kept if appropriate. Directories containing unknown files
3465
will not be deleted.
3467
The working tree contains a list of pending merged revisions, which will
3468
be included as parents in the next commit. Normally, revert clears that
3469
list as well as reverting the files. If any files are specified, revert
3470
leaves the pending merge list alone and reverts only the files. Use "bzr
3471
revert ." in the tree root to revert all files but keep the merge record,
3472
and "bzr revert --forget-merges" to clear the pending merge list without
3473
reverting any files.
3476
_see_also = ['cat', 'export']
3479
Option('no-backup', "Do not save backups of reverted files."),
3480
Option('forget-merges',
3481
'Remove pending merge marker, without changing any files.'),
3483
takes_args = ['file*']
3485
def run(self, revision=None, no_backup=False, file_list=None,
3486
forget_merges=None):
3487
tree, file_list = tree_files(file_list)
3491
tree.set_parent_ids(tree.get_parent_ids()[:1])
3493
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
3498
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
3499
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
3500
pb = ui.ui_factory.nested_progress_bar()
3502
tree.revert(file_list, rev_tree, not no_backup, pb,
3503
report_changes=True)
3508
class cmd_assert_fail(Command):
3509
"""Test reporting of assertion failures"""
3510
# intended just for use in testing
3515
raise AssertionError("always fails")
3518
class cmd_help(Command):
3519
"""Show help on a command or other topic.
3522
_see_also = ['topics']
3524
Option('long', 'Show help on all commands.'),
3526
takes_args = ['topic?']
3527
aliases = ['?', '--help', '-?', '-h']
3530
def run(self, topic=None, long=False):
3532
if topic is None and long:
3534
bzrlib.help.help(topic)
3537
class cmd_shell_complete(Command):
3538
"""Show appropriate completions for context.
3540
For a list of all available commands, say 'bzr shell-complete'.
3542
takes_args = ['context?']
3547
def run(self, context=None):
3548
import shellcomplete
3549
shellcomplete.shellcomplete(context)
3552
class cmd_missing(Command):
3553
"""Show unmerged/unpulled revisions between two branches.
3555
OTHER_BRANCH may be local or remote.
3557
To filter on a range of revirions, you can use the command -r begin..end
3558
-r revision requests a specific revision, -r ..end or -r begin.. are
3563
Determine the missing revisions between this and the branch at the
3564
remembered pull location::
3568
Determine the missing revisions between this and another branch::
3570
bzr missing http://server/branch
3572
Determine the missing revisions up to a specific revision on the other
3575
bzr missing -r ..-10
3577
Determine the missing revisions up to a specific revision on this
3580
bzr missing --my-revision ..-10
3583
_see_also = ['merge', 'pull']
3584
takes_args = ['other_branch?']
3586
Option('reverse', 'Reverse the order of revisions.'),
3588
'Display changes in the local branch only.'),
3589
Option('this' , 'Same as --mine-only.'),
3590
Option('theirs-only',
3591
'Display changes in the remote branch only.'),
3592
Option('other', 'Same as --theirs-only.'),
3596
custom_help('revision',
3597
help='Filter on other branch revisions (inclusive). '
3598
'See "help revisionspec" for details.'),
3599
Option('my-revision',
3600
type=_parse_revision_str,
3601
help='Filter on local branch revisions (inclusive). '
3602
'See "help revisionspec" for details.'),
3603
Option('include-merges', 'Show merged revisions.'),
3605
encoding_type = 'replace'
3608
def run(self, other_branch=None, reverse=False, mine_only=False,
3610
log_format=None, long=False, short=False, line=False,
3611
show_ids=False, verbose=False, this=False, other=False,
3612
include_merges=False, revision=None, my_revision=None):
3613
from bzrlib.missing import find_unmerged, iter_log_revisions
3622
# TODO: We should probably check that we don't have mine-only and
3623
# theirs-only set, but it gets complicated because we also have
3624
# this and other which could be used.
3631
local_branch = Branch.open_containing(u".")[0]
3632
parent = local_branch.get_parent()
3633
if other_branch is None:
3634
other_branch = parent
3635
if other_branch is None:
3636
raise errors.BzrCommandError("No peer location known"
3638
display_url = urlutils.unescape_for_display(parent,
3640
message("Using saved parent location: "
3641
+ display_url + "\n")
3643
remote_branch = Branch.open(other_branch)
3644
if remote_branch.base == local_branch.base:
3645
remote_branch = local_branch
3647
local_revid_range = _revision_range_to_revid_range(
3648
_get_revision_range(my_revision, local_branch,
3651
remote_revid_range = _revision_range_to_revid_range(
3652
_get_revision_range(revision,
3653
remote_branch, self.name()))
3655
local_branch.lock_read()
3657
remote_branch.lock_read()
3659
local_extra, remote_extra = find_unmerged(
3660
local_branch, remote_branch, restrict,
3661
backward=not reverse,
3662
include_merges=include_merges,
3663
local_revid_range=local_revid_range,
3664
remote_revid_range=remote_revid_range)
3666
if log_format is None:
3667
registry = log.log_formatter_registry
3668
log_format = registry.get_default(local_branch)
3669
lf = log_format(to_file=self.outf,
3671
show_timezone='original')
3674
if local_extra and not theirs_only:
3675
message("You have %d extra revision(s):\n" %
3677
for revision in iter_log_revisions(local_extra,
3678
local_branch.repository,
3680
lf.log_revision(revision)
3681
printed_local = True
3684
printed_local = False
3686
if remote_extra and not mine_only:
3687
if printed_local is True:
3689
message("You are missing %d revision(s):\n" %
3691
for revision in iter_log_revisions(remote_extra,
3692
remote_branch.repository,
3694
lf.log_revision(revision)
3697
if mine_only and not local_extra:
3698
# We checked local, and found nothing extra
3699
message('This branch is up to date.\n')
3700
elif theirs_only and not remote_extra:
3701
# We checked remote, and found nothing extra
3702
message('Other branch is up to date.\n')
3703
elif not (mine_only or theirs_only or local_extra or
3705
# We checked both branches, and neither one had extra
3707
message("Branches are up to date.\n")
3709
remote_branch.unlock()
3711
local_branch.unlock()
3712
if not status_code and parent is None and other_branch is not None:
3713
local_branch.lock_write()
3715
# handle race conditions - a parent might be set while we run.
3716
if local_branch.get_parent() is None:
3717
local_branch.set_parent(remote_branch.base)
3719
local_branch.unlock()
3723
class cmd_pack(Command):
3724
"""Compress the data within a repository."""
3726
_see_also = ['repositories']
3727
takes_args = ['branch_or_repo?']
3729
def run(self, branch_or_repo='.'):
3730
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3732
branch = dir.open_branch()
3733
repository = branch.repository
3734
except errors.NotBranchError:
3735
repository = dir.open_repository()
3739
class cmd_plugins(Command):
3740
"""List the installed plugins.
3742
This command displays the list of installed plugins including
3743
version of plugin and a short description of each.
3745
--verbose shows the path where each plugin is located.
3747
A plugin is an external component for Bazaar that extends the
3748
revision control system, by adding or replacing code in Bazaar.
3749
Plugins can do a variety of things, including overriding commands,
3750
adding new commands, providing additional network transports and
3751
customizing log output.
3753
See the Bazaar web site, http://bazaar-vcs.org, for further
3754
information on plugins including where to find them and how to
3755
install them. Instructions are also provided there on how to
3756
write new plugins using the Python programming language.
3758
takes_options = ['verbose']
3761
def run(self, verbose=False):
3762
import bzrlib.plugin
3763
from inspect import getdoc
3765
for name, plugin in bzrlib.plugin.plugins().items():
3766
version = plugin.__version__
3767
if version == 'unknown':
3769
name_ver = '%s %s' % (name, version)
3770
d = getdoc(plugin.module)
3772
doc = d.split('\n')[0]
3774
doc = '(no description)'
3775
result.append((name_ver, doc, plugin.path()))
3776
for name_ver, doc, path in sorted(result):
3784
class cmd_testament(Command):
3785
"""Show testament (signing-form) of a revision."""
3788
Option('long', help='Produce long-format testament.'),
3790
help='Produce a strict-format testament.')]
3791
takes_args = ['branch?']
3793
def run(self, branch=u'.', revision=None, long=False, strict=False):
3794
from bzrlib.testament import Testament, StrictTestament
3796
testament_class = StrictTestament
3798
testament_class = Testament
3800
b = Branch.open_containing(branch)[0]
3802
b = Branch.open(branch)
3805
if revision is None:
3806
rev_id = b.last_revision()
3808
rev_id = revision[0].as_revision_id(b)
3809
t = testament_class.from_revision(b.repository, rev_id)
3811
sys.stdout.writelines(t.as_text_lines())
3813
sys.stdout.write(t.as_short_text())
3818
class cmd_annotate(Command):
3819
"""Show the origin of each line in a file.
3821
This prints out the given file with an annotation on the left side
3822
indicating which revision, author and date introduced the change.
3824
If the origin is the same for a run of consecutive lines, it is
3825
shown only at the top, unless the --all option is given.
3827
# TODO: annotate directories; showing when each file was last changed
3828
# TODO: if the working copy is modified, show annotations on that
3829
# with new uncommitted lines marked
3830
aliases = ['ann', 'blame', 'praise']
3831
takes_args = ['filename']
3832
takes_options = [Option('all', help='Show annotations on all lines.'),
3833
Option('long', help='Show commit date in annotations.'),
3837
encoding_type = 'exact'
3840
def run(self, filename, all=False, long=False, revision=None,
3842
from bzrlib.annotate import annotate_file, annotate_file_tree
3843
wt, branch, relpath = \
3844
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
3850
tree = _get_one_revision_tree('annotate', revision, branch=branch)
3852
file_id = wt.path2id(relpath)
3854
file_id = tree.path2id(relpath)
3856
raise errors.NotVersionedError(filename)
3857
file_version = tree.inventory[file_id].revision
3858
if wt is not None and revision is None:
3859
# If there is a tree and we're not annotating historical
3860
# versions, annotate the working tree's content.
3861
annotate_file_tree(wt, file_id, self.outf, long, all,
3864
annotate_file(branch, file_version, file_id, long, all, self.outf,
3873
class cmd_re_sign(Command):
3874
"""Create a digital signature for an existing revision."""
3875
# TODO be able to replace existing ones.
3877
hidden = True # is this right ?
3878
takes_args = ['revision_id*']
3879
takes_options = ['revision']
3881
def run(self, revision_id_list=None, revision=None):
3882
if revision_id_list is not None and revision is not None:
3883
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
3884
if revision_id_list is None and revision is None:
3885
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
3886
b = WorkingTree.open_containing(u'.')[0].branch
3889
return self._run(b, revision_id_list, revision)
3893
def _run(self, b, revision_id_list, revision):
3894
import bzrlib.gpg as gpg
3895
gpg_strategy = gpg.GPGStrategy(b.get_config())
3896
if revision_id_list is not None:
3897
b.repository.start_write_group()
3899
for revision_id in revision_id_list:
3900
b.repository.sign_revision(revision_id, gpg_strategy)
3902
b.repository.abort_write_group()
3905
b.repository.commit_write_group()
3906
elif revision is not None:
3907
if len(revision) == 1:
3908
revno, rev_id = revision[0].in_history(b)
3909
b.repository.start_write_group()
3911
b.repository.sign_revision(rev_id, gpg_strategy)
3913
b.repository.abort_write_group()
3916
b.repository.commit_write_group()
3917
elif len(revision) == 2:
3918
# are they both on rh- if so we can walk between them
3919
# might be nice to have a range helper for arbitrary
3920
# revision paths. hmm.
3921
from_revno, from_revid = revision[0].in_history(b)
3922
to_revno, to_revid = revision[1].in_history(b)
3923
if to_revid is None:
3924
to_revno = b.revno()
3925
if from_revno is None or to_revno is None:
3926
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
3927
b.repository.start_write_group()
3929
for revno in range(from_revno, to_revno + 1):
3930
b.repository.sign_revision(b.get_rev_id(revno),
3933
b.repository.abort_write_group()
3936
b.repository.commit_write_group()
3938
raise errors.BzrCommandError('Please supply either one revision, or a range.')
3941
class cmd_bind(Command):
3942
"""Convert the current branch into a checkout of the supplied branch.
3944
Once converted into a checkout, commits must succeed on the master branch
3945
before they will be applied to the local branch.
3947
Bound branches use the nickname of its master branch unless it is set
3948
locally, in which case binding will update the the local nickname to be
3952
_see_also = ['checkouts', 'unbind']
3953
takes_args = ['location?']
3956
def run(self, location=None):
3957
b, relpath = Branch.open_containing(u'.')
3958
if location is None:
3960
location = b.get_old_bound_location()
3961
except errors.UpgradeRequired:
3962
raise errors.BzrCommandError('No location supplied. '
3963
'This format does not remember old locations.')
3965
if location is None:
3966
raise errors.BzrCommandError('No location supplied and no '
3967
'previous location known')
3968
b_other = Branch.open(location)
3971
except errors.DivergedBranches:
3972
raise errors.BzrCommandError('These branches have diverged.'
3973
' Try merging, and then bind again.')
3974
if b.get_config().has_explicit_nickname():
3975
b.nick = b_other.nick
3978
class cmd_unbind(Command):
3979
"""Convert the current checkout into a regular branch.
3981
After unbinding, the local branch is considered independent and subsequent
3982
commits will be local only.
3985
_see_also = ['checkouts', 'bind']
3990
b, relpath = Branch.open_containing(u'.')
3992
raise errors.BzrCommandError('Local branch is not bound')
3995
class cmd_uncommit(Command):
3996
"""Remove the last committed revision.
3998
--verbose will print out what is being removed.
3999
--dry-run will go through all the motions, but not actually
4002
If --revision is specified, uncommit revisions to leave the branch at the
4003
specified revision. For example, "bzr uncommit -r 15" will leave the
4004
branch at revision 15.
4006
Uncommit leaves the working tree ready for a new commit. The only change
4007
it may make is to restore any pending merges that were present before
4011
# TODO: jam 20060108 Add an option to allow uncommit to remove
4012
# unreferenced information in 'branch-as-repository' branches.
4013
# TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
4014
# information in shared branches as well.
4015
_see_also = ['commit']
4016
takes_options = ['verbose', 'revision',
4017
Option('dry-run', help='Don\'t actually make changes.'),
4018
Option('force', help='Say yes to all questions.'),
4020
help="Only remove the commits from the local branch"
4021
" when in a checkout."
4024
takes_args = ['location?']
4026
encoding_type = 'replace'
4028
def run(self, location=None,
4029
dry_run=False, verbose=False,
4030
revision=None, force=False, local=False):
4031
if location is None:
4033
control, relpath = bzrdir.BzrDir.open_containing(location)
4035
tree = control.open_workingtree()
4037
except (errors.NoWorkingTree, errors.NotLocalUrl):
4039
b = control.open_branch()
4041
if tree is not None:
4046
return self._run(b, tree, dry_run, verbose, revision, force,
4049
if tree is not None:
4054
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4055
from bzrlib.log import log_formatter, show_log
4056
from bzrlib.uncommit import uncommit
4058
last_revno, last_rev_id = b.last_revision_info()
4061
if revision is None:
4063
rev_id = last_rev_id
4065
# 'bzr uncommit -r 10' actually means uncommit
4066
# so that the final tree is at revno 10.
4067
# but bzrlib.uncommit.uncommit() actually uncommits
4068
# the revisions that are supplied.
4069
# So we need to offset it by one
4070
revno = revision[0].in_history(b).revno + 1
4071
if revno <= last_revno:
4072
rev_id = b.get_rev_id(revno)
4074
if rev_id is None or _mod_revision.is_null(rev_id):
4075
self.outf.write('No revisions to uncommit.\n')
4078
lf = log_formatter('short',
4080
show_timezone='original')
4085
direction='forward',
4086
start_revision=revno,
4087
end_revision=last_revno)
4090
print 'Dry-run, pretending to remove the above revisions.'
4092
val = raw_input('Press <enter> to continue')
4094
print 'The above revision(s) will be removed.'
4096
val = raw_input('Are you sure [y/N]? ')
4097
if val.lower() not in ('y', 'yes'):
4101
mutter('Uncommitting from {%s} to {%s}',
4102
last_rev_id, rev_id)
4103
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4104
revno=revno, local=local)
4105
note('You can restore the old tip by running:\n'
4106
' bzr pull . -r revid:%s', last_rev_id)
4109
class cmd_break_lock(Command):
4110
"""Break a dead lock on a repository, branch or working directory.
4112
CAUTION: Locks should only be broken when you are sure that the process
4113
holding the lock has been stopped.
4115
You can get information on what locks are open via the 'bzr info' command.
4120
takes_args = ['location?']
4122
def run(self, location=None, show=False):
4123
if location is None:
4125
control, relpath = bzrdir.BzrDir.open_containing(location)
4127
control.break_lock()
4128
except NotImplementedError:
4132
class cmd_wait_until_signalled(Command):
4133
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4135
This just prints a line to signal when it is ready, then blocks on stdin.
4141
sys.stdout.write("running\n")
4143
sys.stdin.readline()
4146
class cmd_serve(Command):
4147
"""Run the bzr server."""
4149
aliases = ['server']
4153
help='Serve on stdin/out for use from inetd or sshd.'),
4155
help='Listen for connections on nominated port of the form '
4156
'[hostname:]portnumber. Passing 0 as the port number will '
4157
'result in a dynamically allocated port. The default port is '
4161
help='Serve contents of this directory.',
4163
Option('allow-writes',
4164
help='By default the server is a readonly server. Supplying '
4165
'--allow-writes enables write access to the contents of '
4166
'the served directory and below.'
4170
def run_smart_server(self, smart_server):
4171
"""Run 'smart_server' forever, with no UI output at all."""
4172
# For the duration of this server, no UI output is permitted. note
4173
# that this may cause problems with blackbox tests. This should be
4174
# changed with care though, as we dont want to use bandwidth sending
4175
# progress over stderr to smart server clients!
4176
from bzrlib import lockdir
4177
old_factory = ui.ui_factory
4178
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
4180
ui.ui_factory = ui.SilentUIFactory()
4181
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
4182
smart_server.serve()
4184
ui.ui_factory = old_factory
4185
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4187
def get_host_and_port(self, port):
4188
"""Return the host and port to run the smart server on.
4190
If 'port' is None, the default host (`medium.BZR_DEFAULT_INTERFACE`)
4191
and port (`medium.BZR_DEFAULT_PORT`) will be used.
4193
If 'port' has a colon in it, the string before the colon will be
4194
interpreted as the host.
4196
:param port: A string of the port to run the server on.
4197
:return: A tuple of (host, port), where 'host' is a host name or IP,
4198
and port is an integer TCP/IP port.
4200
from bzrlib.smart import medium
4201
host = medium.BZR_DEFAULT_INTERFACE
4203
port = medium.BZR_DEFAULT_PORT
4206
host, port = port.split(':')
4210
def get_smart_server(self, transport, inet, port):
4211
"""Construct a smart server.
4213
:param transport: The base transport from which branches will be
4215
:param inet: If True, serve over stdin and stdout. Used for running
4217
:param port: The port to listen on. By default, it's `
4218
medium.BZR_DEFAULT_PORT`. See `get_host_and_port` for more
4220
:return: A smart server.
4222
from bzrlib.smart import medium, server
4224
smart_server = medium.SmartServerPipeStreamMedium(
4225
sys.stdin, sys.stdout, transport)
4227
host, port = self.get_host_and_port(port)
4228
smart_server = server.SmartTCPServer(
4229
transport, host=host, port=port)
4230
note('listening on port: %s' % smart_server.port)
4233
def run(self, port=None, inet=False, directory=None, allow_writes=False):
4234
from bzrlib.transport import get_transport
4235
from bzrlib.transport.chroot import ChrootServer
4236
if directory is None:
4237
directory = os.getcwd()
4238
url = urlutils.local_path_to_url(directory)
4239
if not allow_writes:
4240
url = 'readonly+' + url
4241
chroot_server = ChrootServer(get_transport(url))
4242
chroot_server.setUp()
4243
t = get_transport(chroot_server.get_url())
4244
smart_server = self.get_smart_server(t, inet, port)
4245
self.run_smart_server(smart_server)
4248
class cmd_join(Command):
4249
"""Combine a subtree into its containing tree.
4251
This command is for experimental use only. It requires the target tree
4252
to be in dirstate-with-subtree format, which cannot be converted into
4255
The TREE argument should be an independent tree, inside another tree, but
4256
not part of it. (Such trees can be produced by "bzr split", but also by
4257
running "bzr branch" with the target inside a tree.)
4259
The result is a combined tree, with the subtree no longer an independant
4260
part. This is marked as a merge of the subtree into the containing tree,
4261
and all history is preserved.
4263
If --reference is specified, the subtree retains its independence. It can
4264
be branched by itself, and can be part of multiple projects at the same
4265
time. But operations performed in the containing tree, such as commit
4266
and merge, will recurse into the subtree.
4269
_see_also = ['split']
4270
takes_args = ['tree']
4272
Option('reference', help='Join by reference.'),
4276
def run(self, tree, reference=False):
4277
sub_tree = WorkingTree.open(tree)
4278
parent_dir = osutils.dirname(sub_tree.basedir)
4279
containing_tree = WorkingTree.open_containing(parent_dir)[0]
4280
repo = containing_tree.branch.repository
4281
if not repo.supports_rich_root():
4282
raise errors.BzrCommandError(
4283
"Can't join trees because %s doesn't support rich root data.\n"
4284
"You can use bzr upgrade on the repository."
4288
containing_tree.add_reference(sub_tree)
4289
except errors.BadReferenceTarget, e:
4290
# XXX: Would be better to just raise a nicely printable
4291
# exception from the real origin. Also below. mbp 20070306
4292
raise errors.BzrCommandError("Cannot join %s. %s" %
4296
containing_tree.subsume(sub_tree)
4297
except errors.BadSubsumeSource, e:
4298
raise errors.BzrCommandError("Cannot join %s. %s" %
4302
class cmd_split(Command):
4303
"""Split a subdirectory of a tree into a separate tree.
4305
This command will produce a target tree in a format that supports
4306
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4307
converted into earlier formats like 'dirstate-tags'.
4309
The TREE argument should be a subdirectory of a working tree. That
4310
subdirectory will be converted into an independent tree, with its own
4311
branch. Commits in the top-level tree will not apply to the new subtree.
4314
# join is not un-hidden yet
4315
#_see_also = ['join']
4316
takes_args = ['tree']
4318
def run(self, tree):
4319
containing_tree, subdir = WorkingTree.open_containing(tree)
4320
sub_id = containing_tree.path2id(subdir)
4322
raise errors.NotVersionedError(subdir)
4324
containing_tree.extract(sub_id)
4325
except errors.RootNotRich:
4326
raise errors.UpgradeRequired(containing_tree.branch.base)
4329
class cmd_merge_directive(Command):
4330
"""Generate a merge directive for auto-merge tools.
4332
A directive requests a merge to be performed, and also provides all the
4333
information necessary to do so. This means it must either include a
4334
revision bundle, or the location of a branch containing the desired
4337
A submit branch (the location to merge into) must be supplied the first
4338
time the command is issued. After it has been supplied once, it will
4339
be remembered as the default.
4341
A public branch is optional if a revision bundle is supplied, but required
4342
if --diff or --plain is specified. It will be remembered as the default
4343
after the first use.
4346
takes_args = ['submit_branch?', 'public_branch?']
4350
_see_also = ['send']
4353
RegistryOption.from_kwargs('patch-type',
4354
'The type of patch to include in the directive.',
4356
value_switches=True,
4358
bundle='Bazaar revision bundle (default).',
4359
diff='Normal unified diff.',
4360
plain='No patch, just directive.'),
4361
Option('sign', help='GPG-sign the directive.'), 'revision',
4362
Option('mail-to', type=str,
4363
help='Instead of printing the directive, email to this address.'),
4364
Option('message', type=str, short_name='m',
4365
help='Message to use when committing this merge.')
4368
encoding_type = 'exact'
4370
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
4371
sign=False, revision=None, mail_to=None, message=None):
4372
from bzrlib.revision import ensure_null, NULL_REVISION
4373
include_patch, include_bundle = {
4374
'plain': (False, False),
4375
'diff': (True, False),
4376
'bundle': (True, True),
4378
branch = Branch.open('.')
4379
stored_submit_branch = branch.get_submit_branch()
4380
if submit_branch is None:
4381
submit_branch = stored_submit_branch
4383
if stored_submit_branch is None:
4384
branch.set_submit_branch(submit_branch)
4385
if submit_branch is None:
4386
submit_branch = branch.get_parent()
4387
if submit_branch is None:
4388
raise errors.BzrCommandError('No submit branch specified or known')
4390
stored_public_branch = branch.get_public_branch()
4391
if public_branch is None:
4392
public_branch = stored_public_branch
4393
elif stored_public_branch is None:
4394
branch.set_public_branch(public_branch)
4395
if not include_bundle and public_branch is None:
4396
raise errors.BzrCommandError('No public branch specified or'
4398
base_revision_id = None
4399
if revision is not None:
4400
if len(revision) > 2:
4401
raise errors.BzrCommandError('bzr merge-directive takes '
4402
'at most two one revision identifiers')
4403
revision_id = revision[-1].as_revision_id(branch)
4404
if len(revision) == 2:
4405
base_revision_id = revision[0].as_revision_id(branch)
4407
revision_id = branch.last_revision()
4408
revision_id = ensure_null(revision_id)
4409
if revision_id == NULL_REVISION:
4410
raise errors.BzrCommandError('No revisions to bundle.')
4411
directive = merge_directive.MergeDirective2.from_objects(
4412
branch.repository, revision_id, time.time(),
4413
osutils.local_time_offset(), submit_branch,
4414
public_branch=public_branch, include_patch=include_patch,
4415
include_bundle=include_bundle, message=message,
4416
base_revision_id=base_revision_id)
4419
self.outf.write(directive.to_signed(branch))
4421
self.outf.writelines(directive.to_lines())
4423
message = directive.to_email(mail_to, branch, sign)
4424
s = SMTPConnection(branch.get_config())
4425
s.send_email(message)
4428
class cmd_send(Command):
4429
"""Mail or create a merge-directive for submitting changes.
4431
A merge directive provides many things needed for requesting merges:
4433
* A machine-readable description of the merge to perform
4435
* An optional patch that is a preview of the changes requested
4437
* An optional bundle of revision data, so that the changes can be applied
4438
directly from the merge directive, without retrieving data from a
4441
If --no-bundle is specified, then public_branch is needed (and must be
4442
up-to-date), so that the receiver can perform the merge using the
4443
public_branch. The public_branch is always included if known, so that
4444
people can check it later.
4446
The submit branch defaults to the parent, but can be overridden. Both
4447
submit branch and public branch will be remembered if supplied.
4449
If a public_branch is known for the submit_branch, that public submit
4450
branch is used in the merge instructions. This means that a local mirror
4451
can be used as your actual submit branch, once you have set public_branch
4454
Mail is sent using your preferred mail program. This should be transparent
4455
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4456
If the preferred client can't be found (or used), your editor will be used.
4458
To use a specific mail program, set the mail_client configuration option.
4459
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4460
specific clients are "claws", "evolution", "kmail", "mutt", and
4461
"thunderbird"; generic options are "default", "editor", "emacsclient",
4462
"mapi", and "xdg-email". Plugins may also add supported clients.
4464
If mail is being sent, a to address is required. This can be supplied
4465
either on the commandline, by setting the submit_to configuration
4466
option in the branch itself or the child_submit_to configuration option
4467
in the submit branch.
4469
Two formats are currently supported: "4" uses revision bundle format 4 and
4470
merge directive format 2. It is significantly faster and smaller than
4471
older formats. It is compatible with Bazaar 0.19 and later. It is the
4472
default. "0.9" uses revision bundle format 0.9 and merge directive
4473
format 1. It is compatible with Bazaar 0.12 - 0.18.
4475
Merge directives are applied using the merge command or the pull command.
4478
encoding_type = 'exact'
4480
_see_also = ['merge', 'pull']
4482
takes_args = ['submit_branch?', 'public_branch?']
4486
help='Do not include a bundle in the merge directive.'),
4487
Option('no-patch', help='Do not include a preview patch in the merge'
4490
help='Remember submit and public branch.'),
4492
help='Branch to generate the submission from, '
4493
'rather than the one containing the working directory.',
4496
Option('output', short_name='o',
4497
help='Write merge directive to this file; '
4498
'use - for stdout.',
4500
Option('mail-to', help='Mail the request to this address.',
4504
RegistryOption.from_kwargs('format',
4505
'Use the specified output format.',
4506
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4507
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4510
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4511
no_patch=False, revision=None, remember=False, output=None,
4512
format='4', mail_to=None, message=None, **kwargs):
4513
return self._run(submit_branch, revision, public_branch, remember,
4514
format, no_bundle, no_patch, output,
4515
kwargs.get('from', '.'), mail_to, message)
4517
def _run(self, submit_branch, revision, public_branch, remember, format,
4518
no_bundle, no_patch, output, from_, mail_to, message):
4519
from bzrlib.revision import NULL_REVISION
4520
branch = Branch.open_containing(from_)[0]
4522
outfile = cStringIO.StringIO()
4526
outfile = open(output, 'wb')
4527
# we may need to write data into branch's repository to calculate
4532
config = branch.get_config()
4534
mail_to = config.get_user_option('submit_to')
4535
mail_client = config.get_mail_client()
4536
if remember and submit_branch is None:
4537
raise errors.BzrCommandError(
4538
'--remember requires a branch to be specified.')
4539
stored_submit_branch = branch.get_submit_branch()
4540
remembered_submit_branch = None
4541
if submit_branch is None:
4542
submit_branch = stored_submit_branch
4543
remembered_submit_branch = "submit"
4545
if stored_submit_branch is None or remember:
4546
branch.set_submit_branch(submit_branch)
4547
if submit_branch is None:
4548
submit_branch = branch.get_parent()
4549
remembered_submit_branch = "parent"
4550
if submit_branch is None:
4551
raise errors.BzrCommandError('No submit branch known or'
4553
if remembered_submit_branch is not None:
4554
note('Using saved %s location "%s" to determine what '
4555
'changes to submit.', remembered_submit_branch,
4559
submit_config = Branch.open(submit_branch).get_config()
4560
mail_to = submit_config.get_user_option("child_submit_to")
4562
stored_public_branch = branch.get_public_branch()
4563
if public_branch is None:
4564
public_branch = stored_public_branch
4565
elif stored_public_branch is None or remember:
4566
branch.set_public_branch(public_branch)
4567
if no_bundle and public_branch is None:
4568
raise errors.BzrCommandError('No public branch specified or'
4570
base_revision_id = None
4572
if revision is not None:
4573
if len(revision) > 2:
4574
raise errors.BzrCommandError('bzr send takes '
4575
'at most two one revision identifiers')
4576
revision_id = revision[-1].as_revision_id(branch)
4577
if len(revision) == 2:
4578
base_revision_id = revision[0].as_revision_id(branch)
4579
if revision_id is None:
4580
revision_id = branch.last_revision()
4581
if revision_id == NULL_REVISION:
4582
raise errors.BzrCommandError('No revisions to submit.')
4584
directive = merge_directive.MergeDirective2.from_objects(
4585
branch.repository, revision_id, time.time(),
4586
osutils.local_time_offset(), submit_branch,
4587
public_branch=public_branch, include_patch=not no_patch,
4588
include_bundle=not no_bundle, message=message,
4589
base_revision_id=base_revision_id)
4590
elif format == '0.9':
4593
patch_type = 'bundle'
4595
raise errors.BzrCommandError('Format 0.9 does not'
4596
' permit bundle with no patch')
4602
directive = merge_directive.MergeDirective.from_objects(
4603
branch.repository, revision_id, time.time(),
4604
osutils.local_time_offset(), submit_branch,
4605
public_branch=public_branch, patch_type=patch_type,
4608
outfile.writelines(directive.to_lines())
4610
subject = '[MERGE] '
4611
if message is not None:
4614
revision = branch.repository.get_revision(revision_id)
4615
subject += revision.get_summary()
4616
basename = directive.get_disk_name(branch)
4617
mail_client.compose_merge_request(mail_to, subject,
4618
outfile.getvalue(), basename)
4625
class cmd_bundle_revisions(cmd_send):
4627
"""Create a merge-directive for submitting changes.
4629
A merge directive provides many things needed for requesting merges:
4631
* A machine-readable description of the merge to perform
4633
* An optional patch that is a preview of the changes requested
4635
* An optional bundle of revision data, so that the changes can be applied
4636
directly from the merge directive, without retrieving data from a
4639
If --no-bundle is specified, then public_branch is needed (and must be
4640
up-to-date), so that the receiver can perform the merge using the
4641
public_branch. The public_branch is always included if known, so that
4642
people can check it later.
4644
The submit branch defaults to the parent, but can be overridden. Both
4645
submit branch and public branch will be remembered if supplied.
4647
If a public_branch is known for the submit_branch, that public submit
4648
branch is used in the merge instructions. This means that a local mirror
4649
can be used as your actual submit branch, once you have set public_branch
4652
Two formats are currently supported: "4" uses revision bundle format 4 and
4653
merge directive format 2. It is significantly faster and smaller than
4654
older formats. It is compatible with Bazaar 0.19 and later. It is the
4655
default. "0.9" uses revision bundle format 0.9 and merge directive
4656
format 1. It is compatible with Bazaar 0.12 - 0.18.
4661
help='Do not include a bundle in the merge directive.'),
4662
Option('no-patch', help='Do not include a preview patch in the merge'
4665
help='Remember submit and public branch.'),
4667
help='Branch to generate the submission from, '
4668
'rather than the one containing the working directory.',
4671
Option('output', short_name='o', help='Write directive to this file.',
4674
RegistryOption.from_kwargs('format',
4675
'Use the specified output format.',
4676
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4677
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4679
aliases = ['bundle']
4681
_see_also = ['send', 'merge']
4685
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4686
no_patch=False, revision=None, remember=False, output=None,
4687
format='4', **kwargs):
4690
return self._run(submit_branch, revision, public_branch, remember,
4691
format, no_bundle, no_patch, output,
4692
kwargs.get('from', '.'), None, None)
4695
class cmd_tag(Command):
4696
"""Create, remove or modify a tag naming a revision.
4698
Tags give human-meaningful names to revisions. Commands that take a -r
4699
(--revision) option can be given -rtag:X, where X is any previously
4702
Tags are stored in the branch. Tags are copied from one branch to another
4703
along when you branch, push, pull or merge.
4705
It is an error to give a tag name that already exists unless you pass
4706
--force, in which case the tag is moved to point to the new revision.
4708
To rename a tag (change the name but keep it on the same revsion), run ``bzr
4709
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
4712
_see_also = ['commit', 'tags']
4713
takes_args = ['tag_name']
4716
help='Delete this tag rather than placing it.',
4719
help='Branch in which to place the tag.',
4724
help='Replace existing tags.',
4729
def run(self, tag_name,
4735
branch, relpath = Branch.open_containing(directory)
4739
branch.tags.delete_tag(tag_name)
4740
self.outf.write('Deleted tag %s.\n' % tag_name)
4743
if len(revision) != 1:
4744
raise errors.BzrCommandError(
4745
"Tags can only be placed on a single revision, "
4747
revision_id = revision[0].as_revision_id(branch)
4749
revision_id = branch.last_revision()
4750
if (not force) and branch.tags.has_tag(tag_name):
4751
raise errors.TagAlreadyExists(tag_name)
4752
branch.tags.set_tag(tag_name, revision_id)
4753
self.outf.write('Created tag %s.\n' % tag_name)
4758
class cmd_tags(Command):
4761
This command shows a table of tag names and the revisions they reference.
4767
help='Branch whose tags should be displayed.',
4771
RegistryOption.from_kwargs('sort',
4772
'Sort tags by different criteria.', title='Sorting',
4773
alpha='Sort tags lexicographically (default).',
4774
time='Sort tags chronologically.',
4787
branch, relpath = Branch.open_containing(directory)
4789
tags = branch.tags.get_tag_dict().items()
4796
graph = branch.repository.get_graph()
4797
rev1, rev2 = _get_revision_range(revision, branch, self.name())
4798
revid1, revid2 = rev1.rev_id, rev2.rev_id
4799
# only show revisions between revid1 and revid2 (inclusive)
4800
tags = [(tag, revid) for tag, revid in tags if
4801
graph.is_between(revid, revid1, revid2)]
4806
elif sort == 'time':
4808
for tag, revid in tags:
4810
revobj = branch.repository.get_revision(revid)
4811
except errors.NoSuchRevision:
4812
timestamp = sys.maxint # place them at the end
4814
timestamp = revobj.timestamp
4815
timestamps[revid] = timestamp
4816
tags.sort(key=lambda x: timestamps[x[1]])
4818
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
4819
revno_map = branch.get_revision_id_to_revno_map()
4820
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
4821
for tag, revid in tags ]
4822
for tag, revspec in tags:
4823
self.outf.write('%-20s %s\n' % (tag, revspec))
4826
class cmd_reconfigure(Command):
4827
"""Reconfigure the type of a bzr directory.
4829
A target configuration must be specified.
4831
For checkouts, the bind-to location will be auto-detected if not specified.
4832
The order of preference is
4833
1. For a lightweight checkout, the current bound location.
4834
2. For branches that used to be checkouts, the previously-bound location.
4835
3. The push location.
4836
4. The parent location.
4837
If none of these is available, --bind-to must be specified.
4840
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
4841
takes_args = ['location?']
4842
takes_options = [RegistryOption.from_kwargs('target_type',
4843
title='Target type',
4844
help='The type to reconfigure the directory to.',
4845
value_switches=True, enum_switch=False,
4846
branch='Reconfigure to be an unbound branch '
4847
'with no working tree.',
4848
tree='Reconfigure to be an unbound branch '
4849
'with a working tree.',
4850
checkout='Reconfigure to be a bound branch '
4851
'with a working tree.',
4852
lightweight_checkout='Reconfigure to be a lightweight'
4853
' checkout (with no local history).',
4854
standalone='Reconfigure to be a standalone branch '
4855
'(i.e. stop using shared repository).',
4856
use_shared='Reconfigure to use a shared repository.'),
4857
Option('bind-to', help='Branch to bind checkout to.',
4860
help='Perform reconfiguration even if local changes'
4864
def run(self, location=None, target_type=None, bind_to=None, force=False):
4865
directory = bzrdir.BzrDir.open(location)
4866
if target_type is None:
4867
raise errors.BzrCommandError('No target configuration specified')
4868
elif target_type == 'branch':
4869
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4870
elif target_type == 'tree':
4871
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4872
elif target_type == 'checkout':
4873
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4875
elif target_type == 'lightweight-checkout':
4876
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4878
elif target_type == 'use-shared':
4879
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
4880
elif target_type == 'standalone':
4881
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
4882
reconfiguration.apply(force)
4885
class cmd_switch(Command):
4886
"""Set the branch of a checkout and update.
4888
For lightweight checkouts, this changes the branch being referenced.
4889
For heavyweight checkouts, this checks that there are no local commits
4890
versus the current bound branch, then it makes the local branch a mirror
4891
of the new location and binds to it.
4893
In both cases, the working tree is updated and uncommitted changes
4894
are merged. The user can commit or revert these as they desire.
4896
Pending merges need to be committed or reverted before using switch.
4898
The path to the branch to switch to can be specified relative to the parent
4899
directory of the current branch. For example, if you are currently in a
4900
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4903
Bound branches use the nickname of its master branch unless it is set
4904
locally, in which case switching will update the the local nickname to be
4908
takes_args = ['to_location']
4909
takes_options = [Option('force',
4910
help='Switch even if local commits will be lost.')
4913
def run(self, to_location, force=False):
4914
from bzrlib import switch
4916
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4917
branch = control_dir.open_branch()
4919
to_branch = Branch.open(to_location)
4920
except errors.NotBranchError:
4921
this_branch = control_dir.open_branch()
4922
# This may be a heavy checkout, where we want the master branch
4923
this_url = this_branch.get_bound_location()
4924
# If not, use a local sibling
4925
if this_url is None:
4926
this_url = this_branch.base
4927
to_branch = Branch.open(
4928
urlutils.join(this_url, '..', to_location))
4929
switch.switch(control_dir, to_branch, force)
4930
if branch.get_config().has_explicit_nickname():
4931
branch = control_dir.open_branch() #get the new branch!
4932
branch.nick = to_branch.nick
4933
note('Switched to branch: %s',
4934
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4937
class cmd_hooks(Command):
4938
"""Show a branch's currently registered hooks.
4942
takes_args = ['path?']
4944
def run(self, path=None):
4947
branch_hooks = Branch.open(path).hooks
4948
for hook_type in branch_hooks:
4949
hooks = branch_hooks[hook_type]
4950
self.outf.write("%s:\n" % (hook_type,))
4953
self.outf.write(" %s\n" %
4954
(branch_hooks.get_hook_name(hook),))
4956
self.outf.write(" <no hooks installed>\n")
4959
class cmd_shelve(Command):
4960
"""Temporarily set aside some changes from the current tree.
4962
Shelve allows you to temporarily put changes you've made "on the shelf",
4963
ie. out of the way, until a later time when you can bring them back from
4964
the shelf with the 'unshelve' command.
4966
If shelve --list is specified, previously-shelved changes are listed.
4968
Shelve is intended to help separate several sets of changes that have
4969
been inappropriately mingled. If you just want to get rid of all changes
4970
and you don't need to restore them later, use revert. If you want to
4971
shelve all text changes at once, use shelve --all.
4973
If filenames are specified, only the changes to those files will be
4974
shelved. Other files will be left untouched.
4976
If a revision is specified, changes since that revision will be shelved.
4978
You can put multiple items on the shelf, and by default, 'unshelve' will
4979
restore the most recently shelved changes.
4982
takes_args = ['file*']
4986
Option('all', help='Shelve all changes.'),
4988
RegistryOption('writer', 'Method to use for writing diffs.',
4989
bzrlib.option.diff_writer_registry,
4990
value_switches=True, enum_switch=False),
4992
Option('list', help='List shelved changes.'),
4994
_see_also = ['unshelve']
4996
def run(self, revision=None, all=False, file_list=None, message=None,
4997
writer=None, list=False):
4999
return self.run_for_list()
5000
from bzrlib.shelf_ui import Shelver
5002
writer = bzrlib.option.diff_writer_registry.get()
5004
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5006
except errors.UserAbort:
5009
def run_for_list(self):
5010
tree = WorkingTree.open_containing('.')[0]
5013
manager = tree.get_shelf_manager()
5014
shelves = manager.active_shelves()
5015
if len(shelves) == 0:
5016
note('No shelved changes.')
5018
for shelf_id in reversed(shelves):
5019
message = manager.get_metadata(shelf_id).get('message')
5021
message = '<no message>'
5022
self.outf.write('%3d: %s\n' % (shelf_id, message))
5028
class cmd_unshelve(Command):
5029
"""Restore shelved changes.
5031
By default, the most recently shelved changes are restored. However if you
5032
specify a patch by name those changes will be restored instead. This
5033
works best when the changes don't depend on each other.
5036
takes_args = ['shelf_id?']
5038
RegistryOption.from_kwargs(
5039
'action', help="The action to perform.",
5040
enum_switch=False, value_switches=True,
5041
apply="Apply changes and remove from the shelf.",
5042
dry_run="Show changes, but do not apply or remove them.",
5043
delete_only="Delete changes without applying them."
5046
_see_also = ['shelve']
5048
def run(self, shelf_id=None, action='apply'):
5049
from bzrlib.shelf_ui import Unshelver
5050
Unshelver.from_args(shelf_id, action).run()
5053
def _create_prefix(cur_transport):
5054
needed = [cur_transport]
5055
# Recurse upwards until we can create a directory successfully
5057
new_transport = cur_transport.clone('..')
5058
if new_transport.base == cur_transport.base:
5059
raise errors.BzrCommandError(
5060
"Failed to create path prefix for %s."
5061
% cur_transport.base)
5063
new_transport.mkdir('.')
5064
except errors.NoSuchFile:
5065
needed.append(new_transport)
5066
cur_transport = new_transport
5069
# Now we only need to create child directories
5071
cur_transport = needed.pop()
5072
cur_transport.ensure_base()
5075
# these get imported and then picked up by the scan for cmd_*
5076
# TODO: Some more consistent way to split command definitions across files;
5077
# we do need to load at least some information about them to know of
5078
# aliases. ideally we would avoid loading the implementation until the
5079
# details were needed.
5080
from bzrlib.cmd_version_info import cmd_version_info
5081
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5082
from bzrlib.bundle.commands import (
5085
from bzrlib.sign_my_commits import cmd_sign_my_commits
5086
from bzrlib.weave_commands import cmd_versionedfile_list, \
5087
cmd_weave_plan_merge, cmd_weave_merge_text