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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""builtin bzr commands"""
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
45
revision as _mod_revision,
53
from bzrlib.branch import Branch
54
from bzrlib.conflicts import ConflictList
55
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
56
from bzrlib.smtp_connection import SMTPConnection
57
from bzrlib.workingtree import WorkingTree
60
from bzrlib.commands import Command, display_command
61
from bzrlib.option import (
68
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
71
def tree_files(file_list, default_branch=u'.', canonicalize=True,
74
return internal_tree_files(file_list, default_branch, canonicalize,
76
except errors.FileInWrongBranch, e:
77
raise errors.BzrCommandError("%s is not in the same branch as %s" %
78
(e.path, file_list[0]))
81
def tree_files_for_add(file_list):
83
Return a tree and list of absolute paths from a file list.
85
Similar to tree_files, but add handles files a bit differently, so it a
86
custom implementation. In particular, MutableTreeTree.smart_add expects
87
absolute paths, which it immediately converts to relative paths.
89
# FIXME Would be nice to just return the relative paths like
90
# internal_tree_files does, but there are a large number of unit tests
91
# that assume the current interface to mutabletree.smart_add
93
tree, relpath = WorkingTree.open_containing(file_list[0])
94
if tree.supports_views():
95
view_files = tree.views.lookup_view()
97
for filename in file_list:
98
if not osutils.is_inside_any(view_files, filename):
99
raise errors.FileOutsideView(filename, view_files)
100
file_list = file_list[:]
101
file_list[0] = tree.abspath(relpath)
103
tree = WorkingTree.open_containing(u'.')[0]
104
if tree.supports_views():
105
view_files = tree.views.lookup_view()
107
file_list = view_files
108
view_str = views.view_display_str(view_files)
109
note("Ignoring files outside view. View is %s" % view_str)
110
return tree, file_list
113
def _get_one_revision(command_name, revisions):
114
if revisions is None:
116
if len(revisions) != 1:
117
raise errors.BzrCommandError(
118
'bzr %s --revision takes exactly one revision identifier' % (
123
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
126
if revisions is None:
128
rev_tree = tree.basis_tree()
130
rev_tree = branch.basis_tree()
132
revision = _get_one_revision(command_name, revisions)
133
rev_tree = revision.as_tree(branch)
137
# XXX: Bad function name; should possibly also be a class method of
138
# WorkingTree rather than a function.
139
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
141
"""Convert command-line paths to a WorkingTree and relative paths.
143
This is typically used for command-line processors that take one or
144
more filenames, and infer the workingtree that contains them.
146
The filenames given are not required to exist.
148
:param file_list: Filenames to convert.
150
:param default_branch: Fallback tree path to use if file_list is empty or
153
:param apply_view: if True and a view is set, apply it or check that
154
specified files are within it
156
:return: workingtree, [relative_paths]
158
if file_list is None or len(file_list) == 0:
159
tree = WorkingTree.open_containing(default_branch)[0]
160
if tree.supports_views() and apply_view:
161
view_files = tree.views.lookup_view()
163
file_list = view_files
164
view_str = views.view_display_str(view_files)
165
note("Ignoring files outside view. View is %s" % view_str)
166
return tree, file_list
167
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
168
return tree, safe_relpath_files(tree, file_list, canonicalize,
169
apply_view=apply_view)
172
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
173
"""Convert file_list into a list of relpaths in tree.
175
:param tree: A tree to operate on.
176
:param file_list: A list of user provided paths or None.
177
:param apply_view: if True and a view is set, apply it or check that
178
specified files are within it
179
:return: A list of relative paths.
180
:raises errors.PathNotChild: When a provided path is in a different tree
183
if file_list is None:
185
if tree.supports_views() and apply_view:
186
view_files = tree.views.lookup_view()
190
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
191
# doesn't - fix that up here before we enter the loop.
193
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
196
for filename in file_list:
198
relpath = fixer(osutils.dereference_path(filename))
199
if view_files and not osutils.is_inside_any(view_files, relpath):
200
raise errors.FileOutsideView(filename, view_files)
201
new_list.append(relpath)
202
except errors.PathNotChild:
203
raise errors.FileInWrongBranch(tree.branch, filename)
207
def _get_view_info_for_change_reporter(tree):
208
"""Get the view information from a tree for change reporting."""
211
current_view = tree.views.get_view_info()[0]
212
if current_view is not None:
213
view_info = (current_view, tree.views.lookup_view())
214
except errors.ViewsNotSupported:
219
# TODO: Make sure no commands unconditionally use the working directory as a
220
# branch. If a filename argument is used, the first of them should be used to
221
# specify the branch. (Perhaps this can be factored out into some kind of
222
# Argument class, representing a file in a branch, where the first occurrence
225
class cmd_status(Command):
226
"""Display status summary.
228
This reports on versioned and unknown files, reporting them
229
grouped by state. Possible states are:
232
Versioned in the working copy but not in the previous revision.
235
Versioned in the previous revision but removed or deleted
239
Path of this file changed from the previous revision;
240
the text may also have changed. This includes files whose
241
parent directory was renamed.
244
Text has changed since the previous revision.
247
File kind has been changed (e.g. from file to directory).
250
Not versioned and not matching an ignore pattern.
252
To see ignored files use 'bzr ignored'. For details on the
253
changes to file texts, use 'bzr diff'.
255
Note that --short or -S gives status flags for each item, similar
256
to Subversion's status command. To get output similar to svn -q,
259
If no arguments are specified, the status of the entire working
260
directory is shown. Otherwise, only the status of the specified
261
files or directories is reported. If a directory is given, status
262
is reported for everything inside that directory.
264
Before merges are committed, the pending merge tip revisions are
265
shown. To see all pending merge revisions, use the -v option.
266
To skip the display of pending merge information altogether, use
267
the no-pending option or specify a file/directory.
269
If a revision argument is given, the status is calculated against
270
that revision, or between two revisions if two are provided.
273
# TODO: --no-recurse, --recurse options
275
takes_args = ['file*']
276
takes_options = ['show-ids', 'revision', 'change', 'verbose',
277
Option('short', help='Use short status indicators.',
279
Option('versioned', help='Only show versioned files.',
281
Option('no-pending', help='Don\'t show pending merges.',
284
aliases = ['st', 'stat']
286
encoding_type = 'replace'
287
_see_also = ['diff', 'revert', 'status-flags']
290
def run(self, show_ids=False, file_list=None, revision=None, short=False,
291
versioned=False, no_pending=False, verbose=False):
292
from bzrlib.status import show_tree_status
294
if revision and len(revision) > 2:
295
raise errors.BzrCommandError('bzr status --revision takes exactly'
296
' one or two revision specifiers')
298
tree, relfile_list = tree_files(file_list)
299
# Avoid asking for specific files when that is not needed.
300
if relfile_list == ['']:
302
# Don't disable pending merges for full trees other than '.'.
303
if file_list == ['.']:
305
# A specific path within a tree was given.
306
elif relfile_list is not None:
308
show_tree_status(tree, show_ids=show_ids,
309
specific_files=relfile_list, revision=revision,
310
to_file=self.outf, short=short, versioned=versioned,
311
show_pending=(not no_pending), verbose=verbose)
314
class cmd_cat_revision(Command):
315
"""Write out metadata for a revision.
317
The revision to print can either be specified by a specific
318
revision identifier, or you can use --revision.
322
takes_args = ['revision_id?']
323
takes_options = ['revision']
324
# cat-revision is more for frontends so should be exact
328
def run(self, revision_id=None, revision=None):
329
if revision_id is not None and revision is not None:
330
raise errors.BzrCommandError('You can only supply one of'
331
' revision_id or --revision')
332
if revision_id is None and revision is None:
333
raise errors.BzrCommandError('You must supply either'
334
' --revision or a revision_id')
335
b = WorkingTree.open_containing(u'.')[0].branch
337
# TODO: jam 20060112 should cat-revision always output utf-8?
338
if revision_id is not None:
339
revision_id = osutils.safe_revision_id(revision_id, warn=False)
341
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
342
except errors.NoSuchRevision:
343
msg = "The repository %s contains no revision %s." % (b.repository.base,
345
raise errors.BzrCommandError(msg)
346
elif revision is not None:
349
raise errors.BzrCommandError('You cannot specify a NULL'
351
rev_id = rev.as_revision_id(b)
352
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
355
class cmd_dump_btree(Command):
356
"""Dump the contents of a btree index file to stdout.
358
PATH is a btree index file, it can be any URL. This includes things like
359
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
361
By default, the tuples stored in the index file will be displayed. With
362
--raw, we will uncompress the pages, but otherwise display the raw bytes
366
# TODO: Do we want to dump the internal nodes as well?
367
# TODO: It would be nice to be able to dump the un-parsed information,
368
# rather than only going through iter_all_entries. However, this is
369
# good enough for a start
371
encoding_type = 'exact'
372
takes_args = ['path']
373
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
374
' rather than the parsed tuples.'),
377
def run(self, path, raw=False):
378
dirname, basename = osutils.split(path)
379
t = transport.get_transport(dirname)
381
self._dump_raw_bytes(t, basename)
383
self._dump_entries(t, basename)
385
def _get_index_and_bytes(self, trans, basename):
386
"""Create a BTreeGraphIndex and raw bytes."""
387
bt = btree_index.BTreeGraphIndex(trans, basename, None)
388
bytes = trans.get_bytes(basename)
389
bt._file = cStringIO.StringIO(bytes)
390
bt._size = len(bytes)
393
def _dump_raw_bytes(self, trans, basename):
396
# We need to parse at least the root node.
397
# This is because the first page of every row starts with an
398
# uncompressed header.
399
bt, bytes = self._get_index_and_bytes(trans, basename)
400
for page_idx, page_start in enumerate(xrange(0, len(bytes),
401
btree_index._PAGE_SIZE)):
402
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
403
page_bytes = bytes[page_start:page_end]
405
self.outf.write('Root node:\n')
406
header_end, data = bt._parse_header_from_bytes(page_bytes)
407
self.outf.write(page_bytes[:header_end])
409
self.outf.write('\nPage %d\n' % (page_idx,))
410
decomp_bytes = zlib.decompress(page_bytes)
411
self.outf.write(decomp_bytes)
412
self.outf.write('\n')
414
def _dump_entries(self, trans, basename):
416
st = trans.stat(basename)
417
except errors.TransportNotPossible:
418
# We can't stat, so we'll fake it because we have to do the 'get()'
420
bt, _ = self._get_index_and_bytes(trans, basename)
422
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
423
for node in bt.iter_all_entries():
424
# Node is made up of:
425
# (index, key, value, [references])
426
self.outf.write('%s\n' % (node[1:],))
429
class cmd_remove_tree(Command):
430
"""Remove the working tree from a given branch/checkout.
432
Since a lightweight checkout is little more than a working tree
433
this will refuse to run against one.
435
To re-create the working tree, use "bzr checkout".
437
_see_also = ['checkout', 'working-trees']
438
takes_args = ['location?']
441
help='Remove the working tree even if it has '
442
'uncommitted changes.'),
445
def run(self, location='.', force=False):
446
d = bzrdir.BzrDir.open(location)
449
working = d.open_workingtree()
450
except errors.NoWorkingTree:
451
raise errors.BzrCommandError("No working tree to remove")
452
except errors.NotLocalUrl:
453
raise errors.BzrCommandError("You cannot remove the working tree of a "
456
changes = working.changes_from(working.basis_tree())
457
if changes.has_changed():
458
raise errors.UncommittedChanges(working)
460
working_path = working.bzrdir.root_transport.base
461
branch_path = working.branch.bzrdir.root_transport.base
462
if working_path != branch_path:
463
raise errors.BzrCommandError("You cannot remove the working tree from "
464
"a lightweight checkout")
466
d.destroy_workingtree()
469
class cmd_revno(Command):
470
"""Show current revision number.
472
This is equal to the number of revisions on this branch.
476
takes_args = ['location?']
479
def run(self, location=u'.'):
480
self.outf.write(str(Branch.open_containing(location)[0].revno()))
481
self.outf.write('\n')
484
class cmd_revision_info(Command):
485
"""Show revision number and revision id for a given revision identifier.
488
takes_args = ['revision_info*']
492
help='Branch to examine, '
493
'rather than the one containing the working directory.',
500
def run(self, revision=None, directory=u'.', revision_info_list=[]):
503
if revision is not None:
504
revs.extend(revision)
505
if revision_info_list is not None:
506
for rev in revision_info_list:
507
revs.append(RevisionSpec.from_string(rev))
509
b = Branch.open_containing(directory)[0]
512
revs.append(RevisionSpec.from_string('-1'))
515
revision_id = rev.as_revision_id(b)
517
revno = '%4d' % (b.revision_id_to_revno(revision_id))
518
except errors.NoSuchRevision:
519
dotted_map = b.get_revision_id_to_revno_map()
520
revno = '.'.join(str(i) for i in dotted_map[revision_id])
521
print '%s %s' % (revno, revision_id)
524
class cmd_add(Command):
525
"""Add specified files or directories.
527
In non-recursive mode, all the named items are added, regardless
528
of whether they were previously ignored. A warning is given if
529
any of the named files are already versioned.
531
In recursive mode (the default), files are treated the same way
532
but the behaviour for directories is different. Directories that
533
are already versioned do not give a warning. All directories,
534
whether already versioned or not, are searched for files or
535
subdirectories that are neither versioned or ignored, and these
536
are added. This search proceeds recursively into versioned
537
directories. If no names are given '.' is assumed.
539
Therefore simply saying 'bzr add' will version all files that
540
are currently unknown.
542
Adding a file whose parent directory is not versioned will
543
implicitly add the parent, and so on up to the root. This means
544
you should never need to explicitly add a directory, they'll just
545
get added when you add a file in the directory.
547
--dry-run will show which files would be added, but not actually
550
--file-ids-from will try to use the file ids from the supplied path.
551
It looks up ids trying to find a matching parent directory with the
552
same filename, and then by pure path. This option is rarely needed
553
but can be useful when adding the same logical file into two
554
branches that will be merged later (without showing the two different
555
adds as a conflict). It is also useful when merging another project
556
into a subdirectory of this one.
558
takes_args = ['file*']
561
help="Don't recursively add the contents of directories."),
563
help="Show what would be done, but don't actually do anything."),
565
Option('file-ids-from',
567
help='Lookup file ids from this tree.'),
569
encoding_type = 'replace'
570
_see_also = ['remove']
572
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
577
if file_ids_from is not None:
579
base_tree, base_path = WorkingTree.open_containing(
581
except errors.NoWorkingTree:
582
base_branch, base_path = Branch.open_containing(
584
base_tree = base_branch.basis_tree()
586
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
587
to_file=self.outf, should_print=(not is_quiet()))
589
action = bzrlib.add.AddAction(to_file=self.outf,
590
should_print=(not is_quiet()))
593
base_tree.lock_read()
595
file_list = self._maybe_expand_globs(file_list)
596
tree, file_list = tree_files_for_add(file_list)
597
added, ignored = tree.smart_add(file_list, not
598
no_recurse, action=action, save=not dry_run)
600
if base_tree is not None:
604
for glob in sorted(ignored.keys()):
605
for path in ignored[glob]:
606
self.outf.write("ignored %s matching \"%s\"\n"
610
for glob, paths in ignored.items():
611
match_len += len(paths)
612
self.outf.write("ignored %d file(s).\n" % match_len)
613
self.outf.write("If you wish to add ignored files, "
614
"please add them explicitly by name. "
615
"(\"bzr ignored\" gives a list)\n")
618
class cmd_mkdir(Command):
619
"""Create a new versioned directory.
621
This is equivalent to creating the directory and then adding it.
624
takes_args = ['dir+']
625
encoding_type = 'replace'
627
def run(self, dir_list):
630
wt, dd = WorkingTree.open_containing(d)
632
self.outf.write('added %s\n' % d)
635
class cmd_relpath(Command):
636
"""Show path of a file relative to root"""
638
takes_args = ['filename']
642
def run(self, filename):
643
# TODO: jam 20050106 Can relpath return a munged path if
644
# sys.stdout encoding cannot represent it?
645
tree, relpath = WorkingTree.open_containing(filename)
646
self.outf.write(relpath)
647
self.outf.write('\n')
650
class cmd_inventory(Command):
651
"""Show inventory of the current working copy or a revision.
653
It is possible to limit the output to a particular entry
654
type using the --kind option. For example: --kind file.
656
It is also possible to restrict the list of files to a specific
657
set. For example: bzr inventory --show-ids this/file
666
help='List entries of a particular kind: file, directory, symlink.',
669
takes_args = ['file*']
672
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
673
if kind and kind not in ['file', 'directory', 'symlink']:
674
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
676
revision = _get_one_revision('inventory', revision)
677
work_tree, file_list = tree_files(file_list)
678
work_tree.lock_read()
680
if revision is not None:
681
tree = revision.as_tree(work_tree.branch)
683
extra_trees = [work_tree]
689
if file_list is not None:
690
file_ids = tree.paths2ids(file_list, trees=extra_trees,
691
require_versioned=True)
692
# find_ids_across_trees may include some paths that don't
694
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
695
for file_id in file_ids if file_id in tree)
697
entries = tree.inventory.entries()
700
if tree is not work_tree:
703
for path, entry in entries:
704
if kind and kind != entry.kind:
707
self.outf.write('%-50s %s\n' % (path, entry.file_id))
709
self.outf.write(path)
710
self.outf.write('\n')
713
class cmd_mv(Command):
714
"""Move or rename a file.
717
bzr mv OLDNAME NEWNAME
719
bzr mv SOURCE... DESTINATION
721
If the last argument is a versioned directory, all the other names
722
are moved into it. Otherwise, there must be exactly two arguments
723
and the file is changed to a new name.
725
If OLDNAME does not exist on the filesystem but is versioned and
726
NEWNAME does exist on the filesystem but is not versioned, mv
727
assumes that the file has been manually moved and only updates
728
its internal inventory to reflect that change.
729
The same is valid when moving many SOURCE files to a DESTINATION.
731
Files cannot be moved between branches.
734
takes_args = ['names*']
735
takes_options = [Option("after", help="Move only the bzr identifier"
736
" of the file, because the file has already been moved."),
737
Option('auto', help='Automatically guess renames.'),
738
Option('dry-run', help='Avoid making changes when guessing renames.'),
740
aliases = ['move', 'rename']
741
encoding_type = 'replace'
743
def run(self, names_list, after=False, auto=False, dry_run=False):
745
return self.run_auto(names_list, after, dry_run)
747
raise errors.BzrCommandError('--dry-run requires --auto.')
748
if names_list is None:
750
if len(names_list) < 2:
751
raise errors.BzrCommandError("missing file argument")
752
tree, rel_names = tree_files(names_list, canonicalize=False)
755
self._run(tree, names_list, rel_names, after)
759
def run_auto(self, names_list, after, dry_run):
760
if names_list is not None and len(names_list) > 1:
761
raise errors.BzrCommandError('Only one path may be specified to'
764
raise errors.BzrCommandError('--after cannot be specified with'
766
work_tree, file_list = tree_files(names_list, default_branch='.')
767
work_tree.lock_write()
769
rename_map.RenameMap.guess_renames(work_tree, dry_run)
773
def _run(self, tree, names_list, rel_names, after):
774
into_existing = osutils.isdir(names_list[-1])
775
if into_existing and len(names_list) == 2:
777
# a. case-insensitive filesystem and change case of dir
778
# b. move directory after the fact (if the source used to be
779
# a directory, but now doesn't exist in the working tree
780
# and the target is an existing directory, just rename it)
781
if (not tree.case_sensitive
782
and rel_names[0].lower() == rel_names[1].lower()):
783
into_existing = False
786
# 'fix' the case of a potential 'from'
787
from_id = tree.path2id(
788
tree.get_canonical_inventory_path(rel_names[0]))
789
if (not osutils.lexists(names_list[0]) and
790
from_id and inv.get_file_kind(from_id) == "directory"):
791
into_existing = False
794
# move into existing directory
795
# All entries reference existing inventory items, so fix them up
796
# for cicp file-systems.
797
rel_names = tree.get_canonical_inventory_paths(rel_names)
798
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
799
self.outf.write("%s => %s\n" % pair)
801
if len(names_list) != 2:
802
raise errors.BzrCommandError('to mv multiple files the'
803
' destination must be a versioned'
806
# for cicp file-systems: the src references an existing inventory
808
src = tree.get_canonical_inventory_path(rel_names[0])
809
# Find the canonical version of the destination: In all cases, the
810
# parent of the target must be in the inventory, so we fetch the
811
# canonical version from there (we do not always *use* the
812
# canonicalized tail portion - we may be attempting to rename the
814
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
815
dest_parent = osutils.dirname(canon_dest)
816
spec_tail = osutils.basename(rel_names[1])
817
# For a CICP file-system, we need to avoid creating 2 inventory
818
# entries that differ only by case. So regardless of the case
819
# we *want* to use (ie, specified by the user or the file-system),
820
# we must always choose to use the case of any existing inventory
821
# items. The only exception to this is when we are attempting a
822
# case-only rename (ie, canonical versions of src and dest are
824
dest_id = tree.path2id(canon_dest)
825
if dest_id is None or tree.path2id(src) == dest_id:
826
# No existing item we care about, so work out what case we
827
# are actually going to use.
829
# If 'after' is specified, the tail must refer to a file on disk.
831
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
833
# pathjoin with an empty tail adds a slash, which breaks
835
dest_parent_fq = tree.basedir
837
dest_tail = osutils.canonical_relpath(
839
osutils.pathjoin(dest_parent_fq, spec_tail))
841
# not 'after', so case as specified is used
842
dest_tail = spec_tail
844
# Use the existing item so 'mv' fails with AlreadyVersioned.
845
dest_tail = os.path.basename(canon_dest)
846
dest = osutils.pathjoin(dest_parent, dest_tail)
847
mutter("attempting to move %s => %s", src, dest)
848
tree.rename_one(src, dest, after=after)
849
self.outf.write("%s => %s\n" % (src, dest))
852
class cmd_pull(Command):
853
"""Turn this branch into a mirror of another branch.
855
This command only works on branches that have not diverged. Branches are
856
considered diverged if the destination branch's most recent commit is one
857
that has not been merged (directly or indirectly) into the parent.
859
If branches have diverged, you can use 'bzr merge' to integrate the changes
860
from one into the other. Once one branch has merged, the other should
861
be able to pull it again.
863
If you want to forget your local changes and just update your branch to
864
match the remote one, use pull --overwrite.
866
If there is no default location set, the first pull will set it. After
867
that, you can omit the location to use the default. To change the
868
default, use --remember. The value will only be saved if the remote
869
location can be accessed.
871
Note: The location can be specified either in the form of a branch,
872
or in the form of a path to a file containing a merge directive generated
876
_see_also = ['push', 'update', 'status-flags', 'send']
877
takes_options = ['remember', 'overwrite', 'revision',
878
custom_help('verbose',
879
help='Show logs of pulled revisions.'),
881
help='Branch to pull into, '
882
'rather than the one containing the working directory.',
887
help="Perform a local pull in a bound "
888
"branch. Local pulls are not applied to "
892
takes_args = ['location?']
893
encoding_type = 'replace'
895
def run(self, location=None, remember=False, overwrite=False,
896
revision=None, verbose=False,
897
directory=None, local=False):
898
# FIXME: too much stuff is in the command class
901
if directory is None:
904
tree_to = WorkingTree.open_containing(directory)[0]
905
branch_to = tree_to.branch
906
except errors.NoWorkingTree:
908
branch_to = Branch.open_containing(directory)[0]
910
if local and not branch_to.get_bound_location():
911
raise errors.LocalRequiresBoundBranch()
913
possible_transports = []
914
if location is not None:
916
mergeable = bundle.read_mergeable_from_url(location,
917
possible_transports=possible_transports)
918
except errors.NotABundle:
921
stored_loc = branch_to.get_parent()
923
if stored_loc is None:
924
raise errors.BzrCommandError("No pull location known or"
927
display_url = urlutils.unescape_for_display(stored_loc,
930
self.outf.write("Using saved parent location: %s\n" % display_url)
931
location = stored_loc
933
revision = _get_one_revision('pull', revision)
934
if mergeable is not None:
935
if revision is not None:
936
raise errors.BzrCommandError(
937
'Cannot use -r with merge directives or bundles')
938
mergeable.install_revisions(branch_to.repository)
939
base_revision_id, revision_id, verified = \
940
mergeable.get_merge_request(branch_to.repository)
941
branch_from = branch_to
943
branch_from = Branch.open(location,
944
possible_transports=possible_transports)
946
if branch_to.get_parent() is None or remember:
947
branch_to.set_parent(branch_from.base)
949
if branch_from is not branch_to:
950
branch_from.lock_read()
952
if revision is not None:
953
revision_id = revision.as_revision_id(branch_from)
955
branch_to.lock_write()
957
if tree_to is not None:
958
view_info = _get_view_info_for_change_reporter(tree_to)
959
change_reporter = delta._ChangeReporter(
960
unversioned_filter=tree_to.is_ignored,
962
result = tree_to.pull(
963
branch_from, overwrite, revision_id, change_reporter,
964
possible_transports=possible_transports, local=local)
966
result = branch_to.pull(
967
branch_from, overwrite, revision_id, local=local)
969
result.report(self.outf)
970
if verbose and result.old_revid != result.new_revid:
971
log.show_branch_change(
972
branch_to, self.outf, result.old_revno,
977
if branch_from is not branch_to:
981
class cmd_push(Command):
982
"""Update a mirror of this branch.
984
The target branch will not have its working tree populated because this
985
is both expensive, and is not supported on remote file systems.
987
Some smart servers or protocols *may* put the working tree in place in
990
This command only works on branches that have not diverged. Branches are
991
considered diverged if the destination branch's most recent commit is one
992
that has not been merged (directly or indirectly) by the source branch.
994
If branches have diverged, you can use 'bzr push --overwrite' to replace
995
the other branch completely, discarding its unmerged changes.
997
If you want to ensure you have the different changes in the other branch,
998
do a merge (see bzr help merge) from the other branch, and commit that.
999
After that you will be able to do a push without '--overwrite'.
1001
If there is no default push location set, the first push will set it.
1002
After that, you can omit the location to use the default. To change the
1003
default, use --remember. The value will only be saved if the remote
1004
location can be accessed.
1007
_see_also = ['pull', 'update', 'working-trees']
1008
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1009
Option('create-prefix',
1010
help='Create the path leading up to the branch '
1011
'if it does not already exist.'),
1013
help='Branch to push from, '
1014
'rather than the one containing the working directory.',
1018
Option('use-existing-dir',
1019
help='By default push will fail if the target'
1020
' directory exists, but does not already'
1021
' have a control directory. This flag will'
1022
' allow push to proceed.'),
1024
help='Create a stacked branch that references the public location '
1025
'of the parent branch.'),
1026
Option('stacked-on',
1027
help='Create a stacked branch that refers to another branch '
1028
'for the commit history. Only the work not present in the '
1029
'referenced branch is included in the branch created.',
1032
takes_args = ['location?']
1033
encoding_type = 'replace'
1035
def run(self, location=None, remember=False, overwrite=False,
1036
create_prefix=False, verbose=False, revision=None,
1037
use_existing_dir=False, directory=None, stacked_on=None,
1039
from bzrlib.push import _show_push_branch
1041
# Get the source branch and revision_id
1042
if directory is None:
1044
br_from = Branch.open_containing(directory)[0]
1045
revision = _get_one_revision('push', revision)
1046
if revision is not None:
1047
revision_id = revision.in_history(br_from).rev_id
1051
# Get the stacked_on branch, if any
1052
if stacked_on is not None:
1053
stacked_on = urlutils.normalize_url(stacked_on)
1055
parent_url = br_from.get_parent()
1057
parent = Branch.open(parent_url)
1058
stacked_on = parent.get_public_branch()
1060
# I considered excluding non-http url's here, thus forcing
1061
# 'public' branches only, but that only works for some
1062
# users, so it's best to just depend on the user spotting an
1063
# error by the feedback given to them. RBC 20080227.
1064
stacked_on = parent_url
1066
raise errors.BzrCommandError(
1067
"Could not determine branch to refer to.")
1069
# Get the destination location
1070
if location is None:
1071
stored_loc = br_from.get_push_location()
1072
if stored_loc is None:
1073
raise errors.BzrCommandError(
1074
"No push location known or specified.")
1076
display_url = urlutils.unescape_for_display(stored_loc,
1078
self.outf.write("Using saved push location: %s\n" % display_url)
1079
location = stored_loc
1081
_show_push_branch(br_from, revision_id, location, self.outf,
1082
verbose=verbose, overwrite=overwrite, remember=remember,
1083
stacked_on=stacked_on, create_prefix=create_prefix,
1084
use_existing_dir=use_existing_dir)
1087
class cmd_branch(Command):
1088
"""Create a new branch that is a copy of an existing branch.
1090
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1091
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1092
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
1093
is derived from the FROM_LOCATION by stripping a leading scheme or drive
1094
identifier, if any. For example, "branch lp:foo-bar" will attempt to
1097
To retrieve the branch as of a particular revision, supply the --revision
1098
parameter, as in "branch foo/bar -r 5".
1101
_see_also = ['checkout']
1102
takes_args = ['from_location', 'to_location?']
1103
takes_options = ['revision', Option('hardlink',
1104
help='Hard-link working tree files where possible.'),
1106
help="Create a branch without a working-tree."),
1108
help='Create a stacked branch referring to the source branch. '
1109
'The new branch will depend on the availability of the source '
1110
'branch for all operations.'),
1111
Option('standalone',
1112
help='Do not use a shared repository, even if available.'),
1114
aliases = ['get', 'clone']
1116
def run(self, from_location, to_location=None, revision=None,
1117
hardlink=False, stacked=False, standalone=False, no_tree=False):
1118
from bzrlib.tag import _merge_tags_if_possible
1120
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1122
if (accelerator_tree is not None and
1123
accelerator_tree.supports_content_filtering()):
1124
accelerator_tree = None
1125
revision = _get_one_revision('branch', revision)
1128
if revision is not None:
1129
revision_id = revision.as_revision_id(br_from)
1131
# FIXME - wt.last_revision, fallback to branch, fall back to
1132
# None or perhaps NULL_REVISION to mean copy nothing
1134
revision_id = br_from.last_revision()
1135
if to_location is None:
1136
to_location = urlutils.derive_to_location(from_location)
1137
to_transport = transport.get_transport(to_location)
1139
to_transport.mkdir('.')
1140
except errors.FileExists:
1141
raise errors.BzrCommandError('Target directory "%s" already'
1142
' exists.' % to_location)
1143
except errors.NoSuchFile:
1144
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1147
# preserve whatever source format we have.
1148
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1149
possible_transports=[to_transport],
1150
accelerator_tree=accelerator_tree,
1151
hardlink=hardlink, stacked=stacked,
1152
force_new_repo=standalone,
1153
create_tree_if_local=not no_tree,
1154
source_branch=br_from)
1155
branch = dir.open_branch()
1156
except errors.NoSuchRevision:
1157
to_transport.delete_tree('.')
1158
msg = "The branch %s has no revision %s." % (from_location,
1160
raise errors.BzrCommandError(msg)
1161
_merge_tags_if_possible(br_from, branch)
1162
# If the source branch is stacked, the new branch may
1163
# be stacked whether we asked for that explicitly or not.
1164
# We therefore need a try/except here and not just 'if stacked:'
1166
note('Created new stacked branch referring to %s.' %
1167
branch.get_stacked_on_url())
1168
except (errors.NotStacked, errors.UnstackableBranchFormat,
1169
errors.UnstackableRepositoryFormat), e:
1170
note('Branched %d revision(s).' % branch.revno())
1175
class cmd_checkout(Command):
1176
"""Create a new checkout of an existing branch.
1178
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1179
the branch found in '.'. This is useful if you have removed the working tree
1180
or if it was never created - i.e. if you pushed the branch to its current
1181
location using SFTP.
1183
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
1184
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
1185
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1186
is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
1187
identifier, if any. For example, "checkout lp:foo-bar" will attempt to
1190
To retrieve the branch as of a particular revision, supply the --revision
1191
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
1192
out of date [so you cannot commit] but it may be useful (i.e. to examine old
1196
_see_also = ['checkouts', 'branch']
1197
takes_args = ['branch_location?', 'to_location?']
1198
takes_options = ['revision',
1199
Option('lightweight',
1200
help="Perform a lightweight checkout. Lightweight "
1201
"checkouts depend on access to the branch for "
1202
"every operation. Normal checkouts can perform "
1203
"common operations like diff and status without "
1204
"such access, and also support local commits."
1206
Option('files-from', type=str,
1207
help="Get file contents from this tree."),
1209
help='Hard-link working tree files where possible.'
1214
def run(self, branch_location=None, to_location=None, revision=None,
1215
lightweight=False, files_from=None, hardlink=False):
1216
if branch_location is None:
1217
branch_location = osutils.getcwd()
1218
to_location = branch_location
1219
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1221
revision = _get_one_revision('checkout', revision)
1222
if files_from is not None:
1223
accelerator_tree = WorkingTree.open(files_from)
1224
if revision is not None:
1225
revision_id = revision.as_revision_id(source)
1228
if to_location is None:
1229
to_location = urlutils.derive_to_location(branch_location)
1230
# if the source and to_location are the same,
1231
# and there is no working tree,
1232
# then reconstitute a branch
1233
if (osutils.abspath(to_location) ==
1234
osutils.abspath(branch_location)):
1236
source.bzrdir.open_workingtree()
1237
except errors.NoWorkingTree:
1238
source.bzrdir.create_workingtree(revision_id)
1240
source.create_checkout(to_location, revision_id, lightweight,
1241
accelerator_tree, hardlink)
1244
class cmd_renames(Command):
1245
"""Show list of renamed files.
1247
# TODO: Option to show renames between two historical versions.
1249
# TODO: Only show renames under dir, rather than in the whole branch.
1250
_see_also = ['status']
1251
takes_args = ['dir?']
1254
def run(self, dir=u'.'):
1255
tree = WorkingTree.open_containing(dir)[0]
1258
new_inv = tree.inventory
1259
old_tree = tree.basis_tree()
1260
old_tree.lock_read()
1262
old_inv = old_tree.inventory
1264
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1265
for f, paths, c, v, p, n, k, e in iterator:
1266
if paths[0] == paths[1]:
1270
renames.append(paths)
1272
for old_name, new_name in renames:
1273
self.outf.write("%s => %s\n" % (old_name, new_name))
1280
class cmd_update(Command):
1281
"""Update a tree to have the latest code committed to its branch.
1283
This will perform a merge into the working tree, and may generate
1284
conflicts. If you have any local changes, you will still
1285
need to commit them after the update for the update to be complete.
1287
If you want to discard your local changes, you can just do a
1288
'bzr revert' instead of 'bzr commit' after the update.
1291
_see_also = ['pull', 'working-trees', 'status-flags']
1292
takes_args = ['dir?']
1295
def run(self, dir='.'):
1296
tree = WorkingTree.open_containing(dir)[0]
1297
possible_transports = []
1298
master = tree.branch.get_master_branch(
1299
possible_transports=possible_transports)
1300
if master is not None:
1303
tree.lock_tree_write()
1305
existing_pending_merges = tree.get_parent_ids()[1:]
1306
last_rev = _mod_revision.ensure_null(tree.last_revision())
1307
if last_rev == _mod_revision.ensure_null(
1308
tree.branch.last_revision()):
1309
# may be up to date, check master too.
1310
if master is None or last_rev == _mod_revision.ensure_null(
1311
master.last_revision()):
1312
revno = tree.branch.revision_id_to_revno(last_rev)
1313
note("Tree is up to date at revision %d." % (revno,))
1315
view_info = _get_view_info_for_change_reporter(tree)
1316
conflicts = tree.update(
1317
delta._ChangeReporter(unversioned_filter=tree.is_ignored,
1318
view_info=view_info), possible_transports=possible_transports)
1319
revno = tree.branch.revision_id_to_revno(
1320
_mod_revision.ensure_null(tree.last_revision()))
1321
note('Updated to revision %d.' % (revno,))
1322
if tree.get_parent_ids()[1:] != existing_pending_merges:
1323
note('Your local commits will now show as pending merges with '
1324
"'bzr status', and can be committed with 'bzr commit'.")
1333
class cmd_info(Command):
1334
"""Show information about a working tree, branch or repository.
1336
This command will show all known locations and formats associated to the
1337
tree, branch or repository.
1339
In verbose mode, statistical information is included with each report.
1340
To see extended statistic information, use a verbosity level of 2 or
1341
higher by specifying the verbose option multiple times, e.g. -vv.
1343
Branches and working trees will also report any missing revisions.
1347
Display information on the format and related locations:
1351
Display the above together with extended format information and
1352
basic statistics (like the number of files in the working tree and
1353
number of revisions in the branch and repository):
1357
Display the above together with number of committers to the branch:
1361
_see_also = ['revno', 'working-trees', 'repositories']
1362
takes_args = ['location?']
1363
takes_options = ['verbose']
1364
encoding_type = 'replace'
1367
def run(self, location=None, verbose=False):
1369
noise_level = get_verbosity_level()
1372
from bzrlib.info import show_bzrdir_info
1373
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1374
verbose=noise_level, outfile=self.outf)
1377
class cmd_remove(Command):
1378
"""Remove files or directories.
1380
This makes bzr stop tracking changes to the specified files. bzr will delete
1381
them if they can easily be recovered using revert. If no options or
1382
parameters are given bzr will scan for files that are being tracked by bzr
1383
but missing in your tree and stop tracking them for you.
1385
takes_args = ['file*']
1386
takes_options = ['verbose',
1387
Option('new', help='Only remove files that have never been committed.'),
1388
RegistryOption.from_kwargs('file-deletion-strategy',
1389
'The file deletion mode to be used.',
1390
title='Deletion Strategy', value_switches=True, enum_switch=False,
1391
safe='Only delete files if they can be'
1392
' safely recovered (default).',
1393
keep="Don't delete any files.",
1394
force='Delete all the specified files, even if they can not be '
1395
'recovered and even if they are non-empty directories.')]
1396
aliases = ['rm', 'del']
1397
encoding_type = 'replace'
1399
def run(self, file_list, verbose=False, new=False,
1400
file_deletion_strategy='safe'):
1401
tree, file_list = tree_files(file_list)
1403
if file_list is not None:
1404
file_list = [f for f in file_list]
1408
# Heuristics should probably all move into tree.remove_smart or
1411
added = tree.changes_from(tree.basis_tree(),
1412
specific_files=file_list).added
1413
file_list = sorted([f[0] for f in added], reverse=True)
1414
if len(file_list) == 0:
1415
raise errors.BzrCommandError('No matching files.')
1416
elif file_list is None:
1417
# missing files show up in iter_changes(basis) as
1418
# versioned-with-no-kind.
1420
for change in tree.iter_changes(tree.basis_tree()):
1421
# Find paths in the working tree that have no kind:
1422
if change[1][1] is not None and change[6][1] is None:
1423
missing.append(change[1][1])
1424
file_list = sorted(missing, reverse=True)
1425
file_deletion_strategy = 'keep'
1426
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1427
keep_files=file_deletion_strategy=='keep',
1428
force=file_deletion_strategy=='force')
1433
class cmd_file_id(Command):
1434
"""Print file_id of a particular file or directory.
1436
The file_id is assigned when the file is first added and remains the
1437
same through all revisions where the file exists, even when it is
1442
_see_also = ['inventory', 'ls']
1443
takes_args = ['filename']
1446
def run(self, filename):
1447
tree, relpath = WorkingTree.open_containing(filename)
1448
i = tree.path2id(relpath)
1450
raise errors.NotVersionedError(filename)
1452
self.outf.write(i + '\n')
1455
class cmd_file_path(Command):
1456
"""Print path of file_ids to a file or directory.
1458
This prints one line for each directory down to the target,
1459
starting at the branch root.
1463
takes_args = ['filename']
1466
def run(self, filename):
1467
tree, relpath = WorkingTree.open_containing(filename)
1468
fid = tree.path2id(relpath)
1470
raise errors.NotVersionedError(filename)
1471
segments = osutils.splitpath(relpath)
1472
for pos in range(1, len(segments) + 1):
1473
path = osutils.joinpath(segments[:pos])
1474
self.outf.write("%s\n" % tree.path2id(path))
1477
class cmd_reconcile(Command):
1478
"""Reconcile bzr metadata in a branch.
1480
This can correct data mismatches that may have been caused by
1481
previous ghost operations or bzr upgrades. You should only
1482
need to run this command if 'bzr check' or a bzr developer
1483
advises you to run it.
1485
If a second branch is provided, cross-branch reconciliation is
1486
also attempted, which will check that data like the tree root
1487
id which was not present in very early bzr versions is represented
1488
correctly in both branches.
1490
At the same time it is run it may recompress data resulting in
1491
a potential saving in disk space or performance gain.
1493
The branch *MUST* be on a listable system such as local disk or sftp.
1496
_see_also = ['check']
1497
takes_args = ['branch?']
1499
def run(self, branch="."):
1500
from bzrlib.reconcile import reconcile
1501
dir = bzrdir.BzrDir.open(branch)
1505
class cmd_revision_history(Command):
1506
"""Display the list of revision ids on a branch."""
1509
takes_args = ['location?']
1514
def run(self, location="."):
1515
branch = Branch.open_containing(location)[0]
1516
for revid in branch.revision_history():
1517
self.outf.write(revid)
1518
self.outf.write('\n')
1521
class cmd_ancestry(Command):
1522
"""List all revisions merged into this branch."""
1524
_see_also = ['log', 'revision-history']
1525
takes_args = ['location?']
1530
def run(self, location="."):
1532
wt = WorkingTree.open_containing(location)[0]
1533
except errors.NoWorkingTree:
1534
b = Branch.open(location)
1535
last_revision = b.last_revision()
1538
last_revision = wt.last_revision()
1540
revision_ids = b.repository.get_ancestry(last_revision)
1542
for revision_id in revision_ids:
1543
self.outf.write(revision_id + '\n')
1546
class cmd_init(Command):
1547
"""Make a directory into a versioned branch.
1549
Use this to create an empty branch, or before importing an
1552
If there is a repository in a parent directory of the location, then
1553
the history of the branch will be stored in the repository. Otherwise
1554
init creates a standalone branch which carries its own history
1555
in the .bzr directory.
1557
If there is already a branch at the location but it has no working tree,
1558
the tree can be populated with 'bzr checkout'.
1560
Recipe for importing a tree of files::
1566
bzr commit -m "imported project"
1569
_see_also = ['init-repository', 'branch', 'checkout']
1570
takes_args = ['location?']
1572
Option('create-prefix',
1573
help='Create the path leading up to the branch '
1574
'if it does not already exist.'),
1575
RegistryOption('format',
1576
help='Specify a format for this branch. '
1577
'See "help formats".',
1578
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1579
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1580
value_switches=True,
1581
title="Branch Format",
1583
Option('append-revisions-only',
1584
help='Never change revnos or the existing log.'
1585
' Append revisions to it only.')
1587
def run(self, location=None, format=None, append_revisions_only=False,
1588
create_prefix=False):
1590
format = bzrdir.format_registry.make_bzrdir('default')
1591
if location is None:
1594
to_transport = transport.get_transport(location)
1596
# The path has to exist to initialize a
1597
# branch inside of it.
1598
# Just using os.mkdir, since I don't
1599
# believe that we want to create a bunch of
1600
# locations if the user supplies an extended path
1602
to_transport.ensure_base()
1603
except errors.NoSuchFile:
1604
if not create_prefix:
1605
raise errors.BzrCommandError("Parent directory of %s"
1607
"\nYou may supply --create-prefix to create all"
1608
" leading parent directories."
1610
to_transport.create_prefix()
1613
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1614
except errors.NotBranchError:
1615
# really a NotBzrDir error...
1616
create_branch = bzrdir.BzrDir.create_branch_convenience
1617
branch = create_branch(to_transport.base, format=format,
1618
possible_transports=[to_transport])
1619
a_bzrdir = branch.bzrdir
1621
from bzrlib.transport.local import LocalTransport
1622
if a_bzrdir.has_branch():
1623
if (isinstance(to_transport, LocalTransport)
1624
and not a_bzrdir.has_workingtree()):
1625
raise errors.BranchExistsWithoutWorkingTree(location)
1626
raise errors.AlreadyBranchError(location)
1627
branch = a_bzrdir.create_branch()
1628
a_bzrdir.create_workingtree()
1629
if append_revisions_only:
1631
branch.set_append_revisions_only(True)
1632
except errors.UpgradeRequired:
1633
raise errors.BzrCommandError('This branch format cannot be set'
1634
' to append-revisions-only. Try --experimental-branch6')
1636
from bzrlib.info import describe_layout, describe_format
1638
tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
1639
except (errors.NoWorkingTree, errors.NotLocalUrl):
1641
repository = branch.repository
1642
layout = describe_layout(repository, branch, tree).lower()
1643
format = describe_format(a_bzrdir, repository, branch, tree)
1644
self.outf.write("Created a %s (format: %s)\n" % (layout, format))
1645
if repository.is_shared():
1646
#XXX: maybe this can be refactored into transport.path_or_url()
1647
url = repository.bzrdir.root_transport.external_url()
1649
url = urlutils.local_path_from_url(url)
1650
except errors.InvalidURL:
1652
self.outf.write("Using shared repository: %s\n" % url)
1655
class cmd_init_repository(Command):
1656
"""Create a shared repository to hold branches.
1658
New branches created under the repository directory will store their
1659
revisions in the repository, not in the branch directory.
1661
If the --no-trees option is used then the branches in the repository
1662
will not have working trees by default.
1665
Create a shared repositories holding just branches::
1667
bzr init-repo --no-trees repo
1670
Make a lightweight checkout elsewhere::
1672
bzr checkout --lightweight repo/trunk trunk-checkout
1677
_see_also = ['init', 'branch', 'checkout', 'repositories']
1678
takes_args = ["location"]
1679
takes_options = [RegistryOption('format',
1680
help='Specify a format for this repository. See'
1681
' "bzr help formats" for details.',
1682
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1683
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1684
value_switches=True, title='Repository format'),
1686
help='Branches in the repository will default to'
1687
' not having a working tree.'),
1689
aliases = ["init-repo"]
1691
def run(self, location, format=None, no_trees=False):
1693
format = bzrdir.format_registry.make_bzrdir('default')
1695
if location is None:
1698
to_transport = transport.get_transport(location)
1699
to_transport.ensure_base()
1701
newdir = format.initialize_on_transport(to_transport)
1702
repo = newdir.create_repository(shared=True)
1703
repo.set_make_working_trees(not no_trees)
1705
from bzrlib.info import show_bzrdir_info
1706
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
1709
class cmd_diff(Command):
1710
"""Show differences in the working tree, between revisions or branches.
1712
If no arguments are given, all changes for the current tree are listed.
1713
If files are given, only the changes in those files are listed.
1714
Remote and multiple branches can be compared by using the --old and
1715
--new options. If not provided, the default for both is derived from
1716
the first argument, if any, or the current tree if no arguments are
1719
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1720
produces patches suitable for "patch -p1".
1724
2 - unrepresentable changes
1729
Shows the difference in the working tree versus the last commit::
1733
Difference between the working tree and revision 1::
1737
Difference between revision 2 and revision 1::
1741
Difference between revision 2 and revision 1 for branch xxx::
1745
Show just the differences for file NEWS::
1749
Show the differences in working tree xxx for file NEWS::
1753
Show the differences from branch xxx to this working tree:
1757
Show the differences between two branches for file NEWS::
1759
bzr diff --old xxx --new yyy NEWS
1761
Same as 'bzr diff' but prefix paths with old/ and new/::
1763
bzr diff --prefix old/:new/
1765
_see_also = ['status']
1766
takes_args = ['file*']
1768
Option('diff-options', type=str,
1769
help='Pass these options to the external diff program.'),
1770
Option('prefix', type=str,
1772
help='Set prefixes added to old and new filenames, as '
1773
'two values separated by a colon. (eg "old/:new/").'),
1775
help='Branch/tree to compare from.',
1779
help='Branch/tree to compare to.',
1785
help='Use this command to compare files.',
1789
aliases = ['di', 'dif']
1790
encoding_type = 'exact'
1793
def run(self, revision=None, file_list=None, diff_options=None,
1794
prefix=None, old=None, new=None, using=None):
1795
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1797
if (prefix is None) or (prefix == '0'):
1805
old_label, new_label = prefix.split(":")
1807
raise errors.BzrCommandError(
1808
'--prefix expects two values separated by a colon'
1809
' (eg "old/:new/")')
1811
if revision and len(revision) > 2:
1812
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1813
' one or two revision specifiers')
1815
old_tree, new_tree, specific_files, extra_trees = \
1816
_get_trees_to_diff(file_list, revision, old, new,
1818
return show_diff_trees(old_tree, new_tree, sys.stdout,
1819
specific_files=specific_files,
1820
external_diff_options=diff_options,
1821
old_label=old_label, new_label=new_label,
1822
extra_trees=extra_trees, using=using)
1825
class cmd_deleted(Command):
1826
"""List files deleted in the working tree.
1828
# TODO: Show files deleted since a previous revision, or
1829
# between two revisions.
1830
# TODO: Much more efficient way to do this: read in new
1831
# directories with readdir, rather than stating each one. Same
1832
# level of effort but possibly much less IO. (Or possibly not,
1833
# if the directories are very large...)
1834
_see_also = ['status', 'ls']
1835
takes_options = ['show-ids']
1838
def run(self, show_ids=False):
1839
tree = WorkingTree.open_containing(u'.')[0]
1842
old = tree.basis_tree()
1845
for path, ie in old.inventory.iter_entries():
1846
if not tree.has_id(ie.file_id):
1847
self.outf.write(path)
1849
self.outf.write(' ')
1850
self.outf.write(ie.file_id)
1851
self.outf.write('\n')
1858
class cmd_modified(Command):
1859
"""List files modified in working tree.
1863
_see_also = ['status', 'ls']
1866
help='Write an ascii NUL (\\0) separator '
1867
'between files rather than a newline.')
1871
def run(self, null=False):
1872
tree = WorkingTree.open_containing(u'.')[0]
1873
td = tree.changes_from(tree.basis_tree())
1874
for path, id, kind, text_modified, meta_modified in td.modified:
1876
self.outf.write(path + '\0')
1878
self.outf.write(osutils.quotefn(path) + '\n')
1881
class cmd_added(Command):
1882
"""List files added in working tree.
1886
_see_also = ['status', 'ls']
1889
help='Write an ascii NUL (\\0) separator '
1890
'between files rather than a newline.')
1894
def run(self, null=False):
1895
wt = WorkingTree.open_containing(u'.')[0]
1898
basis = wt.basis_tree()
1901
basis_inv = basis.inventory
1904
if file_id in basis_inv:
1906
if inv.is_root(file_id) and len(basis_inv) == 0:
1908
path = inv.id2path(file_id)
1909
if not os.access(osutils.abspath(path), os.F_OK):
1912
self.outf.write(path + '\0')
1914
self.outf.write(osutils.quotefn(path) + '\n')
1921
class cmd_root(Command):
1922
"""Show the tree root directory.
1924
The root is the nearest enclosing directory with a .bzr control
1927
takes_args = ['filename?']
1929
def run(self, filename=None):
1930
"""Print the branch root."""
1931
tree = WorkingTree.open_containing(filename)[0]
1932
self.outf.write(tree.basedir + '\n')
1935
def _parse_limit(limitstring):
1937
return int(limitstring)
1939
msg = "The limit argument must be an integer."
1940
raise errors.BzrCommandError(msg)
1943
def _parse_levels(s):
1947
msg = "The levels argument must be an integer."
1948
raise errors.BzrCommandError(msg)
1951
class cmd_log(Command):
1952
"""Show historical log for a branch or subset of a branch.
1954
log is bzr's default tool for exploring the history of a branch.
1955
The branch to use is taken from the first parameter. If no parameters
1956
are given, the branch containing the working directory is logged.
1957
Here are some simple examples::
1959
bzr log log the current branch
1960
bzr log foo.py log a file in its branch
1961
bzr log http://server/branch log a branch on a server
1963
The filtering, ordering and information shown for each revision can
1964
be controlled as explained below. By default, all revisions are
1965
shown sorted (topologically) so that newer revisions appear before
1966
older ones and descendants always appear before ancestors. If displayed,
1967
merged revisions are shown indented under the revision in which they
1972
The log format controls how information about each revision is
1973
displayed. The standard log formats are called ``long``, ``short``
1974
and ``line``. The default is long. See ``bzr help log-formats``
1975
for more details on log formats.
1977
The following options can be used to control what information is
1980
-l N display a maximum of N revisions
1981
-n N display N levels of revisions (0 for all, 1 for collapsed)
1982
-v display a status summary (delta) for each revision
1983
-p display a diff (patch) for each revision
1984
--show-ids display revision-ids (and file-ids), not just revnos
1986
Note that the default number of levels to display is a function of the
1987
log format. If the -n option is not used, the standard log formats show
1988
just the top level (mainline).
1990
Status summaries are shown using status flags like A, M, etc. To see
1991
the changes explained using words like ``added`` and ``modified``
1992
instead, use the -vv option.
1996
To display revisions from oldest to newest, use the --forward option.
1997
In most cases, using this option will have little impact on the total
1998
time taken to produce a log, though --forward does not incrementally
1999
display revisions like --reverse does when it can.
2001
:Revision filtering:
2003
The -r option can be used to specify what revision or range of revisions
2004
to filter against. The various forms are shown below::
2006
-rX display revision X
2007
-rX.. display revision X and later
2008
-r..Y display up to and including revision Y
2009
-rX..Y display from X to Y inclusive
2011
See ``bzr help revisionspec`` for details on how to specify X and Y.
2012
Some common examples are given below::
2014
-r-1 show just the tip
2015
-r-10.. show the last 10 mainline revisions
2016
-rsubmit:.. show what's new on this branch
2017
-rancestor:path.. show changes since the common ancestor of this
2018
branch and the one at location path
2019
-rdate:yesterday.. show changes since yesterday
2021
When logging a range of revisions using -rX..Y, log starts at
2022
revision Y and searches back in history through the primary
2023
("left-hand") parents until it finds X. When logging just the
2024
top level (using -n1), an error is reported if X is not found
2025
along the way. If multi-level logging is used (-n0), X may be
2026
a nested merge revision and the log will be truncated accordingly.
2030
If parameters are given and the first one is not a branch, the log
2031
will be filtered to show only those revisions that changed the
2032
nominated files or directories.
2034
Filenames are interpreted within their historical context. To log a
2035
deleted file, specify a revision range so that the file existed at
2036
the end or start of the range.
2038
Historical context is also important when interpreting pathnames of
2039
renamed files/directories. Consider the following example:
2041
* revision 1: add tutorial.txt
2042
* revision 2: modify tutorial.txt
2043
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2047
* ``bzr log guide.txt`` will log the file added in revision 1
2049
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2051
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2052
the original file in revision 2.
2054
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2055
was no file called guide.txt in revision 2.
2057
Renames are always followed by log. By design, there is no need to
2058
explicitly ask for this (and no way to stop logging a file back
2059
until it was last renamed).
2063
The --message option can be used for finding revisions that match a
2064
regular expression in a commit message.
2068
GUI tools and IDEs are often better at exploring history than command
2069
line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2070
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2071
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2073
Web interfaces are often better at exploring history than command line
2074
tools, particularly for branches on servers. You may prefer Loggerhead
2075
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2077
You may find it useful to add the aliases below to ``bazaar.conf``::
2081
top = log -l10 --line
2084
``bzr tip`` will then show the latest revision while ``bzr top``
2085
will show the last 10 mainline revisions. To see the details of a
2086
particular revision X, ``bzr show -rX``.
2088
If you are interested in looking deeper into a particular merge X,
2089
use ``bzr log -n0 -rX``.
2091
``bzr log -v`` on a branch with lots of history is currently
2092
very slow. A fix for this issue is currently under development.
2093
With or without that fix, it is recommended that a revision range
2094
be given when using the -v option.
2096
bzr has a generic full-text matching plugin, bzr-search, that can be
2097
used to find revisions matching user names, commit messages, etc.
2098
Among other features, this plugin can find all revisions containing
2099
a list of words but not others.
2101
When exploring non-mainline history on large projects with deep
2102
history, the performance of log can be greatly improved by installing
2103
the historycache plugin. This plugin buffers historical information
2104
trading disk space for faster speed.
2106
takes_args = ['file*']
2107
_see_also = ['log-formats', 'revisionspec']
2110
help='Show from oldest to newest.'),
2112
custom_help('verbose',
2113
help='Show files changed in each revision.'),
2117
type=bzrlib.option._parse_revision_str,
2119
help='Show just the specified revision.'
2120
' See also "help revisionspec".'),
2124
help='Number of levels to display - 0 for all, 1 for flat.',
2126
type=_parse_levels),
2129
help='Show revisions whose message matches this '
2130
'regular expression.',
2134
help='Limit the output to the first N revisions.',
2139
help='Show changes made in each revision as a patch.'),
2140
Option('include-merges',
2141
help='Show merged revisions like --levels 0 does.'),
2143
encoding_type = 'replace'
2146
def run(self, file_list=None, timezone='original',
2157
include_merges=False):
2158
from bzrlib.log import (
2160
make_log_request_dict,
2161
_get_info_for_log_files,
2163
direction = (forward and 'forward') or 'reverse'
2168
raise errors.BzrCommandError(
2169
'--levels and --include-merges are mutually exclusive')
2171
if change is not None:
2173
raise errors.RangeInChangeOption()
2174
if revision is not None:
2175
raise errors.BzrCommandError(
2176
'--revision and --change are mutually exclusive')
2181
filter_by_dir = False
2183
# find the file ids to log and check for directory filtering
2184
b, file_info_list, rev1, rev2 = _get_info_for_log_files(revision,
2186
for relpath, file_id, kind in file_info_list:
2188
raise errors.BzrCommandError(
2189
"Path unknown at end or start of revision range: %s" %
2191
# If the relpath is the top of the tree, we log everything
2196
file_ids.append(file_id)
2197
filter_by_dir = filter_by_dir or (
2198
kind in ['directory', 'tree-reference'])
2201
# FIXME ? log the current subdir only RBC 20060203
2202
if revision is not None \
2203
and len(revision) > 0 and revision[0].get_branch():
2204
location = revision[0].get_branch()
2207
dir, relpath = bzrdir.BzrDir.open_containing(location)
2208
b = dir.open_branch()
2209
rev1, rev2 = _get_revision_range(revision, b, self.name())
2211
# Decide on the type of delta & diff filtering to use
2212
# TODO: add an --all-files option to make this configurable & consistent
2220
diff_type = 'partial'
2226
# Build the log formatter
2227
if log_format is None:
2228
log_format = log.log_formatter_registry.get_default(b)
2229
lf = log_format(show_ids=show_ids, to_file=self.outf,
2230
show_timezone=timezone,
2231
delta_format=get_verbosity_level(),
2233
show_advice=levels is None)
2235
# Choose the algorithm for doing the logging. It's annoying
2236
# having multiple code paths like this but necessary until
2237
# the underlying repository format is faster at generating
2238
# deltas or can provide everything we need from the indices.
2239
# The default algorithm - match-using-deltas - works for
2240
# multiple files and directories and is faster for small
2241
# amounts of history (200 revisions say). However, it's too
2242
# slow for logging a single file in a repository with deep
2243
# history, i.e. > 10K revisions. In the spirit of "do no
2244
# evil when adding features", we continue to use the
2245
# original algorithm - per-file-graph - for the "single
2246
# file that isn't a directory without showing a delta" case.
2247
partial_history = revision and b.repository._format.supports_chks
2248
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2249
or delta_type or partial_history)
2251
# Build the LogRequest and execute it
2252
if len(file_ids) == 0:
2254
rqst = make_log_request_dict(
2255
direction=direction, specific_fileids=file_ids,
2256
start_revision=rev1, end_revision=rev2, limit=limit,
2257
message_search=message, delta_type=delta_type,
2258
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2259
Logger(b, rqst).show(lf)
2264
def _get_revision_range(revisionspec_list, branch, command_name):
2265
"""Take the input of a revision option and turn it into a revision range.
2267
It returns RevisionInfo objects which can be used to obtain the rev_id's
2268
of the desired revisions. It does some user input validations.
2270
if revisionspec_list is None:
2273
elif len(revisionspec_list) == 1:
2274
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2275
elif len(revisionspec_list) == 2:
2276
start_spec = revisionspec_list[0]
2277
end_spec = revisionspec_list[1]
2278
if end_spec.get_branch() != start_spec.get_branch():
2279
# b is taken from revision[0].get_branch(), and
2280
# show_log will use its revision_history. Having
2281
# different branches will lead to weird behaviors.
2282
raise errors.BzrCommandError(
2283
"bzr %s doesn't accept two revisions in different"
2284
" branches." % command_name)
2285
rev1 = start_spec.in_history(branch)
2286
# Avoid loading all of history when we know a missing
2287
# end of range means the last revision ...
2288
if end_spec.spec is None:
2289
last_revno, last_revision_id = branch.last_revision_info()
2290
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2292
rev2 = end_spec.in_history(branch)
2294
raise errors.BzrCommandError(
2295
'bzr %s --revision takes one or two values.' % command_name)
2299
def _revision_range_to_revid_range(revision_range):
2302
if revision_range[0] is not None:
2303
rev_id1 = revision_range[0].rev_id
2304
if revision_range[1] is not None:
2305
rev_id2 = revision_range[1].rev_id
2306
return rev_id1, rev_id2
2308
def get_log_format(long=False, short=False, line=False, default='long'):
2309
log_format = default
2313
log_format = 'short'
2319
class cmd_touching_revisions(Command):
2320
"""Return revision-ids which affected a particular file.
2322
A more user-friendly interface is "bzr log FILE".
2326
takes_args = ["filename"]
2329
def run(self, filename):
2330
tree, relpath = WorkingTree.open_containing(filename)
2332
file_id = tree.path2id(relpath)
2333
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
2334
self.outf.write("%6d %s\n" % (revno, what))
2337
class cmd_ls(Command):
2338
"""List files in a tree.
2341
_see_also = ['status', 'cat']
2342
takes_args = ['path?']
2346
Option('recursive', short_name='R',
2347
help='Recurse into subdirectories.'),
2349
help='Print paths relative to the root of the branch.'),
2350
Option('unknown', help='Print unknown files.'),
2351
Option('versioned', help='Print versioned files.',
2353
Option('ignored', help='Print ignored files.'),
2355
help='Write an ascii NUL (\\0) separator '
2356
'between files rather than a newline.'),
2358
help='List entries of a particular kind: file, directory, symlink.',
2363
def run(self, revision=None, verbose=False,
2364
recursive=False, from_root=False,
2365
unknown=False, versioned=False, ignored=False,
2366
null=False, kind=None, show_ids=False, path=None):
2368
if kind and kind not in ('file', 'directory', 'symlink'):
2369
raise errors.BzrCommandError('invalid kind specified')
2371
if verbose and null:
2372
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2373
all = not (unknown or versioned or ignored)
2375
selection = {'I':ignored, '?':unknown, 'V':versioned}
2382
raise errors.BzrCommandError('cannot specify both --from-root'
2386
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2392
if revision is not None or tree is None:
2393
tree = _get_one_revision_tree('ls', revision, branch=branch)
2396
if isinstance(tree, WorkingTree) and tree.supports_views():
2397
view_files = tree.views.lookup_view()
2400
view_str = views.view_display_str(view_files)
2401
note("Ignoring files outside view. View is %s" % view_str)
2405
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2406
if fp.startswith(relpath):
2407
rp = fp[len(relpath):]
2408
fp = osutils.pathjoin(prefix, rp)
2409
if not recursive and '/' in rp:
2411
if not all and not selection[fc]:
2413
if kind is not None and fkind != kind:
2417
views.check_path_in_view(tree, fp)
2418
except errors.FileOutsideView:
2420
kindch = entry.kind_character()
2421
outstring = fp + kindch
2422
ui.ui_factory.clear_term()
2424
outstring = '%-8s %s' % (fc, outstring)
2425
if show_ids and fid is not None:
2426
outstring = "%-50s %s" % (outstring, fid)
2427
self.outf.write(outstring + '\n')
2429
self.outf.write(fp + '\0')
2432
self.outf.write(fid)
2433
self.outf.write('\0')
2441
self.outf.write('%-50s %s\n' % (outstring, my_id))
2443
self.outf.write(outstring + '\n')
2448
class cmd_unknowns(Command):
2449
"""List unknown files.
2457
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2458
self.outf.write(osutils.quotefn(f) + '\n')
2461
class cmd_ignore(Command):
2462
"""Ignore specified files or patterns.
2464
See ``bzr help patterns`` for details on the syntax of patterns.
2466
To remove patterns from the ignore list, edit the .bzrignore file.
2467
After adding, editing or deleting that file either indirectly by
2468
using this command or directly by using an editor, be sure to commit
2471
Note: ignore patterns containing shell wildcards must be quoted from
2475
Ignore the top level Makefile::
2477
bzr ignore ./Makefile
2479
Ignore class files in all directories::
2481
bzr ignore "*.class"
2483
Ignore .o files under the lib directory::
2485
bzr ignore "lib/**/*.o"
2487
Ignore .o files under the lib directory::
2489
bzr ignore "RE:lib/.*\.o"
2491
Ignore everything but the "debian" toplevel directory::
2493
bzr ignore "RE:(?!debian/).*"
2496
_see_also = ['status', 'ignored', 'patterns']
2497
takes_args = ['name_pattern*']
2499
Option('old-default-rules',
2500
help='Write out the ignore rules bzr < 0.9 always used.')
2503
def run(self, name_pattern_list=None, old_default_rules=None):
2504
from bzrlib import ignores
2505
if old_default_rules is not None:
2506
# dump the rules and exit
2507
for pattern in ignores.OLD_DEFAULTS:
2510
if not name_pattern_list:
2511
raise errors.BzrCommandError("ignore requires at least one "
2512
"NAME_PATTERN or --old-default-rules")
2513
name_pattern_list = [globbing.normalize_pattern(p)
2514
for p in name_pattern_list]
2515
for name_pattern in name_pattern_list:
2516
if (name_pattern[0] == '/' or
2517
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2518
raise errors.BzrCommandError(
2519
"NAME_PATTERN should not be an absolute path")
2520
tree, relpath = WorkingTree.open_containing(u'.')
2521
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2522
ignored = globbing.Globster(name_pattern_list)
2525
for entry in tree.list_files():
2529
if ignored.match(filename):
2530
matches.append(filename.encode('utf-8'))
2532
if len(matches) > 0:
2533
print "Warning: the following files are version controlled and" \
2534
" match your ignore pattern:\n%s" \
2535
"\nThese files will continue to be version controlled" \
2536
" unless you 'bzr remove' them." % ("\n".join(matches),)
2539
class cmd_ignored(Command):
2540
"""List ignored files and the patterns that matched them.
2542
List all the ignored files and the ignore pattern that caused the file to
2545
Alternatively, to list just the files::
2550
encoding_type = 'replace'
2551
_see_also = ['ignore', 'ls']
2555
tree = WorkingTree.open_containing(u'.')[0]
2558
for path, file_class, kind, file_id, entry in tree.list_files():
2559
if file_class != 'I':
2561
## XXX: Slightly inefficient since this was already calculated
2562
pat = tree.is_ignored(path)
2563
self.outf.write('%-50s %s\n' % (path, pat))
2568
class cmd_lookup_revision(Command):
2569
"""Lookup the revision-id from a revision-number
2572
bzr lookup-revision 33
2575
takes_args = ['revno']
2578
def run(self, revno):
2582
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2584
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2587
class cmd_export(Command):
2588
"""Export current or past revision to a destination directory or archive.
2590
If no revision is specified this exports the last committed revision.
2592
Format may be an "exporter" name, such as tar, tgz, tbz2. If none is
2593
given, try to find the format with the extension. If no extension
2594
is found exports to a directory (equivalent to --format=dir).
2596
If root is supplied, it will be used as the root directory inside
2597
container formats (tar, zip, etc). If it is not supplied it will default
2598
to the exported filename. The root option has no effect for 'dir' format.
2600
If branch is omitted then the branch containing the current working
2601
directory will be used.
2603
Note: Export of tree with non-ASCII filenames to zip is not supported.
2605
================= =========================
2606
Supported formats Autodetected by extension
2607
================= =========================
2610
tbz2 .tar.bz2, .tbz2
2613
================= =========================
2615
takes_args = ['dest', 'branch_or_subdir?']
2618
help="Type of file to export to.",
2621
Option('filters', help='Apply content filters to export the '
2622
'convenient form.'),
2625
help="Name of the root directory inside the exported file."),
2627
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2628
root=None, filters=False):
2629
from bzrlib.export import export
2631
if branch_or_subdir is None:
2632
tree = WorkingTree.open_containing(u'.')[0]
2636
b, subdir = Branch.open_containing(branch_or_subdir)
2639
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2641
export(rev_tree, dest, format, root, subdir, filtered=filters)
2642
except errors.NoSuchExportFormat, e:
2643
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2646
class cmd_cat(Command):
2647
"""Write the contents of a file as of a given revision to standard output.
2649
If no revision is nominated, the last revision is used.
2651
Note: Take care to redirect standard output when using this command on a
2657
Option('name-from-revision', help='The path name in the old tree.'),
2658
Option('filters', help='Apply content filters to display the '
2659
'convenience form.'),
2662
takes_args = ['filename']
2663
encoding_type = 'exact'
2666
def run(self, filename, revision=None, name_from_revision=False,
2668
if revision is not None and len(revision) != 1:
2669
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2670
" one revision specifier")
2671
tree, branch, relpath = \
2672
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2675
return self._run(tree, branch, relpath, filename, revision,
2676
name_from_revision, filters)
2680
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2683
tree = b.basis_tree()
2684
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2686
old_file_id = rev_tree.path2id(relpath)
2688
if name_from_revision:
2689
# Try in revision if requested
2690
if old_file_id is None:
2691
raise errors.BzrCommandError(
2692
"%r is not present in revision %s" % (
2693
filename, rev_tree.get_revision_id()))
2695
content = rev_tree.get_file_text(old_file_id)
2697
cur_file_id = tree.path2id(relpath)
2699
if cur_file_id is not None:
2700
# Then try with the actual file id
2702
content = rev_tree.get_file_text(cur_file_id)
2704
except errors.NoSuchId:
2705
# The actual file id didn't exist at that time
2707
if not found and old_file_id is not None:
2708
# Finally try with the old file id
2709
content = rev_tree.get_file_text(old_file_id)
2712
# Can't be found anywhere
2713
raise errors.BzrCommandError(
2714
"%r is not present in revision %s" % (
2715
filename, rev_tree.get_revision_id()))
2717
from bzrlib.filters import (
2718
ContentFilterContext,
2719
filtered_output_bytes,
2721
filters = rev_tree._content_filter_stack(relpath)
2722
chunks = content.splitlines(True)
2723
content = filtered_output_bytes(chunks, filters,
2724
ContentFilterContext(relpath, rev_tree))
2725
self.outf.writelines(content)
2727
self.outf.write(content)
2730
class cmd_local_time_offset(Command):
2731
"""Show the offset in seconds from GMT to local time."""
2735
print osutils.local_time_offset()
2739
class cmd_commit(Command):
2740
"""Commit changes into a new revision.
2742
An explanatory message needs to be given for each commit. This is
2743
often done by using the --message option (getting the message from the
2744
command line) or by using the --file option (getting the message from
2745
a file). If neither of these options is given, an editor is opened for
2746
the user to enter the message. To see the changed files in the
2747
boilerplate text loaded into the editor, use the --show-diff option.
2749
By default, the entire tree is committed and the person doing the
2750
commit is assumed to be the author. These defaults can be overridden
2755
If selected files are specified, only changes to those files are
2756
committed. If a directory is specified then the directory and
2757
everything within it is committed.
2759
When excludes are given, they take precedence over selected files.
2760
For example, to commit only changes within foo, but not changes
2763
bzr commit foo -x foo/bar
2765
A selective commit after a merge is not yet supported.
2769
If the author of the change is not the same person as the committer,
2770
you can specify the author's name using the --author option. The
2771
name should be in the same format as a committer-id, e.g.
2772
"John Doe <jdoe@example.com>". If there is more than one author of
2773
the change you can specify the option multiple times, once for each
2778
A common mistake is to forget to add a new file or directory before
2779
running the commit command. The --strict option checks for unknown
2780
files and aborts the commit if any are found. More advanced pre-commit
2781
checks can be implemented by defining hooks. See ``bzr help hooks``
2786
If you accidentially commit the wrong changes or make a spelling
2787
mistake in the commit message say, you can use the uncommit command
2788
to undo it. See ``bzr help uncommit`` for details.
2790
Hooks can also be configured to run after a commit. This allows you
2791
to trigger updates to external systems like bug trackers. The --fixes
2792
option can be used to record the association between a revision and
2793
one or more bugs. See ``bzr help bugs`` for details.
2795
A selective commit may fail in some cases where the committed
2796
tree would be invalid. Consider::
2801
bzr commit foo -m "committing foo"
2802
bzr mv foo/bar foo/baz
2805
bzr commit foo/bar -m "committing bar but not baz"
2807
In the example above, the last commit will fail by design. This gives
2808
the user the opportunity to decide whether they want to commit the
2809
rename at the same time, separately first, or not at all. (As a general
2810
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2812
# TODO: Run hooks on tree to-be-committed, and after commit.
2814
# TODO: Strict commit that fails if there are deleted files.
2815
# (what does "deleted files" mean ??)
2817
# TODO: Give better message for -s, --summary, used by tla people
2819
# XXX: verbose currently does nothing
2821
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2822
takes_args = ['selected*']
2824
ListOption('exclude', type=str, short_name='x',
2825
help="Do not consider changes made to a given path."),
2826
Option('message', type=unicode,
2828
help="Description of the new revision."),
2831
help='Commit even if nothing has changed.'),
2832
Option('file', type=str,
2835
help='Take commit message from this file.'),
2837
help="Refuse to commit if there are unknown "
2838
"files in the working tree."),
2839
ListOption('fixes', type=str,
2840
help="Mark a bug as being fixed by this revision "
2841
"(see \"bzr help bugs\")."),
2842
ListOption('author', type=unicode,
2843
help="Set the author's name, if it's different "
2844
"from the committer."),
2846
help="Perform a local commit in a bound "
2847
"branch. Local commits are not pushed to "
2848
"the master branch until a normal commit "
2852
help='When no message is supplied, show the diff along'
2853
' with the status summary in the message editor.'),
2855
aliases = ['ci', 'checkin']
2857
def _iter_bug_fix_urls(self, fixes, branch):
2858
# Configure the properties for bug fixing attributes.
2859
for fixed_bug in fixes:
2860
tokens = fixed_bug.split(':')
2861
if len(tokens) != 2:
2862
raise errors.BzrCommandError(
2863
"Invalid bug %s. Must be in the form of 'tracker:id'. "
2864
"See \"bzr help bugs\" for more information on this "
2865
"feature.\nCommit refused." % fixed_bug)
2866
tag, bug_id = tokens
2868
yield bugtracker.get_bug_url(tag, branch, bug_id)
2869
except errors.UnknownBugTrackerAbbreviation:
2870
raise errors.BzrCommandError(
2871
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2872
except errors.MalformedBugIdentifier, e:
2873
raise errors.BzrCommandError(
2874
"%s\nCommit refused." % (str(e),))
2876
def run(self, message=None, file=None, verbose=False, selected_list=None,
2877
unchanged=False, strict=False, local=False, fixes=None,
2878
author=None, show_diff=False, exclude=None):
2879
from bzrlib.errors import (
2884
from bzrlib.msgeditor import (
2885
edit_commit_message_encoded,
2886
generate_commit_message_template,
2887
make_commit_message_template_encoded
2890
# TODO: Need a blackbox test for invoking the external editor; may be
2891
# slightly problematic to run this cross-platform.
2893
# TODO: do more checks that the commit will succeed before
2894
# spending the user's valuable time typing a commit message.
2898
tree, selected_list = tree_files(selected_list)
2899
if selected_list == ['']:
2900
# workaround - commit of root of tree should be exactly the same
2901
# as just default commit in that tree, and succeed even though
2902
# selected-file merge commit is not done yet
2907
bug_property = bugtracker.encode_fixes_bug_urls(
2908
self._iter_bug_fix_urls(fixes, tree.branch))
2910
properties['bugs'] = bug_property
2912
if local and not tree.branch.get_bound_location():
2913
raise errors.LocalRequiresBoundBranch()
2915
def get_message(commit_obj):
2916
"""Callback to get commit message"""
2917
my_message = message
2918
if my_message is None and not file:
2919
t = make_commit_message_template_encoded(tree,
2920
selected_list, diff=show_diff,
2921
output_encoding=osutils.get_user_encoding())
2922
start_message = generate_commit_message_template(commit_obj)
2923
my_message = edit_commit_message_encoded(t,
2924
start_message=start_message)
2925
if my_message is None:
2926
raise errors.BzrCommandError("please specify a commit"
2927
" message with either --message or --file")
2928
elif my_message and file:
2929
raise errors.BzrCommandError(
2930
"please specify either --message or --file")
2932
my_message = codecs.open(file, 'rt',
2933
osutils.get_user_encoding()).read()
2934
if my_message == "":
2935
raise errors.BzrCommandError("empty commit message specified")
2939
tree.commit(message_callback=get_message,
2940
specific_files=selected_list,
2941
allow_pointless=unchanged, strict=strict, local=local,
2942
reporter=None, verbose=verbose, revprops=properties,
2944
exclude=safe_relpath_files(tree, exclude))
2945
except PointlessCommit:
2946
# FIXME: This should really happen before the file is read in;
2947
# perhaps prepare the commit; get the message; then actually commit
2948
raise errors.BzrCommandError("No changes to commit."
2949
" Use --unchanged to commit anyhow.")
2950
except ConflictsInTree:
2951
raise errors.BzrCommandError('Conflicts detected in working '
2952
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
2954
except StrictCommitFailed:
2955
raise errors.BzrCommandError("Commit refused because there are"
2956
" unknown files in the working tree.")
2957
except errors.BoundBranchOutOfDate, e:
2958
raise errors.BzrCommandError(str(e) + "\n"
2959
'To commit to master branch, run update and then commit.\n'
2960
'You can also pass --local to commit to continue working '
2964
class cmd_check(Command):
2965
"""Validate working tree structure, branch consistency and repository history.
2967
This command checks various invariants about branch and repository storage
2968
to detect data corruption or bzr bugs.
2970
The working tree and branch checks will only give output if a problem is
2971
detected. The output fields of the repository check are:
2973
revisions: This is just the number of revisions checked. It doesn't
2975
versionedfiles: This is just the number of versionedfiles checked. It
2976
doesn't indicate a problem.
2977
unreferenced ancestors: Texts that are ancestors of other texts, but
2978
are not properly referenced by the revision ancestry. This is a
2979
subtle problem that Bazaar can work around.
2980
unique file texts: This is the total number of unique file contents
2981
seen in the checked revisions. It does not indicate a problem.
2982
repeated file texts: This is the total number of repeated texts seen
2983
in the checked revisions. Texts can be repeated when their file
2984
entries are modified, but the file contents are not. It does not
2987
If no restrictions are specified, all Bazaar data that is found at the given
2988
location will be checked.
2992
Check the tree and branch at 'foo'::
2994
bzr check --tree --branch foo
2996
Check only the repository at 'bar'::
2998
bzr check --repo bar
3000
Check everything at 'baz'::
3005
_see_also = ['reconcile']
3006
takes_args = ['path?']
3007
takes_options = ['verbose',
3008
Option('branch', help="Check the branch related to the"
3009
" current directory."),
3010
Option('repo', help="Check the repository related to the"
3011
" current directory."),
3012
Option('tree', help="Check the working tree related to"
3013
" the current directory.")]
3015
def run(self, path=None, verbose=False, branch=False, repo=False,
3017
from bzrlib.check import check_dwim
3020
if not branch and not repo and not tree:
3021
branch = repo = tree = True
3022
check_dwim(path, verbose, do_branch=branch, do_repo=repo, do_tree=tree)
3025
class cmd_upgrade(Command):
3026
"""Upgrade branch storage to current format.
3028
The check command or bzr developers may sometimes advise you to run
3029
this command. When the default format has changed you may also be warned
3030
during other operations to upgrade.
3033
_see_also = ['check']
3034
takes_args = ['url?']
3036
RegistryOption('format',
3037
help='Upgrade to a specific format. See "bzr help'
3038
' formats" for details.',
3039
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3040
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3041
value_switches=True, title='Branch format'),
3044
def run(self, url='.', format=None):
3045
from bzrlib.upgrade import upgrade
3046
upgrade(url, format)
3049
class cmd_whoami(Command):
3050
"""Show or set bzr user id.
3053
Show the email of the current user::
3057
Set the current user::
3059
bzr whoami "Frank Chu <fchu@example.com>"
3061
takes_options = [ Option('email',
3062
help='Display email address only.'),
3064
help='Set identity for the current branch instead of '
3067
takes_args = ['name?']
3068
encoding_type = 'replace'
3071
def run(self, email=False, branch=False, name=None):
3073
# use branch if we're inside one; otherwise global config
3075
c = Branch.open_containing('.')[0].get_config()
3076
except errors.NotBranchError:
3077
c = config.GlobalConfig()
3079
self.outf.write(c.user_email() + '\n')
3081
self.outf.write(c.username() + '\n')
3084
# display a warning if an email address isn't included in the given name.
3086
config.extract_email_address(name)
3087
except errors.NoEmailInUsername, e:
3088
warning('"%s" does not seem to contain an email address. '
3089
'This is allowed, but not recommended.', name)
3091
# use global config unless --branch given
3093
c = Branch.open_containing('.')[0].get_config()
3095
c = config.GlobalConfig()
3096
c.set_user_option('email', name)
3099
class cmd_nick(Command):
3100
"""Print or set the branch nickname.
3102
If unset, the tree root directory name is used as the nickname.
3103
To print the current nickname, execute with no argument.
3105
Bound branches use the nickname of its master branch unless it is set
3109
_see_also = ['info']
3110
takes_args = ['nickname?']
3111
def run(self, nickname=None):
3112
branch = Branch.open_containing(u'.')[0]
3113
if nickname is None:
3114
self.printme(branch)
3116
branch.nick = nickname
3119
def printme(self, branch):
3123
class cmd_alias(Command):
3124
"""Set/unset and display aliases.
3127
Show the current aliases::
3131
Show the alias specified for 'll'::
3135
Set an alias for 'll'::
3137
bzr alias ll="log --line -r-10..-1"
3139
To remove an alias for 'll'::
3141
bzr alias --remove ll
3144
takes_args = ['name?']
3146
Option('remove', help='Remove the alias.'),
3149
def run(self, name=None, remove=False):
3151
self.remove_alias(name)
3153
self.print_aliases()
3155
equal_pos = name.find('=')
3157
self.print_alias(name)
3159
self.set_alias(name[:equal_pos], name[equal_pos+1:])
3161
def remove_alias(self, alias_name):
3162
if alias_name is None:
3163
raise errors.BzrCommandError(
3164
'bzr alias --remove expects an alias to remove.')
3165
# If alias is not found, print something like:
3166
# unalias: foo: not found
3167
c = config.GlobalConfig()
3168
c.unset_alias(alias_name)
3171
def print_aliases(self):
3172
"""Print out the defined aliases in a similar format to bash."""
3173
aliases = config.GlobalConfig().get_aliases()
3174
for key, value in sorted(aliases.iteritems()):
3175
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3178
def print_alias(self, alias_name):
3179
from bzrlib.commands import get_alias
3180
alias = get_alias(alias_name)
3182
self.outf.write("bzr alias: %s: not found\n" % alias_name)
3185
'bzr alias %s="%s"\n' % (alias_name, ' '.join(alias)))
3187
def set_alias(self, alias_name, alias_command):
3188
"""Save the alias in the global config."""
3189
c = config.GlobalConfig()
3190
c.set_alias(alias_name, alias_command)
3193
class cmd_selftest(Command):
3194
"""Run internal test suite.
3196
If arguments are given, they are regular expressions that say which tests
3197
should run. Tests matching any expression are run, and other tests are
3200
Alternatively if --first is given, matching tests are run first and then
3201
all other tests are run. This is useful if you have been working in a
3202
particular area, but want to make sure nothing else was broken.
3204
If --exclude is given, tests that match that regular expression are
3205
excluded, regardless of whether they match --first or not.
3207
To help catch accidential dependencies between tests, the --randomize
3208
option is useful. In most cases, the argument used is the word 'now'.
3209
Note that the seed used for the random number generator is displayed
3210
when this option is used. The seed can be explicitly passed as the
3211
argument to this option if required. This enables reproduction of the
3212
actual ordering used if and when an order sensitive problem is encountered.
3214
If --list-only is given, the tests that would be run are listed. This is
3215
useful when combined with --first, --exclude and/or --randomize to
3216
understand their impact. The test harness reports "Listed nn tests in ..."
3217
instead of "Ran nn tests in ..." when list mode is enabled.
3219
If the global option '--no-plugins' is given, plugins are not loaded
3220
before running the selftests. This has two effects: features provided or
3221
modified by plugins will not be tested, and tests provided by plugins will
3224
Tests that need working space on disk use a common temporary directory,
3225
typically inside $TMPDIR or /tmp.
3228
Run only tests relating to 'ignore'::
3232
Disable plugins and list tests as they're run::
3234
bzr --no-plugins selftest -v
3236
# NB: this is used from the class without creating an instance, which is
3237
# why it does not have a self parameter.
3238
def get_transport_type(typestring):
3239
"""Parse and return a transport specifier."""
3240
if typestring == "sftp":
3241
from bzrlib.transport.sftp import SFTPAbsoluteServer
3242
return SFTPAbsoluteServer
3243
if typestring == "memory":
3244
from bzrlib.transport.memory import MemoryServer
3246
if typestring == "fakenfs":
3247
from bzrlib.transport.fakenfs import FakeNFSServer
3248
return FakeNFSServer
3249
msg = "No known transport type %s. Supported types are: sftp\n" %\
3251
raise errors.BzrCommandError(msg)
3254
takes_args = ['testspecs*']
3255
takes_options = ['verbose',
3257
help='Stop when one test fails.',
3261
help='Use a different transport by default '
3262
'throughout the test suite.',
3263
type=get_transport_type),
3265
help='Run the benchmarks rather than selftests.'),
3266
Option('lsprof-timed',
3267
help='Generate lsprof output for benchmarked'
3268
' sections of code.'),
3269
Option('cache-dir', type=str,
3270
help='Cache intermediate benchmark output in this '
3273
help='Run all tests, but run specified tests first.',
3277
help='List the tests instead of running them.'),
3278
RegistryOption('parallel',
3279
help="Run the test suite in parallel.",
3280
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3281
value_switches=False,
3283
Option('randomize', type=str, argname="SEED",
3284
help='Randomize the order of tests using the given'
3285
' seed or "now" for the current time.'),
3286
Option('exclude', type=str, argname="PATTERN",
3288
help='Exclude tests that match this regular'
3291
help='Output test progress via subunit.'),
3292
Option('strict', help='Fail on missing dependencies or '
3294
Option('load-list', type=str, argname='TESTLISTFILE',
3295
help='Load a test id list from a text file.'),
3296
ListOption('debugflag', type=str, short_name='E',
3297
help='Turn on a selftest debug flag.'),
3298
ListOption('starting-with', type=str, argname='TESTID',
3299
param_name='starting_with', short_name='s',
3301
'Load only the tests starting with TESTID.'),
3303
encoding_type = 'replace'
3306
Command.__init__(self)
3307
self.additional_selftest_args = {}
3309
def run(self, testspecs_list=None, verbose=False, one=False,
3310
transport=None, benchmark=None,
3311
lsprof_timed=None, cache_dir=None,
3312
first=False, list_only=False,
3313
randomize=None, exclude=None, strict=False,
3314
load_list=None, debugflag=None, starting_with=None, subunit=False,
3316
from bzrlib.tests import selftest
3317
import bzrlib.benchmarks as benchmarks
3318
from bzrlib.benchmarks import tree_creator
3320
# Make deprecation warnings visible, unless -Werror is set
3321
symbol_versioning.activate_deprecation_warnings(override=False)
3323
if cache_dir is not None:
3324
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3325
if testspecs_list is not None:
3326
pattern = '|'.join(testspecs_list)
3331
from bzrlib.tests import SubUnitBzrRunner
3333
raise errors.BzrCommandError("subunit not available. subunit "
3334
"needs to be installed to use --subunit.")
3335
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3337
self.additional_selftest_args.setdefault(
3338
'suite_decorators', []).append(parallel)
3340
test_suite_factory = benchmarks.test_suite
3341
# Unless user explicitly asks for quiet, be verbose in benchmarks
3342
verbose = not is_quiet()
3343
# TODO: should possibly lock the history file...
3344
benchfile = open(".perf_history", "at", buffering=1)
3346
test_suite_factory = None
3349
selftest_kwargs = {"verbose": verbose,
3351
"stop_on_failure": one,
3352
"transport": transport,
3353
"test_suite_factory": test_suite_factory,
3354
"lsprof_timed": lsprof_timed,
3355
"bench_history": benchfile,
3356
"matching_tests_first": first,
3357
"list_only": list_only,
3358
"random_seed": randomize,
3359
"exclude_pattern": exclude,
3361
"load_list": load_list,
3362
"debug_flags": debugflag,
3363
"starting_with": starting_with
3365
selftest_kwargs.update(self.additional_selftest_args)
3366
result = selftest(**selftest_kwargs)
3368
if benchfile is not None:
3370
return int(not result)
3373
class cmd_version(Command):
3374
"""Show version of bzr."""
3376
encoding_type = 'replace'
3378
Option("short", help="Print just the version number."),
3382
def run(self, short=False):
3383
from bzrlib.version import show_version
3385
self.outf.write(bzrlib.version_string + '\n')
3387
show_version(to_file=self.outf)
3390
class cmd_rocks(Command):
3391
"""Statement of optimism."""
3397
print "It sure does!"
3400
class cmd_find_merge_base(Command):
3401
"""Find and print a base revision for merging two branches."""
3402
# TODO: Options to specify revisions on either side, as if
3403
# merging only part of the history.
3404
takes_args = ['branch', 'other']
3408
def run(self, branch, other):
3409
from bzrlib.revision import ensure_null
3411
branch1 = Branch.open_containing(branch)[0]
3412
branch2 = Branch.open_containing(other)[0]
3417
last1 = ensure_null(branch1.last_revision())
3418
last2 = ensure_null(branch2.last_revision())
3420
graph = branch1.repository.get_graph(branch2.repository)
3421
base_rev_id = graph.find_unique_lca(last1, last2)
3423
print 'merge base is revision %s' % base_rev_id
3430
class cmd_merge(Command):
3431
"""Perform a three-way merge.
3433
The source of the merge can be specified either in the form of a branch,
3434
or in the form of a path to a file containing a merge directive generated
3435
with bzr send. If neither is specified, the default is the upstream branch
3436
or the branch most recently merged using --remember.
3438
When merging a branch, by default the tip will be merged. To pick a different
3439
revision, pass --revision. If you specify two values, the first will be used as
3440
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3441
available revisions, like this is commonly referred to as "cherrypicking".
3443
Revision numbers are always relative to the branch being merged.
3445
By default, bzr will try to merge in all new work from the other
3446
branch, automatically determining an appropriate base. If this
3447
fails, you may need to give an explicit base.
3449
Merge will do its best to combine the changes in two branches, but there
3450
are some kinds of problems only a human can fix. When it encounters those,
3451
it will mark a conflict. A conflict means that you need to fix something,
3452
before you should commit.
3454
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
3456
If there is no default branch set, the first merge will set it. After
3457
that, you can omit the branch to use the default. To change the
3458
default, use --remember. The value will only be saved if the remote
3459
location can be accessed.
3461
The results of the merge are placed into the destination working
3462
directory, where they can be reviewed (with bzr diff), tested, and then
3463
committed to record the result of the merge.
3465
merge refuses to run if there are any uncommitted changes, unless
3469
To merge the latest revision from bzr.dev::
3471
bzr merge ../bzr.dev
3473
To merge changes up to and including revision 82 from bzr.dev::
3475
bzr merge -r 82 ../bzr.dev
3477
To merge the changes introduced by 82, without previous changes::
3479
bzr merge -r 81..82 ../bzr.dev
3481
To apply a merge directive contained in /tmp/merge:
3483
bzr merge /tmp/merge
3486
encoding_type = 'exact'
3487
_see_also = ['update', 'remerge', 'status-flags', 'send']
3488
takes_args = ['location?']
3493
help='Merge even if the destination tree has uncommitted changes.'),
3497
Option('show-base', help="Show base revision text in "
3499
Option('uncommitted', help='Apply uncommitted changes'
3500
' from a working copy, instead of branch changes.'),
3501
Option('pull', help='If the destination is already'
3502
' completely merged into the source, pull from the'
3503
' source rather than merging. When this happens,'
3504
' you do not need to commit the result.'),
3506
help='Branch to merge into, '
3507
'rather than the one containing the working directory.',
3511
Option('preview', help='Instead of merging, show a diff of the merge.')
3514
def run(self, location=None, revision=None, force=False,
3515
merge_type=None, show_base=False, reprocess=None, remember=False,
3516
uncommitted=False, pull=False,
3520
if merge_type is None:
3521
merge_type = _mod_merge.Merge3Merger
3523
if directory is None: directory = u'.'
3524
possible_transports = []
3526
allow_pending = True
3527
verified = 'inapplicable'
3528
tree = WorkingTree.open_containing(directory)[0]
3530
# die as quickly as possible if there are uncommitted changes
3532
basis_tree = tree.revision_tree(tree.last_revision())
3533
except errors.NoSuchRevision:
3534
basis_tree = tree.basis_tree()
3536
changes = tree.changes_from(basis_tree)
3537
if changes.has_changed():
3538
raise errors.UncommittedChanges(tree)
3540
view_info = _get_view_info_for_change_reporter(tree)
3541
change_reporter = delta._ChangeReporter(
3542
unversioned_filter=tree.is_ignored, view_info=view_info)
3545
pb = ui.ui_factory.nested_progress_bar()
3546
cleanups.append(pb.finished)
3548
cleanups.append(tree.unlock)
3549
if location is not None:
3551
mergeable = bundle.read_mergeable_from_url(location,
3552
possible_transports=possible_transports)
3553
except errors.NotABundle:
3557
raise errors.BzrCommandError('Cannot use --uncommitted'
3558
' with bundles or merge directives.')
3560
if revision is not None:
3561
raise errors.BzrCommandError(
3562
'Cannot use -r with merge directives or bundles')
3563
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3566
if merger is None and uncommitted:
3567
if revision is not None and len(revision) > 0:
3568
raise errors.BzrCommandError('Cannot use --uncommitted and'
3569
' --revision at the same time.')
3570
location = self._select_branch_location(tree, location)[0]
3571
other_tree, other_path = WorkingTree.open_containing(location)
3572
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3574
allow_pending = False
3575
if other_path != '':
3576
merger.interesting_files = [other_path]
3579
merger, allow_pending = self._get_merger_from_branch(tree,
3580
location, revision, remember, possible_transports, pb)
3582
merger.merge_type = merge_type
3583
merger.reprocess = reprocess
3584
merger.show_base = show_base
3585
self.sanity_check_merger(merger)
3586
if (merger.base_rev_id == merger.other_rev_id and
3587
merger.other_rev_id is not None):
3588
note('Nothing to do.')
3591
if merger.interesting_files is not None:
3592
raise errors.BzrCommandError('Cannot pull individual files')
3593
if (merger.base_rev_id == tree.last_revision()):
3594
result = tree.pull(merger.other_branch, False,
3595
merger.other_rev_id)
3596
result.report(self.outf)
3598
merger.check_basis(False)
3600
return self._do_preview(merger)
3602
return self._do_merge(merger, change_reporter, allow_pending,
3605
for cleanup in reversed(cleanups):
3608
def _do_preview(self, merger):
3609
from bzrlib.diff import show_diff_trees
3610
tree_merger = merger.make_merger()
3611
tt = tree_merger.make_preview_transform()
3613
result_tree = tt.get_preview_tree()
3614
show_diff_trees(merger.this_tree, result_tree, self.outf,
3615
old_label='', new_label='')
3619
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3620
merger.change_reporter = change_reporter
3621
conflict_count = merger.do_merge()
3623
merger.set_pending()
3624
if verified == 'failed':
3625
warning('Preview patch does not match changes')
3626
if conflict_count != 0:
3631
def sanity_check_merger(self, merger):
3632
if (merger.show_base and
3633
not merger.merge_type is _mod_merge.Merge3Merger):
3634
raise errors.BzrCommandError("Show-base is not supported for this"
3635
" merge type. %s" % merger.merge_type)
3636
if merger.reprocess is None:
3637
if merger.show_base:
3638
merger.reprocess = False
3640
# Use reprocess if the merger supports it
3641
merger.reprocess = merger.merge_type.supports_reprocess
3642
if merger.reprocess and not merger.merge_type.supports_reprocess:
3643
raise errors.BzrCommandError("Conflict reduction is not supported"
3644
" for merge type %s." %
3646
if merger.reprocess and merger.show_base:
3647
raise errors.BzrCommandError("Cannot do conflict reduction and"
3650
def _get_merger_from_branch(self, tree, location, revision, remember,
3651
possible_transports, pb):
3652
"""Produce a merger from a location, assuming it refers to a branch."""
3653
from bzrlib.tag import _merge_tags_if_possible
3654
# find the branch locations
3655
other_loc, user_location = self._select_branch_location(tree, location,
3657
if revision is not None and len(revision) == 2:
3658
base_loc, _unused = self._select_branch_location(tree,
3659
location, revision, 0)
3661
base_loc = other_loc
3663
other_branch, other_path = Branch.open_containing(other_loc,
3664
possible_transports)
3665
if base_loc == other_loc:
3666
base_branch = other_branch
3668
base_branch, base_path = Branch.open_containing(base_loc,
3669
possible_transports)
3670
# Find the revision ids
3671
if revision is None or len(revision) < 1 or revision[-1] is None:
3672
other_revision_id = _mod_revision.ensure_null(
3673
other_branch.last_revision())
3675
other_revision_id = revision[-1].as_revision_id(other_branch)
3676
if (revision is not None and len(revision) == 2
3677
and revision[0] is not None):
3678
base_revision_id = revision[0].as_revision_id(base_branch)
3680
base_revision_id = None
3681
# Remember where we merge from
3682
if ((remember or tree.branch.get_submit_branch() is None) and
3683
user_location is not None):
3684
tree.branch.set_submit_branch(other_branch.base)
3685
_merge_tags_if_possible(other_branch, tree.branch)
3686
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3687
other_revision_id, base_revision_id, other_branch, base_branch)
3688
if other_path != '':
3689
allow_pending = False
3690
merger.interesting_files = [other_path]
3692
allow_pending = True
3693
return merger, allow_pending
3695
def _select_branch_location(self, tree, user_location, revision=None,
3697
"""Select a branch location, according to possible inputs.
3699
If provided, branches from ``revision`` are preferred. (Both
3700
``revision`` and ``index`` must be supplied.)
3702
Otherwise, the ``location`` parameter is used. If it is None, then the
3703
``submit`` or ``parent`` location is used, and a note is printed.
3705
:param tree: The working tree to select a branch for merging into
3706
:param location: The location entered by the user
3707
:param revision: The revision parameter to the command
3708
:param index: The index to use for the revision parameter. Negative
3709
indices are permitted.
3710
:return: (selected_location, user_location). The default location
3711
will be the user-entered location.
3713
if (revision is not None and index is not None
3714
and revision[index] is not None):
3715
branch = revision[index].get_branch()
3716
if branch is not None:
3717
return branch, branch
3718
if user_location is None:
3719
location = self._get_remembered(tree, 'Merging from')
3721
location = user_location
3722
return location, user_location
3724
def _get_remembered(self, tree, verb_string):
3725
"""Use tree.branch's parent if none was supplied.
3727
Report if the remembered location was used.
3729
stored_location = tree.branch.get_submit_branch()
3730
stored_location_type = "submit"
3731
if stored_location is None:
3732
stored_location = tree.branch.get_parent()
3733
stored_location_type = "parent"
3734
mutter("%s", stored_location)
3735
if stored_location is None:
3736
raise errors.BzrCommandError("No location specified or remembered")
3737
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3738
note(u"%s remembered %s location %s", verb_string,
3739
stored_location_type, display_url)
3740
return stored_location
3743
class cmd_remerge(Command):
3746
Use this if you want to try a different merge technique while resolving
3747
conflicts. Some merge techniques are better than others, and remerge
3748
lets you try different ones on different files.
3750
The options for remerge have the same meaning and defaults as the ones for
3751
merge. The difference is that remerge can (only) be run when there is a
3752
pending merge, and it lets you specify particular files.
3755
Re-do the merge of all conflicted files, and show the base text in
3756
conflict regions, in addition to the usual THIS and OTHER texts::
3758
bzr remerge --show-base
3760
Re-do the merge of "foobar", using the weave merge algorithm, with
3761
additional processing to reduce the size of conflict regions::
3763
bzr remerge --merge-type weave --reprocess foobar
3765
takes_args = ['file*']
3770
help="Show base revision text in conflicts."),
3773
def run(self, file_list=None, merge_type=None, show_base=False,
3775
if merge_type is None:
3776
merge_type = _mod_merge.Merge3Merger
3777
tree, file_list = tree_files(file_list)
3780
parents = tree.get_parent_ids()
3781
if len(parents) != 2:
3782
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3783
" merges. Not cherrypicking or"
3785
repository = tree.branch.repository
3786
interesting_ids = None
3788
conflicts = tree.conflicts()
3789
if file_list is not None:
3790
interesting_ids = set()
3791
for filename in file_list:
3792
file_id = tree.path2id(filename)
3794
raise errors.NotVersionedError(filename)
3795
interesting_ids.add(file_id)
3796
if tree.kind(file_id) != "directory":
3799
for name, ie in tree.inventory.iter_entries(file_id):
3800
interesting_ids.add(ie.file_id)
3801
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3803
# Remerge only supports resolving contents conflicts
3804
allowed_conflicts = ('text conflict', 'contents conflict')
3805
restore_files = [c.path for c in conflicts
3806
if c.typestring in allowed_conflicts]
3807
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3808
tree.set_conflicts(ConflictList(new_conflicts))
3809
if file_list is not None:
3810
restore_files = file_list
3811
for filename in restore_files:
3813
restore(tree.abspath(filename))
3814
except errors.NotConflicted:
3816
# Disable pending merges, because the file texts we are remerging
3817
# have not had those merges performed. If we use the wrong parents
3818
# list, we imply that the working tree text has seen and rejected
3819
# all the changes from the other tree, when in fact those changes
3820
# have not yet been seen.
3821
pb = ui.ui_factory.nested_progress_bar()
3822
tree.set_parent_ids(parents[:1])
3824
merger = _mod_merge.Merger.from_revision_ids(pb,
3826
merger.interesting_ids = interesting_ids
3827
merger.merge_type = merge_type
3828
merger.show_base = show_base
3829
merger.reprocess = reprocess
3830
conflicts = merger.do_merge()
3832
tree.set_parent_ids(parents)
3842
class cmd_revert(Command):
3843
"""Revert files to a previous revision.
3845
Giving a list of files will revert only those files. Otherwise, all files
3846
will be reverted. If the revision is not specified with '--revision', the
3847
last committed revision is used.
3849
To remove only some changes, without reverting to a prior version, use
3850
merge instead. For example, "merge . --revision -2..-3" will remove the
3851
changes introduced by -2, without affecting the changes introduced by -1.
3852
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3854
By default, any files that have been manually changed will be backed up
3855
first. (Files changed only by merge are not backed up.) Backup files have
3856
'.~#~' appended to their name, where # is a number.
3858
When you provide files, you can use their current pathname or the pathname
3859
from the target revision. So you can use revert to "undelete" a file by
3860
name. If you name a directory, all the contents of that directory will be
3863
Any files that have been newly added since that revision will be deleted,
3864
with a backup kept if appropriate. Directories containing unknown files
3865
will not be deleted.
3867
The working tree contains a list of pending merged revisions, which will
3868
be included as parents in the next commit. Normally, revert clears that
3869
list as well as reverting the files. If any files are specified, revert
3870
leaves the pending merge list alone and reverts only the files. Use "bzr
3871
revert ." in the tree root to revert all files but keep the merge record,
3872
and "bzr revert --forget-merges" to clear the pending merge list without
3873
reverting any files.
3876
_see_also = ['cat', 'export']
3879
Option('no-backup', "Do not save backups of reverted files."),
3880
Option('forget-merges',
3881
'Remove pending merge marker, without changing any files.'),
3883
takes_args = ['file*']
3885
def run(self, revision=None, no_backup=False, file_list=None,
3886
forget_merges=None):
3887
tree, file_list = tree_files(file_list)
3891
tree.set_parent_ids(tree.get_parent_ids()[:1])
3893
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
3898
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
3899
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
3900
pb = ui.ui_factory.nested_progress_bar()
3902
tree.revert(file_list, rev_tree, not no_backup, pb,
3903
report_changes=True)
3908
class cmd_assert_fail(Command):
3909
"""Test reporting of assertion failures"""
3910
# intended just for use in testing
3915
raise AssertionError("always fails")
3918
class cmd_help(Command):
3919
"""Show help on a command or other topic.
3922
_see_also = ['topics']
3924
Option('long', 'Show help on all commands.'),
3926
takes_args = ['topic?']
3927
aliases = ['?', '--help', '-?', '-h']
3930
def run(self, topic=None, long=False):
3932
if topic is None and long:
3934
bzrlib.help.help(topic)
3937
class cmd_shell_complete(Command):
3938
"""Show appropriate completions for context.
3940
For a list of all available commands, say 'bzr shell-complete'.
3942
takes_args = ['context?']
3947
def run(self, context=None):
3948
import shellcomplete
3949
shellcomplete.shellcomplete(context)
3952
class cmd_missing(Command):
3953
"""Show unmerged/unpulled revisions between two branches.
3955
OTHER_BRANCH may be local or remote.
3957
To filter on a range of revisions, you can use the command -r begin..end
3958
-r revision requests a specific revision, -r ..end or -r begin.. are
3963
Determine the missing revisions between this and the branch at the
3964
remembered pull location::
3968
Determine the missing revisions between this and another branch::
3970
bzr missing http://server/branch
3972
Determine the missing revisions up to a specific revision on the other
3975
bzr missing -r ..-10
3977
Determine the missing revisions up to a specific revision on this
3980
bzr missing --my-revision ..-10
3983
_see_also = ['merge', 'pull']
3984
takes_args = ['other_branch?']
3986
Option('reverse', 'Reverse the order of revisions.'),
3988
'Display changes in the local branch only.'),
3989
Option('this' , 'Same as --mine-only.'),
3990
Option('theirs-only',
3991
'Display changes in the remote branch only.'),
3992
Option('other', 'Same as --theirs-only.'),
3996
custom_help('revision',
3997
help='Filter on other branch revisions (inclusive). '
3998
'See "help revisionspec" for details.'),
3999
Option('my-revision',
4000
type=_parse_revision_str,
4001
help='Filter on local branch revisions (inclusive). '
4002
'See "help revisionspec" for details.'),
4003
Option('include-merges',
4004
'Show all revisions in addition to the mainline ones.'),
4006
encoding_type = 'replace'
4009
def run(self, other_branch=None, reverse=False, mine_only=False,
4011
log_format=None, long=False, short=False, line=False,
4012
show_ids=False, verbose=False, this=False, other=False,
4013
include_merges=False, revision=None, my_revision=None):
4014
from bzrlib.missing import find_unmerged, iter_log_revisions
4023
# TODO: We should probably check that we don't have mine-only and
4024
# theirs-only set, but it gets complicated because we also have
4025
# this and other which could be used.
4032
local_branch = Branch.open_containing(u".")[0]
4033
parent = local_branch.get_parent()
4034
if other_branch is None:
4035
other_branch = parent
4036
if other_branch is None:
4037
raise errors.BzrCommandError("No peer location known"
4039
display_url = urlutils.unescape_for_display(parent,
4041
message("Using saved parent location: "
4042
+ display_url + "\n")
4044
remote_branch = Branch.open(other_branch)
4045
if remote_branch.base == local_branch.base:
4046
remote_branch = local_branch
4048
local_revid_range = _revision_range_to_revid_range(
4049
_get_revision_range(my_revision, local_branch,
4052
remote_revid_range = _revision_range_to_revid_range(
4053
_get_revision_range(revision,
4054
remote_branch, self.name()))
4056
local_branch.lock_read()
4058
remote_branch.lock_read()
4060
local_extra, remote_extra = find_unmerged(
4061
local_branch, remote_branch, restrict,
4062
backward=not reverse,
4063
include_merges=include_merges,
4064
local_revid_range=local_revid_range,
4065
remote_revid_range=remote_revid_range)
4067
if log_format is None:
4068
registry = log.log_formatter_registry
4069
log_format = registry.get_default(local_branch)
4070
lf = log_format(to_file=self.outf,
4072
show_timezone='original')
4075
if local_extra and not theirs_only:
4076
message("You have %d extra revision(s):\n" %
4078
for revision in iter_log_revisions(local_extra,
4079
local_branch.repository,
4081
lf.log_revision(revision)
4082
printed_local = True
4085
printed_local = False
4087
if remote_extra and not mine_only:
4088
if printed_local is True:
4090
message("You are missing %d revision(s):\n" %
4092
for revision in iter_log_revisions(remote_extra,
4093
remote_branch.repository,
4095
lf.log_revision(revision)
4098
if mine_only and not local_extra:
4099
# We checked local, and found nothing extra
4100
message('This branch is up to date.\n')
4101
elif theirs_only and not remote_extra:
4102
# We checked remote, and found nothing extra
4103
message('Other branch is up to date.\n')
4104
elif not (mine_only or theirs_only or local_extra or
4106
# We checked both branches, and neither one had extra
4108
message("Branches are up to date.\n")
4110
remote_branch.unlock()
4112
local_branch.unlock()
4113
if not status_code and parent is None and other_branch is not None:
4114
local_branch.lock_write()
4116
# handle race conditions - a parent might be set while we run.
4117
if local_branch.get_parent() is None:
4118
local_branch.set_parent(remote_branch.base)
4120
local_branch.unlock()
4124
class cmd_pack(Command):
4125
"""Compress the data within a repository."""
4127
_see_also = ['repositories']
4128
takes_args = ['branch_or_repo?']
4130
def run(self, branch_or_repo='.'):
4131
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4133
branch = dir.open_branch()
4134
repository = branch.repository
4135
except errors.NotBranchError:
4136
repository = dir.open_repository()
4140
class cmd_plugins(Command):
4141
"""List the installed plugins.
4143
This command displays the list of installed plugins including
4144
version of plugin and a short description of each.
4146
--verbose shows the path where each plugin is located.
4148
A plugin is an external component for Bazaar that extends the
4149
revision control system, by adding or replacing code in Bazaar.
4150
Plugins can do a variety of things, including overriding commands,
4151
adding new commands, providing additional network transports and
4152
customizing log output.
4154
See the Bazaar web site, http://bazaar-vcs.org, for further
4155
information on plugins including where to find them and how to
4156
install them. Instructions are also provided there on how to
4157
write new plugins using the Python programming language.
4159
takes_options = ['verbose']
4162
def run(self, verbose=False):
4163
import bzrlib.plugin
4164
from inspect import getdoc
4166
for name, plugin in bzrlib.plugin.plugins().items():
4167
version = plugin.__version__
4168
if version == 'unknown':
4170
name_ver = '%s %s' % (name, version)
4171
d = getdoc(plugin.module)
4173
doc = d.split('\n')[0]
4175
doc = '(no description)'
4176
result.append((name_ver, doc, plugin.path()))
4177
for name_ver, doc, path in sorted(result):
4185
class cmd_testament(Command):
4186
"""Show testament (signing-form) of a revision."""
4189
Option('long', help='Produce long-format testament.'),
4191
help='Produce a strict-format testament.')]
4192
takes_args = ['branch?']
4194
def run(self, branch=u'.', revision=None, long=False, strict=False):
4195
from bzrlib.testament import Testament, StrictTestament
4197
testament_class = StrictTestament
4199
testament_class = Testament
4201
b = Branch.open_containing(branch)[0]
4203
b = Branch.open(branch)
4206
if revision is None:
4207
rev_id = b.last_revision()
4209
rev_id = revision[0].as_revision_id(b)
4210
t = testament_class.from_revision(b.repository, rev_id)
4212
sys.stdout.writelines(t.as_text_lines())
4214
sys.stdout.write(t.as_short_text())
4219
class cmd_annotate(Command):
4220
"""Show the origin of each line in a file.
4222
This prints out the given file with an annotation on the left side
4223
indicating which revision, author and date introduced the change.
4225
If the origin is the same for a run of consecutive lines, it is
4226
shown only at the top, unless the --all option is given.
4228
# TODO: annotate directories; showing when each file was last changed
4229
# TODO: if the working copy is modified, show annotations on that
4230
# with new uncommitted lines marked
4231
aliases = ['ann', 'blame', 'praise']
4232
takes_args = ['filename']
4233
takes_options = [Option('all', help='Show annotations on all lines.'),
4234
Option('long', help='Show commit date in annotations.'),
4238
encoding_type = 'exact'
4241
def run(self, filename, all=False, long=False, revision=None,
4243
from bzrlib.annotate import annotate_file, annotate_file_tree
4244
wt, branch, relpath = \
4245
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4251
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4253
file_id = wt.path2id(relpath)
4255
file_id = tree.path2id(relpath)
4257
raise errors.NotVersionedError(filename)
4258
file_version = tree.inventory[file_id].revision
4259
if wt is not None and revision is None:
4260
# If there is a tree and we're not annotating historical
4261
# versions, annotate the working tree's content.
4262
annotate_file_tree(wt, file_id, self.outf, long, all,
4265
annotate_file(branch, file_version, file_id, long, all, self.outf,
4274
class cmd_re_sign(Command):
4275
"""Create a digital signature for an existing revision."""
4276
# TODO be able to replace existing ones.
4278
hidden = True # is this right ?
4279
takes_args = ['revision_id*']
4280
takes_options = ['revision']
4282
def run(self, revision_id_list=None, revision=None):
4283
if revision_id_list is not None and revision is not None:
4284
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4285
if revision_id_list is None and revision is None:
4286
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4287
b = WorkingTree.open_containing(u'.')[0].branch
4290
return self._run(b, revision_id_list, revision)
4294
def _run(self, b, revision_id_list, revision):
4295
import bzrlib.gpg as gpg
4296
gpg_strategy = gpg.GPGStrategy(b.get_config())
4297
if revision_id_list is not None:
4298
b.repository.start_write_group()
4300
for revision_id in revision_id_list:
4301
b.repository.sign_revision(revision_id, gpg_strategy)
4303
b.repository.abort_write_group()
4306
b.repository.commit_write_group()
4307
elif revision is not None:
4308
if len(revision) == 1:
4309
revno, rev_id = revision[0].in_history(b)
4310
b.repository.start_write_group()
4312
b.repository.sign_revision(rev_id, gpg_strategy)
4314
b.repository.abort_write_group()
4317
b.repository.commit_write_group()
4318
elif len(revision) == 2:
4319
# are they both on rh- if so we can walk between them
4320
# might be nice to have a range helper for arbitrary
4321
# revision paths. hmm.
4322
from_revno, from_revid = revision[0].in_history(b)
4323
to_revno, to_revid = revision[1].in_history(b)
4324
if to_revid is None:
4325
to_revno = b.revno()
4326
if from_revno is None or to_revno is None:
4327
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
4328
b.repository.start_write_group()
4330
for revno in range(from_revno, to_revno + 1):
4331
b.repository.sign_revision(b.get_rev_id(revno),
4334
b.repository.abort_write_group()
4337
b.repository.commit_write_group()
4339
raise errors.BzrCommandError('Please supply either one revision, or a range.')
4342
class cmd_bind(Command):
4343
"""Convert the current branch into a checkout of the supplied branch.
4345
Once converted into a checkout, commits must succeed on the master branch
4346
before they will be applied to the local branch.
4348
Bound branches use the nickname of its master branch unless it is set
4349
locally, in which case binding will update the the local nickname to be
4353
_see_also = ['checkouts', 'unbind']
4354
takes_args = ['location?']
4357
def run(self, location=None):
4358
b, relpath = Branch.open_containing(u'.')
4359
if location is None:
4361
location = b.get_old_bound_location()
4362
except errors.UpgradeRequired:
4363
raise errors.BzrCommandError('No location supplied. '
4364
'This format does not remember old locations.')
4366
if location is None:
4367
raise errors.BzrCommandError('No location supplied and no '
4368
'previous location known')
4369
b_other = Branch.open(location)
4372
except errors.DivergedBranches:
4373
raise errors.BzrCommandError('These branches have diverged.'
4374
' Try merging, and then bind again.')
4375
if b.get_config().has_explicit_nickname():
4376
b.nick = b_other.nick
4379
class cmd_unbind(Command):
4380
"""Convert the current checkout into a regular branch.
4382
After unbinding, the local branch is considered independent and subsequent
4383
commits will be local only.
4386
_see_also = ['checkouts', 'bind']
4391
b, relpath = Branch.open_containing(u'.')
4393
raise errors.BzrCommandError('Local branch is not bound')
4396
class cmd_uncommit(Command):
4397
"""Remove the last committed revision.
4399
--verbose will print out what is being removed.
4400
--dry-run will go through all the motions, but not actually
4403
If --revision is specified, uncommit revisions to leave the branch at the
4404
specified revision. For example, "bzr uncommit -r 15" will leave the
4405
branch at revision 15.
4407
Uncommit leaves the working tree ready for a new commit. The only change
4408
it may make is to restore any pending merges that were present before
4412
# TODO: jam 20060108 Add an option to allow uncommit to remove
4413
# unreferenced information in 'branch-as-repository' branches.
4414
# TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
4415
# information in shared branches as well.
4416
_see_also = ['commit']
4417
takes_options = ['verbose', 'revision',
4418
Option('dry-run', help='Don\'t actually make changes.'),
4419
Option('force', help='Say yes to all questions.'),
4421
help="Only remove the commits from the local branch"
4422
" when in a checkout."
4425
takes_args = ['location?']
4427
encoding_type = 'replace'
4429
def run(self, location=None,
4430
dry_run=False, verbose=False,
4431
revision=None, force=False, local=False):
4432
if location is None:
4434
control, relpath = bzrdir.BzrDir.open_containing(location)
4436
tree = control.open_workingtree()
4438
except (errors.NoWorkingTree, errors.NotLocalUrl):
4440
b = control.open_branch()
4442
if tree is not None:
4447
return self._run(b, tree, dry_run, verbose, revision, force,
4450
if tree is not None:
4455
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4456
from bzrlib.log import log_formatter, show_log
4457
from bzrlib.uncommit import uncommit
4459
last_revno, last_rev_id = b.last_revision_info()
4462
if revision is None:
4464
rev_id = last_rev_id
4466
# 'bzr uncommit -r 10' actually means uncommit
4467
# so that the final tree is at revno 10.
4468
# but bzrlib.uncommit.uncommit() actually uncommits
4469
# the revisions that are supplied.
4470
# So we need to offset it by one
4471
revno = revision[0].in_history(b).revno + 1
4472
if revno <= last_revno:
4473
rev_id = b.get_rev_id(revno)
4475
if rev_id is None or _mod_revision.is_null(rev_id):
4476
self.outf.write('No revisions to uncommit.\n')
4479
lf = log_formatter('short',
4481
show_timezone='original')
4486
direction='forward',
4487
start_revision=revno,
4488
end_revision=last_revno)
4491
print 'Dry-run, pretending to remove the above revisions.'
4493
val = raw_input('Press <enter> to continue')
4495
print 'The above revision(s) will be removed.'
4497
val = raw_input('Are you sure [y/N]? ')
4498
if val.lower() not in ('y', 'yes'):
4502
mutter('Uncommitting from {%s} to {%s}',
4503
last_rev_id, rev_id)
4504
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4505
revno=revno, local=local)
4506
note('You can restore the old tip by running:\n'
4507
' bzr pull . -r revid:%s', last_rev_id)
4510
class cmd_break_lock(Command):
4511
"""Break a dead lock on a repository, branch or working directory.
4513
CAUTION: Locks should only be broken when you are sure that the process
4514
holding the lock has been stopped.
4516
You can get information on what locks are open via the 'bzr info' command.
4521
takes_args = ['location?']
4523
def run(self, location=None, show=False):
4524
if location is None:
4526
control, relpath = bzrdir.BzrDir.open_containing(location)
4528
control.break_lock()
4529
except NotImplementedError:
4533
class cmd_wait_until_signalled(Command):
4534
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4536
This just prints a line to signal when it is ready, then blocks on stdin.
4542
sys.stdout.write("running\n")
4544
sys.stdin.readline()
4547
class cmd_serve(Command):
4548
"""Run the bzr server."""
4550
aliases = ['server']
4554
help='Serve on stdin/out for use from inetd or sshd.'),
4555
RegistryOption('protocol',
4556
help="Protocol to serve.",
4557
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
4558
value_switches=True),
4560
help='Listen for connections on nominated port of the form '
4561
'[hostname:]portnumber. Passing 0 as the port number will '
4562
'result in a dynamically allocated port. The default port '
4563
'depends on the protocol.',
4566
help='Serve contents of this directory.',
4568
Option('allow-writes',
4569
help='By default the server is a readonly server. Supplying '
4570
'--allow-writes enables write access to the contents of '
4571
'the served directory and below.'
4575
def get_host_and_port(self, port):
4576
"""Return the host and port to run the smart server on.
4578
If 'port' is None, None will be returned for the host and port.
4580
If 'port' has a colon in it, the string before the colon will be
4581
interpreted as the host.
4583
:param port: A string of the port to run the server on.
4584
:return: A tuple of (host, port), where 'host' is a host name or IP,
4585
and port is an integer TCP/IP port.
4588
if port is not None:
4590
host, port = port.split(':')
4594
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4596
from bzrlib.transport import get_transport, transport_server_registry
4597
if directory is None:
4598
directory = os.getcwd()
4599
if protocol is None:
4600
protocol = transport_server_registry.get()
4601
host, port = self.get_host_and_port(port)
4602
url = urlutils.local_path_to_url(directory)
4603
if not allow_writes:
4604
url = 'readonly+' + url
4605
transport = get_transport(url)
4606
protocol(transport, host, port, inet)
4609
class cmd_join(Command):
4610
"""Combine a tree into its containing tree.
4612
This command requires the target tree to be in a rich-root format.
4614
The TREE argument should be an independent tree, inside another tree, but
4615
not part of it. (Such trees can be produced by "bzr split", but also by
4616
running "bzr branch" with the target inside a tree.)
4618
The result is a combined tree, with the subtree no longer an independant
4619
part. This is marked as a merge of the subtree into the containing tree,
4620
and all history is preserved.
4623
_see_also = ['split']
4624
takes_args = ['tree']
4626
Option('reference', help='Join by reference.', hidden=True),
4629
def run(self, tree, reference=False):
4630
sub_tree = WorkingTree.open(tree)
4631
parent_dir = osutils.dirname(sub_tree.basedir)
4632
containing_tree = WorkingTree.open_containing(parent_dir)[0]
4633
repo = containing_tree.branch.repository
4634
if not repo.supports_rich_root():
4635
raise errors.BzrCommandError(
4636
"Can't join trees because %s doesn't support rich root data.\n"
4637
"You can use bzr upgrade on the repository."
4641
containing_tree.add_reference(sub_tree)
4642
except errors.BadReferenceTarget, e:
4643
# XXX: Would be better to just raise a nicely printable
4644
# exception from the real origin. Also below. mbp 20070306
4645
raise errors.BzrCommandError("Cannot join %s. %s" %
4649
containing_tree.subsume(sub_tree)
4650
except errors.BadSubsumeSource, e:
4651
raise errors.BzrCommandError("Cannot join %s. %s" %
4655
class cmd_split(Command):
4656
"""Split a subdirectory of a tree into a separate tree.
4658
This command will produce a target tree in a format that supports
4659
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4660
converted into earlier formats like 'dirstate-tags'.
4662
The TREE argument should be a subdirectory of a working tree. That
4663
subdirectory will be converted into an independent tree, with its own
4664
branch. Commits in the top-level tree will not apply to the new subtree.
4667
_see_also = ['join']
4668
takes_args = ['tree']
4670
def run(self, tree):
4671
containing_tree, subdir = WorkingTree.open_containing(tree)
4672
sub_id = containing_tree.path2id(subdir)
4674
raise errors.NotVersionedError(subdir)
4676
containing_tree.extract(sub_id)
4677
except errors.RootNotRich:
4678
raise errors.UpgradeRequired(containing_tree.branch.base)
4681
class cmd_merge_directive(Command):
4682
"""Generate a merge directive for auto-merge tools.
4684
A directive requests a merge to be performed, and also provides all the
4685
information necessary to do so. This means it must either include a
4686
revision bundle, or the location of a branch containing the desired
4689
A submit branch (the location to merge into) must be supplied the first
4690
time the command is issued. After it has been supplied once, it will
4691
be remembered as the default.
4693
A public branch is optional if a revision bundle is supplied, but required
4694
if --diff or --plain is specified. It will be remembered as the default
4695
after the first use.
4698
takes_args = ['submit_branch?', 'public_branch?']
4702
_see_also = ['send']
4705
RegistryOption.from_kwargs('patch-type',
4706
'The type of patch to include in the directive.',
4708
value_switches=True,
4710
bundle='Bazaar revision bundle (default).',
4711
diff='Normal unified diff.',
4712
plain='No patch, just directive.'),
4713
Option('sign', help='GPG-sign the directive.'), 'revision',
4714
Option('mail-to', type=str,
4715
help='Instead of printing the directive, email to this address.'),
4716
Option('message', type=str, short_name='m',
4717
help='Message to use when committing this merge.')
4720
encoding_type = 'exact'
4722
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
4723
sign=False, revision=None, mail_to=None, message=None):
4724
from bzrlib.revision import ensure_null, NULL_REVISION
4725
include_patch, include_bundle = {
4726
'plain': (False, False),
4727
'diff': (True, False),
4728
'bundle': (True, True),
4730
branch = Branch.open('.')
4731
stored_submit_branch = branch.get_submit_branch()
4732
if submit_branch is None:
4733
submit_branch = stored_submit_branch
4735
if stored_submit_branch is None:
4736
branch.set_submit_branch(submit_branch)
4737
if submit_branch is None:
4738
submit_branch = branch.get_parent()
4739
if submit_branch is None:
4740
raise errors.BzrCommandError('No submit branch specified or known')
4742
stored_public_branch = branch.get_public_branch()
4743
if public_branch is None:
4744
public_branch = stored_public_branch
4745
elif stored_public_branch is None:
4746
branch.set_public_branch(public_branch)
4747
if not include_bundle and public_branch is None:
4748
raise errors.BzrCommandError('No public branch specified or'
4750
base_revision_id = None
4751
if revision is not None:
4752
if len(revision) > 2:
4753
raise errors.BzrCommandError('bzr merge-directive takes '
4754
'at most two one revision identifiers')
4755
revision_id = revision[-1].as_revision_id(branch)
4756
if len(revision) == 2:
4757
base_revision_id = revision[0].as_revision_id(branch)
4759
revision_id = branch.last_revision()
4760
revision_id = ensure_null(revision_id)
4761
if revision_id == NULL_REVISION:
4762
raise errors.BzrCommandError('No revisions to bundle.')
4763
directive = merge_directive.MergeDirective2.from_objects(
4764
branch.repository, revision_id, time.time(),
4765
osutils.local_time_offset(), submit_branch,
4766
public_branch=public_branch, include_patch=include_patch,
4767
include_bundle=include_bundle, message=message,
4768
base_revision_id=base_revision_id)
4771
self.outf.write(directive.to_signed(branch))
4773
self.outf.writelines(directive.to_lines())
4775
message = directive.to_email(mail_to, branch, sign)
4776
s = SMTPConnection(branch.get_config())
4777
s.send_email(message)
4780
class cmd_send(Command):
4781
"""Mail or create a merge-directive for submitting changes.
4783
A merge directive provides many things needed for requesting merges:
4785
* A machine-readable description of the merge to perform
4787
* An optional patch that is a preview of the changes requested
4789
* An optional bundle of revision data, so that the changes can be applied
4790
directly from the merge directive, without retrieving data from a
4793
If --no-bundle is specified, then public_branch is needed (and must be
4794
up-to-date), so that the receiver can perform the merge using the
4795
public_branch. The public_branch is always included if known, so that
4796
people can check it later.
4798
The submit branch defaults to the parent, but can be overridden. Both
4799
submit branch and public branch will be remembered if supplied.
4801
If a public_branch is known for the submit_branch, that public submit
4802
branch is used in the merge instructions. This means that a local mirror
4803
can be used as your actual submit branch, once you have set public_branch
4806
Mail is sent using your preferred mail program. This should be transparent
4807
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4808
If the preferred client can't be found (or used), your editor will be used.
4810
To use a specific mail program, set the mail_client configuration option.
4811
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4812
specific clients are "claws", "evolution", "kmail", "mutt", and
4813
"thunderbird"; generic options are "default", "editor", "emacsclient",
4814
"mapi", and "xdg-email". Plugins may also add supported clients.
4816
If mail is being sent, a to address is required. This can be supplied
4817
either on the commandline, by setting the submit_to configuration
4818
option in the branch itself or the child_submit_to configuration option
4819
in the submit branch.
4821
Two formats are currently supported: "4" uses revision bundle format 4 and
4822
merge directive format 2. It is significantly faster and smaller than
4823
older formats. It is compatible with Bazaar 0.19 and later. It is the
4824
default. "0.9" uses revision bundle format 0.9 and merge directive
4825
format 1. It is compatible with Bazaar 0.12 - 0.18.
4827
The merge directives created by bzr send may be applied using bzr merge or
4828
bzr pull by specifying a file containing a merge directive as the location.
4831
encoding_type = 'exact'
4833
_see_also = ['merge', 'pull']
4835
takes_args = ['submit_branch?', 'public_branch?']
4839
help='Do not include a bundle in the merge directive.'),
4840
Option('no-patch', help='Do not include a preview patch in the merge'
4843
help='Remember submit and public branch.'),
4845
help='Branch to generate the submission from, '
4846
'rather than the one containing the working directory.',
4849
Option('output', short_name='o',
4850
help='Write merge directive to this file; '
4851
'use - for stdout.',
4853
Option('mail-to', help='Mail the request to this address.',
4857
Option('body', help='Body for the email.', type=unicode),
4858
RegistryOption('format',
4859
help='Use the specified output format.',
4860
lazy_registry=('bzrlib.send', 'format_registry'))
4863
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4864
no_patch=False, revision=None, remember=False, output=None,
4865
format=None, mail_to=None, message=None, body=None, **kwargs):
4866
from bzrlib.send import send
4867
return send(submit_branch, revision, public_branch, remember,
4868
format, no_bundle, no_patch, output,
4869
kwargs.get('from', '.'), mail_to, message, body,
4873
class cmd_bundle_revisions(cmd_send):
4874
"""Create a merge-directive for submitting changes.
4876
A merge directive provides many things needed for requesting merges:
4878
* A machine-readable description of the merge to perform
4880
* An optional patch that is a preview of the changes requested
4882
* An optional bundle of revision data, so that the changes can be applied
4883
directly from the merge directive, without retrieving data from a
4886
If --no-bundle is specified, then public_branch is needed (and must be
4887
up-to-date), so that the receiver can perform the merge using the
4888
public_branch. The public_branch is always included if known, so that
4889
people can check it later.
4891
The submit branch defaults to the parent, but can be overridden. Both
4892
submit branch and public branch will be remembered if supplied.
4894
If a public_branch is known for the submit_branch, that public submit
4895
branch is used in the merge instructions. This means that a local mirror
4896
can be used as your actual submit branch, once you have set public_branch
4899
Two formats are currently supported: "4" uses revision bundle format 4 and
4900
merge directive format 2. It is significantly faster and smaller than
4901
older formats. It is compatible with Bazaar 0.19 and later. It is the
4902
default. "0.9" uses revision bundle format 0.9 and merge directive
4903
format 1. It is compatible with Bazaar 0.12 - 0.18.
4908
help='Do not include a bundle in the merge directive.'),
4909
Option('no-patch', help='Do not include a preview patch in the merge'
4912
help='Remember submit and public branch.'),
4914
help='Branch to generate the submission from, '
4915
'rather than the one containing the working directory.',
4918
Option('output', short_name='o', help='Write directive to this file.',
4921
RegistryOption('format',
4922
help='Use the specified output format.',
4923
lazy_registry=('bzrlib.send', 'format_registry')),
4925
aliases = ['bundle']
4927
_see_also = ['send', 'merge']
4931
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4932
no_patch=False, revision=None, remember=False, output=None,
4933
format=None, **kwargs):
4936
from bzrlib.send import send
4937
return send(submit_branch, revision, public_branch, remember,
4938
format, no_bundle, no_patch, output,
4939
kwargs.get('from', '.'), None, None, None,
4943
class cmd_tag(Command):
4944
"""Create, remove or modify a tag naming a revision.
4946
Tags give human-meaningful names to revisions. Commands that take a -r
4947
(--revision) option can be given -rtag:X, where X is any previously
4950
Tags are stored in the branch. Tags are copied from one branch to another
4951
along when you branch, push, pull or merge.
4953
It is an error to give a tag name that already exists unless you pass
4954
--force, in which case the tag is moved to point to the new revision.
4956
To rename a tag (change the name but keep it on the same revsion), run ``bzr
4957
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
4960
_see_also = ['commit', 'tags']
4961
takes_args = ['tag_name']
4964
help='Delete this tag rather than placing it.',
4967
help='Branch in which to place the tag.',
4972
help='Replace existing tags.',
4977
def run(self, tag_name,
4983
branch, relpath = Branch.open_containing(directory)
4987
branch.tags.delete_tag(tag_name)
4988
self.outf.write('Deleted tag %s.\n' % tag_name)
4991
if len(revision) != 1:
4992
raise errors.BzrCommandError(
4993
"Tags can only be placed on a single revision, "
4995
revision_id = revision[0].as_revision_id(branch)
4997
revision_id = branch.last_revision()
4998
if (not force) and branch.tags.has_tag(tag_name):
4999
raise errors.TagAlreadyExists(tag_name)
5000
branch.tags.set_tag(tag_name, revision_id)
5001
self.outf.write('Created tag %s.\n' % tag_name)
5006
class cmd_tags(Command):
5009
This command shows a table of tag names and the revisions they reference.
5015
help='Branch whose tags should be displayed.',
5019
RegistryOption.from_kwargs('sort',
5020
'Sort tags by different criteria.', title='Sorting',
5021
alpha='Sort tags lexicographically (default).',
5022
time='Sort tags chronologically.',
5035
branch, relpath = Branch.open_containing(directory)
5037
tags = branch.tags.get_tag_dict().items()
5044
graph = branch.repository.get_graph()
5045
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5046
revid1, revid2 = rev1.rev_id, rev2.rev_id
5047
# only show revisions between revid1 and revid2 (inclusive)
5048
tags = [(tag, revid) for tag, revid in tags if
5049
graph.is_between(revid, revid1, revid2)]
5052
elif sort == 'time':
5054
for tag, revid in tags:
5056
revobj = branch.repository.get_revision(revid)
5057
except errors.NoSuchRevision:
5058
timestamp = sys.maxint # place them at the end
5060
timestamp = revobj.timestamp
5061
timestamps[revid] = timestamp
5062
tags.sort(key=lambda x: timestamps[x[1]])
5064
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5065
for index, (tag, revid) in enumerate(tags):
5067
revno = branch.revision_id_to_dotted_revno(revid)
5068
if isinstance(revno, tuple):
5069
revno = '.'.join(map(str, revno))
5070
except errors.NoSuchRevision:
5071
# Bad tag data/merges can lead to tagged revisions
5072
# which are not in this branch. Fail gracefully ...
5074
tags[index] = (tag, revno)
5077
for tag, revspec in tags:
5078
self.outf.write('%-20s %s\n' % (tag, revspec))
5081
class cmd_reconfigure(Command):
5082
"""Reconfigure the type of a bzr directory.
5084
A target configuration must be specified.
5086
For checkouts, the bind-to location will be auto-detected if not specified.
5087
The order of preference is
5088
1. For a lightweight checkout, the current bound location.
5089
2. For branches that used to be checkouts, the previously-bound location.
5090
3. The push location.
5091
4. The parent location.
5092
If none of these is available, --bind-to must be specified.
5095
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5096
takes_args = ['location?']
5098
RegistryOption.from_kwargs(
5100
title='Target type',
5101
help='The type to reconfigure the directory to.',
5102
value_switches=True, enum_switch=False,
5103
branch='Reconfigure to be an unbound branch with no working tree.',
5104
tree='Reconfigure to be an unbound branch with a working tree.',
5105
checkout='Reconfigure to be a bound branch with a working tree.',
5106
lightweight_checkout='Reconfigure to be a lightweight'
5107
' checkout (with no local history).',
5108
standalone='Reconfigure to be a standalone branch '
5109
'(i.e. stop using shared repository).',
5110
use_shared='Reconfigure to use a shared repository.',
5111
with_trees='Reconfigure repository to create '
5112
'working trees on branches by default.',
5113
with_no_trees='Reconfigure repository to not create '
5114
'working trees on branches by default.'
5116
Option('bind-to', help='Branch to bind checkout to.', type=str),
5118
help='Perform reconfiguration even if local changes'
5122
def run(self, location=None, target_type=None, bind_to=None, force=False):
5123
directory = bzrdir.BzrDir.open(location)
5124
if target_type is None:
5125
raise errors.BzrCommandError('No target configuration specified')
5126
elif target_type == 'branch':
5127
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5128
elif target_type == 'tree':
5129
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5130
elif target_type == 'checkout':
5131
reconfiguration = reconfigure.Reconfigure.to_checkout(
5133
elif target_type == 'lightweight-checkout':
5134
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5136
elif target_type == 'use-shared':
5137
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5138
elif target_type == 'standalone':
5139
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5140
elif target_type == 'with-trees':
5141
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5143
elif target_type == 'with-no-trees':
5144
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5146
reconfiguration.apply(force)
5149
class cmd_switch(Command):
5150
"""Set the branch of a checkout and update.
5152
For lightweight checkouts, this changes the branch being referenced.
5153
For heavyweight checkouts, this checks that there are no local commits
5154
versus the current bound branch, then it makes the local branch a mirror
5155
of the new location and binds to it.
5157
In both cases, the working tree is updated and uncommitted changes
5158
are merged. The user can commit or revert these as they desire.
5160
Pending merges need to be committed or reverted before using switch.
5162
The path to the branch to switch to can be specified relative to the parent
5163
directory of the current branch. For example, if you are currently in a
5164
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5167
Bound branches use the nickname of its master branch unless it is set
5168
locally, in which case switching will update the the local nickname to be
5172
takes_args = ['to_location']
5173
takes_options = [Option('force',
5174
help='Switch even if local commits will be lost.')
5177
def run(self, to_location, force=False):
5178
from bzrlib import switch
5180
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5182
branch = control_dir.open_branch()
5183
had_explicit_nick = branch.get_config().has_explicit_nickname()
5184
except errors.NotBranchError:
5185
had_explicit_nick = False
5187
to_branch = Branch.open(to_location)
5188
except errors.NotBranchError:
5189
this_url = self._get_branch_location(control_dir)
5190
to_branch = Branch.open(
5191
urlutils.join(this_url, '..', to_location))
5192
switch.switch(control_dir, to_branch, force)
5193
if had_explicit_nick:
5194
branch = control_dir.open_branch() #get the new branch!
5195
branch.nick = to_branch.nick
5196
note('Switched to branch: %s',
5197
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5199
def _get_branch_location(self, control_dir):
5200
"""Return location of branch for this control dir."""
5202
this_branch = control_dir.open_branch()
5203
# This may be a heavy checkout, where we want the master branch
5204
master_location = this_branch.get_bound_location()
5205
if master_location is not None:
5206
return master_location
5207
# If not, use a local sibling
5208
return this_branch.base
5209
except errors.NotBranchError:
5210
format = control_dir.find_branch_format()
5211
if getattr(format, 'get_reference', None) is not None:
5212
return format.get_reference(control_dir)
5214
return control_dir.root_transport.base
5217
class cmd_view(Command):
5218
"""Manage filtered views.
5220
Views provide a mask over the tree so that users can focus on
5221
a subset of a tree when doing their work. After creating a view,
5222
commands that support a list of files - status, diff, commit, etc -
5223
effectively have that list of files implicitly given each time.
5224
An explicit list of files can still be given but those files
5225
must be within the current view.
5227
In most cases, a view has a short life-span: it is created to make
5228
a selected change and is deleted once that change is committed.
5229
At other times, you may wish to create one or more named views
5230
and switch between them.
5232
To disable the current view without deleting it, you can switch to
5233
the pseudo view called ``off``. This can be useful when you need
5234
to see the whole tree for an operation or two (e.g. merge) but
5235
want to switch back to your view after that.
5238
To define the current view::
5240
bzr view file1 dir1 ...
5242
To list the current view::
5246
To delete the current view::
5250
To disable the current view without deleting it::
5252
bzr view --switch off
5254
To define a named view and switch to it::
5256
bzr view --name view-name file1 dir1 ...
5258
To list a named view::
5260
bzr view --name view-name
5262
To delete a named view::
5264
bzr view --name view-name --delete
5266
To switch to a named view::
5268
bzr view --switch view-name
5270
To list all views defined::
5274
To delete all views::
5276
bzr view --delete --all
5280
takes_args = ['file*']
5283
help='Apply list or delete action to all views.',
5286
help='Delete the view.',
5289
help='Name of the view to define, list or delete.',
5293
help='Name of the view to switch to.',
5298
def run(self, file_list,
5304
tree, file_list = tree_files(file_list, apply_view=False)
5305
current_view, view_dict = tree.views.get_view_info()
5310
raise errors.BzrCommandError(
5311
"Both --delete and a file list specified")
5313
raise errors.BzrCommandError(
5314
"Both --delete and --switch specified")
5316
tree.views.set_view_info(None, {})
5317
self.outf.write("Deleted all views.\n")
5319
raise errors.BzrCommandError("No current view to delete")
5321
tree.views.delete_view(name)
5322
self.outf.write("Deleted '%s' view.\n" % name)
5325
raise errors.BzrCommandError(
5326
"Both --switch and a file list specified")
5328
raise errors.BzrCommandError(
5329
"Both --switch and --all specified")
5330
elif switch == 'off':
5331
if current_view is None:
5332
raise errors.BzrCommandError("No current view to disable")
5333
tree.views.set_view_info(None, view_dict)
5334
self.outf.write("Disabled '%s' view.\n" % (current_view))
5336
tree.views.set_view_info(switch, view_dict)
5337
view_str = views.view_display_str(tree.views.lookup_view())
5338
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5341
self.outf.write('Views defined:\n')
5342
for view in sorted(view_dict):
5343
if view == current_view:
5347
view_str = views.view_display_str(view_dict[view])
5348
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5350
self.outf.write('No views defined.\n')
5353
# No name given and no current view set
5356
raise errors.BzrCommandError(
5357
"Cannot change the 'off' pseudo view")
5358
tree.views.set_view(name, sorted(file_list))
5359
view_str = views.view_display_str(tree.views.lookup_view())
5360
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5364
# No name given and no current view set
5365
self.outf.write('No current view.\n')
5367
view_str = views.view_display_str(tree.views.lookup_view(name))
5368
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5371
class cmd_hooks(Command):
5377
for hook_key in sorted(hooks.known_hooks.keys()):
5378
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5379
self.outf.write("%s:\n" % type(some_hooks).__name__)
5380
for hook_name, hook_point in sorted(some_hooks.items()):
5381
self.outf.write(" %s:\n" % (hook_name,))
5382
found_hooks = list(hook_point)
5384
for hook in found_hooks:
5385
self.outf.write(" %s\n" %
5386
(some_hooks.get_hook_name(hook),))
5388
self.outf.write(" <no hooks installed>\n")
5391
class cmd_shelve(Command):
5392
"""Temporarily set aside some changes from the current tree.
5394
Shelve allows you to temporarily put changes you've made "on the shelf",
5395
ie. out of the way, until a later time when you can bring them back from
5396
the shelf with the 'unshelve' command. The changes are stored alongside
5397
your working tree, and so they aren't propagated along with your branch nor
5398
will they survive its deletion.
5400
If shelve --list is specified, previously-shelved changes are listed.
5402
Shelve is intended to help separate several sets of changes that have
5403
been inappropriately mingled. If you just want to get rid of all changes
5404
and you don't need to restore them later, use revert. If you want to
5405
shelve all text changes at once, use shelve --all.
5407
If filenames are specified, only the changes to those files will be
5408
shelved. Other files will be left untouched.
5410
If a revision is specified, changes since that revision will be shelved.
5412
You can put multiple items on the shelf, and by default, 'unshelve' will
5413
restore the most recently shelved changes.
5416
takes_args = ['file*']
5420
Option('all', help='Shelve all changes.'),
5422
RegistryOption('writer', 'Method to use for writing diffs.',
5423
bzrlib.option.diff_writer_registry,
5424
value_switches=True, enum_switch=False),
5426
Option('list', help='List shelved changes.'),
5428
help='Destroy removed changes instead of shelving them.'),
5430
_see_also = ['unshelve']
5432
def run(self, revision=None, all=False, file_list=None, message=None,
5433
writer=None, list=False, destroy=False):
5435
return self.run_for_list()
5436
from bzrlib.shelf_ui import Shelver
5438
writer = bzrlib.option.diff_writer_registry.get()
5440
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5441
message, destroy=destroy).run()
5442
except errors.UserAbort:
5445
def run_for_list(self):
5446
tree = WorkingTree.open_containing('.')[0]
5449
manager = tree.get_shelf_manager()
5450
shelves = manager.active_shelves()
5451
if len(shelves) == 0:
5452
note('No shelved changes.')
5454
for shelf_id in reversed(shelves):
5455
message = manager.get_metadata(shelf_id).get('message')
5457
message = '<no message>'
5458
self.outf.write('%3d: %s\n' % (shelf_id, message))
5464
class cmd_unshelve(Command):
5465
"""Restore shelved changes.
5467
By default, the most recently shelved changes are restored. However if you
5468
specify a shelf by id those changes will be restored instead. This works
5469
best when the changes don't depend on each other.
5472
takes_args = ['shelf_id?']
5474
RegistryOption.from_kwargs(
5475
'action', help="The action to perform.",
5476
enum_switch=False, value_switches=True,
5477
apply="Apply changes and remove from the shelf.",
5478
dry_run="Show changes, but do not apply or remove them.",
5479
delete_only="Delete changes without applying them."
5482
_see_also = ['shelve']
5484
def run(self, shelf_id=None, action='apply'):
5485
from bzrlib.shelf_ui import Unshelver
5486
Unshelver.from_args(shelf_id, action).run()
5489
class cmd_clean_tree(Command):
5490
"""Remove unwanted files from working tree.
5492
By default, only unknown files, not ignored files, are deleted. Versioned
5493
files are never deleted.
5495
Another class is 'detritus', which includes files emitted by bzr during
5496
normal operations and selftests. (The value of these files decreases with
5499
If no options are specified, unknown files are deleted. Otherwise, option
5500
flags are respected, and may be combined.
5502
To check what clean-tree will do, use --dry-run.
5504
takes_options = [Option('ignored', help='Delete all ignored files.'),
5505
Option('detritus', help='Delete conflict files, merge'
5506
' backups, and failed selftest dirs.'),
5508
help='Delete files unknown to bzr (default).'),
5509
Option('dry-run', help='Show files to delete instead of'
5511
Option('force', help='Do not prompt before deleting.')]
5512
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5514
from bzrlib.clean_tree import clean_tree
5515
if not (unknown or ignored or detritus):
5519
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5520
dry_run=dry_run, no_prompt=force)
5523
class cmd_reference(Command):
5524
"""list, view and set branch locations for nested trees.
5526
If no arguments are provided, lists the branch locations for nested trees.
5527
If one argument is provided, display the branch location for that tree.
5528
If two arguments are provided, set the branch location for that tree.
5533
takes_args = ['path?', 'location?']
5535
def run(self, path=None, location=None):
5537
if path is not None:
5539
tree, branch, relpath =(
5540
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5541
if path is not None:
5544
tree = branch.basis_tree()
5546
info = branch._get_all_reference_info().iteritems()
5547
self._display_reference_info(tree, branch, info)
5549
file_id = tree.path2id(path)
5551
raise errors.NotVersionedError(path)
5552
if location is None:
5553
info = [(file_id, branch.get_reference_info(file_id))]
5554
self._display_reference_info(tree, branch, info)
5556
branch.set_reference_info(file_id, path, location)
5558
def _display_reference_info(self, tree, branch, info):
5560
for file_id, (path, location) in info:
5562
path = tree.id2path(file_id)
5563
except errors.NoSuchId:
5565
ref_list.append((path, location))
5566
for path, location in sorted(ref_list):
5567
self.outf.write('%s %s\n' % (path, location))
5570
# these get imported and then picked up by the scan for cmd_*
5571
# TODO: Some more consistent way to split command definitions across files;
5572
# we do need to load at least some information about them to know of
5573
# aliases. ideally we would avoid loading the implementation until the
5574
# details were needed.
5575
from bzrlib.cmd_version_info import cmd_version_info
5576
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5577
from bzrlib.bundle.commands import (
5580
from bzrlib.foreign import cmd_dpush
5581
from bzrlib.sign_my_commits import cmd_sign_my_commits
5582
from bzrlib.weave_commands import cmd_versionedfile_list, \
5583
cmd_weave_plan_merge, cmd_weave_merge_text