13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""builtin bzr commands"""
20
from StringIO import StringIO
22
23
from bzrlib.lazy_import import lazy_import
23
24
lazy_import(globals(), """
31
31
from bzrlib import (
38
config as _mod_config,
42
43
merge as _mod_merge,
48
revision as _mod_revision,
54
57
from bzrlib.branch import Branch
55
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
56
58
from bzrlib.conflicts import ConflictList
57
from bzrlib.revisionspec import RevisionSpec
59
from bzrlib.transport import memory
60
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
61
from bzrlib.smtp_connection import SMTPConnection
59
62
from bzrlib.workingtree import WorkingTree
63
from bzrlib.i18n import gettext, ngettext
62
from bzrlib.commands import Command, display_command
63
from bzrlib.option import ListOption, Option, RegistryOption
64
from bzrlib.progress import DummyProgress, ProgressPhase
65
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
68
def tree_files(file_list, default_branch=u'.'):
70
return internal_tree_files(file_list, default_branch)
71
except errors.FileInWrongBranch, e:
72
raise errors.BzrCommandError("%s is not in the same branch as %s" %
73
(e.path, file_list[0]))
66
from bzrlib.commands import (
68
builtin_command_registry,
71
from bzrlib.option import (
78
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
84
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
85
def tree_files(file_list, default_branch=u'.', canonicalize=True,
87
return internal_tree_files(file_list, default_branch, canonicalize,
91
def tree_files_for_add(file_list):
93
Return a tree and list of absolute paths from a file list.
95
Similar to tree_files, but add handles files a bit differently, so it a
96
custom implementation. In particular, MutableTreeTree.smart_add expects
97
absolute paths, which it immediately converts to relative paths.
99
# FIXME Would be nice to just return the relative paths like
100
# internal_tree_files does, but there are a large number of unit tests
101
# that assume the current interface to mutabletree.smart_add
103
tree, relpath = WorkingTree.open_containing(file_list[0])
104
if tree.supports_views():
105
view_files = tree.views.lookup_view()
107
for filename in file_list:
108
if not osutils.is_inside_any(view_files, filename):
109
raise errors.FileOutsideView(filename, view_files)
110
file_list = file_list[:]
111
file_list[0] = tree.abspath(relpath)
113
tree = WorkingTree.open_containing(u'.')[0]
114
if tree.supports_views():
115
view_files = tree.views.lookup_view()
117
file_list = view_files
118
view_str = views.view_display_str(view_files)
119
note(gettext("Ignoring files outside view. View is %s") % view_str)
120
return tree, file_list
123
def _get_one_revision(command_name, revisions):
124
if revisions is None:
126
if len(revisions) != 1:
127
raise errors.BzrCommandError(gettext(
128
'bzr %s --revision takes exactly one revision identifier') % (
133
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
134
"""Get a revision tree. Not suitable for commands that change the tree.
136
Specifically, the basis tree in dirstate trees is coupled to the dirstate
137
and doing a commit/uncommit/pull will at best fail due to changing the
140
If tree is passed in, it should be already locked, for lifetime management
141
of the trees internal cached state.
145
if revisions is None:
147
rev_tree = tree.basis_tree()
149
rev_tree = branch.basis_tree()
151
revision = _get_one_revision(command_name, revisions)
152
rev_tree = revision.as_tree(branch)
76
156
# XXX: Bad function name; should possibly also be a class method of
77
157
# WorkingTree rather than a function.
78
def internal_tree_files(file_list, default_branch=u'.'):
158
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
159
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
79
161
"""Convert command-line paths to a WorkingTree and relative paths.
163
Deprecated: use WorkingTree.open_containing_paths instead.
81
165
This is typically used for command-line processors that take one or
82
166
more filenames, and infer the workingtree that contains them.
84
168
The filenames given are not required to exist.
86
:param file_list: Filenames to convert.
170
:param file_list: Filenames to convert.
88
172
:param default_branch: Fallback tree path to use if file_list is empty or
175
:param apply_view: if True and a view is set, apply it or check that
176
specified files are within it
91
178
:return: workingtree, [relative_paths]
93
if file_list is None or len(file_list) == 0:
94
return WorkingTree.open_containing(default_branch)[0], file_list
95
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
97
for filename in file_list:
99
new_list.append(tree.relpath(osutils.dereference_path(filename)))
100
except errors.PathNotChild:
101
raise errors.FileInWrongBranch(tree.branch, filename)
102
return tree, new_list
105
@symbol_versioning.deprecated_function(symbol_versioning.zero_fifteen)
106
def get_format_type(typestring):
107
"""Parse and return a format specifier."""
108
# Have to use BzrDirMetaFormat1 directly, so that
109
# RepositoryFormat.set_default_format works
110
if typestring == "default":
111
return bzrdir.BzrDirMetaFormat1()
180
return WorkingTree.open_containing_paths(
181
file_list, default_directory='.',
186
def _get_view_info_for_change_reporter(tree):
187
"""Get the view information from a tree for change reporting."""
113
return bzrdir.format_registry.make_bzrdir(typestring)
115
msg = 'Unknown bzr format "%s". See "bzr help formats".' % typestring
116
raise errors.BzrCommandError(msg)
190
current_view = tree.views.get_view_info()[0]
191
if current_view is not None:
192
view_info = (current_view, tree.views.lookup_view())
193
except errors.ViewsNotSupported:
198
def _open_directory_or_containing_tree_or_branch(filename, directory):
199
"""Open the tree or branch containing the specified file, unless
200
the --directory option is used to specify a different branch."""
201
if directory is not None:
202
return (None, Branch.open(directory), filename)
203
return controldir.ControlDir.open_containing_tree_or_branch(filename)
119
206
# TODO: Make sure no commands unconditionally use the working directory as a
150
237
Not versioned and not matching an ignore pattern.
239
Additionally for directories, symlinks and files with a changed
240
executable bit, Bazaar indicates their type using a trailing
241
character: '/', '@' or '*' respectively. These decorations can be
242
disabled using the '--no-classify' option.
152
244
To see ignored files use 'bzr ignored'. For details on the
153
245
changes to file texts, use 'bzr diff'.
155
--short gives a status flags for each item, similar to the SVN's status
158
Column 1: versioning / renames
164
P Entry for a pending merge (not a file)
173
* The execute bit was changed
247
Note that --short or -S gives status flags for each item, similar
248
to Subversion's status command. To get output similar to svn -q,
175
251
If no arguments are specified, the status of the entire working
176
252
directory is shown. Otherwise, only the status of the specified
177
253
files or directories is reported. If a directory is given, status
178
254
is reported for everything inside that directory.
180
If a revision argument is given, the status is calculated against
181
that revision, or between two revisions if two are provided.
256
Before merges are committed, the pending merge tip revisions are
257
shown. To see all pending merge revisions, use the -v option.
258
To skip the display of pending merge information altogether, use
259
the no-pending option or specify a file/directory.
261
To compare the working directory to a specific revision, pass a
262
single revision to the revision argument.
264
To see which files have changed in a specific revision, or between
265
two revisions, pass a revision range to the revision argument.
266
This will produce the same results as calling 'bzr diff --summarize'.
184
269
# TODO: --no-recurse, --recurse options
186
271
takes_args = ['file*']
187
takes_options = ['show-ids', 'revision',
188
Option('short', help='Give short SVN-style status lines'),
189
Option('versioned', help='Only show versioned files')]
272
takes_options = ['show-ids', 'revision', 'change', 'verbose',
273
Option('short', help='Use short status indicators.',
275
Option('versioned', help='Only show versioned files.',
277
Option('no-pending', help='Don\'t show pending merges.',
279
Option('no-classify',
280
help='Do not mark object type using indicator.',
190
283
aliases = ['st', 'stat']
192
285
encoding_type = 'replace'
193
_see_also = ['diff', 'revert']
286
_see_also = ['diff', 'revert', 'status-flags']
196
289
def run(self, show_ids=False, file_list=None, revision=None, short=False,
290
versioned=False, no_pending=False, verbose=False,
198
292
from bzrlib.status import show_tree_status
200
tree, file_list = tree_files(file_list)
294
if revision and len(revision) > 2:
295
raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
296
' one or two revision specifiers'))
298
tree, relfile_list = WorkingTree.open_containing_paths(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:
202
308
show_tree_status(tree, show_ids=show_ids,
203
specific_files=file_list, revision=revision,
204
to_file=self.outf, short=short, versioned=versioned)
309
specific_files=relfile_list, revision=revision,
310
to_file=self.outf, short=short, versioned=versioned,
311
show_pending=(not no_pending), verbose=verbose,
312
classify=not no_classify)
207
315
class cmd_cat_revision(Command):
208
"""Write out metadata for a revision.
316
__doc__ = """Write out metadata for a revision.
210
318
The revision to print can either be specified by a specific
211
319
revision identifier, or you can use --revision.
215
323
takes_args = ['revision_id?']
216
takes_options = ['revision']
324
takes_options = ['directory', 'revision']
217
325
# cat-revision is more for frontends so should be exact
218
326
encoding = 'strict'
328
def print_revision(self, revisions, revid):
329
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
330
record = stream.next()
331
if record.storage_kind == 'absent':
332
raise errors.NoSuchRevision(revisions, revid)
333
revtext = record.get_bytes_as('fulltext')
334
self.outf.write(revtext.decode('utf-8'))
221
def run(self, revision_id=None, revision=None):
223
revision_id = osutils.safe_revision_id(revision_id, warn=False)
337
def run(self, revision_id=None, revision=None, directory=u'.'):
224
338
if revision_id is not None and revision is not None:
225
raise errors.BzrCommandError('You can only supply one of'
226
' revision_id or --revision')
339
raise errors.BzrCommandError(gettext('You can only supply one of'
340
' revision_id or --revision'))
227
341
if revision_id is None and revision is None:
228
raise errors.BzrCommandError('You must supply either'
229
' --revision or a revision_id')
230
b = WorkingTree.open_containing(u'.')[0].branch
232
# TODO: jam 20060112 should cat-revision always output utf-8?
233
if revision_id is not None:
234
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
235
elif revision is not None:
238
raise errors.BzrCommandError('You cannot specify a NULL'
240
revno, rev_id = rev.in_history(b)
241
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
342
raise errors.BzrCommandError(gettext('You must supply either'
343
' --revision or a revision_id'))
345
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
347
revisions = b.repository.revisions
348
if revisions is None:
349
raise errors.BzrCommandError(gettext('Repository %r does not support '
350
'access to raw revision texts'))
352
b.repository.lock_read()
354
# TODO: jam 20060112 should cat-revision always output utf-8?
355
if revision_id is not None:
356
revision_id = osutils.safe_revision_id(revision_id, warn=False)
358
self.print_revision(revisions, revision_id)
359
except errors.NoSuchRevision:
360
msg = gettext("The repository {0} contains no revision {1}.").format(
361
b.repository.base, revision_id)
362
raise errors.BzrCommandError(msg)
363
elif revision is not None:
366
raise errors.BzrCommandError(
367
gettext('You cannot specify a NULL revision.'))
368
rev_id = rev.as_revision_id(b)
369
self.print_revision(revisions, rev_id)
371
b.repository.unlock()
374
class cmd_dump_btree(Command):
375
__doc__ = """Dump the contents of a btree index file to stdout.
377
PATH is a btree index file, it can be any URL. This includes things like
378
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
380
By default, the tuples stored in the index file will be displayed. With
381
--raw, we will uncompress the pages, but otherwise display the raw bytes
385
# TODO: Do we want to dump the internal nodes as well?
386
# TODO: It would be nice to be able to dump the un-parsed information,
387
# rather than only going through iter_all_entries. However, this is
388
# good enough for a start
390
encoding_type = 'exact'
391
takes_args = ['path']
392
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
393
' rather than the parsed tuples.'),
396
def run(self, path, raw=False):
397
dirname, basename = osutils.split(path)
398
t = transport.get_transport(dirname)
400
self._dump_raw_bytes(t, basename)
402
self._dump_entries(t, basename)
404
def _get_index_and_bytes(self, trans, basename):
405
"""Create a BTreeGraphIndex and raw bytes."""
406
bt = btree_index.BTreeGraphIndex(trans, basename, None)
407
bytes = trans.get_bytes(basename)
408
bt._file = cStringIO.StringIO(bytes)
409
bt._size = len(bytes)
412
def _dump_raw_bytes(self, trans, basename):
415
# We need to parse at least the root node.
416
# This is because the first page of every row starts with an
417
# uncompressed header.
418
bt, bytes = self._get_index_and_bytes(trans, basename)
419
for page_idx, page_start in enumerate(xrange(0, len(bytes),
420
btree_index._PAGE_SIZE)):
421
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
422
page_bytes = bytes[page_start:page_end]
424
self.outf.write('Root node:\n')
425
header_end, data = bt._parse_header_from_bytes(page_bytes)
426
self.outf.write(page_bytes[:header_end])
428
self.outf.write('\nPage %d\n' % (page_idx,))
429
if len(page_bytes) == 0:
430
self.outf.write('(empty)\n');
432
decomp_bytes = zlib.decompress(page_bytes)
433
self.outf.write(decomp_bytes)
434
self.outf.write('\n')
436
def _dump_entries(self, trans, basename):
438
st = trans.stat(basename)
439
except errors.TransportNotPossible:
440
# We can't stat, so we'll fake it because we have to do the 'get()'
442
bt, _ = self._get_index_and_bytes(trans, basename)
444
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
445
for node in bt.iter_all_entries():
446
# Node is made up of:
447
# (index, key, value, [references])
451
refs_as_tuples = None
453
refs_as_tuples = static_tuple.as_tuples(refs)
454
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
455
self.outf.write('%s\n' % (as_tuple,))
244
458
class cmd_remove_tree(Command):
245
"""Remove the working tree from a given branch/checkout.
459
__doc__ = """Remove the working tree from a given branch/checkout.
247
461
Since a lightweight checkout is little more than a working tree
248
462
this will refuse to run against one.
250
464
To re-create the working tree, use "bzr checkout".
252
466
_see_also = ['checkout', 'working-trees']
254
takes_args = ['location?']
256
def run(self, location='.'):
257
d = bzrdir.BzrDir.open(location)
467
takes_args = ['location*']
470
help='Remove the working tree even if it has '
471
'uncommitted or shelved changes.'),
474
def run(self, location_list, force=False):
475
if not location_list:
478
for location in location_list:
479
d = controldir.ControlDir.open(location)
482
working = d.open_workingtree()
483
except errors.NoWorkingTree:
484
raise errors.BzrCommandError(gettext("No working tree to remove"))
485
except errors.NotLocalUrl:
486
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
487
" of a remote path"))
489
if (working.has_changes()):
490
raise errors.UncommittedChanges(working)
491
if working.get_shelf_manager().last_shelf() is not None:
492
raise errors.ShelvedChanges(working)
494
if working.user_url != working.branch.user_url:
495
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
496
" from a lightweight checkout"))
498
d.destroy_workingtree()
501
class cmd_repair_workingtree(Command):
502
__doc__ = """Reset the working tree state file.
504
This is not meant to be used normally, but more as a way to recover from
505
filesystem corruption, etc. This rebuilds the working inventory back to a
506
'known good' state. Any new modifications (adding a file, renaming, etc)
507
will be lost, though modified files will still be detected as such.
509
Most users will want something more like "bzr revert" or "bzr update"
510
unless the state file has become corrupted.
512
By default this attempts to recover the current state by looking at the
513
headers of the state file. If the state file is too corrupted to even do
514
that, you can supply --revision to force the state of the tree.
517
takes_options = ['revision', 'directory',
519
help='Reset the tree even if it doesn\'t appear to be'
524
def run(self, revision=None, directory='.', force=False):
525
tree, _ = WorkingTree.open_containing(directory)
526
self.add_cleanup(tree.lock_tree_write().unlock)
530
except errors.BzrError:
531
pass # There seems to be a real error here, so we'll reset
534
raise errors.BzrCommandError(gettext(
535
'The tree does not appear to be corrupt. You probably'
536
' want "bzr revert" instead. Use "--force" if you are'
537
' sure you want to reset the working tree.'))
541
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
260
working = d.open_workingtree()
261
except errors.NoWorkingTree:
262
raise errors.BzrCommandError("No working tree to remove")
263
except errors.NotLocalUrl:
264
raise errors.BzrCommandError("You cannot remove the working tree of a "
267
working_path = working.bzrdir.root_transport.base
268
branch_path = working.branch.bzrdir.root_transport.base
269
if working_path != branch_path:
270
raise errors.BzrCommandError("You cannot remove the working tree from "
271
"a lightweight checkout")
273
d.destroy_workingtree()
543
tree.reset_state(revision_ids)
544
except errors.BzrError, e:
545
if revision_ids is None:
546
extra = (gettext(', the header appears corrupt, try passing -r -1'
547
' to set the state to the last commit'))
550
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
276
553
class cmd_revno(Command):
277
"""Show current revision number.
554
__doc__ = """Show current revision number.
279
556
This is equal to the number of revisions on this branch.
282
559
_see_also = ['info']
283
560
takes_args = ['location?']
562
Option('tree', help='Show revno of working tree.'),
286
def run(self, location=u'.'):
287
self.outf.write(str(Branch.open_containing(location)[0].revno()))
288
self.outf.write('\n')
567
def run(self, tree=False, location=u'.', revision=None):
568
if revision is not None and tree:
569
raise errors.BzrCommandError(gettext("--tree and --revision can "
570
"not be used together"))
574
wt = WorkingTree.open_containing(location)[0]
575
self.add_cleanup(wt.lock_read().unlock)
576
except (errors.NoWorkingTree, errors.NotLocalUrl):
577
raise errors.NoWorkingTree(location)
579
revid = wt.last_revision()
581
b = Branch.open_containing(location)[0]
582
self.add_cleanup(b.lock_read().unlock)
584
if len(revision) != 1:
585
raise errors.BzrCommandError(gettext(
586
"Tags can only be placed on a single revision, "
588
revid = revision[0].as_revision_id(b)
590
revid = b.last_revision()
592
revno_t = b.revision_id_to_dotted_revno(revid)
593
except errors.NoSuchRevision:
595
revno = ".".join(str(n) for n in revno_t)
597
self.outf.write(revno + '\n')
291
600
class cmd_revision_info(Command):
292
"""Show revision number and revision id for a given revision identifier.
601
__doc__ = """Show revision number and revision id for a given revision identifier.
295
604
takes_args = ['revision_info*']
296
takes_options = ['revision']
607
custom_help('directory',
608
help='Branch to examine, '
609
'rather than the one containing the working directory.'),
610
Option('tree', help='Show revno of working tree.'),
299
def run(self, revision=None, revision_info_list=[]):
614
def run(self, revision=None, directory=u'.', tree=False,
615
revision_info_list=[]):
618
wt = WorkingTree.open_containing(directory)[0]
620
self.add_cleanup(wt.lock_read().unlock)
621
except (errors.NoWorkingTree, errors.NotLocalUrl):
623
b = Branch.open_containing(directory)[0]
624
self.add_cleanup(b.lock_read().unlock)
302
626
if revision is not None:
303
revs.extend(revision)
627
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
304
628
if revision_info_list is not None:
305
for rev in revision_info_list:
306
revs.append(RevisionSpec.from_string(rev))
308
b = Branch.open_containing(u'.')[0]
311
revs.append(RevisionSpec.from_string('-1'))
314
revinfo = rev.in_history(b)
315
if revinfo.revno is None:
316
dotted_map = b.get_revision_id_to_revno_map()
317
revno = '.'.join(str(i) for i in dotted_map[revinfo.rev_id])
318
print '%s %s' % (revno, revinfo.rev_id)
629
for rev_str in revision_info_list:
630
rev_spec = RevisionSpec.from_string(rev_str)
631
revision_ids.append(rev_spec.as_revision_id(b))
632
# No arguments supplied, default to the last revision
633
if len(revision_ids) == 0:
636
raise errors.NoWorkingTree(directory)
637
revision_ids.append(wt.last_revision())
320
print '%4d %s' % (revinfo.revno, revinfo.rev_id)
639
revision_ids.append(b.last_revision())
643
for revision_id in revision_ids:
645
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
646
revno = '.'.join(str(i) for i in dotted_revno)
647
except errors.NoSuchRevision:
649
maxlen = max(maxlen, len(revno))
650
revinfos.append([revno, revision_id])
654
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
323
657
class cmd_add(Command):
324
"""Add specified files or directories.
658
__doc__ = """Add specified files or directories.
326
660
In non-recursive mode, all the named items are added, regardless
327
661
of whether they were previously ignored. A warning is given if
520
893
takes_args = ['names*']
521
takes_options = [Option("after", help="move only the bzr identifier"
522
" of the file (file has already been moved). Use this flag if"
523
" bzr is not able to detect this itself.")]
894
takes_options = [Option("after", help="Move only the bzr identifier"
895
" of the file, because the file has already been moved."),
896
Option('auto', help='Automatically guess renames.'),
897
Option('dry-run', help='Avoid making changes when guessing renames.'),
524
899
aliases = ['move', 'rename']
525
900
encoding_type = 'replace'
527
def run(self, names_list, after=False):
902
def run(self, names_list, after=False, auto=False, dry_run=False):
904
return self.run_auto(names_list, after, dry_run)
906
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
528
907
if names_list is None:
531
909
if len(names_list) < 2:
532
raise errors.BzrCommandError("missing file argument")
533
tree, rel_names = tree_files(names_list)
535
if os.path.isdir(names_list[-1]):
910
raise errors.BzrCommandError(gettext("missing file argument"))
911
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
912
for file_name in rel_names[0:-1]:
914
raise errors.BzrCommandError(gettext("can not move root of branch"))
915
self.add_cleanup(tree.lock_tree_write().unlock)
916
self._run(tree, names_list, rel_names, after)
918
def run_auto(self, names_list, after, dry_run):
919
if names_list is not None and len(names_list) > 1:
920
raise errors.BzrCommandError(gettext('Only one path may be specified to'
923
raise errors.BzrCommandError(gettext('--after cannot be specified with'
925
work_tree, file_list = WorkingTree.open_containing_paths(
926
names_list, default_directory='.')
927
self.add_cleanup(work_tree.lock_tree_write().unlock)
928
rename_map.RenameMap.guess_renames(work_tree, dry_run)
930
def _run(self, tree, names_list, rel_names, after):
931
into_existing = osutils.isdir(names_list[-1])
932
if into_existing and len(names_list) == 2:
934
# a. case-insensitive filesystem and change case of dir
935
# b. move directory after the fact (if the source used to be
936
# a directory, but now doesn't exist in the working tree
937
# and the target is an existing directory, just rename it)
938
if (not tree.case_sensitive
939
and rel_names[0].lower() == rel_names[1].lower()):
940
into_existing = False
943
# 'fix' the case of a potential 'from'
944
from_id = tree.path2id(
945
tree.get_canonical_inventory_path(rel_names[0]))
946
if (not osutils.lexists(names_list[0]) and
947
from_id and inv.get_file_kind(from_id) == "directory"):
948
into_existing = False
536
951
# move into existing directory
537
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
538
self.outf.write("%s => %s\n" % pair)
952
# All entries reference existing inventory items, so fix them up
953
# for cicp file-systems.
954
rel_names = tree.get_canonical_inventory_paths(rel_names)
955
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
957
self.outf.write("%s => %s\n" % (src, dest))
540
959
if len(names_list) != 2:
541
raise errors.BzrCommandError('to mv multiple files the'
960
raise errors.BzrCommandError(gettext('to mv multiple files the'
542
961
' destination must be a versioned'
544
tree.rename_one(rel_names[0], rel_names[1], after=after)
545
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
964
# for cicp file-systems: the src references an existing inventory
966
src = tree.get_canonical_inventory_path(rel_names[0])
967
# Find the canonical version of the destination: In all cases, the
968
# parent of the target must be in the inventory, so we fetch the
969
# canonical version from there (we do not always *use* the
970
# canonicalized tail portion - we may be attempting to rename the
972
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
973
dest_parent = osutils.dirname(canon_dest)
974
spec_tail = osutils.basename(rel_names[1])
975
# For a CICP file-system, we need to avoid creating 2 inventory
976
# entries that differ only by case. So regardless of the case
977
# we *want* to use (ie, specified by the user or the file-system),
978
# we must always choose to use the case of any existing inventory
979
# items. The only exception to this is when we are attempting a
980
# case-only rename (ie, canonical versions of src and dest are
982
dest_id = tree.path2id(canon_dest)
983
if dest_id is None or tree.path2id(src) == dest_id:
984
# No existing item we care about, so work out what case we
985
# are actually going to use.
987
# If 'after' is specified, the tail must refer to a file on disk.
989
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
991
# pathjoin with an empty tail adds a slash, which breaks
993
dest_parent_fq = tree.basedir
995
dest_tail = osutils.canonical_relpath(
997
osutils.pathjoin(dest_parent_fq, spec_tail))
999
# not 'after', so case as specified is used
1000
dest_tail = spec_tail
1002
# Use the existing item so 'mv' fails with AlreadyVersioned.
1003
dest_tail = os.path.basename(canon_dest)
1004
dest = osutils.pathjoin(dest_parent, dest_tail)
1005
mutter("attempting to move %s => %s", src, dest)
1006
tree.rename_one(src, dest, after=after)
1008
self.outf.write("%s => %s\n" % (src, dest))
548
1011
class cmd_pull(Command):
549
"""Turn this branch into a mirror of another branch.
1012
__doc__ = """Turn this branch into a mirror of another branch.
551
This command only works on branches that have not diverged. Branches are
552
considered diverged if the destination branch's most recent commit is one
553
that has not been merged (directly or indirectly) into the parent.
1014
By default, this command only works on branches that have not diverged.
1015
Branches are considered diverged if the destination branch's most recent
1016
commit is one that has not been merged (directly or indirectly) into the
555
1019
If branches have diverged, you can use 'bzr merge' to integrate the changes
556
1020
from one into the other. Once one branch has merged, the other should
557
1021
be able to pull it again.
559
If you want to forget your local changes and just update your branch to
560
match the remote one, use pull --overwrite.
562
If there is no default location set, the first pull will set it. After
563
that, you can omit the location to use the default. To change the
564
default, use --remember. The value will only be saved if the remote
565
location can be accessed.
1023
If you want to replace your local changes and just want your branch to
1024
match the remote one, use pull --overwrite. This will work even if the two
1025
branches have diverged.
1027
If there is no default location set, the first pull will set it (use
1028
--no-remember to avoid setting it). After that, you can omit the
1029
location to use the default. To change the default, use --remember. The
1030
value will only be saved if the remote location can be accessed.
1032
The --verbose option will display the revisions pulled using the log_format
1033
configuration option. You can use a different format by overriding it with
1034
-Olog_format=<other_format>.
1036
Note: The location can be specified either in the form of a branch,
1037
or in the form of a path to a file containing a merge directive generated
568
_see_also = ['push', 'update']
569
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
571
help='branch to pull into, '
572
'rather than the one containing the working directory',
1041
_see_also = ['push', 'update', 'status-flags', 'send']
1042
takes_options = ['remember', 'overwrite', 'revision',
1043
custom_help('verbose',
1044
help='Show logs of pulled revisions.'),
1045
custom_help('directory',
1046
help='Branch to pull into, '
1047
'rather than the one containing the working directory.'),
1049
help="Perform a local pull in a bound "
1050
"branch. Local pulls are not applied to "
1051
"the master branch."
1054
help="Show base revision text in conflicts.")
577
1056
takes_args = ['location?']
578
1057
encoding_type = 'replace'
580
def run(self, location=None, remember=False, overwrite=False,
1059
def run(self, location=None, remember=None, overwrite=False,
581
1060
revision=None, verbose=False,
583
from bzrlib.tag import _merge_tags_if_possible
1061
directory=None, local=False,
584
1063
# FIXME: too much stuff is in the command class
585
1064
revision_id = None
586
1065
mergeable = None
662
1160
If branches have diverged, you can use 'bzr push --overwrite' to replace
663
1161
the other branch completely, discarding its unmerged changes.
665
1163
If you want to ensure you have the different changes in the other branch,
666
1164
do a merge (see bzr help merge) from the other branch, and commit that.
667
1165
After that you will be able to do a push without '--overwrite'.
669
If there is no default push location set, the first push will set it.
670
After that, you can omit the location to use the default. To change the
671
default, use --remember. The value will only be saved if the remote
672
location can be accessed.
1167
If there is no default push location set, the first push will set it (use
1168
--no-remember to avoid setting it). After that, you can omit the
1169
location to use the default. To change the default, use --remember. The
1170
value will only be saved if the remote location can be accessed.
1172
The --verbose option will display the revisions pushed using the log_format
1173
configuration option. You can use a different format by overriding it with
1174
-Olog_format=<other_format>.
675
1177
_see_also = ['pull', 'update', 'working-trees']
676
takes_options = ['remember', 'overwrite', 'verbose',
1178
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
677
1179
Option('create-prefix',
678
1180
help='Create the path leading up to the branch '
679
'if it does not already exist'),
681
help='branch to push from, '
682
'rather than the one containing the working directory',
1181
'if it does not already exist.'),
1182
custom_help('directory',
1183
help='Branch to push from, '
1184
'rather than the one containing the working directory.'),
686
1185
Option('use-existing-dir',
687
1186
help='By default push will fail if the target'
688
1187
' directory exists, but does not already'
689
' have a control directory. This flag will'
1188
' have a control directory. This flag will'
690
1189
' allow push to proceed.'),
1191
help='Create a stacked branch that references the public location '
1192
'of the parent branch.'),
1193
Option('stacked-on',
1194
help='Create a stacked branch that refers to another branch '
1195
'for the commit history. Only the work not present in the '
1196
'referenced branch is included in the branch created.',
1199
help='Refuse to push if there are uncommitted changes in'
1200
' the working tree, --no-strict disables the check.'),
1202
help="Don't populate the working tree, even for protocols"
1203
" that support it."),
692
1205
takes_args = ['location?']
693
1206
encoding_type = 'replace'
695
def run(self, location=None, remember=False, overwrite=False,
696
create_prefix=False, verbose=False,
697
use_existing_dir=False,
699
# FIXME: Way too big! Put this into a function called from the
1208
def run(self, location=None, remember=None, overwrite=False,
1209
create_prefix=False, verbose=False, revision=None,
1210
use_existing_dir=False, directory=None, stacked_on=None,
1211
stacked=False, strict=None, no_tree=False):
1212
from bzrlib.push import _show_push_branch
701
1214
if directory is None:
703
br_from = Branch.open_containing(directory)[0]
704
stored_loc = br_from.get_push_location()
1216
# Get the source branch
1218
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1219
# Get the tip's revision_id
1220
revision = _get_one_revision('push', revision)
1221
if revision is not None:
1222
revision_id = revision.in_history(br_from).rev_id
1225
if tree is not None and revision_id is None:
1226
tree.check_changed_or_out_of_date(
1227
strict, 'push_strict',
1228
more_error='Use --no-strict to force the push.',
1229
more_warning='Uncommitted changes will not be pushed.')
1230
# Get the stacked_on branch, if any
1231
if stacked_on is not None:
1232
stacked_on = urlutils.normalize_url(stacked_on)
1234
parent_url = br_from.get_parent()
1236
parent = Branch.open(parent_url)
1237
stacked_on = parent.get_public_branch()
1239
# I considered excluding non-http url's here, thus forcing
1240
# 'public' branches only, but that only works for some
1241
# users, so it's best to just depend on the user spotting an
1242
# error by the feedback given to them. RBC 20080227.
1243
stacked_on = parent_url
1245
raise errors.BzrCommandError(gettext(
1246
"Could not determine branch to refer to."))
1248
# Get the destination location
705
1249
if location is None:
1250
stored_loc = br_from.get_push_location()
706
1251
if stored_loc is None:
707
raise errors.BzrCommandError("No push location known or specified.")
1252
raise errors.BzrCommandError(gettext(
1253
"No push location known or specified."))
709
1255
display_url = urlutils.unescape_for_display(stored_loc,
710
1256
self.outf.encoding)
711
self.outf.write("Using saved location: %s\n" % display_url)
1257
note(gettext("Using saved push location: %s") % display_url)
712
1258
location = stored_loc
714
to_transport = transport.get_transport(location)
716
br_to = repository_to = dir_to = None
718
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
719
except errors.NotBranchError:
720
pass # Didn't find anything
722
# If we can open a branch, use its direct repository, otherwise see
723
# if there is a repository without a branch.
725
br_to = dir_to.open_branch()
726
except errors.NotBranchError:
727
# Didn't find a branch, can we find a repository?
729
repository_to = dir_to.find_repository()
730
except errors.NoRepositoryPresent:
733
# Found a branch, so we must have found a repository
734
repository_to = br_to.repository
738
# The destination doesn't exist; create it.
739
# XXX: Refactor the create_prefix/no_create_prefix code into a
740
# common helper function
742
to_transport.mkdir('.')
743
except errors.FileExists:
744
if not use_existing_dir:
745
raise errors.BzrCommandError("Target directory %s"
746
" already exists, but does not have a valid .bzr"
747
" directory. Supply --use-existing-dir to push"
748
" there anyway." % location)
749
except errors.NoSuchFile:
750
if not create_prefix:
751
raise errors.BzrCommandError("Parent directory of %s"
753
"\nYou may supply --create-prefix to create all"
754
" leading parent directories."
757
_create_prefix(to_transport)
759
# Now the target directory exists, but doesn't have a .bzr
760
# directory. So we need to create it, along with any work to create
761
# all of the dependent branches, etc.
762
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
763
revision_id=br_from.last_revision())
764
br_to = dir_to.open_branch()
765
# TODO: Some more useful message about what was copied
766
note('Created new branch.')
767
# We successfully created the target, remember it
768
if br_from.get_push_location() is None or remember:
769
br_from.set_push_location(br_to.base)
770
elif repository_to is None:
771
# we have a bzrdir but no branch or repository
772
# XXX: Figure out what to do other than complain.
773
raise errors.BzrCommandError("At %s you have a valid .bzr control"
774
" directory, but not a branch or repository. This is an"
775
" unsupported configuration. Please move the target directory"
776
" out of the way and try again."
779
# We have a repository but no branch, copy the revisions, and then
781
last_revision_id = br_from.last_revision()
782
repository_to.fetch(br_from.repository,
783
revision_id=last_revision_id)
784
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
785
note('Created new branch.')
786
if br_from.get_push_location() is None or remember:
787
br_from.set_push_location(br_to.base)
788
else: # We have a valid to branch
789
# We were able to connect to the remote location, so remember it
790
# we don't need to successfully push because of possible divergence.
791
if br_from.get_push_location() is None or remember:
792
br_from.set_push_location(br_to.base)
793
old_rh = br_to.revision_history()
796
tree_to = dir_to.open_workingtree()
797
except errors.NotLocalUrl:
798
warning("This transport does not update the working "
799
"tree of: %s. See 'bzr help working-trees' for "
800
"more information." % br_to.base)
801
push_result = br_from.push(br_to, overwrite)
802
except errors.NoWorkingTree:
803
push_result = br_from.push(br_to, overwrite)
807
push_result = br_from.push(tree_to.branch, overwrite)
811
except errors.DivergedBranches:
812
raise errors.BzrCommandError('These branches have diverged.'
813
' Try using "merge" and then "push".')
814
if push_result is not None:
815
push_result.report(self.outf)
817
new_rh = br_to.revision_history()
820
from bzrlib.log import show_changed_revisions
821
show_changed_revisions(br_to, old_rh, new_rh,
824
# we probably did a clone rather than a push, so a message was
1260
_show_push_branch(br_from, revision_id, location, self.outf,
1261
verbose=verbose, overwrite=overwrite, remember=remember,
1262
stacked_on=stacked_on, create_prefix=create_prefix,
1263
use_existing_dir=use_existing_dir, no_tree=no_tree)
829
1266
class cmd_branch(Command):
830
"""Create a new copy of a branch.
1267
__doc__ = """Create a new branch that is a copy of an existing branch.
832
1269
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
833
1270
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
839
1276
To retrieve the branch as of a particular revision, supply the --revision
840
1277
parameter, as in "branch foo/bar -r 5".
1279
The synonyms 'clone' and 'get' for this command are deprecated.
843
1282
_see_also = ['checkout']
844
1283
takes_args = ['from_location', 'to_location?']
845
takes_options = ['revision']
1284
takes_options = ['revision',
1285
Option('hardlink', help='Hard-link working tree files where possible.'),
1286
Option('files-from', type=str,
1287
help="Get file contents from this tree."),
1289
help="Create a branch without a working-tree."),
1291
help="Switch the checkout in the current directory "
1292
"to the new branch."),
1294
help='Create a stacked branch referring to the source branch. '
1295
'The new branch will depend on the availability of the source '
1296
'branch for all operations.'),
1297
Option('standalone',
1298
help='Do not use a shared repository, even if available.'),
1299
Option('use-existing-dir',
1300
help='By default branch will fail if the target'
1301
' directory exists, but does not already'
1302
' have a control directory. This flag will'
1303
' allow branch to proceed.'),
1305
help="Bind new branch to from location."),
846
1307
aliases = ['get', 'clone']
848
def run(self, from_location, to_location=None, revision=None):
1309
def run(self, from_location, to_location=None, revision=None,
1310
hardlink=False, stacked=False, standalone=False, no_tree=False,
1311
use_existing_dir=False, switch=False, bind=False,
1313
from bzrlib import switch as _mod_switch
849
1314
from bzrlib.tag import _merge_tags_if_possible
852
elif len(revision) > 1:
853
raise errors.BzrCommandError(
854
'bzr branch --revision takes exactly 1 revision value')
856
br_from = Branch.open(from_location)
859
if len(revision) == 1 and revision[0] is not None:
860
revision_id = revision[0].in_history(br_from)[1]
862
# FIXME - wt.last_revision, fallback to branch, fall back to
863
# None or perhaps NULL_REVISION to mean copy nothing
865
revision_id = br_from.last_revision()
1315
if self.invoked_as in ['get', 'clone']:
1316
ui.ui_factory.show_user_warning(
1317
'deprecated_command',
1318
deprecated_name=self.invoked_as,
1319
recommended_name='branch',
1320
deprecated_in_version='2.4')
1321
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1323
if not (hardlink or files_from):
1324
# accelerator_tree is usually slower because you have to read N
1325
# files (no readahead, lots of seeks, etc), but allow the user to
1326
# explicitly request it
1327
accelerator_tree = None
1328
if files_from is not None and files_from != from_location:
1329
accelerator_tree = WorkingTree.open(files_from)
1330
revision = _get_one_revision('branch', revision)
1331
self.add_cleanup(br_from.lock_read().unlock)
1332
if revision is not None:
1333
revision_id = revision.as_revision_id(br_from)
1335
# FIXME - wt.last_revision, fallback to branch, fall back to
1336
# None or perhaps NULL_REVISION to mean copy nothing
1338
revision_id = br_from.last_revision()
1339
if to_location is None:
1340
to_location = getattr(br_from, "name", None)
866
1341
if to_location is None:
867
1342
to_location = urlutils.derive_to_location(from_location)
1343
to_transport = transport.get_transport(to_location)
1345
to_transport.mkdir('.')
1346
except errors.FileExists:
1348
to_dir = controldir.ControlDir.open_from_transport(
1350
except errors.NotBranchError:
1351
if not use_existing_dir:
1352
raise errors.BzrCommandError(gettext('Target directory "%s" '
1353
'already exists.') % to_location)
870
name = os.path.basename(to_location) + '\n'
872
to_transport = transport.get_transport(to_location)
874
to_transport.mkdir('.')
875
except errors.FileExists:
876
raise errors.BzrCommandError('Target directory "%s" already'
877
' exists.' % to_location)
878
except errors.NoSuchFile:
879
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1358
to_dir.open_branch()
1359
except errors.NotBranchError:
1362
raise errors.AlreadyBranchError(to_location)
1363
except errors.NoSuchFile:
1364
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
882
1370
# preserve whatever source format we have.
883
dir = br_from.bzrdir.sprout(to_transport.base, revision_id)
884
branch = dir.open_branch()
1371
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1372
possible_transports=[to_transport],
1373
accelerator_tree=accelerator_tree,
1374
hardlink=hardlink, stacked=stacked,
1375
force_new_repo=standalone,
1376
create_tree_if_local=not no_tree,
1377
source_branch=br_from)
1378
branch = to_dir.open_branch(
1379
possible_transports=[
1380
br_from.bzrdir.root_transport, to_transport])
885
1381
except errors.NoSuchRevision:
886
1382
to_transport.delete_tree('.')
887
msg = "The branch %s has no revision %s." % (from_location, revision[0])
1383
msg = gettext("The branch {0} has no revision {1}.").format(
1384
from_location, revision)
888
1385
raise errors.BzrCommandError(msg)
890
branch.control_files.put_utf8('branch-name', name)
891
_merge_tags_if_possible(br_from, branch)
892
note('Branched %d revision(s).' % branch.revno())
1387
branch = br_from.sprout(to_dir, revision_id=revision_id)
1388
_merge_tags_if_possible(br_from, branch)
1389
# If the source branch is stacked, the new branch may
1390
# be stacked whether we asked for that explicitly or not.
1391
# We therefore need a try/except here and not just 'if stacked:'
1393
note(gettext('Created new stacked branch referring to %s.') %
1394
branch.get_stacked_on_url())
1395
except (errors.NotStacked, errors.UnstackableBranchFormat,
1396
errors.UnstackableRepositoryFormat), e:
1397
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1399
# Bind to the parent
1400
parent_branch = Branch.open(from_location)
1401
branch.bind(parent_branch)
1402
note(gettext('New branch bound to %s') % from_location)
1404
# Switch to the new branch
1405
wt, _ = WorkingTree.open_containing('.')
1406
_mod_switch.switch(wt.bzrdir, branch)
1407
note(gettext('Switched to branch: %s'),
1408
urlutils.unescape_for_display(branch.base, 'utf-8'))
1411
class cmd_branches(Command):
1412
__doc__ = """List the branches available at the current location.
1414
This command will print the names of all the branches at the current
1418
takes_args = ['location?']
1420
Option('recursive', short_name='R',
1421
help='Recursively scan for branches rather than '
1422
'just looking in the specified location.')]
1424
def run(self, location=".", recursive=False):
1426
t = transport.get_transport(location)
1427
if not t.listable():
1428
raise errors.BzrCommandError(
1429
"Can't scan this type of location.")
1430
for b in controldir.ControlDir.find_branches(t):
1431
self.outf.write("%s\n" % urlutils.unescape_for_display(
1432
urlutils.relative_url(t.base, b.base),
1433
self.outf.encoding).rstrip("/"))
1435
dir = controldir.ControlDir.open_containing(location)[0]
1436
for branch in dir.list_branches():
1437
if branch.name is None:
1438
self.outf.write(gettext(" (default)\n"))
1440
self.outf.write(" %s\n" % branch.name.encode(
1441
self.outf.encoding))
897
1444
class cmd_checkout(Command):
898
"""Create a new checkout of an existing branch.
1445
__doc__ = """Create a new checkout of an existing branch.
900
1447
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
901
1448
the branch found in '.'. This is useful if you have removed the working tree
902
1449
or if it was never created - i.e. if you pushed the branch to its current
903
1450
location using SFTP.
905
1452
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
906
1453
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
907
1454
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
981
1527
@display_command
982
1528
def run(self, dir=u'.'):
983
1529
tree = WorkingTree.open_containing(dir)[0]
986
new_inv = tree.inventory
987
old_tree = tree.basis_tree()
990
old_inv = old_tree.inventory
991
renames = list(_mod_tree.find_renames(old_inv, new_inv))
993
for old_name, new_name in renames:
994
self.outf.write("%s => %s\n" % (old_name, new_name))
1530
self.add_cleanup(tree.lock_read().unlock)
1531
new_inv = tree.inventory
1532
old_tree = tree.basis_tree()
1533
self.add_cleanup(old_tree.lock_read().unlock)
1534
old_inv = old_tree.inventory
1536
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1537
for f, paths, c, v, p, n, k, e in iterator:
1538
if paths[0] == paths[1]:
1542
renames.append(paths)
1544
for old_name, new_name in renames:
1545
self.outf.write("%s => %s\n" % (old_name, new_name))
1001
1548
class cmd_update(Command):
1002
"""Update a tree to have the latest code committed to its branch.
1004
This will perform a merge into the working tree, and may generate
1005
conflicts. If you have any local changes, you will still
1006
need to commit them after the update for the update to be complete.
1008
If you want to discard your local changes, you can just do a
1009
'bzr revert' instead of 'bzr commit' after the update.
1549
__doc__ = """Update a working tree to a new revision.
1551
This will perform a merge of the destination revision (the tip of the
1552
branch, or the specified revision) into the working tree, and then make
1553
that revision the basis revision for the working tree.
1555
You can use this to visit an older revision, or to update a working tree
1556
that is out of date from its branch.
1558
If there are any uncommitted changes in the tree, they will be carried
1559
across and remain as uncommitted changes after the update. To discard
1560
these changes, use 'bzr revert'. The uncommitted changes may conflict
1561
with the changes brought in by the change in basis revision.
1563
If the tree's branch is bound to a master branch, bzr will also update
1564
the branch from the master.
1566
You cannot update just a single file or directory, because each Bazaar
1567
working tree has just a single basis revision. If you want to restore a
1568
file that has been removed locally, use 'bzr revert' instead of 'bzr
1569
update'. If you want to restore a file to its state in a previous
1570
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1571
out the old content of that file to a new location.
1573
The 'dir' argument, if given, must be the location of the root of a
1574
working tree to update. By default, the working tree that contains the
1575
current working directory is used.
1012
_see_also = ['pull', 'working-trees']
1578
_see_also = ['pull', 'working-trees', 'status-flags']
1013
1579
takes_args = ['dir?']
1580
takes_options = ['revision',
1582
help="Show base revision text in conflicts."),
1014
1584
aliases = ['up']
1016
def run(self, dir='.'):
1017
tree = WorkingTree.open_containing(dir)[0]
1018
master = tree.branch.get_master_branch()
1586
def run(self, dir=None, revision=None, show_base=None):
1587
if revision is not None and len(revision) != 1:
1588
raise errors.BzrCommandError(gettext(
1589
"bzr update --revision takes exactly one revision"))
1591
tree = WorkingTree.open_containing('.')[0]
1593
tree, relpath = WorkingTree.open_containing(dir)
1596
raise errors.BzrCommandError(gettext(
1597
"bzr update can only update a whole tree, "
1598
"not a file or subdirectory"))
1599
branch = tree.branch
1600
possible_transports = []
1601
master = branch.get_master_branch(
1602
possible_transports=possible_transports)
1019
1603
if master is not None:
1604
branch_location = master.base
1020
1605
tree.lock_write()
1607
branch_location = tree.branch.base
1022
1608
tree.lock_tree_write()
1609
self.add_cleanup(tree.unlock)
1610
# get rid of the final '/' and be ready for display
1611
branch_location = urlutils.unescape_for_display(
1612
branch_location.rstrip('/'),
1614
existing_pending_merges = tree.get_parent_ids()[1:]
1618
# may need to fetch data into a heavyweight checkout
1619
# XXX: this may take some time, maybe we should display a
1621
old_tip = branch.update(possible_transports)
1622
if revision is not None:
1623
revision_id = revision[0].as_revision_id(branch)
1625
revision_id = branch.last_revision()
1626
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1627
revno = branch.revision_id_to_dotted_revno(revision_id)
1628
note(gettext("Tree is up to date at revision {0} of branch {1}"
1629
).format('.'.join(map(str, revno)), branch_location))
1631
view_info = _get_view_info_for_change_reporter(tree)
1632
change_reporter = delta._ChangeReporter(
1633
unversioned_filter=tree.is_ignored,
1634
view_info=view_info)
1024
existing_pending_merges = tree.get_parent_ids()[1:]
1025
last_rev = tree.last_revision()
1026
if last_rev == tree.branch.last_revision():
1027
# may be up to date, check master too.
1028
master = tree.branch.get_master_branch()
1029
if master is None or last_rev == master.last_revision():
1030
revno = tree.branch.revision_id_to_revno(last_rev)
1031
note("Tree is up to date at revision %d." % (revno,))
1033
conflicts = tree.update()
1034
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1035
note('Updated to revision %d.' % (revno,))
1036
if tree.get_parent_ids()[1:] != existing_pending_merges:
1037
note('Your local commits will now show as pending merges with '
1038
"'bzr status', and can be committed with 'bzr commit'.")
1636
conflicts = tree.update(
1638
possible_transports=possible_transports,
1639
revision=revision_id,
1641
show_base=show_base)
1642
except errors.NoSuchRevision, e:
1643
raise errors.BzrCommandError(gettext(
1644
"branch has no revision %s\n"
1645
"bzr update --revision only works"
1646
" for a revision in the branch history")
1648
revno = tree.branch.revision_id_to_dotted_revno(
1649
_mod_revision.ensure_null(tree.last_revision()))
1650
note(gettext('Updated to revision {0} of branch {1}').format(
1651
'.'.join(map(str, revno)), branch_location))
1652
parent_ids = tree.get_parent_ids()
1653
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1654
note(gettext('Your local commits will now show as pending merges with '
1655
"'bzr status', and can be committed with 'bzr commit'."))
1047
1662
class cmd_info(Command):
1048
"""Show information about a working tree, branch or repository.
1663
__doc__ = """Show information about a working tree, branch or repository.
1050
1665
This command will show all known locations and formats associated to the
1051
tree, branch or repository. Statistical information is included with
1666
tree, branch or repository.
1668
In verbose mode, statistical information is included with each report.
1669
To see extended statistic information, use a verbosity level of 2 or
1670
higher by specifying the verbose option multiple times, e.g. -vv.
1054
1672
Branches and working trees will also report any missing revisions.
1676
Display information on the format and related locations:
1680
Display the above together with extended format information and
1681
basic statistics (like the number of files in the working tree and
1682
number of revisions in the branch and repository):
1686
Display the above together with number of committers to the branch:
1056
1690
_see_also = ['revno', 'working-trees', 'repositories']
1057
1691
takes_args = ['location?']
1058
1692
takes_options = ['verbose']
1693
encoding_type = 'replace'
1060
1695
@display_command
1061
def run(self, location=None, verbose=0):
1696
def run(self, location=None, verbose=False):
1698
noise_level = get_verbosity_level()
1062
1701
from bzrlib.info import show_bzrdir_info
1063
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1702
show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1703
verbose=noise_level, outfile=self.outf)
1067
1706
class cmd_remove(Command):
1068
"""Remove files or directories.
1070
This makes bzr stop tracking changes to the specified files and
1071
delete them if they can easily be recovered using revert.
1073
You can specify one or more files, and/or --new. If you specify --new,
1074
only 'added' files will be removed. If you specify both, then new files
1075
in the specified directories will be removed. If the directories are
1076
also new, they will also be removed.
1707
__doc__ = """Remove files or directories.
1709
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1710
delete them if they can easily be recovered using revert otherwise they
1711
will be backed up (adding an extention of the form .~#~). If no options or
1712
parameters are given Bazaar will scan for files that are being tracked by
1713
Bazaar but missing in your tree and stop tracking them for you.
1078
1715
takes_args = ['file*']
1079
1716
takes_options = ['verbose',
1080
Option('new', help='remove newly-added files'),
1717
Option('new', help='Only remove files that have never been committed.'),
1081
1718
RegistryOption.from_kwargs('file-deletion-strategy',
1082
'The file deletion mode to be used',
1719
'The file deletion mode to be used.',
1083
1720
title='Deletion Strategy', value_switches=True, enum_switch=False,
1084
safe='Only delete files if they can be'
1085
' safely recovered (default).',
1086
keep="Don't delete any files.",
1721
safe='Backup changed files (default).',
1722
keep='Delete from bzr but leave the working copy.',
1723
no_backup='Don\'t backup changed files.',
1087
1724
force='Delete all the specified files, even if they can not be '
1088
'recovered and even if they are non-empty directories.')]
1725
'recovered and even if they are non-empty directories. '
1726
'(deprecated, use no-backup)')]
1727
aliases = ['rm', 'del']
1090
1728
encoding_type = 'replace'
1092
1730
def run(self, file_list, verbose=False, new=False,
1093
1731
file_deletion_strategy='safe'):
1094
tree, file_list = tree_files(file_list)
1732
if file_deletion_strategy == 'force':
1733
note(gettext("(The --force option is deprecated, rather use --no-backup "
1735
file_deletion_strategy = 'no-backup'
1737
tree, file_list = WorkingTree.open_containing_paths(file_list)
1096
1739
if file_list is not None:
1097
file_list = [f for f in file_list if f != '']
1099
raise errors.BzrCommandError('Specify one or more files to'
1100
' remove, or use --new.')
1740
file_list = [f for f in file_list]
1742
self.add_cleanup(tree.lock_write().unlock)
1743
# Heuristics should probably all move into tree.remove_smart or
1103
1746
added = tree.changes_from(tree.basis_tree(),
1104
1747
specific_files=file_list).added
1105
1748
file_list = sorted([f[0] for f in added], reverse=True)
1106
1749
if len(file_list) == 0:
1107
raise errors.BzrCommandError('No matching files.')
1750
raise errors.BzrCommandError(gettext('No matching files.'))
1751
elif file_list is None:
1752
# missing files show up in iter_changes(basis) as
1753
# versioned-with-no-kind.
1755
for change in tree.iter_changes(tree.basis_tree()):
1756
# Find paths in the working tree that have no kind:
1757
if change[1][1] is not None and change[6][1] is None:
1758
missing.append(change[1][1])
1759
file_list = sorted(missing, reverse=True)
1760
file_deletion_strategy = 'keep'
1108
1761
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1109
1762
keep_files=file_deletion_strategy=='keep',
1110
force=file_deletion_strategy=='force')
1763
force=(file_deletion_strategy=='no-backup'))
1113
1766
class cmd_file_id(Command):
1114
"""Print file_id of a particular file or directory.
1767
__doc__ = """Print file_id of a particular file or directory.
1116
1769
The file_id is assigned when the file is first added and remains the
1117
1770
same through all revisions where the file exists, even when it is
1571
2328
return int(limitstring)
1572
2329
except ValueError:
1573
msg = "The limit argument must be an integer."
2330
msg = gettext("The limit argument must be an integer.")
2331
raise errors.BzrCommandError(msg)
2334
def _parse_levels(s):
2338
msg = gettext("The levels argument must be an integer.")
1574
2339
raise errors.BzrCommandError(msg)
1577
2342
class cmd_log(Command):
1578
"""Show log of a branch, file, or directory.
1580
By default show the log of the branch containing the working directory.
1582
To request a range of logs, you can use the command -r begin..end
1583
-r revision requests a specific revision, -r ..end or -r begin.. are
1589
bzr log -r -10.. http://server/branch
2343
__doc__ = """Show historical log for a branch or subset of a branch.
2345
log is bzr's default tool for exploring the history of a branch.
2346
The branch to use is taken from the first parameter. If no parameters
2347
are given, the branch containing the working directory is logged.
2348
Here are some simple examples::
2350
bzr log log the current branch
2351
bzr log foo.py log a file in its branch
2352
bzr log http://server/branch log a branch on a server
2354
The filtering, ordering and information shown for each revision can
2355
be controlled as explained below. By default, all revisions are
2356
shown sorted (topologically) so that newer revisions appear before
2357
older ones and descendants always appear before ancestors. If displayed,
2358
merged revisions are shown indented under the revision in which they
2363
The log format controls how information about each revision is
2364
displayed. The standard log formats are called ``long``, ``short``
2365
and ``line``. The default is long. See ``bzr help log-formats``
2366
for more details on log formats.
2368
The following options can be used to control what information is
2371
-l N display a maximum of N revisions
2372
-n N display N levels of revisions (0 for all, 1 for collapsed)
2373
-v display a status summary (delta) for each revision
2374
-p display a diff (patch) for each revision
2375
--show-ids display revision-ids (and file-ids), not just revnos
2377
Note that the default number of levels to display is a function of the
2378
log format. If the -n option is not used, the standard log formats show
2379
just the top level (mainline).
2381
Status summaries are shown using status flags like A, M, etc. To see
2382
the changes explained using words like ``added`` and ``modified``
2383
instead, use the -vv option.
2387
To display revisions from oldest to newest, use the --forward option.
2388
In most cases, using this option will have little impact on the total
2389
time taken to produce a log, though --forward does not incrementally
2390
display revisions like --reverse does when it can.
2392
:Revision filtering:
2394
The -r option can be used to specify what revision or range of revisions
2395
to filter against. The various forms are shown below::
2397
-rX display revision X
2398
-rX.. display revision X and later
2399
-r..Y display up to and including revision Y
2400
-rX..Y display from X to Y inclusive
2402
See ``bzr help revisionspec`` for details on how to specify X and Y.
2403
Some common examples are given below::
2405
-r-1 show just the tip
2406
-r-10.. show the last 10 mainline revisions
2407
-rsubmit:.. show what's new on this branch
2408
-rancestor:path.. show changes since the common ancestor of this
2409
branch and the one at location path
2410
-rdate:yesterday.. show changes since yesterday
2412
When logging a range of revisions using -rX..Y, log starts at
2413
revision Y and searches back in history through the primary
2414
("left-hand") parents until it finds X. When logging just the
2415
top level (using -n1), an error is reported if X is not found
2416
along the way. If multi-level logging is used (-n0), X may be
2417
a nested merge revision and the log will be truncated accordingly.
2421
If parameters are given and the first one is not a branch, the log
2422
will be filtered to show only those revisions that changed the
2423
nominated files or directories.
2425
Filenames are interpreted within their historical context. To log a
2426
deleted file, specify a revision range so that the file existed at
2427
the end or start of the range.
2429
Historical context is also important when interpreting pathnames of
2430
renamed files/directories. Consider the following example:
2432
* revision 1: add tutorial.txt
2433
* revision 2: modify tutorial.txt
2434
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2438
* ``bzr log guide.txt`` will log the file added in revision 1
2440
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2442
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2443
the original file in revision 2.
2445
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2446
was no file called guide.txt in revision 2.
2448
Renames are always followed by log. By design, there is no need to
2449
explicitly ask for this (and no way to stop logging a file back
2450
until it was last renamed).
2454
The --match option can be used for finding revisions that match a
2455
regular expression in a commit message, committer, author or bug.
2456
Specifying the option several times will match any of the supplied
2457
expressions. --match-author, --match-bugs, --match-committer and
2458
--match-message can be used to only match a specific field.
2462
GUI tools and IDEs are often better at exploring history than command
2463
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2464
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2465
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2466
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2468
You may find it useful to add the aliases below to ``bazaar.conf``::
2472
top = log -l10 --line
2475
``bzr tip`` will then show the latest revision while ``bzr top``
2476
will show the last 10 mainline revisions. To see the details of a
2477
particular revision X, ``bzr show -rX``.
2479
If you are interested in looking deeper into a particular merge X,
2480
use ``bzr log -n0 -rX``.
2482
``bzr log -v`` on a branch with lots of history is currently
2483
very slow. A fix for this issue is currently under development.
2484
With or without that fix, it is recommended that a revision range
2485
be given when using the -v option.
2487
bzr has a generic full-text matching plugin, bzr-search, that can be
2488
used to find revisions matching user names, commit messages, etc.
2489
Among other features, this plugin can find all revisions containing
2490
a list of words but not others.
2492
When exploring non-mainline history on large projects with deep
2493
history, the performance of log can be greatly improved by installing
2494
the historycache plugin. This plugin buffers historical information
2495
trading disk space for faster speed.
1592
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1594
takes_args = ['location?']
1595
takes_options = [Option('forward',
1596
help='show from oldest to newest'),
1600
help='show files changed in each revision'),
1601
'show-ids', 'revision',
1605
help='show revisions whose message matches this regexp',
1608
help='limit the output to the first N revisions',
2497
takes_args = ['file*']
2498
_see_also = ['log-formats', 'revisionspec']
2501
help='Show from oldest to newest.'),
2503
custom_help('verbose',
2504
help='Show files changed in each revision.'),
2508
type=bzrlib.option._parse_revision_str,
2510
help='Show just the specified revision.'
2511
' See also "help revisionspec".'),
2513
RegistryOption('authors',
2514
'What names to list as authors - first, all or committer.',
2516
lazy_registry=('bzrlib.log', 'author_list_registry'),
2520
help='Number of levels to display - 0 for all, 1 for flat.',
2522
type=_parse_levels),
2524
help='Show revisions whose message matches this '
2525
'regular expression.',
2530
help='Limit the output to the first N revisions.',
2535
help='Show changes made in each revision as a patch.'),
2536
Option('include-merged',
2537
help='Show merged revisions like --levels 0 does.'),
2538
Option('include-merges', hidden=True,
2539
help='Historical alias for --include-merged.'),
2540
Option('omit-merges',
2541
help='Do not report commits with more than one parent.'),
2542
Option('exclude-common-ancestry',
2543
help='Display only the revisions that are not part'
2544
' of both ancestries (require -rX..Y).'
2546
Option('signatures',
2547
help='Show digital signature validity.'),
2550
help='Show revisions whose properties match this '
2553
ListOption('match-message',
2554
help='Show revisions whose message matches this '
2557
ListOption('match-committer',
2558
help='Show revisions whose committer matches this '
2561
ListOption('match-author',
2562
help='Show revisions whose authors match this '
2565
ListOption('match-bugs',
2566
help='Show revisions whose bugs match this '
1611
2570
encoding_type = 'replace'
1613
2572
@display_command
1614
def run(self, location=None, timezone='original',
2573
def run(self, file_list=None, timezone='original',
1616
2575
show_ids=False,
1619
2579
log_format=None,
1622
from bzrlib.log import show_log
1623
assert message is None or isinstance(message, basestring), \
1624
"invalid message argument %r" % message
2584
include_merged=None,
2586
exclude_common_ancestry=False,
2590
match_committer=None,
2594
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2596
from bzrlib.log import (
2598
make_log_request_dict,
2599
_get_info_for_log_files,
1625
2601
direction = (forward and 'forward') or 'reverse'
1630
# find the file id to log:
1632
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1636
tree = b.basis_tree()
1637
file_id = tree.path2id(fp)
2602
if symbol_versioning.deprecated_passed(include_merges):
2603
ui.ui_factory.show_user_warning(
2604
'deprecated_command_option',
2605
deprecated_name='--include-merges',
2606
recommended_name='--include-merged',
2607
deprecated_in_version='2.5',
2608
command=self.invoked_as)
2609
if include_merged is None:
2610
include_merged = include_merges
2612
raise errors.BzrCommandError(gettext(
2613
'{0} and {1} are mutually exclusive').format(
2614
'--include-merges', '--include-merged'))
2615
if include_merged is None:
2616
include_merged = False
2617
if (exclude_common_ancestry
2618
and (revision is None or len(revision) != 2)):
2619
raise errors.BzrCommandError(gettext(
2620
'--exclude-common-ancestry requires -r with two revisions'))
2625
raise errors.BzrCommandError(gettext(
2626
'{0} and {1} are mutually exclusive').format(
2627
'--levels', '--include-merged'))
2629
if change is not None:
2631
raise errors.RangeInChangeOption()
2632
if revision is not None:
2633
raise errors.BzrCommandError(gettext(
2634
'{0} and {1} are mutually exclusive').format(
2635
'--revision', '--change'))
2640
filter_by_dir = False
2642
# find the file ids to log and check for directory filtering
2643
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2644
revision, file_list, self.add_cleanup)
2645
for relpath, file_id, kind in file_info_list:
1638
2646
if file_id is None:
1639
raise errors.BzrCommandError(
1640
"Path does not have any revision history: %s" %
2647
raise errors.BzrCommandError(gettext(
2648
"Path unknown at end or start of revision range: %s") %
2650
# If the relpath is the top of the tree, we log everything
2655
file_ids.append(file_id)
2656
filter_by_dir = filter_by_dir or (
2657
kind in ['directory', 'tree-reference'])
1644
# FIXME ? log the current subdir only RBC 20060203
2660
# FIXME ? log the current subdir only RBC 20060203
1645
2661
if revision is not None \
1646
2662
and len(revision) > 0 and revision[0].get_branch():
1647
2663
location = revision[0].get_branch()
1650
dir, relpath = bzrdir.BzrDir.open_containing(location)
2666
dir, relpath = controldir.ControlDir.open_containing(location)
1651
2667
b = dir.open_branch()
1655
if revision is None:
1658
elif len(revision) == 1:
1659
rev1 = rev2 = revision[0].in_history(b).revno
1660
elif len(revision) == 2:
1661
if revision[1].get_branch() != revision[0].get_branch():
1662
# b is taken from revision[0].get_branch(), and
1663
# show_log will use its revision_history. Having
1664
# different branches will lead to weird behaviors.
1665
raise errors.BzrCommandError(
1666
"Log doesn't accept two revisions in different"
1668
if revision[0].spec is None:
1669
# missing begin-range means first revision
1672
rev1 = revision[0].in_history(b).revno
1674
if revision[1].spec is None:
1675
# missing end-range means last known revision
1678
rev2 = revision[1].in_history(b).revno
1680
raise errors.BzrCommandError(
1681
'bzr log --revision takes one or two values.')
1683
# By this point, the revision numbers are converted to the +ve
1684
# form if they were supplied in the -ve form, so we can do
1685
# this comparison in relative safety
1687
(rev2, rev1) = (rev1, rev2)
1689
if log_format is None:
1690
log_format = log.log_formatter_registry.get_default(b)
1692
lf = log_format(show_ids=show_ids, to_file=self.outf,
1693
show_timezone=timezone)
1699
direction=direction,
1700
start_revision=rev1,
2668
self.add_cleanup(b.lock_read().unlock)
2669
rev1, rev2 = _get_revision_range(revision, b, self.name())
2671
if b.get_config().validate_signatures_in_log():
2675
if not gpg.GPGStrategy.verify_signatures_available():
2676
raise errors.GpgmeNotInstalled(None)
2678
# Decide on the type of delta & diff filtering to use
2679
# TODO: add an --all-files option to make this configurable & consistent
2687
diff_type = 'partial'
2691
# Build the log formatter
2692
if log_format is None:
2693
log_format = log.log_formatter_registry.get_default(b)
2694
# Make a non-encoding output to include the diffs - bug 328007
2695
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2696
lf = log_format(show_ids=show_ids, to_file=self.outf,
2697
to_exact_file=unencoded_output,
2698
show_timezone=timezone,
2699
delta_format=get_verbosity_level(),
2701
show_advice=levels is None,
2702
author_list_handler=authors)
2704
# Choose the algorithm for doing the logging. It's annoying
2705
# having multiple code paths like this but necessary until
2706
# the underlying repository format is faster at generating
2707
# deltas or can provide everything we need from the indices.
2708
# The default algorithm - match-using-deltas - works for
2709
# multiple files and directories and is faster for small
2710
# amounts of history (200 revisions say). However, it's too
2711
# slow for logging a single file in a repository with deep
2712
# history, i.e. > 10K revisions. In the spirit of "do no
2713
# evil when adding features", we continue to use the
2714
# original algorithm - per-file-graph - for the "single
2715
# file that isn't a directory without showing a delta" case.
2716
partial_history = revision and b.repository._format.supports_chks
2717
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2718
or delta_type or partial_history)
2722
match_dict[''] = match
2724
match_dict['message'] = match_message
2726
match_dict['committer'] = match_committer
2728
match_dict['author'] = match_author
2730
match_dict['bugs'] = match_bugs
2732
# Build the LogRequest and execute it
2733
if len(file_ids) == 0:
2735
rqst = make_log_request_dict(
2736
direction=direction, specific_fileids=file_ids,
2737
start_revision=rev1, end_revision=rev2, limit=limit,
2738
message_search=message, delta_type=delta_type,
2739
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2740
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2741
signature=signatures, omit_merges=omit_merges,
2743
Logger(b, rqst).show(lf)
2746
def _get_revision_range(revisionspec_list, branch, command_name):
2747
"""Take the input of a revision option and turn it into a revision range.
2749
It returns RevisionInfo objects which can be used to obtain the rev_id's
2750
of the desired revisions. It does some user input validations.
2752
if revisionspec_list is None:
2755
elif len(revisionspec_list) == 1:
2756
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2757
elif len(revisionspec_list) == 2:
2758
start_spec = revisionspec_list[0]
2759
end_spec = revisionspec_list[1]
2760
if end_spec.get_branch() != start_spec.get_branch():
2761
# b is taken from revision[0].get_branch(), and
2762
# show_log will use its revision_history. Having
2763
# different branches will lead to weird behaviors.
2764
raise errors.BzrCommandError(gettext(
2765
"bzr %s doesn't accept two revisions in different"
2766
" branches.") % command_name)
2767
if start_spec.spec is None:
2768
# Avoid loading all the history.
2769
rev1 = RevisionInfo(branch, None, None)
2771
rev1 = start_spec.in_history(branch)
2772
# Avoid loading all of history when we know a missing
2773
# end of range means the last revision ...
2774
if end_spec.spec is None:
2775
last_revno, last_revision_id = branch.last_revision_info()
2776
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2778
rev2 = end_spec.in_history(branch)
2780
raise errors.BzrCommandError(gettext(
2781
'bzr %s --revision takes one or two values.') % command_name)
2785
def _revision_range_to_revid_range(revision_range):
2788
if revision_range[0] is not None:
2789
rev_id1 = revision_range[0].rev_id
2790
if revision_range[1] is not None:
2791
rev_id2 = revision_range[1].rev_id
2792
return rev_id1, rev_id2
1708
2794
def get_log_format(long=False, short=False, line=False, default='long'):
1709
2795
log_format = default
1728
2814
@display_command
1729
2815
def run(self, filename):
1730
2816
tree, relpath = WorkingTree.open_containing(filename)
2817
file_id = tree.path2id(relpath)
1731
2818
b = tree.branch
1732
file_id = tree.path2id(relpath)
1733
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
2819
self.add_cleanup(b.lock_read().unlock)
2820
touching_revs = log.find_touching_revisions(b, file_id)
2821
for revno, revision_id, what in touching_revs:
1734
2822
self.outf.write("%6d %s\n" % (revno, what))
1737
2825
class cmd_ls(Command):
1738
"""List files in a tree.
2826
__doc__ = """List files in a tree.
1741
2829
_see_also = ['status', 'cat']
1742
2830
takes_args = ['path?']
1743
# TODO: Take a revision or remote path and list that tree instead.
1744
takes_options = ['verbose', 'revision',
1745
Option('non-recursive',
1746
help='don\'t recurse into sub-directories'),
1748
help='Print all paths from the root of the branch.'),
1749
Option('unknown', help='Print unknown files'),
1750
Option('versioned', help='Print versioned files'),
1751
Option('ignored', help='Print ignored files'),
1753
Option('null', help='Null separate the files'),
2834
Option('recursive', short_name='R',
2835
help='Recurse into subdirectories.'),
2837
help='Print paths relative to the root of the branch.'),
2838
Option('unknown', short_name='u',
2839
help='Print unknown files.'),
2840
Option('versioned', help='Print versioned files.',
2842
Option('ignored', short_name='i',
2843
help='Print ignored files.'),
2844
Option('kind', short_name='k',
2845
help='List entries of a particular kind: file, directory, symlink.',
1756
2851
@display_command
1757
def run(self, revision=None, verbose=False,
1758
non_recursive=False, from_root=False,
2852
def run(self, revision=None, verbose=False,
2853
recursive=False, from_root=False,
1759
2854
unknown=False, versioned=False, ignored=False,
1760
null=False, kind=None, show_ids=False, path=None):
2855
null=False, kind=None, show_ids=False, path=None, directory=None):
1762
2857
if kind and kind not in ('file', 'directory', 'symlink'):
1763
raise errors.BzrCommandError('invalid kind specified')
2858
raise errors.BzrCommandError(gettext('invalid kind specified'))
1765
2860
if verbose and null:
1766
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2861
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
1767
2862
all = not (unknown or versioned or ignored)
1769
2864
selection = {'I':ignored, '?':unknown, 'V':versioned}
1771
2866
if path is None:
1776
raise errors.BzrCommandError('cannot specify both --from-root'
2870
raise errors.BzrCommandError(gettext('cannot specify both --from-root'
1780
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2873
tree, branch, relpath = \
2874
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2876
# Calculate the prefix to use
1786
if revision is not None:
1787
tree = branch.repository.revision_tree(
1788
revision[0].in_history(branch).rev_id)
1790
tree = branch.basis_tree()
1794
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1795
if fp.startswith(relpath):
1796
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1797
if non_recursive and '/' in fp:
1799
if not all and not selection[fc]:
1801
if kind is not None and fkind != kind:
1804
kindch = entry.kind_character()
1805
outstring = '%-8s %s%s' % (fc, fp, kindch)
1806
if show_ids and fid is not None:
1807
outstring = "%-50s %s" % (outstring, fid)
1808
self.outf.write(outstring + '\n')
1810
self.outf.write(fp + '\0')
1813
self.outf.write(fid)
1814
self.outf.write('\0')
1822
self.outf.write('%-50s %s\n' % (fp, my_id))
1824
self.outf.write(fp + '\n')
2880
prefix = relpath + '/'
2881
elif fs_path != '.' and not fs_path.endswith('/'):
2882
prefix = fs_path + '/'
2884
if revision is not None or tree is None:
2885
tree = _get_one_revision_tree('ls', revision, branch=branch)
2888
if isinstance(tree, WorkingTree) and tree.supports_views():
2889
view_files = tree.views.lookup_view()
2892
view_str = views.view_display_str(view_files)
2893
note(gettext("Ignoring files outside view. View is %s") % view_str)
2895
self.add_cleanup(tree.lock_read().unlock)
2896
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2897
from_dir=relpath, recursive=recursive):
2898
# Apply additional masking
2899
if not all and not selection[fc]:
2901
if kind is not None and fkind != kind:
2906
fullpath = osutils.pathjoin(relpath, fp)
2909
views.check_path_in_view(tree, fullpath)
2910
except errors.FileOutsideView:
2915
fp = osutils.pathjoin(prefix, fp)
2916
kindch = entry.kind_character()
2917
outstring = fp + kindch
2918
ui.ui_factory.clear_term()
2920
outstring = '%-8s %s' % (fc, outstring)
2921
if show_ids and fid is not None:
2922
outstring = "%-50s %s" % (outstring, fid)
2923
self.outf.write(outstring + '\n')
2925
self.outf.write(fp + '\0')
2928
self.outf.write(fid)
2929
self.outf.write('\0')
2937
self.outf.write('%-50s %s\n' % (outstring, my_id))
2939
self.outf.write(outstring + '\n')
1829
2942
class cmd_unknowns(Command):
1830
"""List unknown files.
2943
__doc__ = """List unknown files.
1834
2947
_see_also = ['ls']
2948
takes_options = ['directory']
1836
2950
@display_command
1838
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2951
def run(self, directory=u'.'):
2952
for f in WorkingTree.open_containing(directory)[0].unknowns():
1839
2953
self.outf.write(osutils.quotefn(f) + '\n')
1842
2956
class cmd_ignore(Command):
1843
"""Ignore specified files or patterns.
2957
__doc__ = """Ignore specified files or patterns.
2959
See ``bzr help patterns`` for details on the syntax of patterns.
2961
If a .bzrignore file does not exist, the ignore command
2962
will create one and add the specified files or patterns to the newly
2963
created file. The ignore command will also automatically add the
2964
.bzrignore file to be versioned. Creating a .bzrignore file without
2965
the use of the ignore command will require an explicit add command.
1845
2967
To remove patterns from the ignore list, edit the .bzrignore file.
1847
Trailing slashes on patterns are ignored.
1848
If the pattern contains a slash or is a regular expression, it is compared
1849
to the whole path from the branch root. Otherwise, it is compared to only
1850
the last component of the path. To match a file only in the root
1851
directory, prepend './'.
1853
Ignore patterns specifying absolute paths are not allowed.
1855
Ignore patterns may include globbing wildcards such as:
1856
? - Matches any single character except '/'
1857
* - Matches 0 or more characters except '/'
1858
/**/ - Matches 0 or more directories in a path
1859
[a-z] - Matches a single character from within a group of characters
1861
Ignore patterns may also be Python regular expressions.
1862
Regular expression ignore patterns are identified by a 'RE:' prefix
1863
followed by the regular expression. Regular expression ignore patterns
1864
may not include named or numbered groups.
1866
Note: ignore patterns containing shell wildcards must be quoted from
1870
bzr ignore ./Makefile
1871
bzr ignore '*.class'
1872
bzr ignore 'lib/**/*.o'
1873
bzr ignore 'RE:lib/.*\.o'
2968
After adding, editing or deleting that file either indirectly by
2969
using this command or directly by using an editor, be sure to commit
2972
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2973
the global ignore file can be found in the application data directory as
2974
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2975
Global ignores are not touched by this command. The global ignore file
2976
can be edited directly using an editor.
2978
Patterns prefixed with '!' are exceptions to ignore patterns and take
2979
precedence over regular ignores. Such exceptions are used to specify
2980
files that should be versioned which would otherwise be ignored.
2982
Patterns prefixed with '!!' act as regular ignore patterns, but have
2983
precedence over the '!' exception patterns.
2987
* Ignore patterns containing shell wildcards must be quoted from
2990
* Ignore patterns starting with "#" act as comments in the ignore file.
2991
To ignore patterns that begin with that character, use the "RE:" prefix.
2994
Ignore the top level Makefile::
2996
bzr ignore ./Makefile
2998
Ignore .class files in all directories...::
3000
bzr ignore "*.class"
3002
...but do not ignore "special.class"::
3004
bzr ignore "!special.class"
3006
Ignore files whose name begins with the "#" character::
3010
Ignore .o files under the lib directory::
3012
bzr ignore "lib/**/*.o"
3014
Ignore .o files under the lib directory::
3016
bzr ignore "RE:lib/.*\.o"
3018
Ignore everything but the "debian" toplevel directory::
3020
bzr ignore "RE:(?!debian/).*"
3022
Ignore everything except the "local" toplevel directory,
3023
but always ignore autosave files ending in ~, even under local/::
3026
bzr ignore "!./local"
1876
_see_also = ['status', 'ignored']
3030
_see_also = ['status', 'ignored', 'patterns']
1877
3031
takes_args = ['name_pattern*']
1879
Option('old-default-rules',
1880
help='Out the ignore rules bzr < 0.9 always used.')
1883
def run(self, name_pattern_list=None, old_default_rules=None):
1884
from bzrlib.atomicfile import AtomicFile
1885
if old_default_rules is not None:
1886
# dump the rules and exit
1887
for pattern in ignores.OLD_DEFAULTS:
3032
takes_options = ['directory',
3033
Option('default-rules',
3034
help='Display the default ignore rules that bzr uses.')
3037
def run(self, name_pattern_list=None, default_rules=None,
3039
from bzrlib import ignores
3040
if default_rules is not None:
3041
# dump the default rules and exit
3042
for pattern in ignores.USER_DEFAULTS:
3043
self.outf.write("%s\n" % pattern)
1890
3045
if not name_pattern_list:
1891
raise errors.BzrCommandError("ignore requires at least one "
1892
"NAME_PATTERN or --old-default-rules")
1893
name_pattern_list = [globbing.normalize_pattern(p)
3046
raise errors.BzrCommandError(gettext("ignore requires at least one "
3047
"NAME_PATTERN or --default-rules."))
3048
name_pattern_list = [globbing.normalize_pattern(p)
1894
3049
for p in name_pattern_list]
3051
bad_patterns_count = 0
3052
for p in name_pattern_list:
3053
if not globbing.Globster.is_pattern_valid(p):
3054
bad_patterns_count += 1
3055
bad_patterns += ('\n %s' % p)
3057
msg = (ngettext('Invalid ignore pattern found. %s',
3058
'Invalid ignore patterns found. %s',
3059
bad_patterns_count) % bad_patterns)
3060
ui.ui_factory.show_error(msg)
3061
raise errors.InvalidPattern('')
1895
3062
for name_pattern in name_pattern_list:
1896
if (name_pattern[0] == '/' or
3063
if (name_pattern[0] == '/' or
1897
3064
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1898
raise errors.BzrCommandError(
1899
"NAME_PATTERN should not be an absolute path")
1900
tree, relpath = WorkingTree.open_containing(u'.')
1901
ifn = tree.abspath('.bzrignore')
1902
if os.path.exists(ifn):
1905
igns = f.read().decode('utf-8')
1911
# TODO: If the file already uses crlf-style termination, maybe
1912
# we should use that for the newly added lines?
1914
if igns and igns[-1] != '\n':
1916
for name_pattern in name_pattern_list:
1917
igns += name_pattern + '\n'
1919
f = AtomicFile(ifn, 'wb')
1921
f.write(igns.encode('utf-8'))
1926
if not tree.path2id('.bzrignore'):
1927
tree.add(['.bzrignore'])
3065
raise errors.BzrCommandError(gettext(
3066
"NAME_PATTERN should not be an absolute path"))
3067
tree, relpath = WorkingTree.open_containing(directory)
3068
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3069
ignored = globbing.Globster(name_pattern_list)
3071
self.add_cleanup(tree.lock_read().unlock)
3072
for entry in tree.list_files():
3076
if ignored.match(filename):
3077
matches.append(filename)
3078
if len(matches) > 0:
3079
self.outf.write(gettext("Warning: the following files are version "
3080
"controlled and match your ignore pattern:\n%s"
3081
"\nThese files will continue to be version controlled"
3082
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
1930
3085
class cmd_ignored(Command):
1931
"""List ignored files and the patterns that matched them.
3086
__doc__ = """List ignored files and the patterns that matched them.
3088
List all the ignored files and the ignore pattern that caused the file to
3091
Alternatively, to list just the files::
1934
_see_also = ['ignore']
3096
encoding_type = 'replace'
3097
_see_also = ['ignore', 'ls']
3098
takes_options = ['directory']
1935
3100
@display_command
1937
tree = WorkingTree.open_containing(u'.')[0]
1940
for path, file_class, kind, file_id, entry in tree.list_files():
1941
if file_class != 'I':
1943
## XXX: Slightly inefficient since this was already calculated
1944
pat = tree.is_ignored(path)
1945
print '%-50s %s' % (path, pat)
3101
def run(self, directory=u'.'):
3102
tree = WorkingTree.open_containing(directory)[0]
3103
self.add_cleanup(tree.lock_read().unlock)
3104
for path, file_class, kind, file_id, entry in tree.list_files():
3105
if file_class != 'I':
3107
## XXX: Slightly inefficient since this was already calculated
3108
pat = tree.is_ignored(path)
3109
self.outf.write('%-50s %s\n' % (path, pat))
1950
3112
class cmd_lookup_revision(Command):
1951
"""Lookup the revision-id from a revision-number
3113
__doc__ = """Lookup the revision-id from a revision-number
1954
3116
bzr lookup-revision 33
1957
3119
takes_args = ['revno']
3120
takes_options = ['directory']
1959
3122
@display_command
1960
def run(self, revno):
3123
def run(self, revno, directory=u'.'):
1962
3125
revno = int(revno)
1963
3126
except ValueError:
1964
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
1966
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
3127
raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3129
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3130
self.outf.write("%s\n" % revid)
1969
3133
class cmd_export(Command):
1970
"""Export current or past revision to a destination directory or archive.
3134
__doc__ = """Export current or past revision to a destination directory or archive.
1972
3136
If no revision is specified this exports the last committed revision.
1985
3149
Note: Export of tree with non-ASCII filenames to zip is not supported.
1987
Supported formats Autodetected by extension
1988
----------------- -------------------------
3151
================= =========================
3152
Supported formats Autodetected by extension
3153
================= =========================
1991
3156
tbz2 .tar.bz2, .tbz2
1992
3157
tgz .tar.gz, .tgz
3159
================= =========================
1995
takes_args = ['dest', 'branch?']
1996
takes_options = ['revision', 'format', 'root']
1997
def run(self, dest, branch=None, revision=None, format=None, root=None):
3162
takes_args = ['dest', 'branch_or_subdir?']
3163
takes_options = ['directory',
3165
help="Type of file to export to.",
3168
Option('filters', help='Apply content filters to export the '
3169
'convenient form.'),
3172
help="Name of the root directory inside the exported file."),
3173
Option('per-file-timestamps',
3174
help='Set modification time of files to that of the last '
3175
'revision in which it was changed.'),
3176
Option('uncommitted',
3177
help='Export the working tree contents rather than that of the '
3180
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3181
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
1998
3183
from bzrlib.export import export
2001
tree = WorkingTree.open_containing(u'.')[0]
2004
b = Branch.open(branch)
2006
if revision is None:
2007
# should be tree.last_revision FIXME
2008
rev_id = b.last_revision()
2010
if len(revision) != 1:
2011
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
2012
rev_id = revision[0].in_history(b).rev_id
2013
t = b.repository.revision_tree(rev_id)
3185
if branch_or_subdir is None:
3186
branch_or_subdir = directory
3188
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3190
if tree is not None:
3191
self.add_cleanup(tree.lock_read().unlock)
3195
raise errors.BzrCommandError(
3196
gettext("--uncommitted requires a working tree"))
3199
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2015
export(t, dest, format, root)
3201
export(export_tree, dest, format, root, subdir, filtered=filters,
3202
per_file_timestamps=per_file_timestamps)
2016
3203
except errors.NoSuchExportFormat, e:
2017
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3204
raise errors.BzrCommandError(
3205
gettext('Unsupported export format: %s') % e.format)
2020
3208
class cmd_cat(Command):
2021
"""Write the contents of a file as of a given revision to standard output.
3209
__doc__ = """Write the contents of a file as of a given revision to standard output.
2023
3211
If no revision is nominated, the last revision is used.
2025
3213
Note: Take care to redirect standard output when using this command on a
2029
3217
_see_also = ['ls']
2030
takes_options = ['revision', 'name-from-revision']
3218
takes_options = ['directory',
3219
Option('name-from-revision', help='The path name in the old tree.'),
3220
Option('filters', help='Apply content filters to display the '
3221
'convenience form.'),
2031
3224
takes_args = ['filename']
2032
3225
encoding_type = 'exact'
2034
3227
@display_command
2035
def run(self, filename, revision=None, name_from_revision=False):
3228
def run(self, filename, revision=None, name_from_revision=False,
3229
filters=False, directory=None):
2036
3230
if revision is not None and len(revision) != 1:
2037
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2042
tree, b, relpath = \
2043
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2044
except errors.NotBranchError:
2047
if revision is not None and revision[0].get_branch() is not None:
2048
b = Branch.open(revision[0].get_branch())
3231
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3232
" one revision specifier"))
3233
tree, branch, relpath = \
3234
_open_directory_or_containing_tree_or_branch(filename, directory)
3235
self.add_cleanup(branch.lock_read().unlock)
3236
return self._run(tree, branch, relpath, filename, revision,
3237
name_from_revision, filters)
3239
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2049
3241
if tree is None:
2050
3242
tree = b.basis_tree()
2051
if revision is None:
2052
revision_id = b.last_revision()
2054
revision_id = revision[0].in_history(b).rev_id
3243
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3244
self.add_cleanup(rev_tree.lock_read().unlock)
2056
cur_file_id = tree.path2id(relpath)
2057
rev_tree = b.repository.revision_tree(revision_id)
2058
3246
old_file_id = rev_tree.path2id(relpath)
3248
# TODO: Split out this code to something that generically finds the
3249
# best id for a path across one or more trees; it's like
3250
# find_ids_across_trees but restricted to find just one. -- mbp
2060
3252
if name_from_revision:
3253
# Try in revision if requested
2061
3254
if old_file_id is None:
2062
raise errors.BzrCommandError("%r is not present in revision %s"
2063
% (filename, revision_id))
2065
rev_tree.print_file(old_file_id)
2066
elif cur_file_id is not None:
2067
rev_tree.print_file(cur_file_id)
2068
elif old_file_id is not None:
2069
rev_tree.print_file(old_file_id)
2071
raise errors.BzrCommandError("%r is not present in revision %s" %
2072
(filename, revision_id))
3255
raise errors.BzrCommandError(gettext(
3256
"{0!r} is not present in revision {1}").format(
3257
filename, rev_tree.get_revision_id()))
3259
actual_file_id = old_file_id
3261
cur_file_id = tree.path2id(relpath)
3262
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3263
actual_file_id = cur_file_id
3264
elif old_file_id is not None:
3265
actual_file_id = old_file_id
3267
raise errors.BzrCommandError(gettext(
3268
"{0!r} is not present in revision {1}").format(
3269
filename, rev_tree.get_revision_id()))
3271
from bzrlib.filter_tree import ContentFilterTree
3272
filter_tree = ContentFilterTree(rev_tree,
3273
rev_tree._content_filter_stack)
3274
content = filter_tree.get_file_text(actual_file_id)
3276
content = rev_tree.get_file_text(actual_file_id)
3278
self.outf.write(content)
2075
3281
class cmd_local_time_offset(Command):
2076
"""Show the offset in seconds from GMT to local time."""
3282
__doc__ = """Show the offset in seconds from GMT to local time."""
2078
3284
@display_command
2080
print osutils.local_time_offset()
3286
self.outf.write("%s\n" % osutils.local_time_offset())
2084
3290
class cmd_commit(Command):
2085
"""Commit changes into a new revision.
2087
If no arguments are given, the entire tree is committed.
2089
If selected files are specified, only changes to those files are
2090
committed. If a directory is specified then the directory and everything
2091
within it is committed.
2093
A selected-file commit may fail in some cases where the committed
2094
tree would be invalid. Consider::
2099
bzr commit foo -m "committing foo"
2100
bzr mv foo/bar foo/baz
2103
bzr commit foo/bar -m "committing bar but not baz"
2105
In the example above, the last commit will fail by design. This gives
2106
the user the opportunity to decide whether they want to commit the
2107
rename at the same time, separately first, or not at all. (As a general
2108
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2110
Note: A selected-file commit after a merge is not yet supported.
3291
__doc__ = """Commit changes into a new revision.
3293
An explanatory message needs to be given for each commit. This is
3294
often done by using the --message option (getting the message from the
3295
command line) or by using the --file option (getting the message from
3296
a file). If neither of these options is given, an editor is opened for
3297
the user to enter the message. To see the changed files in the
3298
boilerplate text loaded into the editor, use the --show-diff option.
3300
By default, the entire tree is committed and the person doing the
3301
commit is assumed to be the author. These defaults can be overridden
3306
If selected files are specified, only changes to those files are
3307
committed. If a directory is specified then the directory and
3308
everything within it is committed.
3310
When excludes are given, they take precedence over selected files.
3311
For example, to commit only changes within foo, but not changes
3314
bzr commit foo -x foo/bar
3316
A selective commit after a merge is not yet supported.
3320
If the author of the change is not the same person as the committer,
3321
you can specify the author's name using the --author option. The
3322
name should be in the same format as a committer-id, e.g.
3323
"John Doe <jdoe@example.com>". If there is more than one author of
3324
the change you can specify the option multiple times, once for each
3329
A common mistake is to forget to add a new file or directory before
3330
running the commit command. The --strict option checks for unknown
3331
files and aborts the commit if any are found. More advanced pre-commit
3332
checks can be implemented by defining hooks. See ``bzr help hooks``
3337
If you accidentially commit the wrong changes or make a spelling
3338
mistake in the commit message say, you can use the uncommit command
3339
to undo it. See ``bzr help uncommit`` for details.
3341
Hooks can also be configured to run after a commit. This allows you
3342
to trigger updates to external systems like bug trackers. The --fixes
3343
option can be used to record the association between a revision and
3344
one or more bugs. See ``bzr help bugs`` for details.
2112
# TODO: Run hooks on tree to-be-committed, and after commit.
2114
# TODO: Strict commit that fails if there are deleted files.
2115
# (what does "deleted files" mean ??)
2117
# TODO: Give better message for -s, --summary, used by tla people
2119
# XXX: verbose currently does nothing
2121
_see_also = ['bugs', 'uncommit']
3347
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2122
3348
takes_args = ['selected*']
2123
takes_options = ['message', 'verbose',
2125
help='commit even if nothing has changed'),
2126
Option('file', type=str,
2129
help='file containing commit message'),
2131
help="refuse to commit if there are unknown "
2132
"files in the working tree."),
2133
ListOption('fixes', type=str,
2134
help="mark a bug as being fixed by this "
2137
help="perform a local only commit in a bound "
2138
"branch. Such commits are not pushed to "
2139
"the master branch until a normal commit "
3350
ListOption('exclude', type=str, short_name='x',
3351
help="Do not consider changes made to a given path."),
3352
Option('message', type=unicode,
3354
help="Description of the new revision."),
3357
help='Commit even if nothing has changed.'),
3358
Option('file', type=str,
3361
help='Take commit message from this file.'),
3363
help="Refuse to commit if there are unknown "
3364
"files in the working tree."),
3365
Option('commit-time', type=str,
3366
help="Manually set a commit time using commit date "
3367
"format, e.g. '2009-10-10 08:00:00 +0100'."),
3368
ListOption('fixes', type=str,
3369
help="Mark a bug as being fixed by this revision "
3370
"(see \"bzr help bugs\")."),
3371
ListOption('author', type=unicode,
3372
help="Set the author's name, if it's different "
3373
"from the committer."),
3375
help="Perform a local commit in a bound "
3376
"branch. Local commits are not pushed to "
3377
"the master branch until a normal commit "
3380
Option('show-diff', short_name='p',
3381
help='When no message is supplied, show the diff along'
3382
' with the status summary in the message editor.'),
3384
help='When committing to a foreign version control '
3385
'system do not push data that can not be natively '
2143
3388
aliases = ['ci', 'checkin']
2145
def _get_bug_fix_properties(self, fixes, branch):
3390
def _iter_bug_fix_urls(self, fixes, branch):
3391
default_bugtracker = None
2147
3392
# Configure the properties for bug fixing attributes.
2148
3393
for fixed_bug in fixes:
2149
3394
tokens = fixed_bug.split(':')
2150
if len(tokens) != 2:
2151
raise errors.BzrCommandError(
2152
"Invalid bug %s. Must be in the form of 'tag:id'. "
2153
"Commit refused." % fixed_bug)
2154
tag, bug_id = tokens
3395
if len(tokens) == 1:
3396
if default_bugtracker is None:
3397
branch_config = branch.get_config()
3398
default_bugtracker = branch_config.get_user_option(
3400
if default_bugtracker is None:
3401
raise errors.BzrCommandError(gettext(
3402
"No tracker specified for bug %s. Use the form "
3403
"'tracker:id' or specify a default bug tracker "
3404
"using the `bugtracker` option.\nSee "
3405
"\"bzr help bugs\" for more information on this "
3406
"feature. Commit refused.") % fixed_bug)
3407
tag = default_bugtracker
3409
elif len(tokens) != 2:
3410
raise errors.BzrCommandError(gettext(
3411
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3412
"See \"bzr help bugs\" for more information on this "
3413
"feature.\nCommit refused.") % fixed_bug)
3415
tag, bug_id = tokens
2156
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
3417
yield bugtracker.get_bug_url(tag, branch, bug_id)
2157
3418
except errors.UnknownBugTrackerAbbreviation:
2158
raise errors.BzrCommandError(
2159
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2160
except errors.MalformedBugIdentifier:
2161
raise errors.BzrCommandError(
2162
"Invalid bug identifier for %s. Commit refused."
2164
properties.append('%s fixed' % bug_url)
2165
return '\n'.join(properties)
2167
def run(self, message=None, file=None, verbose=True, selected_list=None,
2168
unchanged=False, strict=False, local=False, fixes=None):
2169
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2170
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2172
from bzrlib.msgeditor import edit_commit_message, \
2173
make_commit_message_template
2175
# TODO: Need a blackbox test for invoking the external editor; may be
2176
# slightly problematic to run this cross-platform.
2178
# TODO: do more checks that the commit will succeed before
2179
# spending the user's valuable time typing a commit message.
3419
raise errors.BzrCommandError(gettext(
3420
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3421
except errors.MalformedBugIdentifier, e:
3422
raise errors.BzrCommandError(gettext(
3423
"%s\nCommit refused.") % (str(e),))
3425
def run(self, message=None, file=None, verbose=False, selected_list=None,
3426
unchanged=False, strict=False, local=False, fixes=None,
3427
author=None, show_diff=False, exclude=None, commit_time=None,
3429
from bzrlib.errors import (
3434
from bzrlib.msgeditor import (
3435
edit_commit_message_encoded,
3436
generate_commit_message_template,
3437
make_commit_message_template_encoded,
3441
commit_stamp = offset = None
3442
if commit_time is not None:
3444
commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3445
except ValueError, e:
3446
raise errors.BzrCommandError(gettext(
3447
"Could not parse --commit-time: " + str(e)))
2181
3449
properties = {}
2183
tree, selected_list = tree_files(selected_list)
3451
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
2184
3452
if selected_list == ['']:
2185
3453
# workaround - commit of root of tree should be exactly the same
2186
3454
# as just default commit in that tree, and succeed even though
2187
3455
# selected-file merge commit is not done yet
2188
3456
selected_list = []
2190
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
3460
bug_property = bugtracker.encode_fixes_bug_urls(
3461
self._iter_bug_fix_urls(fixes, tree.branch))
2191
3462
if bug_property:
2192
3463
properties['bugs'] = bug_property
2194
3465
if local and not tree.branch.get_bound_location():
2195
3466
raise errors.LocalRequiresBoundBranch()
3468
if message is not None:
3470
file_exists = osutils.lexists(message)
3471
except UnicodeError:
3472
# The commit message contains unicode characters that can't be
3473
# represented in the filesystem encoding, so that can't be a
3478
'The commit message is a file name: "%(f)s".\n'
3479
'(use --file "%(f)s" to take commit message from that file)'
3481
ui.ui_factory.show_warning(warning_msg)
3483
message = message.replace('\r\n', '\n')
3484
message = message.replace('\r', '\n')
3486
raise errors.BzrCommandError(gettext(
3487
"please specify either --message or --file"))
2197
3489
def get_message(commit_obj):
2198
3490
"""Callback to get commit message"""
2199
my_message = message
2200
if my_message is None and not file:
2201
template = make_commit_message_template(tree, selected_list)
2202
my_message = edit_commit_message(template)
2203
if my_message is None:
2204
raise errors.BzrCommandError("please specify a commit"
2205
" message with either --message or --file")
2206
elif my_message and file:
2207
raise errors.BzrCommandError(
2208
"please specify either --message or --file")
2210
my_message = codecs.open(file, 'rt',
2211
bzrlib.user_encoding).read()
2212
if my_message == "":
2213
raise errors.BzrCommandError("empty commit message specified")
3494
my_message = f.read().decode(osutils.get_user_encoding())
3497
elif message is not None:
3498
my_message = message
3500
# No message supplied: make one up.
3501
# text is the status of the tree
3502
text = make_commit_message_template_encoded(tree,
3503
selected_list, diff=show_diff,
3504
output_encoding=osutils.get_user_encoding())
3505
# start_message is the template generated from hooks
3506
# XXX: Warning - looks like hooks return unicode,
3507
# make_commit_message_template_encoded returns user encoding.
3508
# We probably want to be using edit_commit_message instead to
3510
my_message = set_commit_message(commit_obj)
3511
if my_message is None:
3512
start_message = generate_commit_message_template(commit_obj)
3513
my_message = edit_commit_message_encoded(text,
3514
start_message=start_message)
3515
if my_message is None:
3516
raise errors.BzrCommandError(gettext("please specify a commit"
3517
" message with either --message or --file"))
3518
if my_message == "":
3519
raise errors.BzrCommandError(gettext("Empty commit message specified."
3520
" Please specify a commit message with either"
3521
" --message or --file or leave a blank message"
3522
" with --message \"\"."))
2214
3523
return my_message
2217
reporter = ReportCommitToLog()
2219
reporter = NullCommitReporter()
3525
# The API permits a commit with a filter of [] to mean 'select nothing'
3526
# but the command line should not do that.
3527
if not selected_list:
3528
selected_list = None
2222
3530
tree.commit(message_callback=get_message,
2223
3531
specific_files=selected_list,
2224
3532
allow_pointless=unchanged, strict=strict, local=local,
2225
reporter=reporter, revprops=properties)
3533
reporter=None, verbose=verbose, revprops=properties,
3534
authors=author, timestamp=commit_stamp,
3536
exclude=tree.safe_relpath_files(exclude),
2226
3538
except PointlessCommit:
2227
# FIXME: This should really happen before the file is read in;
2228
# perhaps prepare the commit; get the message; then actually commit
2229
raise errors.BzrCommandError("no changes to commit."
2230
" use --unchanged to commit anyhow")
3539
raise errors.BzrCommandError(gettext("No changes to commit."
3540
" Please 'bzr add' the files you want to commit, or use"
3541
" --unchanged to force an empty commit."))
2231
3542
except ConflictsInTree:
2232
raise errors.BzrCommandError('Conflicts detected in working '
3543
raise errors.BzrCommandError(gettext('Conflicts detected in working '
2233
3544
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
2235
3546
except StrictCommitFailed:
2236
raise errors.BzrCommandError("Commit refused because there are"
2237
" unknown files in the working tree.")
3547
raise errors.BzrCommandError(gettext("Commit refused because there are"
3548
" unknown files in the working tree."))
2238
3549
except errors.BoundBranchOutOfDate, e:
2239
raise errors.BzrCommandError(str(e) + "\n"
2240
'To commit to master branch, run update and then commit.\n'
2241
'You can also pass --local to commit to continue working '
3550
e.extra_help = (gettext("\n"
3551
'To commit to master branch, run update and then commit.\n'
3552
'You can also pass --local to commit to continue working '
2245
3557
class cmd_check(Command):
2246
"""Validate consistency of branch history.
2248
This command checks various invariants about the branch storage to
2249
detect data corruption or bzr bugs.
3558
__doc__ = """Validate working tree structure, branch consistency and repository history.
3560
This command checks various invariants about branch and repository storage
3561
to detect data corruption or bzr bugs.
3563
The working tree and branch checks will only give output if a problem is
3564
detected. The output fields of the repository check are:
3567
This is just the number of revisions checked. It doesn't
3571
This is just the number of versionedfiles checked. It
3572
doesn't indicate a problem.
3574
unreferenced ancestors
3575
Texts that are ancestors of other texts, but
3576
are not properly referenced by the revision ancestry. This is a
3577
subtle problem that Bazaar can work around.
3580
This is the total number of unique file contents
3581
seen in the checked revisions. It does not indicate a problem.
3584
This is the total number of repeated texts seen
3585
in the checked revisions. Texts can be repeated when their file
3586
entries are modified, but the file contents are not. It does not
3589
If no restrictions are specified, all Bazaar data that is found at the given
3590
location will be checked.
3594
Check the tree and branch at 'foo'::
3596
bzr check --tree --branch foo
3598
Check only the repository at 'bar'::
3600
bzr check --repo bar
3602
Check everything at 'baz'::
2252
3607
_see_also = ['reconcile']
2253
takes_args = ['branch?']
2254
takes_options = ['verbose']
3608
takes_args = ['path?']
3609
takes_options = ['verbose',
3610
Option('branch', help="Check the branch related to the"
3611
" current directory."),
3612
Option('repo', help="Check the repository related to the"
3613
" current directory."),
3614
Option('tree', help="Check the working tree related to"
3615
" the current directory.")]
2256
def run(self, branch=None, verbose=False):
2257
from bzrlib.check import check
2259
tree = WorkingTree.open_containing()[0]
2260
branch = tree.branch
2262
branch = Branch.open(branch)
2263
check(branch, verbose)
3617
def run(self, path=None, verbose=False, branch=False, repo=False,
3619
from bzrlib.check import check_dwim
3622
if not branch and not repo and not tree:
3623
branch = repo = tree = True
3624
check_dwim(path, verbose, do_branch=branch, do_repo=repo, do_tree=tree)
2266
3627
class cmd_upgrade(Command):
2267
"""Upgrade branch storage to current format.
2269
The check command or bzr developers may sometimes advise you to run
2270
this command. When the default format has changed you may also be warned
2271
during other operations to upgrade.
3628
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3630
When the default format has changed after a major new release of
3631
Bazaar, you may be informed during certain operations that you
3632
should upgrade. Upgrading to a newer format may improve performance
3633
or make new features available. It may however limit interoperability
3634
with older repositories or with older versions of Bazaar.
3636
If you wish to upgrade to a particular format rather than the
3637
current default, that can be specified using the --format option.
3638
As a consequence, you can use the upgrade command this way to
3639
"downgrade" to an earlier format, though some conversions are
3640
a one way process (e.g. changing from the 1.x default to the
3641
2.x default) so downgrading is not always possible.
3643
A backup.bzr.~#~ directory is created at the start of the conversion
3644
process (where # is a number). By default, this is left there on
3645
completion. If the conversion fails, delete the new .bzr directory
3646
and rename this one back in its place. Use the --clean option to ask
3647
for the backup.bzr directory to be removed on successful conversion.
3648
Alternatively, you can delete it by hand if everything looks good
3651
If the location given is a shared repository, dependent branches
3652
are also converted provided the repository converts successfully.
3653
If the conversion of a branch fails, remaining branches are still
3656
For more information on upgrades, see the Bazaar Upgrade Guide,
3657
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
2274
_see_also = ['check']
3660
_see_also = ['check', 'reconcile', 'formats']
2275
3661
takes_args = ['url?']
2276
3662
takes_options = [
2277
RegistryOption('format',
2278
help='Upgrade to a specific format. See "bzr help'
2279
' formats" for details',
2280
registry=bzrdir.format_registry,
2281
converter=bzrdir.format_registry.make_bzrdir,
2282
value_switches=True, title='Branch format'),
3663
RegistryOption('format',
3664
help='Upgrade to a specific format. See "bzr help'
3665
' formats" for details.',
3666
lazy_registry=('bzrlib.controldir', 'format_registry'),
3667
converter=lambda name: controldir.format_registry.make_bzrdir(name),
3668
value_switches=True, title='Branch format'),
3670
help='Remove the backup.bzr directory if successful.'),
3672
help="Show what would be done, but don't actually do anything."),
2285
def run(self, url='.', format=None):
3675
def run(self, url='.', format=None, clean=False, dry_run=False):
2286
3676
from bzrlib.upgrade import upgrade
2288
format = bzrdir.format_registry.make_bzrdir('default')
2289
upgrade(url, format)
3677
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3679
if len(exceptions) == 1:
3680
# Compatibility with historical behavior
2292
3686
class cmd_whoami(Command):
2293
"""Show or set bzr user id.
2297
bzr whoami 'Frank Chu <fchu@example.com>'
3687
__doc__ = """Show or set bzr user id.
3690
Show the email of the current user::
3694
Set the current user::
3696
bzr whoami "Frank Chu <fchu@example.com>"
2299
takes_options = [ Option('email',
2300
help='display email address only'),
3698
takes_options = [ 'directory',
3700
help='Display email address only.'),
2301
3701
Option('branch',
2302
help='set identity for the current branch instead of '
3702
help='Set identity for the current branch instead of '
2305
3705
takes_args = ['name?']
2306
3706
encoding_type = 'replace'
2308
3708
@display_command
2309
def run(self, email=False, branch=False, name=None):
3709
def run(self, email=False, branch=False, name=None, directory=None):
2310
3710
if name is None:
2311
# use branch if we're inside one; otherwise global config
2313
c = Branch.open_containing('.')[0].get_config()
2314
except errors.NotBranchError:
2315
c = config.GlobalConfig()
3711
if directory is None:
3712
# use branch if we're inside one; otherwise global config
3714
c = Branch.open_containing(u'.')[0].get_config()
3715
except errors.NotBranchError:
3716
c = _mod_config.GlobalConfig()
3718
c = Branch.open(directory).get_config()
2317
3720
self.outf.write(c.user_email() + '\n')
2319
3722
self.outf.write(c.username() + '\n')
3726
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
2322
3729
# display a warning if an email address isn't included in the given name.
2324
config.extract_email_address(name)
3731
_mod_config.extract_email_address(name)
2325
3732
except errors.NoEmailInUsername, e:
2326
3733
warning('"%s" does not seem to contain an email address. '
2327
3734
'This is allowed, but not recommended.', name)
2329
3736
# use global config unless --branch given
2331
c = Branch.open_containing('.')[0].get_config()
3738
if directory is None:
3739
c = Branch.open_containing(u'.')[0].get_config()
3741
c = Branch.open(directory).get_config()
2333
c = config.GlobalConfig()
3743
c = _mod_config.GlobalConfig()
2334
3744
c.set_user_option('email', name)
2337
3747
class cmd_nick(Command):
2338
"""Print or set the branch nickname.
2340
If unset, the tree root directory name is used as the nickname
2341
To print the current nickname, execute with no argument.
3748
__doc__ = """Print or set the branch nickname.
3750
If unset, the tree root directory name is used as the nickname.
3751
To print the current nickname, execute with no argument.
3753
Bound branches use the nickname of its master branch unless it is set
2344
3757
_see_also = ['info']
2345
3758
takes_args = ['nickname?']
2346
def run(self, nickname=None):
2347
branch = Branch.open_containing(u'.')[0]
3759
takes_options = ['directory']
3760
def run(self, nickname=None, directory=u'.'):
3761
branch = Branch.open_containing(directory)[0]
2348
3762
if nickname is None:
2349
3763
self.printme(branch)
2420
3909
takes_args = ['testspecs*']
2421
3910
takes_options = ['verbose',
2423
help='stop when one test fails',
3912
help='Stop when one test fails.',
2424
3913
short_name='1',
2426
Option('keep-output',
2427
help='keep output directories when tests fail'),
2428
3915
Option('transport',
2429
3916
help='Use a different transport by default '
2430
3917
'throughout the test suite.',
2431
3918
type=get_transport_type),
2432
Option('benchmark', help='run the bzr benchmarks.'),
3920
help='Run the benchmarks rather than selftests.',
2433
3922
Option('lsprof-timed',
2434
help='generate lsprof output for benchmarked'
3923
help='Generate lsprof output for benchmarked'
2435
3924
' sections of code.'),
2436
Option('cache-dir', type=str,
2437
help='a directory to cache intermediate'
2438
' benchmark steps'),
2439
Option('clean-output',
2440
help='clean temporary tests directories'
2441
' without running tests'),
3925
Option('lsprof-tests',
3926
help='Generate lsprof output for each test.'),
2442
3927
Option('first',
2443
help='run all tests, but run specified tests first',
3928
help='Run all tests, but run specified tests first.',
2444
3929
short_name='f',
2446
Option('numbered-dirs',
2447
help='use numbered dirs for TestCaseInTempDir'),
2448
3931
Option('list-only',
2449
help='list the tests instead of running them'),
3932
help='List the tests instead of running them.'),
3933
RegistryOption('parallel',
3934
help="Run the test suite in parallel.",
3935
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3936
value_switches=False,
2450
3938
Option('randomize', type=str, argname="SEED",
2451
help='randomize the order of tests using the given'
2452
' seed or "now" for the current time'),
2453
Option('exclude', type=str, argname="PATTERN",
2455
help='exclude tests that match this regular'
3939
help='Randomize the order of tests using the given'
3940
' seed or "now" for the current time.'),
3941
ListOption('exclude', type=str, argname="PATTERN",
3943
help='Exclude tests that match this regular'
3946
help='Output test progress via subunit.'),
3947
Option('strict', help='Fail on missing dependencies or '
3949
Option('load-list', type=str, argname='TESTLISTFILE',
3950
help='Load a test id list from a text file.'),
3951
ListOption('debugflag', type=str, short_name='E',
3952
help='Turn on a selftest debug flag.'),
3953
ListOption('starting-with', type=str, argname='TESTID',
3954
param_name='starting_with', short_name='s',
3956
'Load only the tests starting with TESTID.'),
3958
help="By default we disable fsync and fdatasync"
3959
" while running the test suite.")
2458
3961
encoding_type = 'replace'
2460
def run(self, testspecs_list=None, verbose=None, one=False,
2461
keep_output=False, transport=None, benchmark=None,
2462
lsprof_timed=None, cache_dir=None, clean_output=False,
2463
first=False, numbered_dirs=None, list_only=False,
2464
randomize=None, exclude=None):
2466
from bzrlib.tests import selftest
2467
import bzrlib.benchmarks as benchmarks
2468
from bzrlib.benchmarks import tree_creator
2471
from bzrlib.tests import clean_selftest_output
2472
clean_selftest_output()
2475
warning("notice: selftest --keep-output "
2476
"is no longer supported; "
2477
"test output is always removed")
2479
if numbered_dirs is None and sys.platform == 'win32':
2480
numbered_dirs = True
2482
if cache_dir is not None:
2483
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2484
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2485
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
3964
Command.__init__(self)
3965
self.additional_selftest_args = {}
3967
def run(self, testspecs_list=None, verbose=False, one=False,
3968
transport=None, benchmark=None,
3970
first=False, list_only=False,
3971
randomize=None, exclude=None, strict=False,
3972
load_list=None, debugflag=None, starting_with=None, subunit=False,
3973
parallel=None, lsprof_tests=False,
3975
from bzrlib import tests
2487
3977
if testspecs_list is not None:
2488
3978
pattern = '|'.join(testspecs_list)
3983
from bzrlib.tests import SubUnitBzrRunner
3985
raise errors.BzrCommandError(gettext("subunit not available. subunit "
3986
"needs to be installed to use --subunit."))
3987
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3988
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3989
# stdout, which would corrupt the subunit stream.
3990
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3991
# following code can be deleted when it's sufficiently deployed
3992
# -- vila/mgz 20100514
3993
if (sys.platform == "win32"
3994
and getattr(sys.stdout, 'fileno', None) is not None):
3996
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3998
self.additional_selftest_args.setdefault(
3999
'suite_decorators', []).append(parallel)
2492
test_suite_factory = benchmarks.test_suite
2495
# TODO: should possibly lock the history file...
2496
benchfile = open(".perf_history", "at", buffering=1)
4001
raise errors.BzrCommandError(gettext(
4002
"--benchmark is no longer supported from bzr 2.2; "
4003
"use bzr-usertest instead"))
4004
test_suite_factory = None
4006
exclude_pattern = None
2498
test_suite_factory = None
4008
exclude_pattern = '(' + '|'.join(exclude) + ')'
4010
self._disable_fsync()
4011
selftest_kwargs = {"verbose": verbose,
4013
"stop_on_failure": one,
4014
"transport": transport,
4015
"test_suite_factory": test_suite_factory,
4016
"lsprof_timed": lsprof_timed,
4017
"lsprof_tests": lsprof_tests,
4018
"matching_tests_first": first,
4019
"list_only": list_only,
4020
"random_seed": randomize,
4021
"exclude_pattern": exclude_pattern,
4023
"load_list": load_list,
4024
"debug_flags": debugflag,
4025
"starting_with": starting_with
4027
selftest_kwargs.update(self.additional_selftest_args)
4029
# Make deprecation warnings visible, unless -Werror is set
4030
cleanup = symbol_versioning.activate_deprecation_warnings(
2503
result = selftest(verbose=verbose,
2505
stop_on_failure=one,
2506
transport=transport,
2507
test_suite_factory=test_suite_factory,
2508
lsprof_timed=lsprof_timed,
2509
bench_history=benchfile,
2510
matching_tests_first=first,
2511
numbered_dirs=numbered_dirs,
2512
list_only=list_only,
2513
random_seed=randomize,
2514
exclude_pattern=exclude
4033
result = tests.selftest(**selftest_kwargs)
2517
if benchfile is not None:
2520
info('tests passed')
2522
info('tests failed')
2523
4036
return int(not result)
4038
def _disable_fsync(self):
4039
"""Change the 'os' functionality to not synchronize."""
4040
self._orig_fsync = getattr(os, 'fsync', None)
4041
if self._orig_fsync is not None:
4042
os.fsync = lambda filedes: None
4043
self._orig_fdatasync = getattr(os, 'fdatasync', None)
4044
if self._orig_fdatasync is not None:
4045
os.fdatasync = lambda filedes: None
2526
4048
class cmd_version(Command):
2527
"""Show version of bzr."""
4049
__doc__ = """Show version of bzr."""
4051
encoding_type = 'replace'
4053
Option("short", help="Print just the version number."),
2529
4056
@display_command
4057
def run(self, short=False):
2531
4058
from bzrlib.version import show_version
4060
self.outf.write(bzrlib.version_string + '\n')
4062
show_version(to_file=self.outf)
2535
4065
class cmd_rocks(Command):
2536
"""Statement of optimism."""
4066
__doc__ = """Statement of optimism."""
2540
4070
@display_command
2542
print "It sure does!"
4072
self.outf.write(gettext("It sure does!\n"))
2545
4075
class cmd_find_merge_base(Command):
2546
"""Find and print a base revision for merging two branches."""
4076
__doc__ = """Find and print a base revision for merging two branches."""
2547
4077
# TODO: Options to specify revisions on either side, as if
2548
4078
# merging only part of the history.
2549
4079
takes_args = ['branch', 'other']
2552
4082
@display_command
2553
4083
def run(self, branch, other):
2554
from bzrlib.revision import ensure_null, MultipleRevisionSources
4084
from bzrlib.revision import ensure_null
2556
4086
branch1 = Branch.open_containing(branch)[0]
2557
4087
branch2 = Branch.open_containing(other)[0]
4088
self.add_cleanup(branch1.lock_read().unlock)
4089
self.add_cleanup(branch2.lock_read().unlock)
2559
4090
last1 = ensure_null(branch1.last_revision())
2560
4091
last2 = ensure_null(branch2.last_revision())
2562
4093
graph = branch1.repository.get_graph(branch2.repository)
2563
4094
base_rev_id = graph.find_unique_lca(last1, last2)
2565
print 'merge base is revision %s' % base_rev_id
4096
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
2568
4099
class cmd_merge(Command):
2569
"""Perform a three-way merge.
2571
The branch is the branch you will merge from. By default, it will merge
2572
the latest revision. If you specify a revision, that revision will be
2573
merged. If you specify two revisions, the first will be used as a BASE,
2574
and the second one as OTHER. Revision numbers are always relative to the
2577
By default, bzr will try to merge in all new work from the other
2578
branch, automatically determining an appropriate base. If this
2579
fails, you may need to give an explicit base.
4100
__doc__ = """Perform a three-way merge.
4102
The source of the merge can be specified either in the form of a branch,
4103
or in the form of a path to a file containing a merge directive generated
4104
with bzr send. If neither is specified, the default is the upstream branch
4105
or the branch most recently merged using --remember. The source of the
4106
merge may also be specified in the form of a path to a file in another
4107
branch: in this case, only the modifications to that file are merged into
4108
the current working tree.
4110
When merging from a branch, by default bzr will try to merge in all new
4111
work from the other branch, automatically determining an appropriate base
4112
revision. If this fails, you may need to give an explicit base.
4114
To pick a different ending revision, pass "--revision OTHER". bzr will
4115
try to merge in all new work up to and including revision OTHER.
4117
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4118
through OTHER, excluding BASE but including OTHER, will be merged. If this
4119
causes some revisions to be skipped, i.e. if the destination branch does
4120
not already contain revision BASE, such a merge is commonly referred to as
4121
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4122
cherrypicks. The changes look like a normal commit, and the history of the
4123
changes from the other branch is not stored in the commit.
4125
Revision numbers are always relative to the source branch.
2581
4127
Merge will do its best to combine the changes in two branches, but there
2582
4128
are some kinds of problems only a human can fix. When it encounters those,
2583
4129
it will mark a conflict. A conflict means that you need to fix something,
2586
4132
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
2588
If there is no default branch set, the first merge will set it. After
2589
that, you can omit the branch to use the default. To change the
2590
default, use --remember. The value will only be saved if the remote
2591
location can be accessed.
4134
If there is no default branch set, the first merge will set it (use
4135
--no-remember to avoid setting it). After that, you can omit the branch
4136
to use the default. To change the default, use --remember. The value will
4137
only be saved if the remote location can be accessed.
2593
4139
The results of the merge are placed into the destination working
2594
4140
directory, where they can be reviewed (with bzr diff), tested, and then
2595
4141
committed to record the result of the merge.
2599
To merge the latest revision from bzr.dev:
2600
bzr merge ../bzr.dev
2602
To merge changes up to and including revision 82 from bzr.dev:
2603
bzr merge -r 82 ../bzr.dev
2605
To merge the changes introduced by 82, without previous changes:
2606
bzr merge -r 81..82 ../bzr.dev
2608
4143
merge refuses to run if there are any uncommitted changes, unless
4144
--force is given. If --force is given, then the changes from the source
4145
will be merged with the current working tree, including any uncommitted
4146
changes in the tree. The --force option can also be used to create a
4147
merge revision which has more than two parents.
4149
If one would like to merge changes from the working tree of the other
4150
branch without merging any committed revisions, the --uncommitted option
4153
To select only some changes to merge, use "merge -i", which will prompt
4154
you to apply each diff hunk and file change, similar to "shelve".
4157
To merge all new revisions from bzr.dev::
4159
bzr merge ../bzr.dev
4161
To merge changes up to and including revision 82 from bzr.dev::
4163
bzr merge -r 82 ../bzr.dev
4165
To merge the changes introduced by 82, without previous changes::
4167
bzr merge -r 81..82 ../bzr.dev
4169
To apply a merge directive contained in /tmp/merge::
4171
bzr merge /tmp/merge
4173
To create a merge revision with three parents from two branches
4174
feature1a and feature1b:
4176
bzr merge ../feature1a
4177
bzr merge ../feature1b --force
4178
bzr commit -m 'revision with three parents'
2612
_see_also = ['update', 'remerge']
2613
takes_args = ['branch?']
2614
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
4181
encoding_type = 'exact'
4182
_see_also = ['update', 'remerge', 'status-flags', 'send']
4183
takes_args = ['location?']
4188
help='Merge even if the destination tree has uncommitted changes.'),
2615
4192
Option('show-base', help="Show base revision text in "
2617
4194
Option('uncommitted', help='Apply uncommitted changes'
2618
' from a working copy, instead of branch changes'),
4195
' from a working copy, instead of branch changes.'),
2619
4196
Option('pull', help='If the destination is already'
2620
4197
' completely merged into the source, pull from the'
2621
' source rather than merging. When this happens,'
4198
' source rather than merging. When this happens,'
2622
4199
' you do not need to commit the result.'),
2624
help='Branch to merge into, '
2625
'rather than the one containing the working directory',
4200
custom_help('directory',
4201
help='Branch to merge into, '
4202
'rather than the one containing the working directory.'),
4203
Option('preview', help='Instead of merging, show a diff of the'
4205
Option('interactive', help='Select changes interactively.',
2631
def run(self, branch=None, revision=None, force=False, merge_type=None,
2632
show_base=False, reprocess=False, remember=False,
4209
def run(self, location=None, revision=None, force=False,
4210
merge_type=None, show_base=False, reprocess=None, remember=None,
2633
4211
uncommitted=False, pull=False,
2634
4212
directory=None,
2636
from bzrlib.tag import _merge_tags_if_possible
2637
other_revision_id = None
2638
4216
if merge_type is None:
2639
4217
merge_type = _mod_merge.Merge3Merger
2641
4219
if directory is None: directory = u'.'
2642
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2643
# inventory. Because merge is a mutating operation, it really
2644
# should be a lock_write() for the whole cmd_merge operation.
2645
# However, cmd_merge open's its own tree in _merge_helper, which
2646
# means if we lock here, the later lock_write() will always block.
2647
# Either the merge helper code should be updated to take a tree,
2648
# (What about tree.merge_from_branch?)
4220
possible_transports = []
4222
allow_pending = True
4223
verified = 'inapplicable'
2649
4225
tree = WorkingTree.open_containing(directory)[0]
4226
if tree.branch.revno() == 0:
4227
raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4228
'https://bugs.launchpad.net/bzr/+bug/308562'))
4231
basis_tree = tree.revision_tree(tree.last_revision())
4232
except errors.NoSuchRevision:
4233
basis_tree = tree.basis_tree()
4235
# die as quickly as possible if there are uncommitted changes
4237
if tree.has_changes():
4238
raise errors.UncommittedChanges(tree)
4240
view_info = _get_view_info_for_change_reporter(tree)
2650
4241
change_reporter = delta._ChangeReporter(
2651
unversioned_filter=tree.is_ignored)
2653
if branch is not None:
4242
unversioned_filter=tree.is_ignored, view_info=view_info)
4243
pb = ui.ui_factory.nested_progress_bar()
4244
self.add_cleanup(pb.finished)
4245
self.add_cleanup(tree.lock_write().unlock)
4246
if location is not None:
2655
mergeable = bundle.read_mergeable_from_url(
4248
mergeable = bundle.read_mergeable_from_url(location,
4249
possible_transports=possible_transports)
2657
4250
except errors.NotABundle:
2658
pass # Continue on considering this url a Branch
4254
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4255
' with bundles or merge directives.'))
2660
4257
if revision is not None:
2661
raise errors.BzrCommandError(
2662
'Cannot use -r with merge directives or bundles')
2663
other_revision_id = mergeable.install_revisions(
2664
tree.branch.repository)
2665
revision = [RevisionSpec.from_string(
2666
'revid:' + other_revision_id)]
2668
if revision is None \
2669
or len(revision) < 1 or revision[0].needs_branch():
2670
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2672
if revision is None or len(revision) < 1:
2675
other = [branch, None]
2678
other = [branch, -1]
2679
other_branch, path = Branch.open_containing(branch)
2682
raise errors.BzrCommandError('Cannot use --uncommitted and'
2683
' --revision at the same time.')
2684
branch = revision[0].get_branch() or branch
2685
if len(revision) == 1:
2687
if other_revision_id is not None:
2692
other_branch, path = Branch.open_containing(branch)
2693
revno = revision[0].in_history(other_branch).revno
2694
other = [branch, revno]
2696
assert len(revision) == 2
2697
if None in revision:
2698
raise errors.BzrCommandError(
2699
"Merge doesn't permit empty revision specifier.")
2700
base_branch, path = Branch.open_containing(branch)
2701
branch1 = revision[1].get_branch() or branch
2702
other_branch, path1 = Branch.open_containing(branch1)
2703
if revision[0].get_branch() is not None:
2704
# then path was obtained from it, and is None.
2707
base = [branch, revision[0].in_history(base_branch).revno]
2708
other = [branch1, revision[1].in_history(other_branch).revno]
2710
if ((tree.branch.get_parent() is None or remember) and
2711
other_branch is not None):
2712
tree.branch.set_parent(other_branch.base)
2714
# pull tags now... it's a bit inconsistent to do it ahead of copying
2715
# the history but that's done inside the merge code
2716
if other_branch is not None:
2717
_merge_tags_if_possible(other_branch, tree.branch)
2720
interesting_files = [path]
2722
interesting_files = None
2723
pb = ui.ui_factory.nested_progress_bar()
4258
raise errors.BzrCommandError(gettext(
4259
'Cannot use -r with merge directives or bundles'))
4260
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4263
if merger is None and uncommitted:
4264
if revision is not None and len(revision) > 0:
4265
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4266
' --revision at the same time.'))
4267
merger = self.get_merger_from_uncommitted(tree, location, None)
4268
allow_pending = False
4271
merger, allow_pending = self._get_merger_from_branch(tree,
4272
location, revision, remember, possible_transports, None)
4274
merger.merge_type = merge_type
4275
merger.reprocess = reprocess
4276
merger.show_base = show_base
4277
self.sanity_check_merger(merger)
4278
if (merger.base_rev_id == merger.other_rev_id and
4279
merger.other_rev_id is not None):
4280
# check if location is a nonexistent file (and not a branch) to
4281
# disambiguate the 'Nothing to do'
4282
if merger.interesting_files:
4283
if not merger.other_tree.has_filename(
4284
merger.interesting_files[0]):
4285
note(gettext("merger: ") + str(merger))
4286
raise errors.PathsDoNotExist([location])
4287
note(gettext('Nothing to do.'))
4289
if pull and not preview:
4290
if merger.interesting_files is not None:
4291
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4292
if (merger.base_rev_id == tree.last_revision()):
4293
result = tree.pull(merger.other_branch, False,
4294
merger.other_rev_id)
4295
result.report(self.outf)
4297
if merger.this_basis is None:
4298
raise errors.BzrCommandError(gettext(
4299
"This branch has no commits."
4300
" (perhaps you would prefer 'bzr pull')"))
4302
return self._do_preview(merger)
4304
return self._do_interactive(merger)
4306
return self._do_merge(merger, change_reporter, allow_pending,
4309
def _get_preview(self, merger):
4310
tree_merger = merger.make_merger()
4311
tt = tree_merger.make_preview_transform()
4312
self.add_cleanup(tt.finalize)
4313
result_tree = tt.get_preview_tree()
4316
def _do_preview(self, merger):
4317
from bzrlib.diff import show_diff_trees
4318
result_tree = self._get_preview(merger)
4319
path_encoding = osutils.get_diff_header_encoding()
4320
show_diff_trees(merger.this_tree, result_tree, self.outf,
4321
old_label='', new_label='',
4322
path_encoding=path_encoding)
4324
def _do_merge(self, merger, change_reporter, allow_pending, verified):
4325
merger.change_reporter = change_reporter
4326
conflict_count = merger.do_merge()
4328
merger.set_pending()
4329
if verified == 'failed':
4330
warning('Preview patch does not match changes')
4331
if conflict_count != 0:
4336
def _do_interactive(self, merger):
4337
"""Perform an interactive merge.
4339
This works by generating a preview tree of the merge, then using
4340
Shelver to selectively remove the differences between the working tree
4341
and the preview tree.
4343
from bzrlib import shelf_ui
4344
result_tree = self._get_preview(merger)
4345
writer = bzrlib.option.diff_writer_registry.get()
4346
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
4347
reporter=shelf_ui.ApplyReporter(),
4348
diff_writer=writer(sys.stdout))
2726
conflict_count = _merge_helper(
2727
other, base, other_rev_id=other_revision_id,
2728
check_clean=(not force),
2729
merge_type=merge_type,
2730
reprocess=reprocess,
2731
show_base=show_base,
2734
pb=pb, file_list=interesting_files,
2735
change_reporter=change_reporter)
2738
if conflict_count != 0:
4354
def sanity_check_merger(self, merger):
4355
if (merger.show_base and
4356
not merger.merge_type is _mod_merge.Merge3Merger):
4357
raise errors.BzrCommandError(gettext("Show-base is not supported for this"
4358
" merge type. %s") % merger.merge_type)
4359
if merger.reprocess is None:
4360
if merger.show_base:
4361
merger.reprocess = False
2742
except errors.AmbiguousBase, e:
2743
m = ("sorry, bzr can't determine the right merge base yet\n"
2744
"candidates are:\n "
2745
+ "\n ".join(e.bases)
2747
"please specify an explicit base with -r,\n"
2748
"and (if you want) report this to the bzr developers\n")
2751
# TODO: move up to common parent; this isn't merge-specific anymore.
2752
def _get_remembered_parent(self, tree, supplied_location, verb_string):
4363
# Use reprocess if the merger supports it
4364
merger.reprocess = merger.merge_type.supports_reprocess
4365
if merger.reprocess and not merger.merge_type.supports_reprocess:
4366
raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
4367
" for merge type %s.") %
4369
if merger.reprocess and merger.show_base:
4370
raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
4373
def _get_merger_from_branch(self, tree, location, revision, remember,
4374
possible_transports, pb):
4375
"""Produce a merger from a location, assuming it refers to a branch."""
4376
from bzrlib.tag import _merge_tags_if_possible
4377
# find the branch locations
4378
other_loc, user_location = self._select_branch_location(tree, location,
4380
if revision is not None and len(revision) == 2:
4381
base_loc, _unused = self._select_branch_location(tree,
4382
location, revision, 0)
4384
base_loc = other_loc
4386
other_branch, other_path = Branch.open_containing(other_loc,
4387
possible_transports)
4388
if base_loc == other_loc:
4389
base_branch = other_branch
4391
base_branch, base_path = Branch.open_containing(base_loc,
4392
possible_transports)
4393
# Find the revision ids
4394
other_revision_id = None
4395
base_revision_id = None
4396
if revision is not None:
4397
if len(revision) >= 1:
4398
other_revision_id = revision[-1].as_revision_id(other_branch)
4399
if len(revision) == 2:
4400
base_revision_id = revision[0].as_revision_id(base_branch)
4401
if other_revision_id is None:
4402
other_revision_id = _mod_revision.ensure_null(
4403
other_branch.last_revision())
4404
# Remember where we merge from. We need to remember if:
4405
# - user specify a location (and we don't merge from the parent
4407
# - user ask to remember or there is no previous location set to merge
4408
# from and user didn't ask to *not* remember
4409
if (user_location is not None
4411
or (remember is None
4412
and tree.branch.get_submit_branch() is None)))):
4413
tree.branch.set_submit_branch(other_branch.base)
4414
# Merge tags (but don't set them in the master branch yet, the user
4415
# might revert this merge). Commit will propagate them.
4416
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
4417
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4418
other_revision_id, base_revision_id, other_branch, base_branch)
4419
if other_path != '':
4420
allow_pending = False
4421
merger.interesting_files = [other_path]
4423
allow_pending = True
4424
return merger, allow_pending
4426
def get_merger_from_uncommitted(self, tree, location, pb):
4427
"""Get a merger for uncommitted changes.
4429
:param tree: The tree the merger should apply to.
4430
:param location: The location containing uncommitted changes.
4431
:param pb: The progress bar to use for showing progress.
4433
location = self._select_branch_location(tree, location)[0]
4434
other_tree, other_path = WorkingTree.open_containing(location)
4435
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
4436
if other_path != '':
4437
merger.interesting_files = [other_path]
4440
def _select_branch_location(self, tree, user_location, revision=None,
4442
"""Select a branch location, according to possible inputs.
4444
If provided, branches from ``revision`` are preferred. (Both
4445
``revision`` and ``index`` must be supplied.)
4447
Otherwise, the ``location`` parameter is used. If it is None, then the
4448
``submit`` or ``parent`` location is used, and a note is printed.
4450
:param tree: The working tree to select a branch for merging into
4451
:param location: The location entered by the user
4452
:param revision: The revision parameter to the command
4453
:param index: The index to use for the revision parameter. Negative
4454
indices are permitted.
4455
:return: (selected_location, user_location). The default location
4456
will be the user-entered location.
4458
if (revision is not None and index is not None
4459
and revision[index] is not None):
4460
branch = revision[index].get_branch()
4461
if branch is not None:
4462
return branch, branch
4463
if user_location is None:
4464
location = self._get_remembered(tree, 'Merging from')
4466
location = user_location
4467
return location, user_location
4469
def _get_remembered(self, tree, verb_string):
2753
4470
"""Use tree.branch's parent if none was supplied.
2755
4472
Report if the remembered location was used.
2757
if supplied_location is not None:
2758
return supplied_location
2759
stored_location = tree.branch.get_parent()
4474
stored_location = tree.branch.get_submit_branch()
4475
stored_location_type = "submit"
4476
if stored_location is None:
4477
stored_location = tree.branch.get_parent()
4478
stored_location_type = "parent"
2760
4479
mutter("%s", stored_location)
2761
4480
if stored_location is None:
2762
raise errors.BzrCommandError("No location specified or remembered")
2763
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2764
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
4481
raise errors.BzrCommandError(gettext("No location specified or remembered"))
4482
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4483
note(gettext("{0} remembered {1} location {2}").format(verb_string,
4484
stored_location_type, display_url))
2765
4485
return stored_location
2768
4488
class cmd_remerge(Command):
4489
__doc__ = """Redo a merge.
2771
4491
Use this if you want to try a different merge technique while resolving
2772
conflicts. Some merge techniques are better than others, and remerge
4492
conflicts. Some merge techniques are better than others, and remerge
2773
4493
lets you try different ones on different files.
2775
4495
The options for remerge have the same meaning and defaults as the ones for
2776
4496
merge. The difference is that remerge can (only) be run when there is a
2777
4497
pending merge, and it lets you specify particular files.
2781
$ bzr remerge --show-base
2782
4500
Re-do the merge of all conflicted files, and show the base text in
2783
conflict regions, in addition to the usual THIS and OTHER texts.
2785
$ bzr remerge --merge-type weave --reprocess foobar
4501
conflict regions, in addition to the usual THIS and OTHER texts::
4503
bzr remerge --show-base
2786
4505
Re-do the merge of "foobar", using the weave merge algorithm, with
2787
additional processing to reduce the size of conflict regions.
4506
additional processing to reduce the size of conflict regions::
4508
bzr remerge --merge-type weave --reprocess foobar
2789
4510
takes_args = ['file*']
2790
takes_options = ['merge-type', 'reprocess',
2791
Option('show-base', help="Show base revision text in "
4515
help="Show base revision text in conflicts."),
2794
4518
def run(self, file_list=None, merge_type=None, show_base=False,
2795
4519
reprocess=False):
4520
from bzrlib.conflicts import restore
2796
4521
if merge_type is None:
2797
4522
merge_type = _mod_merge.Merge3Merger
2798
tree, file_list = tree_files(file_list)
4523
tree, file_list = WorkingTree.open_containing_paths(file_list)
4524
self.add_cleanup(tree.lock_write().unlock)
4525
parents = tree.get_parent_ids()
4526
if len(parents) != 2:
4527
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4528
" merges. Not cherrypicking or"
4530
repository = tree.branch.repository
4531
interesting_ids = None
4533
conflicts = tree.conflicts()
4534
if file_list is not None:
4535
interesting_ids = set()
4536
for filename in file_list:
4537
file_id = tree.path2id(filename)
4539
raise errors.NotVersionedError(filename)
4540
interesting_ids.add(file_id)
4541
if tree.kind(file_id) != "directory":
4544
for name, ie in tree.inventory.iter_entries(file_id):
4545
interesting_ids.add(ie.file_id)
4546
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4548
# Remerge only supports resolving contents conflicts
4549
allowed_conflicts = ('text conflict', 'contents conflict')
4550
restore_files = [c.path for c in conflicts
4551
if c.typestring in allowed_conflicts]
4552
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4553
tree.set_conflicts(ConflictList(new_conflicts))
4554
if file_list is not None:
4555
restore_files = file_list
4556
for filename in restore_files:
4558
restore(tree.abspath(filename))
4559
except errors.NotConflicted:
4561
# Disable pending merges, because the file texts we are remerging
4562
# have not had those merges performed. If we use the wrong parents
4563
# list, we imply that the working tree text has seen and rejected
4564
# all the changes from the other tree, when in fact those changes
4565
# have not yet been seen.
4566
tree.set_parent_ids(parents[:1])
2801
parents = tree.get_parent_ids()
2802
if len(parents) != 2:
2803
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2804
" merges. Not cherrypicking or"
2806
repository = tree.branch.repository
2807
graph = repository.get_graph()
2808
base_revision = graph.find_unique_lca(parents[0], parents[1])
2809
base_tree = repository.revision_tree(base_revision)
2810
other_tree = repository.revision_tree(parents[1])
2811
interesting_ids = None
2813
conflicts = tree.conflicts()
2814
if file_list is not None:
2815
interesting_ids = set()
2816
for filename in file_list:
2817
file_id = tree.path2id(filename)
2819
raise errors.NotVersionedError(filename)
2820
interesting_ids.add(file_id)
2821
if tree.kind(file_id) != "directory":
2824
for name, ie in tree.inventory.iter_entries(file_id):
2825
interesting_ids.add(ie.file_id)
2826
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2828
# Remerge only supports resolving contents conflicts
2829
allowed_conflicts = ('text conflict', 'contents conflict')
2830
restore_files = [c.path for c in conflicts
2831
if c.typestring in allowed_conflicts]
2832
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2833
tree.set_conflicts(ConflictList(new_conflicts))
2834
if file_list is not None:
2835
restore_files = file_list
2836
for filename in restore_files:
2838
restore(tree.abspath(filename))
2839
except errors.NotConflicted:
2841
conflicts = _mod_merge.merge_inner(
2842
tree.branch, other_tree, base_tree,
2844
interesting_ids=interesting_ids,
2845
other_rev_id=parents[1],
2846
merge_type=merge_type,
2847
show_base=show_base,
2848
reprocess=reprocess)
4568
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4569
merger.interesting_ids = interesting_ids
4570
merger.merge_type = merge_type
4571
merger.show_base = show_base
4572
merger.reprocess = reprocess
4573
conflicts = merger.do_merge()
4575
tree.set_parent_ids(parents)
2851
4576
if conflicts > 0:
2934
4683
class cmd_shell_complete(Command):
2935
"""Show appropriate completions for context.
4684
__doc__ = """Show appropriate completions for context.
2937
4686
For a list of all available commands, say 'bzr shell-complete'.
2939
4688
takes_args = ['context?']
2940
4689
aliases = ['s-c']
2943
4692
@display_command
2944
4693
def run(self, context=None):
2945
4694
import shellcomplete
2946
4695
shellcomplete.shellcomplete(context)
2949
class cmd_fetch(Command):
2950
"""Copy in history from another branch but don't merge it.
2952
This is an internal method used for pull and merge.
2955
takes_args = ['from_branch', 'to_branch']
2956
def run(self, from_branch, to_branch):
2957
from bzrlib.fetch import Fetcher
2958
from_b = Branch.open(from_branch)
2959
to_b = Branch.open(to_branch)
2960
Fetcher(to_b, from_b)
2963
4698
class cmd_missing(Command):
2964
"""Show unmerged/unpulled revisions between two branches.
4699
__doc__ = """Show unmerged/unpulled revisions between two branches.
2966
4701
OTHER_BRANCH may be local or remote.
4703
To filter on a range of revisions, you can use the command -r begin..end
4704
-r revision requests a specific revision, -r ..end or -r begin.. are
4708
1 - some missing revisions
4709
0 - no missing revisions
4713
Determine the missing revisions between this and the branch at the
4714
remembered pull location::
4718
Determine the missing revisions between this and another branch::
4720
bzr missing http://server/branch
4722
Determine the missing revisions up to a specific revision on the other
4725
bzr missing -r ..-10
4727
Determine the missing revisions up to a specific revision on this
4730
bzr missing --my-revision ..-10
2969
4733
_see_also = ['merge', 'pull']
2970
4734
takes_args = ['other_branch?']
2971
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2973
'Display changes in the local branch only'),
2974
Option('this' , 'same as --mine-only'),
2975
Option('theirs-only',
2976
'Display changes in the remote branch only'),
2977
Option('other', 'same as --theirs-only'),
4737
Option('reverse', 'Reverse the order of revisions.'),
4739
'Display changes in the local branch only.'),
4740
Option('this' , 'Same as --mine-only.'),
4741
Option('theirs-only',
4742
'Display changes in the remote branch only.'),
4743
Option('other', 'Same as --theirs-only.'),
4747
custom_help('revision',
4748
help='Filter on other branch revisions (inclusive). '
4749
'See "help revisionspec" for details.'),
4750
Option('my-revision',
4751
type=_parse_revision_str,
4752
help='Filter on local branch revisions (inclusive). '
4753
'See "help revisionspec" for details.'),
4754
Option('include-merged',
4755
'Show all revisions in addition to the mainline ones.'),
4756
Option('include-merges', hidden=True,
4757
help='Historical alias for --include-merged.'),
2982
4759
encoding_type = 'replace'
2984
4761
@display_command
2985
4762
def run(self, other_branch=None, reverse=False, mine_only=False,
2986
theirs_only=False, log_format=None, long=False, short=False, line=False,
2987
show_ids=False, verbose=False, this=False, other=False):
4764
log_format=None, long=False, short=False, line=False,
4765
show_ids=False, verbose=False, this=False, other=False,
4766
include_merged=None, revision=None, my_revision=None,
4768
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
2988
4769
from bzrlib.missing import find_unmerged, iter_log_revisions
2989
from bzrlib.log import log_formatter
4774
if symbol_versioning.deprecated_passed(include_merges):
4775
ui.ui_factory.show_user_warning(
4776
'deprecated_command_option',
4777
deprecated_name='--include-merges',
4778
recommended_name='--include-merged',
4779
deprecated_in_version='2.5',
4780
command=self.invoked_as)
4781
if include_merged is None:
4782
include_merged = include_merges
4784
raise errors.BzrCommandError(gettext(
4785
'{0} and {1} are mutually exclusive').format(
4786
'--include-merges', '--include-merged'))
4787
if include_merged is None:
4788
include_merged = False
2996
local_branch = Branch.open_containing(u".")[0]
4793
# TODO: We should probably check that we don't have mine-only and
4794
# theirs-only set, but it gets complicated because we also have
4795
# this and other which could be used.
4802
local_branch = Branch.open_containing(directory)[0]
4803
self.add_cleanup(local_branch.lock_read().unlock)
2997
4805
parent = local_branch.get_parent()
2998
4806
if other_branch is None:
2999
4807
other_branch = parent
3000
4808
if other_branch is None:
3001
raise errors.BzrCommandError("No peer location known or specified.")
4809
raise errors.BzrCommandError(gettext("No peer location known"
3002
4811
display_url = urlutils.unescape_for_display(parent,
3003
4812
self.outf.encoding)
3004
print "Using last location: " + display_url
4813
message(gettext("Using saved parent location: {0}\n").format(
3006
4816
remote_branch = Branch.open(other_branch)
3007
4817
if remote_branch.base == local_branch.base:
3008
4818
remote_branch = local_branch
3009
local_branch.lock_read()
3011
remote_branch.lock_read()
3013
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
3014
if (log_format is None):
3015
log_format = log.log_formatter_registry.get_default(
3017
lf = log_format(to_file=self.outf,
3019
show_timezone='original')
3020
if reverse is False:
3021
local_extra.reverse()
3022
remote_extra.reverse()
3023
if local_extra and not theirs_only:
3024
print "You have %d extra revision(s):" % len(local_extra)
3025
for revision in iter_log_revisions(local_extra,
3026
local_branch.repository,
3028
lf.log_revision(revision)
3029
printed_local = True
3031
printed_local = False
3032
if remote_extra and not mine_only:
3033
if printed_local is True:
3035
print "You are missing %d revision(s):" % len(remote_extra)
3036
for revision in iter_log_revisions(remote_extra,
3037
remote_branch.repository,
3039
lf.log_revision(revision)
3040
if not remote_extra and not local_extra:
3042
print "Branches are up to date."
3046
remote_branch.unlock()
3048
local_branch.unlock()
4820
self.add_cleanup(remote_branch.lock_read().unlock)
4822
local_revid_range = _revision_range_to_revid_range(
4823
_get_revision_range(my_revision, local_branch,
4826
remote_revid_range = _revision_range_to_revid_range(
4827
_get_revision_range(revision,
4828
remote_branch, self.name()))
4830
local_extra, remote_extra = find_unmerged(
4831
local_branch, remote_branch, restrict,
4832
backward=not reverse,
4833
include_merged=include_merged,
4834
local_revid_range=local_revid_range,
4835
remote_revid_range=remote_revid_range)
4837
if log_format is None:
4838
registry = log.log_formatter_registry
4839
log_format = registry.get_default(local_branch)
4840
lf = log_format(to_file=self.outf,
4842
show_timezone='original')
4845
if local_extra and not theirs_only:
4846
message(ngettext("You have %d extra revision:\n",
4847
"You have %d extra revisions:\n",
4850
for revision in iter_log_revisions(local_extra,
4851
local_branch.repository,
4853
lf.log_revision(revision)
4854
printed_local = True
4857
printed_local = False
4859
if remote_extra and not mine_only:
4860
if printed_local is True:
4862
message(ngettext("You are missing %d revision:\n",
4863
"You are missing %d revisions:\n",
4864
len(remote_extra)) %
4866
for revision in iter_log_revisions(remote_extra,
4867
remote_branch.repository,
4869
lf.log_revision(revision)
4872
if mine_only and not local_extra:
4873
# We checked local, and found nothing extra
4874
message(gettext('This branch has no new revisions.\n'))
4875
elif theirs_only and not remote_extra:
4876
# We checked remote, and found nothing extra
4877
message(gettext('Other branch has no new revisions.\n'))
4878
elif not (mine_only or theirs_only or local_extra or
4880
# We checked both branches, and neither one had extra
4882
message(gettext("Branches are up to date.\n"))
3049
4884
if not status_code and parent is None and other_branch is not None:
3050
local_branch.lock_write()
3052
# handle race conditions - a parent might be set while we run.
3053
if local_branch.get_parent() is None:
3054
local_branch.set_parent(remote_branch.base)
3056
local_branch.unlock()
4885
self.add_cleanup(local_branch.lock_write().unlock)
4886
# handle race conditions - a parent might be set while we run.
4887
if local_branch.get_parent() is None:
4888
local_branch.set_parent(remote_branch.base)
3057
4889
return status_code
4892
class cmd_pack(Command):
4893
__doc__ = """Compress the data within a repository.
4895
This operation compresses the data within a bazaar repository. As
4896
bazaar supports automatic packing of repository, this operation is
4897
normally not required to be done manually.
4899
During the pack operation, bazaar takes a backup of existing repository
4900
data, i.e. pack files. This backup is eventually removed by bazaar
4901
automatically when it is safe to do so. To save disk space by removing
4902
the backed up pack files, the --clean-obsolete-packs option may be
4905
Warning: If you use --clean-obsolete-packs and your machine crashes
4906
during or immediately after repacking, you may be left with a state
4907
where the deletion has been written to disk but the new packs have not
4908
been. In this case the repository may be unusable.
4911
_see_also = ['repositories']
4912
takes_args = ['branch_or_repo?']
4914
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4917
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4918
dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4920
branch = dir.open_branch()
4921
repository = branch.repository
4922
except errors.NotBranchError:
4923
repository = dir.open_repository()
4924
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
3060
4927
class cmd_plugins(Command):
4928
__doc__ = """List the installed plugins.
4930
This command displays the list of installed plugins including
4931
version of plugin and a short description of each.
4933
--verbose shows the path where each plugin is located.
4935
A plugin is an external component for Bazaar that extends the
4936
revision control system, by adding or replacing code in Bazaar.
4937
Plugins can do a variety of things, including overriding commands,
4938
adding new commands, providing additional network transports and
4939
customizing log output.
4941
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4942
for further information on plugins including where to find them and how to
4943
install them. Instructions are also provided there on how to write new
4944
plugins using the Python programming language.
4946
takes_options = ['verbose']
3063
4948
@display_command
3065
import bzrlib.plugin
3066
from inspect import getdoc
3067
for name, plugin in bzrlib.plugin.all_plugins().items():
3068
if getattr(plugin, '__path__', None) is not None:
3069
print plugin.__path__[0]
3070
elif getattr(plugin, '__file__', None) is not None:
3071
print plugin.__file__
3077
print '\t', d.split('\n')[0]
4949
def run(self, verbose=False):
4950
from bzrlib import plugin
4951
# Don't give writelines a generator as some codecs don't like that
4952
self.outf.writelines(
4953
list(plugin.describe_plugins(show_paths=verbose)))
3080
4956
class cmd_testament(Command):
3081
"""Show testament (signing-form) of a revision."""
3082
takes_options = ['revision',
3083
Option('long', help='Produce long-format testament'),
3084
Option('strict', help='Produce a strict-format'
4957
__doc__ = """Show testament (signing-form) of a revision."""
4960
Option('long', help='Produce long-format testament.'),
4962
help='Produce a strict-format testament.')]
3086
4963
takes_args = ['branch?']
3087
4964
@display_command
3088
4965
def run(self, branch=u'.', revision=None, long=False, strict=False):
3592
5581
s.send_email(message)
5584
class cmd_send(Command):
5585
__doc__ = """Mail or create a merge-directive for submitting changes.
5587
A merge directive provides many things needed for requesting merges:
5589
* A machine-readable description of the merge to perform
5591
* An optional patch that is a preview of the changes requested
5593
* An optional bundle of revision data, so that the changes can be applied
5594
directly from the merge directive, without retrieving data from a
5597
`bzr send` creates a compact data set that, when applied using bzr
5598
merge, has the same effect as merging from the source branch.
5600
By default the merge directive is self-contained and can be applied to any
5601
branch containing submit_branch in its ancestory without needing access to
5604
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5605
revisions, but only a structured request to merge from the
5606
public_location. In that case the public_branch is needed and it must be
5607
up-to-date and accessible to the recipient. The public_branch is always
5608
included if known, so that people can check it later.
5610
The submit branch defaults to the parent of the source branch, but can be
5611
overridden. Both submit branch and public branch will be remembered in
5612
branch.conf the first time they are used for a particular branch. The
5613
source branch defaults to that containing the working directory, but can
5614
be changed using --from.
5616
Both the submit branch and the public branch follow the usual behavior with
5617
respect to --remember: If there is no default location set, the first send
5618
will set it (use --no-remember to avoid setting it). After that, you can
5619
omit the location to use the default. To change the default, use
5620
--remember. The value will only be saved if the location can be accessed.
5622
In order to calculate those changes, bzr must analyse the submit branch.
5623
Therefore it is most efficient for the submit branch to be a local mirror.
5624
If a public location is known for the submit_branch, that location is used
5625
in the merge directive.
5627
The default behaviour is to send the merge directive by mail, unless -o is
5628
given, in which case it is sent to a file.
5630
Mail is sent using your preferred mail program. This should be transparent
5631
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5632
If the preferred client can't be found (or used), your editor will be used.
5634
To use a specific mail program, set the mail_client configuration option.
5635
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5636
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5637
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5638
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5641
If mail is being sent, a to address is required. This can be supplied
5642
either on the commandline, by setting the submit_to configuration
5643
option in the branch itself or the child_submit_to configuration option
5644
in the submit branch.
5646
Two formats are currently supported: "4" uses revision bundle format 4 and
5647
merge directive format 2. It is significantly faster and smaller than
5648
older formats. It is compatible with Bazaar 0.19 and later. It is the
5649
default. "0.9" uses revision bundle format 0.9 and merge directive
5650
format 1. It is compatible with Bazaar 0.12 - 0.18.
5652
The merge directives created by bzr send may be applied using bzr merge or
5653
bzr pull by specifying a file containing a merge directive as the location.
5655
bzr send makes extensive use of public locations to map local locations into
5656
URLs that can be used by other people. See `bzr help configuration` to
5657
set them, and use `bzr info` to display them.
5660
encoding_type = 'exact'
5662
_see_also = ['merge', 'pull']
5664
takes_args = ['submit_branch?', 'public_branch?']
5668
help='Do not include a bundle in the merge directive.'),
5669
Option('no-patch', help='Do not include a preview patch in the merge'
5672
help='Remember submit and public branch.'),
5674
help='Branch to generate the submission from, '
5675
'rather than the one containing the working directory.',
5678
Option('output', short_name='o',
5679
help='Write merge directive to this file or directory; '
5680
'use - for stdout.',
5683
help='Refuse to send if there are uncommitted changes in'
5684
' the working tree, --no-strict disables the check.'),
5685
Option('mail-to', help='Mail the request to this address.',
5689
Option('body', help='Body for the email.', type=unicode),
5690
RegistryOption('format',
5691
help='Use the specified output format.',
5692
lazy_registry=('bzrlib.send', 'format_registry')),
5695
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5696
no_patch=False, revision=None, remember=None, output=None,
5697
format=None, mail_to=None, message=None, body=None,
5698
strict=None, **kwargs):
5699
from bzrlib.send import send
5700
return send(submit_branch, revision, public_branch, remember,
5701
format, no_bundle, no_patch, output,
5702
kwargs.get('from', '.'), mail_to, message, body,
5707
class cmd_bundle_revisions(cmd_send):
5708
__doc__ = """Create a merge-directive for submitting changes.
5710
A merge directive provides many things needed for requesting merges:
5712
* A machine-readable description of the merge to perform
5714
* An optional patch that is a preview of the changes requested
5716
* An optional bundle of revision data, so that the changes can be applied
5717
directly from the merge directive, without retrieving data from a
5720
If --no-bundle is specified, then public_branch is needed (and must be
5721
up-to-date), so that the receiver can perform the merge using the
5722
public_branch. The public_branch is always included if known, so that
5723
people can check it later.
5725
The submit branch defaults to the parent, but can be overridden. Both
5726
submit branch and public branch will be remembered if supplied.
5728
If a public_branch is known for the submit_branch, that public submit
5729
branch is used in the merge instructions. This means that a local mirror
5730
can be used as your actual submit branch, once you have set public_branch
5733
Two formats are currently supported: "4" uses revision bundle format 4 and
5734
merge directive format 2. It is significantly faster and smaller than
5735
older formats. It is compatible with Bazaar 0.19 and later. It is the
5736
default. "0.9" uses revision bundle format 0.9 and merge directive
5737
format 1. It is compatible with Bazaar 0.12 - 0.18.
5742
help='Do not include a bundle in the merge directive.'),
5743
Option('no-patch', help='Do not include a preview patch in the merge'
5746
help='Remember submit and public branch.'),
5748
help='Branch to generate the submission from, '
5749
'rather than the one containing the working directory.',
5752
Option('output', short_name='o', help='Write directive to this file.',
5755
help='Refuse to bundle revisions if there are uncommitted'
5756
' changes in the working tree, --no-strict disables the check.'),
5758
RegistryOption('format',
5759
help='Use the specified output format.',
5760
lazy_registry=('bzrlib.send', 'format_registry')),
5762
aliases = ['bundle']
5764
_see_also = ['send', 'merge']
5768
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5769
no_patch=False, revision=None, remember=False, output=None,
5770
format=None, strict=None, **kwargs):
5773
from bzrlib.send import send
5774
return send(submit_branch, revision, public_branch, remember,
5775
format, no_bundle, no_patch, output,
5776
kwargs.get('from', '.'), None, None, None,
5777
self.outf, strict=strict)
3595
5780
class cmd_tag(Command):
3596
"""Create a tag naming a revision.
5781
__doc__ = """Create, remove or modify a tag naming a revision.
3598
5783
Tags give human-meaningful names to revisions. Commands that take a -r
3599
5784
(--revision) option can be given -rtag:X, where X is any previously
3602
5787
Tags are stored in the branch. Tags are copied from one branch to another
3603
5788
along when you branch, push, pull or merge.
3605
It is an error to give a tag name that already exists unless you pass
5790
It is an error to give a tag name that already exists unless you pass
3606
5791
--force, in which case the tag is moved to point to the new revision.
5793
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5794
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5796
If no tag name is specified it will be determined through the
5797
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5798
upstream releases by reading configure.ac. See ``bzr help hooks`` for
3609
5802
_see_also = ['commit', 'tags']
3610
takes_args = ['tag_name']
5803
takes_args = ['tag_name?']
3611
5804
takes_options = [
3612
5805
Option('delete',
3613
5806
help='Delete this tag rather than placing it.',
3616
help='Branch in which to place the tag.',
5808
custom_help('directory',
5809
help='Branch in which to place the tag.'),
3620
5810
Option('force',
3621
help='Replace existing tags',
5811
help='Replace existing tags.',
3626
def run(self, tag_name,
5816
def run(self, tag_name=None,
3632
5822
branch, relpath = Branch.open_containing(directory)
3636
branch.tags.delete_tag(tag_name)
3637
self.outf.write('Deleted tag %s.\n' % tag_name)
3640
if len(revision) != 1:
3641
raise errors.BzrCommandError(
3642
"Tags can only be placed on a single revision, "
3644
revision_id = revision[0].in_history(branch).rev_id
3646
revision_id = branch.last_revision()
3647
if (not force) and branch.tags.has_tag(tag_name):
3648
raise errors.TagAlreadyExists(tag_name)
5823
self.add_cleanup(branch.lock_write().unlock)
5825
if tag_name is None:
5826
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5827
branch.tags.delete_tag(tag_name)
5828
note(gettext('Deleted tag %s.') % tag_name)
5831
if len(revision) != 1:
5832
raise errors.BzrCommandError(gettext(
5833
"Tags can only be placed on a single revision, "
5835
revision_id = revision[0].as_revision_id(branch)
5837
revision_id = branch.last_revision()
5838
if tag_name is None:
5839
tag_name = branch.automatic_tag_name(revision_id)
5840
if tag_name is None:
5841
raise errors.BzrCommandError(gettext(
5842
"Please specify a tag name."))
5844
existing_target = branch.tags.lookup_tag(tag_name)
5845
except errors.NoSuchTag:
5846
existing_target = None
5847
if not force and existing_target not in (None, revision_id):
5848
raise errors.TagAlreadyExists(tag_name)
5849
if existing_target == revision_id:
5850
note(gettext('Tag %s already exists for that revision.') % tag_name)
3649
5852
branch.tags.set_tag(tag_name, revision_id)
3650
self.outf.write('Created tag %s.\n' % tag_name)
5853
if existing_target is None:
5854
note(gettext('Created tag %s.') % tag_name)
5856
note(gettext('Updated tag %s.') % tag_name)
3655
5859
class cmd_tags(Command):
5860
__doc__ = """List tags.
3658
This tag shows a table of tag names and the revisions they reference.
5862
This command shows a table of tag names and the revisions they reference.
3661
5865
_see_also = ['tag']
3662
5866
takes_options = [
3664
help='Branch whose tags should be displayed',
5867
custom_help('directory',
5868
help='Branch whose tags should be displayed.'),
5869
RegistryOption('sort',
5870
'Sort tags by different criteria.', title='Sorting',
5871
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
3670
5877
@display_command
5878
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5879
from bzrlib.tag import tag_sort_methods
5880
branch, relpath = Branch.open_containing(directory)
5882
tags = branch.tags.get_tag_dict().items()
5886
self.add_cleanup(branch.lock_read().unlock)
5888
# Restrict to the specified range
5889
tags = self._tags_for_range(branch, revision)
5891
sort = tag_sort_methods.get()
5894
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5895
for index, (tag, revid) in enumerate(tags):
5897
revno = branch.revision_id_to_dotted_revno(revid)
5898
if isinstance(revno, tuple):
5899
revno = '.'.join(map(str, revno))
5900
except (errors.NoSuchRevision,
5901
errors.GhostRevisionsHaveNoRevno,
5902
errors.UnsupportedOperation):
5903
# Bad tag data/merges can lead to tagged revisions
5904
# which are not in this branch. Fail gracefully ...
5906
tags[index] = (tag, revno)
5908
for tag, revspec in tags:
5909
self.outf.write('%-20s %s\n' % (tag, revspec))
5911
def _tags_for_range(self, branch, revision):
5913
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5914
revid1, revid2 = rev1.rev_id, rev2.rev_id
5915
# _get_revision_range will always set revid2 if it's not specified.
5916
# If revid1 is None, it means we want to start from the branch
5917
# origin which is always a valid ancestor. If revid1 == revid2, the
5918
# ancestry check is useless.
5919
if revid1 and revid1 != revid2:
5920
# FIXME: We really want to use the same graph than
5921
# branch.iter_merge_sorted_revisions below, but this is not
5922
# easily available -- vila 2011-09-23
5923
if branch.repository.get_graph().is_ancestor(revid2, revid1):
5924
# We don't want to output anything in this case...
5926
# only show revisions between revid1 and revid2 (inclusive)
5927
tagged_revids = branch.tags.get_reverse_tag_dict()
5929
for r in branch.iter_merge_sorted_revisions(
5930
start_revision_id=revid2, stop_revision_id=revid1,
5931
stop_rule='include'):
5932
revid_tags = tagged_revids.get(r[0], None)
5934
found.extend([(tag, r[0]) for tag in revid_tags])
5938
class cmd_reconfigure(Command):
5939
__doc__ = """Reconfigure the type of a bzr directory.
5941
A target configuration must be specified.
5943
For checkouts, the bind-to location will be auto-detected if not specified.
5944
The order of preference is
5945
1. For a lightweight checkout, the current bound location.
5946
2. For branches that used to be checkouts, the previously-bound location.
5947
3. The push location.
5948
4. The parent location.
5949
If none of these is available, --bind-to must be specified.
5952
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5953
takes_args = ['location?']
5955
RegistryOption.from_kwargs(
5958
help='The relation between branch and tree.',
5959
value_switches=True, enum_switch=False,
5960
branch='Reconfigure to be an unbound branch with no working tree.',
5961
tree='Reconfigure to be an unbound branch with a working tree.',
5962
checkout='Reconfigure to be a bound branch with a working tree.',
5963
lightweight_checkout='Reconfigure to be a lightweight'
5964
' checkout (with no local history).',
5966
RegistryOption.from_kwargs(
5968
title='Repository type',
5969
help='Location fo the repository.',
5970
value_switches=True, enum_switch=False,
5971
standalone='Reconfigure to be a standalone branch '
5972
'(i.e. stop using shared repository).',
5973
use_shared='Reconfigure to use a shared repository.',
5975
RegistryOption.from_kwargs(
5977
title='Trees in Repository',
5978
help='Whether new branches in the repository have trees.',
5979
value_switches=True, enum_switch=False,
5980
with_trees='Reconfigure repository to create '
5981
'working trees on branches by default.',
5982
with_no_trees='Reconfigure repository to not create '
5983
'working trees on branches by default.'
5985
Option('bind-to', help='Branch to bind checkout to.', type=str),
5987
help='Perform reconfiguration even if local changes'
5989
Option('stacked-on',
5990
help='Reconfigure a branch to be stacked on another branch.',
5994
help='Reconfigure a branch to be unstacked. This '
5995
'may require copying substantial data into it.',
5999
def run(self, location=None, bind_to=None, force=False,
6000
tree_type=None, repository_type=None, repository_trees=None,
6001
stacked_on=None, unstacked=None):
6002
directory = controldir.ControlDir.open(location)
6003
if stacked_on and unstacked:
6004
raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
6005
elif stacked_on is not None:
6006
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
6008
reconfigure.ReconfigureUnstacked().apply(directory)
6009
# At the moment you can use --stacked-on and a different
6010
# reconfiguration shape at the same time; there seems no good reason
6012
if (tree_type is None and
6013
repository_type is None and
6014
repository_trees is None):
6015
if stacked_on or unstacked:
6018
raise errors.BzrCommandError(gettext('No target configuration '
6020
reconfiguration = None
6021
if tree_type == 'branch':
6022
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6023
elif tree_type == 'tree':
6024
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6025
elif tree_type == 'checkout':
6026
reconfiguration = reconfigure.Reconfigure.to_checkout(
6028
elif tree_type == 'lightweight-checkout':
6029
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6032
reconfiguration.apply(force)
6033
reconfiguration = None
6034
if repository_type == 'use-shared':
6035
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6036
elif repository_type == 'standalone':
6037
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6039
reconfiguration.apply(force)
6040
reconfiguration = None
6041
if repository_trees == 'with-trees':
6042
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6044
elif repository_trees == 'with-no-trees':
6045
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6048
reconfiguration.apply(force)
6049
reconfiguration = None
6052
class cmd_switch(Command):
6053
__doc__ = """Set the branch of a checkout and update.
6055
For lightweight checkouts, this changes the branch being referenced.
6056
For heavyweight checkouts, this checks that there are no local commits
6057
versus the current bound branch, then it makes the local branch a mirror
6058
of the new location and binds to it.
6060
In both cases, the working tree is updated and uncommitted changes
6061
are merged. The user can commit or revert these as they desire.
6063
Pending merges need to be committed or reverted before using switch.
6065
The path to the branch to switch to can be specified relative to the parent
6066
directory of the current branch. For example, if you are currently in a
6067
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
6070
Bound branches use the nickname of its master branch unless it is set
6071
locally, in which case switching will update the local nickname to be
6075
takes_args = ['to_location?']
6076
takes_options = ['directory',
6078
help='Switch even if local commits will be lost.'),
6080
Option('create-branch', short_name='b',
6081
help='Create the target branch from this one before'
6082
' switching to it.'),
6085
def run(self, to_location=None, force=False, create_branch=False,
6086
revision=None, directory=u'.'):
6087
from bzrlib import switch
6088
tree_location = directory
6089
revision = _get_one_revision('switch', revision)
6090
control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6091
if to_location is None:
6092
if revision is None:
6093
raise errors.BzrCommandError(gettext('You must supply either a'
6094
' revision or a location'))
6095
to_location = tree_location
6097
branch = control_dir.open_branch()
6098
had_explicit_nick = branch.get_config().has_explicit_nickname()
6099
except errors.NotBranchError:
6101
had_explicit_nick = False
6104
raise errors.BzrCommandError(gettext('cannot create branch without'
6106
to_location = directory_service.directories.dereference(
6108
if '/' not in to_location and '\\' not in to_location:
6109
# This path is meant to be relative to the existing branch
6110
this_url = self._get_branch_location(control_dir)
6111
# Perhaps the target control dir supports colocated branches?
6113
root = controldir.ControlDir.open(this_url,
6114
possible_transports=[control_dir.user_transport])
6115
except errors.NotBranchError:
6118
colocated = root._format.colocated_branches
6120
to_location = urlutils.join_segment_parameters(this_url,
6121
{"branch": urlutils.escape(to_location)})
6123
to_location = urlutils.join(
6124
this_url, '..', urlutils.escape(to_location))
6125
to_branch = branch.bzrdir.sprout(to_location,
6126
possible_transports=[branch.bzrdir.root_transport],
6127
source_branch=branch).open_branch()
6129
# Perhaps it's a colocated branch?
6131
to_branch = control_dir.open_branch(to_location)
6132
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6134
to_branch = Branch.open(to_location)
6135
except errors.NotBranchError:
6136
this_url = self._get_branch_location(control_dir)
6137
to_branch = Branch.open(
6139
this_url, '..', urlutils.escape(to_location)))
6140
if revision is not None:
6141
revision = revision.as_revision_id(to_branch)
6142
switch.switch(control_dir, to_branch, force, revision_id=revision)
6143
if had_explicit_nick:
6144
branch = control_dir.open_branch() #get the new branch!
6145
branch.nick = to_branch.nick
6146
note(gettext('Switched to branch: %s'),
6147
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6149
def _get_branch_location(self, control_dir):
6150
"""Return location of branch for this control dir."""
6152
this_branch = control_dir.open_branch()
6153
# This may be a heavy checkout, where we want the master branch
6154
master_location = this_branch.get_bound_location()
6155
if master_location is not None:
6156
return master_location
6157
# If not, use a local sibling
6158
return this_branch.base
6159
except errors.NotBranchError:
6160
format = control_dir.find_branch_format()
6161
if getattr(format, 'get_reference', None) is not None:
6162
return format.get_reference(control_dir)
6164
return control_dir.root_transport.base
6167
class cmd_view(Command):
6168
__doc__ = """Manage filtered views.
6170
Views provide a mask over the tree so that users can focus on
6171
a subset of a tree when doing their work. After creating a view,
6172
commands that support a list of files - status, diff, commit, etc -
6173
effectively have that list of files implicitly given each time.
6174
An explicit list of files can still be given but those files
6175
must be within the current view.
6177
In most cases, a view has a short life-span: it is created to make
6178
a selected change and is deleted once that change is committed.
6179
At other times, you may wish to create one or more named views
6180
and switch between them.
6182
To disable the current view without deleting it, you can switch to
6183
the pseudo view called ``off``. This can be useful when you need
6184
to see the whole tree for an operation or two (e.g. merge) but
6185
want to switch back to your view after that.
6188
To define the current view::
6190
bzr view file1 dir1 ...
6192
To list the current view::
6196
To delete the current view::
6200
To disable the current view without deleting it::
6202
bzr view --switch off
6204
To define a named view and switch to it::
6206
bzr view --name view-name file1 dir1 ...
6208
To list a named view::
6210
bzr view --name view-name
6212
To delete a named view::
6214
bzr view --name view-name --delete
6216
To switch to a named view::
6218
bzr view --switch view-name
6220
To list all views defined::
6224
To delete all views::
6226
bzr view --delete --all
6230
takes_args = ['file*']
6233
help='Apply list or delete action to all views.',
6236
help='Delete the view.',
6239
help='Name of the view to define, list or delete.',
6243
help='Name of the view to switch to.',
6248
def run(self, file_list,
3674
branch, relpath = Branch.open_containing(directory)
3675
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3676
self.outf.write('%-20s %s\n' % (tag_name, target))
3679
# command-line interpretation helper for merge-related commands
3680
def _merge_helper(other_revision, base_revision,
3681
check_clean=True, ignore_zero=False,
3682
this_dir=None, backup_files=False,
3684
file_list=None, show_base=False, reprocess=False,
3687
change_reporter=None,
3689
"""Merge changes into a tree.
3692
list(path, revno) Base for three-way merge.
3693
If [None, None] then a base will be automatically determined.
3695
list(path, revno) Other revision for three-way merge.
3697
Directory to merge changes into; '.' by default.
3699
If true, this_dir must have no uncommitted changes before the
3701
ignore_zero - If true, suppress the "zero conflicts" message when
3702
there are no conflicts; should be set when doing something we expect
3703
to complete perfectly.
3704
file_list - If supplied, merge only changes to selected files.
3706
All available ancestors of other_revision and base_revision are
3707
automatically pulled into the branch.
3709
The revno may be -1 to indicate the last revision on the branch, which is
3712
This function is intended for use from the command line; programmatic
3713
clients might prefer to call merge.merge_inner(), which has less magic
3716
# Loading it late, so that we don't always have to import bzrlib.merge
3717
if merge_type is None:
3718
merge_type = _mod_merge.Merge3Merger
3719
if this_dir is None:
3721
this_tree = WorkingTree.open_containing(this_dir)[0]
3722
if show_base and not merge_type is _mod_merge.Merge3Merger:
3723
raise errors.BzrCommandError("Show-base is not supported for this merge"
3724
" type. %s" % merge_type)
3725
if reprocess and not merge_type.supports_reprocess:
3726
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3727
" type %s." % merge_type)
3728
if reprocess and show_base:
3729
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3730
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3731
# only want to take out a lock_tree_write() if we don't have to pull
3732
# any ancestry. But merge might fetch ancestry in the middle, in
3733
# which case we would need a lock_write().
3734
# Because we cannot upgrade locks, for now we live with the fact that
3735
# the tree will be locked multiple times during a merge. (Maybe
3736
# read-only some of the time, but it means things will get read
3739
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3740
pb=pb, change_reporter=change_reporter)
3741
merger.pp = ProgressPhase("Merge phase", 5, pb)
3742
merger.pp.next_phase()
3743
merger.check_basis(check_clean)
3744
if other_rev_id is not None:
3745
merger.set_other_revision(other_rev_id, this_tree.branch)
6254
tree, file_list = WorkingTree.open_containing_paths(file_list,
6256
current_view, view_dict = tree.views.get_view_info()
6261
raise errors.BzrCommandError(gettext(
6262
"Both --delete and a file list specified"))
6264
raise errors.BzrCommandError(gettext(
6265
"Both --delete and --switch specified"))
6267
tree.views.set_view_info(None, {})
6268
self.outf.write(gettext("Deleted all views.\n"))
6270
raise errors.BzrCommandError(gettext("No current view to delete"))
6272
tree.views.delete_view(name)
6273
self.outf.write(gettext("Deleted '%s' view.\n") % name)
6276
raise errors.BzrCommandError(gettext(
6277
"Both --switch and a file list specified"))
6279
raise errors.BzrCommandError(gettext(
6280
"Both --switch and --all specified"))
6281
elif switch == 'off':
6282
if current_view is None:
6283
raise errors.BzrCommandError(gettext("No current view to disable"))
6284
tree.views.set_view_info(None, view_dict)
6285
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
6287
tree.views.set_view_info(switch, view_dict)
6288
view_str = views.view_display_str(tree.views.lookup_view())
6289
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6292
self.outf.write(gettext('Views defined:\n'))
6293
for view in sorted(view_dict):
6294
if view == current_view:
6298
view_str = views.view_display_str(view_dict[view])
6299
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6301
self.outf.write(gettext('No views defined.\n'))
6304
# No name given and no current view set
6307
raise errors.BzrCommandError(gettext(
6308
"Cannot change the 'off' pseudo view"))
6309
tree.views.set_view(name, sorted(file_list))
6310
view_str = views.view_display_str(tree.views.lookup_view())
6311
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
3747
merger.set_other(other_revision)
3748
merger.pp.next_phase()
3749
merger.set_base(base_revision)
3750
if merger.base_rev_id == merger.other_rev_id:
3751
note('Nothing to do.')
3753
if file_list is None:
3754
if pull and merger.base_rev_id == merger.this_rev_id:
3755
# FIXME: deduplicate with pull
3756
result = merger.this_tree.pull(merger.this_branch,
3757
False, merger.other_rev_id)
3758
if result.old_revid == result.new_revid:
3759
note('No revisions to pull.')
6315
# No name given and no current view set
6316
self.outf.write(gettext('No current view.\n'))
6318
view_str = views.view_display_str(tree.views.lookup_view(name))
6319
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6322
class cmd_hooks(Command):
6323
__doc__ = """Show hooks."""
6328
for hook_key in sorted(hooks.known_hooks.keys()):
6329
some_hooks = hooks.known_hooks_key_to_object(hook_key)
6330
self.outf.write("%s:\n" % type(some_hooks).__name__)
6331
for hook_name, hook_point in sorted(some_hooks.items()):
6332
self.outf.write(" %s:\n" % (hook_name,))
6333
found_hooks = list(hook_point)
6335
for hook in found_hooks:
6336
self.outf.write(" %s\n" %
6337
(some_hooks.get_hook_name(hook),))
3761
note('Now on revision %d.' % result.new_revno)
3763
merger.backup_files = backup_files
3764
merger.merge_type = merge_type
3765
merger.set_interesting_files(file_list)
3766
merger.show_base = show_base
3767
merger.reprocess = reprocess
3768
conflicts = merger.do_merge()
3769
if file_list is None:
3770
merger.set_pending()
3776
def _create_prefix(cur_transport):
3777
needed = [cur_transport]
3778
# Recurse upwards until we can create a directory successfully
3780
new_transport = cur_transport.clone('..')
3781
if new_transport.base == cur_transport.base:
3782
raise errors.BzrCommandError("Failed to create path"
3786
new_transport.mkdir('.')
3787
except errors.NoSuchFile:
3788
needed.append(new_transport)
3789
cur_transport = new_transport
6339
self.outf.write(gettext(" <no hooks installed>\n"))
6342
class cmd_remove_branch(Command):
6343
__doc__ = """Remove a branch.
6345
This will remove the branch from the specified location but
6346
will keep any working tree or repository in place.
6350
Remove the branch at repo/trunk::
6352
bzr remove-branch repo/trunk
6356
takes_args = ["location?"]
6358
aliases = ["rmbranch"]
6360
def run(self, location=None):
6361
if location is None:
6363
branch = Branch.open_containing(location)[0]
6364
branch.bzrdir.destroy_branch()
6367
class cmd_shelve(Command):
6368
__doc__ = """Temporarily set aside some changes from the current tree.
6370
Shelve allows you to temporarily put changes you've made "on the shelf",
6371
ie. out of the way, until a later time when you can bring them back from
6372
the shelf with the 'unshelve' command. The changes are stored alongside
6373
your working tree, and so they aren't propagated along with your branch nor
6374
will they survive its deletion.
6376
If shelve --list is specified, previously-shelved changes are listed.
6378
Shelve is intended to help separate several sets of changes that have
6379
been inappropriately mingled. If you just want to get rid of all changes
6380
and you don't need to restore them later, use revert. If you want to
6381
shelve all text changes at once, use shelve --all.
6383
If filenames are specified, only the changes to those files will be
6384
shelved. Other files will be left untouched.
6386
If a revision is specified, changes since that revision will be shelved.
6388
You can put multiple items on the shelf, and by default, 'unshelve' will
6389
restore the most recently shelved changes.
6391
For complicated changes, it is possible to edit the changes in a separate
6392
editor program to decide what the file remaining in the working copy
6393
should look like. To do this, add the configuration option
6395
change_editor = PROGRAM @new_path @old_path
6397
where @new_path is replaced with the path of the new version of the
6398
file and @old_path is replaced with the path of the old version of
6399
the file. The PROGRAM should save the new file with the desired
6400
contents of the file in the working tree.
6404
takes_args = ['file*']
6409
Option('all', help='Shelve all changes.'),
6411
RegistryOption('writer', 'Method to use for writing diffs.',
6412
bzrlib.option.diff_writer_registry,
6413
value_switches=True, enum_switch=False),
6415
Option('list', help='List shelved changes.'),
6417
help='Destroy removed changes instead of shelving them.'),
6419
_see_also = ['unshelve', 'configuration']
6421
def run(self, revision=None, all=False, file_list=None, message=None,
6422
writer=None, list=False, destroy=False, directory=None):
6424
return self.run_for_list(directory=directory)
6425
from bzrlib.shelf_ui import Shelver
6427
writer = bzrlib.option.diff_writer_registry.get()
6429
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6430
file_list, message, destroy=destroy, directory=directory)
6435
except errors.UserAbort:
6438
def run_for_list(self, directory=None):
6439
if directory is None:
6441
tree = WorkingTree.open_containing(directory)[0]
6442
self.add_cleanup(tree.lock_read().unlock)
6443
manager = tree.get_shelf_manager()
6444
shelves = manager.active_shelves()
6445
if len(shelves) == 0:
6446
note(gettext('No shelved changes.'))
6448
for shelf_id in reversed(shelves):
6449
message = manager.get_metadata(shelf_id).get('message')
6451
message = '<no message>'
6452
self.outf.write('%3d: %s\n' % (shelf_id, message))
6456
class cmd_unshelve(Command):
6457
__doc__ = """Restore shelved changes.
6459
By default, the most recently shelved changes are restored. However if you
6460
specify a shelf by id those changes will be restored instead. This works
6461
best when the changes don't depend on each other.
6464
takes_args = ['shelf_id?']
6467
RegistryOption.from_kwargs(
6468
'action', help="The action to perform.",
6469
enum_switch=False, value_switches=True,
6470
apply="Apply changes and remove from the shelf.",
6471
dry_run="Show changes, but do not apply or remove them.",
6472
preview="Instead of unshelving the changes, show the diff that "
6473
"would result from unshelving.",
6474
delete_only="Delete changes without applying them.",
6475
keep="Apply changes but don't delete them.",
6478
_see_also = ['shelve']
6480
def run(self, shelf_id=None, action='apply', directory=u'.'):
6481
from bzrlib.shelf_ui import Unshelver
6482
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
6486
unshelver.tree.unlock()
6489
class cmd_clean_tree(Command):
6490
__doc__ = """Remove unwanted files from working tree.
6492
By default, only unknown files, not ignored files, are deleted. Versioned
6493
files are never deleted.
6495
Another class is 'detritus', which includes files emitted by bzr during
6496
normal operations and selftests. (The value of these files decreases with
6499
If no options are specified, unknown files are deleted. Otherwise, option
6500
flags are respected, and may be combined.
6502
To check what clean-tree will do, use --dry-run.
6504
takes_options = ['directory',
6505
Option('ignored', help='Delete all ignored files.'),
6506
Option('detritus', help='Delete conflict files, merge and revert'
6507
' backups, and failed selftest dirs.'),
6509
help='Delete files unknown to bzr (default).'),
6510
Option('dry-run', help='Show files to delete instead of'
6512
Option('force', help='Do not prompt before deleting.')]
6513
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6514
force=False, directory=u'.'):
6515
from bzrlib.clean_tree import clean_tree
6516
if not (unknown or ignored or detritus):
6520
clean_tree(directory, unknown=unknown, ignored=ignored,
6521
detritus=detritus, dry_run=dry_run, no_prompt=force)
6524
class cmd_reference(Command):
6525
__doc__ = """list, view and set branch locations for nested trees.
6527
If no arguments are provided, lists the branch locations for nested trees.
6528
If one argument is provided, display the branch location for that tree.
6529
If two arguments are provided, set the branch location for that tree.
6534
takes_args = ['path?', 'location?']
6536
def run(self, path=None, location=None):
6538
if path is not None:
6540
tree, branch, relpath =(
6541
controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6542
if path is not None:
6545
tree = branch.basis_tree()
6547
info = branch._get_all_reference_info().iteritems()
6548
self._display_reference_info(tree, branch, info)
3793
# Now we only need to create child directories
3795
cur_transport = needed.pop()
3796
cur_transport.ensure_base()
3799
merge = _merge_helper
3802
# these get imported and then picked up by the scan for cmd_*
3803
# TODO: Some more consistent way to split command definitions across files;
3804
# we do need to load at least some information about them to know of
3805
# aliases. ideally we would avoid loading the implementation until the
3806
# details were needed.
3807
from bzrlib.cmd_version_info import cmd_version_info
3808
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
3809
from bzrlib.bundle.commands import cmd_bundle_revisions
3810
from bzrlib.sign_my_commits import cmd_sign_my_commits
3811
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
3812
cmd_weave_plan_merge, cmd_weave_merge_text
6550
file_id = tree.path2id(path)
6552
raise errors.NotVersionedError(path)
6553
if location is None:
6554
info = [(file_id, branch.get_reference_info(file_id))]
6555
self._display_reference_info(tree, branch, info)
6557
branch.set_reference_info(file_id, path, location)
6559
def _display_reference_info(self, tree, branch, info):
6561
for file_id, (path, location) in info:
6563
path = tree.id2path(file_id)
6564
except errors.NoSuchId:
6566
ref_list.append((path, location))
6567
for path, location in sorted(ref_list):
6568
self.outf.write('%s %s\n' % (path, location))
6571
class cmd_export_pot(Command):
6572
__doc__ = """Export command helps and error messages in po format."""
6575
takes_options = [Option('plugin',
6576
help='Export help text from named command '\
6577
'(defaults to all built in commands).',
6579
Option('include-duplicates',
6580
help='Output multiple copies of the same msgid '
6581
'string if it appears more than once.'),
6584
def run(self, plugin=None, include_duplicates=False):
6585
from bzrlib.export_pot import export_pot
6586
export_pot(self.outf, plugin, include_duplicates)
6589
def _register_lazy_builtins():
6590
# register lazy builtins from other modules; called at startup and should
6591
# be only called once.
6592
for (name, aliases, module_name) in [
6593
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6594
('cmd_config', [], 'bzrlib.config'),
6595
('cmd_dpush', [], 'bzrlib.foreign'),
6596
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6597
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6598
('cmd_conflicts', [], 'bzrlib.conflicts'),
6599
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6600
('cmd_verify_signatures', [],
6601
'bzrlib.commit_signature_commands'),
6602
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6604
builtin_command_registry.register_lazy(name, aliases, module_name)