143
239
Not versioned and not matching an ignore pattern.
145
To see ignored files use 'bzr ignored'. For details in the
241
Additionally for directories, symlinks and files with a changed
242
executable bit, Bazaar indicates their type using a trailing
243
character: '/', '@' or '*' respectively. These decorations can be
244
disabled using the '--no-classify' option.
246
To see ignored files use 'bzr ignored'. For details on the
146
247
changes to file texts, use 'bzr diff'.
148
--short gives a status flags for each item, similar to the SVN's status
151
Column 1: versioning / renames
157
P Entry for a pending merge (not a file)
166
* The execute bit was changed
249
Note that --short or -S gives status flags for each item, similar
250
to Subversion's status command. To get output similar to svn -q,
168
253
If no arguments are specified, the status of the entire working
169
254
directory is shown. Otherwise, only the status of the specified
170
255
files or directories is reported. If a directory is given, status
171
256
is reported for everything inside that directory.
173
If a revision argument is given, the status is calculated against
174
that revision, or between two revisions if two are provided.
258
Before merges are committed, the pending merge tip revisions are
259
shown. To see all pending merge revisions, use the -v option.
260
To skip the display of pending merge information altogether, use
261
the no-pending option or specify a file/directory.
263
To compare the working directory to a specific revision, pass a
264
single revision to the revision argument.
266
To see which files have changed in a specific revision, or between
267
two revisions, pass a revision range to the revision argument.
268
This will produce the same results as calling 'bzr diff --summarize'.
177
271
# TODO: --no-recurse, --recurse options
179
273
takes_args = ['file*']
180
takes_options = ['show-ids', 'revision', 'short']
274
takes_options = ['show-ids', 'revision', 'change', 'verbose',
275
Option('short', help='Use short status indicators.',
277
Option('versioned', help='Only show versioned files.',
279
Option('no-pending', help='Don\'t show pending merges.',
281
Option('no-classify',
282
help='Do not mark object type using indicator.',
181
285
aliases = ['st', 'stat']
183
287
encoding_type = 'replace'
288
_see_also = ['diff', 'revert', 'status-flags']
186
def run(self, show_ids=False, file_list=None, revision=None, short=False):
291
def run(self, show_ids=False, file_list=None, revision=None, short=False,
292
versioned=False, no_pending=False, verbose=False,
187
294
from bzrlib.status import show_tree_status
189
tree, file_list = tree_files(file_list)
296
if revision and len(revision) > 2:
297
raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
298
' one or two revision specifiers'))
300
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
301
# Avoid asking for specific files when that is not needed.
302
if relfile_list == ['']:
304
# Don't disable pending merges for full trees other than '.'.
305
if file_list == ['.']:
307
# A specific path within a tree was given.
308
elif relfile_list is not None:
191
310
show_tree_status(tree, show_ids=show_ids,
192
specific_files=file_list, revision=revision,
311
specific_files=relfile_list, revision=revision,
312
to_file=self.outf, short=short, versioned=versioned,
313
show_pending=(not no_pending), verbose=verbose,
314
classify=not no_classify)
197
317
class cmd_cat_revision(Command):
198
"""Write out metadata for a revision.
318
__doc__ = """Write out metadata for a revision.
200
320
The revision to print can either be specified by a specific
201
321
revision identifier, or you can use --revision.
205
325
takes_args = ['revision_id?']
206
takes_options = ['revision']
326
takes_options = ['directory', 'revision']
207
327
# cat-revision is more for frontends so should be exact
208
328
encoding = 'strict'
330
def print_revision(self, revisions, revid):
331
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
332
record = stream.next()
333
if record.storage_kind == 'absent':
334
raise errors.NoSuchRevision(revisions, revid)
335
revtext = record.get_bytes_as('fulltext')
336
self.outf.write(revtext.decode('utf-8'))
211
def run(self, revision_id=None, revision=None):
339
def run(self, revision_id=None, revision=None, directory=u'.'):
213
340
if revision_id is not None and revision is not None:
214
raise errors.BzrCommandError('You can only supply one of'
215
' revision_id or --revision')
341
raise errors.BzrCommandError(gettext('You can only supply one of'
342
' revision_id or --revision'))
216
343
if revision_id is None and revision is None:
217
raise errors.BzrCommandError('You must supply either'
218
' --revision or a revision_id')
219
b = WorkingTree.open_containing(u'.')[0].branch
221
# TODO: jam 20060112 should cat-revision always output utf-8?
222
if revision_id is not None:
223
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
224
elif revision is not None:
227
raise errors.BzrCommandError('You cannot specify a NULL'
229
revno, rev_id = rev.in_history(b)
230
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
344
raise errors.BzrCommandError(gettext('You must supply either'
345
' --revision or a revision_id'))
347
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
349
revisions = b.repository.revisions
350
if revisions is None:
351
raise errors.BzrCommandError(gettext('Repository %r does not support '
352
'access to raw revision texts'))
354
b.repository.lock_read()
356
# TODO: jam 20060112 should cat-revision always output utf-8?
357
if revision_id is not None:
358
revision_id = osutils.safe_revision_id(revision_id, warn=False)
360
self.print_revision(revisions, revision_id)
361
except errors.NoSuchRevision:
362
msg = gettext("The repository {0} contains no revision {1}.").format(
363
b.repository.base, revision_id)
364
raise errors.BzrCommandError(msg)
365
elif revision is not None:
368
raise errors.BzrCommandError(
369
gettext('You cannot specify a NULL revision.'))
370
rev_id = rev.as_revision_id(b)
371
self.print_revision(revisions, rev_id)
373
b.repository.unlock()
376
class cmd_dump_btree(Command):
377
__doc__ = """Dump the contents of a btree index file to stdout.
379
PATH is a btree index file, it can be any URL. This includes things like
380
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
382
By default, the tuples stored in the index file will be displayed. With
383
--raw, we will uncompress the pages, but otherwise display the raw bytes
387
# TODO: Do we want to dump the internal nodes as well?
388
# TODO: It would be nice to be able to dump the un-parsed information,
389
# rather than only going through iter_all_entries. However, this is
390
# good enough for a start
392
encoding_type = 'exact'
393
takes_args = ['path']
394
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
395
' rather than the parsed tuples.'),
398
def run(self, path, raw=False):
399
dirname, basename = osutils.split(path)
400
t = transport.get_transport(dirname)
402
self._dump_raw_bytes(t, basename)
404
self._dump_entries(t, basename)
406
def _get_index_and_bytes(self, trans, basename):
407
"""Create a BTreeGraphIndex and raw bytes."""
408
bt = btree_index.BTreeGraphIndex(trans, basename, None)
409
bytes = trans.get_bytes(basename)
410
bt._file = cStringIO.StringIO(bytes)
411
bt._size = len(bytes)
414
def _dump_raw_bytes(self, trans, basename):
417
# We need to parse at least the root node.
418
# This is because the first page of every row starts with an
419
# uncompressed header.
420
bt, bytes = self._get_index_and_bytes(trans, basename)
421
for page_idx, page_start in enumerate(xrange(0, len(bytes),
422
btree_index._PAGE_SIZE)):
423
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
424
page_bytes = bytes[page_start:page_end]
426
self.outf.write('Root node:\n')
427
header_end, data = bt._parse_header_from_bytes(page_bytes)
428
self.outf.write(page_bytes[:header_end])
430
self.outf.write('\nPage %d\n' % (page_idx,))
431
if len(page_bytes) == 0:
432
self.outf.write('(empty)\n');
434
decomp_bytes = zlib.decompress(page_bytes)
435
self.outf.write(decomp_bytes)
436
self.outf.write('\n')
438
def _dump_entries(self, trans, basename):
440
st = trans.stat(basename)
441
except errors.TransportNotPossible:
442
# We can't stat, so we'll fake it because we have to do the 'get()'
444
bt, _ = self._get_index_and_bytes(trans, basename)
446
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
447
for node in bt.iter_all_entries():
448
# Node is made up of:
449
# (index, key, value, [references])
453
refs_as_tuples = None
455
refs_as_tuples = static_tuple.as_tuples(refs)
456
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
457
self.outf.write('%s\n' % (as_tuple,))
233
460
class cmd_remove_tree(Command):
234
"""Remove the working tree from a given branch/checkout.
461
__doc__ = """Remove the working tree from a given branch/checkout.
236
463
Since a lightweight checkout is little more than a working tree
237
464
this will refuse to run against one.
240
takes_args = ['location?']
242
def run(self, location='.'):
243
d = bzrdir.BzrDir.open(location)
466
To re-create the working tree, use "bzr checkout".
468
_see_also = ['checkout', 'working-trees']
469
takes_args = ['location*']
472
help='Remove the working tree even if it has '
473
'uncommitted or shelved changes.'),
476
def run(self, location_list, force=False):
477
if not location_list:
480
for location in location_list:
481
d = controldir.ControlDir.open(location)
484
working = d.open_workingtree()
485
except errors.NoWorkingTree:
486
raise errors.BzrCommandError(gettext("No working tree to remove"))
487
except errors.NotLocalUrl:
488
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
489
" of a remote path"))
491
if (working.has_changes()):
492
raise errors.UncommittedChanges(working)
493
if working.get_shelf_manager().last_shelf() is not None:
494
raise errors.ShelvedChanges(working)
496
if working.user_url != working.branch.user_url:
497
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
498
" from a lightweight checkout"))
500
d.destroy_workingtree()
503
class cmd_repair_workingtree(Command):
504
__doc__ = """Reset the working tree state file.
506
This is not meant to be used normally, but more as a way to recover from
507
filesystem corruption, etc. This rebuilds the working inventory back to a
508
'known good' state. Any new modifications (adding a file, renaming, etc)
509
will be lost, though modified files will still be detected as such.
511
Most users will want something more like "bzr revert" or "bzr update"
512
unless the state file has become corrupted.
514
By default this attempts to recover the current state by looking at the
515
headers of the state file. If the state file is too corrupted to even do
516
that, you can supply --revision to force the state of the tree.
519
takes_options = ['revision', 'directory',
521
help='Reset the tree even if it doesn\'t appear to be'
526
def run(self, revision=None, directory='.', force=False):
527
tree, _ = WorkingTree.open_containing(directory)
528
self.add_cleanup(tree.lock_tree_write().unlock)
532
except errors.BzrError:
533
pass # There seems to be a real error here, so we'll reset
536
raise errors.BzrCommandError(gettext(
537
'The tree does not appear to be corrupt. You probably'
538
' want "bzr revert" instead. Use "--force" if you are'
539
' sure you want to reset the working tree.'))
543
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
246
working = d.open_workingtree()
247
except errors.NoWorkingTree:
248
raise errors.BzrCommandError("No working tree to remove")
249
except errors.NotLocalUrl:
250
raise errors.BzrCommandError("You cannot remove the working tree of a "
253
working_path = working.bzrdir.root_transport.base
254
branch_path = working.branch.bzrdir.root_transport.base
255
if working_path != branch_path:
256
raise errors.BzrCommandError("You cannot remove the working tree from "
257
"a lightweight checkout")
259
d.destroy_workingtree()
545
tree.reset_state(revision_ids)
546
except errors.BzrError, e:
547
if revision_ids is None:
548
extra = (gettext(', the header appears corrupt, try passing -r -1'
549
' to set the state to the last commit'))
552
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
262
555
class cmd_revno(Command):
263
"""Show current revision number.
556
__doc__ = """Show current revision number.
265
558
This is equal to the number of revisions on this branch.
268
562
takes_args = ['location?']
564
Option('tree', help='Show revno of working tree.'),
271
def run(self, location=u'.'):
272
self.outf.write(str(Branch.open_containing(location)[0].revno()))
273
self.outf.write('\n')
569
def run(self, tree=False, location=u'.', revision=None):
570
if revision is not None and tree:
571
raise errors.BzrCommandError(gettext("--tree and --revision can "
572
"not be used together"))
576
wt = WorkingTree.open_containing(location)[0]
577
self.add_cleanup(wt.lock_read().unlock)
578
except (errors.NoWorkingTree, errors.NotLocalUrl):
579
raise errors.NoWorkingTree(location)
581
revid = wt.last_revision()
583
b = Branch.open_containing(location)[0]
584
self.add_cleanup(b.lock_read().unlock)
586
if len(revision) != 1:
587
raise errors.BzrCommandError(gettext(
588
"Tags can only be placed on a single revision, "
590
revid = revision[0].as_revision_id(b)
592
revid = b.last_revision()
594
revno_t = b.revision_id_to_dotted_revno(revid)
595
except errors.NoSuchRevision:
597
revno = ".".join(str(n) for n in revno_t)
599
self.outf.write(revno + '\n')
276
602
class cmd_revision_info(Command):
277
"""Show revision number and revision id for a given revision identifier.
603
__doc__ = """Show revision number and revision id for a given revision identifier.
280
606
takes_args = ['revision_info*']
281
takes_options = ['revision']
609
custom_help('directory',
610
help='Branch to examine, '
611
'rather than the one containing the working directory.'),
612
Option('tree', help='Show revno of working tree.'),
284
def run(self, revision=None, revision_info_list=[]):
616
def run(self, revision=None, directory=u'.', tree=False,
617
revision_info_list=[]):
620
wt = WorkingTree.open_containing(directory)[0]
622
self.add_cleanup(wt.lock_read().unlock)
623
except (errors.NoWorkingTree, errors.NotLocalUrl):
625
b = Branch.open_containing(directory)[0]
626
self.add_cleanup(b.lock_read().unlock)
287
628
if revision is not None:
288
revs.extend(revision)
629
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
289
630
if revision_info_list is not None:
290
for rev in revision_info_list:
291
revs.append(RevisionSpec.from_string(rev))
293
raise errors.BzrCommandError('You must supply a revision identifier')
295
b = WorkingTree.open_containing(u'.')[0].branch
298
revinfo = rev.in_history(b)
299
if revinfo.revno is None:
300
print ' %s' % revinfo.rev_id
631
for rev_str in revision_info_list:
632
rev_spec = RevisionSpec.from_string(rev_str)
633
revision_ids.append(rev_spec.as_revision_id(b))
634
# No arguments supplied, default to the last revision
635
if len(revision_ids) == 0:
638
raise errors.NoWorkingTree(directory)
639
revision_ids.append(wt.last_revision())
302
print '%4d %s' % (revinfo.revno, revinfo.rev_id)
641
revision_ids.append(b.last_revision())
645
for revision_id in revision_ids:
647
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
648
revno = '.'.join(str(i) for i in dotted_revno)
649
except errors.NoSuchRevision:
651
maxlen = max(maxlen, len(revno))
652
revinfos.append([revno, revision_id])
656
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
305
659
class cmd_add(Command):
306
"""Add specified files or directories.
660
__doc__ = """Add specified files or directories.
308
662
In non-recursive mode, all the named items are added, regardless
309
663
of whether they were previously ignored. A warning is given if
493
895
takes_args = ['names*']
494
takes_options = [Option("after", help="move only the bzr identifier"
495
" of the file (file has already been moved). Use this flag if"
496
" bzr is not able to detect this itself.")]
896
takes_options = [Option("after", help="Move only the bzr identifier"
897
" of the file, because the file has already been moved."),
898
Option('auto', help='Automatically guess renames.'),
899
Option('dry-run', help='Avoid making changes when guessing renames.'),
497
901
aliases = ['move', 'rename']
498
902
encoding_type = 'replace'
500
def run(self, names_list, after=False):
904
def run(self, names_list, after=False, auto=False, dry_run=False):
906
return self.run_auto(names_list, after, dry_run)
908
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
501
909
if names_list is None:
504
911
if len(names_list) < 2:
505
raise errors.BzrCommandError("missing file argument")
506
tree, rel_names = tree_files(names_list)
508
if os.path.isdir(names_list[-1]):
912
raise errors.BzrCommandError(gettext("missing file argument"))
913
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
914
for file_name in rel_names[0:-1]:
916
raise errors.BzrCommandError(gettext("can not move root of branch"))
917
self.add_cleanup(tree.lock_tree_write().unlock)
918
self._run(tree, names_list, rel_names, after)
920
def run_auto(self, names_list, after, dry_run):
921
if names_list is not None and len(names_list) > 1:
922
raise errors.BzrCommandError(gettext('Only one path may be specified to'
925
raise errors.BzrCommandError(gettext('--after cannot be specified with'
927
work_tree, file_list = WorkingTree.open_containing_paths(
928
names_list, default_directory='.')
929
self.add_cleanup(work_tree.lock_tree_write().unlock)
930
rename_map.RenameMap.guess_renames(work_tree, dry_run)
932
def _run(self, tree, names_list, rel_names, after):
933
into_existing = osutils.isdir(names_list[-1])
934
if into_existing and len(names_list) == 2:
936
# a. case-insensitive filesystem and change case of dir
937
# b. move directory after the fact (if the source used to be
938
# a directory, but now doesn't exist in the working tree
939
# and the target is an existing directory, just rename it)
940
if (not tree.case_sensitive
941
and rel_names[0].lower() == rel_names[1].lower()):
942
into_existing = False
945
# 'fix' the case of a potential 'from'
946
from_id = tree.path2id(
947
tree.get_canonical_inventory_path(rel_names[0]))
948
if (not osutils.lexists(names_list[0]) and
949
from_id and inv.get_file_kind(from_id) == "directory"):
950
into_existing = False
509
953
# move into existing directory
510
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
511
self.outf.write("%s => %s\n" % pair)
954
# All entries reference existing inventory items, so fix them up
955
# for cicp file-systems.
956
rel_names = tree.get_canonical_inventory_paths(rel_names)
957
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
959
self.outf.write("%s => %s\n" % (src, dest))
513
961
if len(names_list) != 2:
514
raise errors.BzrCommandError('to mv multiple files the'
962
raise errors.BzrCommandError(gettext('to mv multiple files the'
515
963
' destination must be a versioned'
517
tree.rename_one(rel_names[0], rel_names[1], after=after)
518
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
966
# for cicp file-systems: the src references an existing inventory
968
src = tree.get_canonical_inventory_path(rel_names[0])
969
# Find the canonical version of the destination: In all cases, the
970
# parent of the target must be in the inventory, so we fetch the
971
# canonical version from there (we do not always *use* the
972
# canonicalized tail portion - we may be attempting to rename the
974
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
975
dest_parent = osutils.dirname(canon_dest)
976
spec_tail = osutils.basename(rel_names[1])
977
# For a CICP file-system, we need to avoid creating 2 inventory
978
# entries that differ only by case. So regardless of the case
979
# we *want* to use (ie, specified by the user or the file-system),
980
# we must always choose to use the case of any existing inventory
981
# items. The only exception to this is when we are attempting a
982
# case-only rename (ie, canonical versions of src and dest are
984
dest_id = tree.path2id(canon_dest)
985
if dest_id is None or tree.path2id(src) == dest_id:
986
# No existing item we care about, so work out what case we
987
# are actually going to use.
989
# If 'after' is specified, the tail must refer to a file on disk.
991
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
993
# pathjoin with an empty tail adds a slash, which breaks
995
dest_parent_fq = tree.basedir
997
dest_tail = osutils.canonical_relpath(
999
osutils.pathjoin(dest_parent_fq, spec_tail))
1001
# not 'after', so case as specified is used
1002
dest_tail = spec_tail
1004
# Use the existing item so 'mv' fails with AlreadyVersioned.
1005
dest_tail = os.path.basename(canon_dest)
1006
dest = osutils.pathjoin(dest_parent, dest_tail)
1007
mutter("attempting to move %s => %s", src, dest)
1008
tree.rename_one(src, dest, after=after)
1010
self.outf.write("%s => %s\n" % (src, dest))
521
1013
class cmd_pull(Command):
522
"""Turn this branch into a mirror of another branch.
1014
__doc__ = """Turn this branch into a mirror of another branch.
524
This command only works on branches that have not diverged. Branches are
525
considered diverged if the destination branch's most recent commit is one
526
that has not been merged (directly or indirectly) into the parent.
1016
By default, this command only works on branches that have not diverged.
1017
Branches are considered diverged if the destination branch's most recent
1018
commit is one that has not been merged (directly or indirectly) into the
528
1021
If branches have diverged, you can use 'bzr merge' to integrate the changes
529
1022
from one into the other. Once one branch has merged, the other should
530
1023
be able to pull it again.
532
If you want to forget your local changes and just update your branch to
533
match the remote one, use pull --overwrite.
535
If there is no default location set, the first pull will set it. After
536
that, you can omit the location to use the default. To change the
537
default, use --remember. The value will only be saved if the remote
538
location can be accessed.
1025
If you want to replace your local changes and just want your branch to
1026
match the remote one, use pull --overwrite. This will work even if the two
1027
branches have diverged.
1029
If there is no default location set, the first pull will set it (use
1030
--no-remember to avoid setting it). After that, you can omit the
1031
location to use the default. To change the default, use --remember. The
1032
value will only be saved if the remote location can be accessed.
1034
The --verbose option will display the revisions pulled using the log_format
1035
configuration option. You can use a different format by overriding it with
1036
-Olog_format=<other_format>.
1038
Note: The location can be specified either in the form of a branch,
1039
or in the form of a path to a file containing a merge directive generated
541
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
543
help='branch to pull into, '
544
'rather than the one containing the working directory',
1043
_see_also = ['push', 'update', 'status-flags', 'send']
1044
takes_options = ['remember', 'overwrite', 'revision',
1045
custom_help('verbose',
1046
help='Show logs of pulled revisions.'),
1047
custom_help('directory',
1048
help='Branch to pull into, '
1049
'rather than the one containing the working directory.'),
1051
help="Perform a local pull in a bound "
1052
"branch. Local pulls are not applied to "
1053
"the master branch."
1056
help="Show base revision text in conflicts.")
549
1058
takes_args = ['location?']
550
1059
encoding_type = 'replace'
552
def run(self, location=None, remember=False, overwrite=False,
1061
def run(self, location=None, remember=None, overwrite=False,
553
1062
revision=None, verbose=False,
1063
directory=None, local=False,
555
1065
# FIXME: too much stuff is in the command class
556
1068
if directory is None:
557
1069
directory = u'.'
559
1071
tree_to = WorkingTree.open_containing(directory)[0]
560
1072
branch_to = tree_to.branch
1073
self.add_cleanup(tree_to.lock_write().unlock)
561
1074
except errors.NoWorkingTree:
563
1076
branch_to = Branch.open_containing(directory)[0]
1077
self.add_cleanup(branch_to.lock_write().unlock)
1079
if tree_to is None and show_base:
1080
raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1082
if local and not branch_to.get_bound_location():
1083
raise errors.LocalRequiresBoundBranch()
1085
possible_transports = []
566
1086
if location is not None:
568
reader = bundle.read_bundle_from_url(location)
1088
mergeable = bundle.read_mergeable_from_url(location,
1089
possible_transports=possible_transports)
569
1090
except errors.NotABundle:
570
pass # Continue on considering this url a Branch
572
1093
stored_loc = branch_to.get_parent()
573
1094
if location is None:
574
1095
if stored_loc is None:
575
raise errors.BzrCommandError("No pull location known or"
1096
raise errors.BzrCommandError(gettext("No pull location known or"
578
1099
display_url = urlutils.unescape_for_display(stored_loc,
579
1100
self.outf.encoding)
580
self.outf.write("Using saved location: %s\n" % display_url)
1102
self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
581
1103
location = stored_loc
583
if reader is not None:
584
install_bundle(branch_to.repository, reader)
1105
revision = _get_one_revision('pull', revision)
1106
if mergeable is not None:
1107
if revision is not None:
1108
raise errors.BzrCommandError(gettext(
1109
'Cannot use -r with merge directives or bundles'))
1110
mergeable.install_revisions(branch_to.repository)
1111
base_revision_id, revision_id, verified = \
1112
mergeable.get_merge_request(branch_to.repository)
585
1113
branch_from = branch_to
587
branch_from = Branch.open(location)
589
if branch_to.get_parent() is None or remember:
1115
branch_from = Branch.open(location,
1116
possible_transports=possible_transports)
1117
self.add_cleanup(branch_from.lock_read().unlock)
1118
# Remembers if asked explicitly or no previous location is set
1120
or (remember is None and branch_to.get_parent() is None)):
590
1121
branch_to.set_parent(branch_from.base)
594
if reader is not None:
595
rev_id = reader.target
596
elif len(revision) == 1:
597
rev_id = revision[0].in_history(branch_from).rev_id
599
raise errors.BzrCommandError('bzr pull --revision takes one value.')
1123
if revision is not None:
1124
revision_id = revision.as_revision_id(branch_from)
601
old_rh = branch_to.revision_history()
602
1126
if tree_to is not None:
603
# lock the tree we are pulling too, so that its inventory is
604
# stable. This is a hack to workaround the _iter_changes interface
605
# not exposing the old path, which will be fixed soon. RBC 20070301
608
count = tree_to.pull(branch_from, overwrite, rev_id,
609
delta.ChangeReporter(tree_to.inventory))
1127
view_info = _get_view_info_for_change_reporter(tree_to)
1128
change_reporter = delta._ChangeReporter(
1129
unversioned_filter=tree_to.is_ignored,
1130
view_info=view_info)
1131
result = tree_to.pull(
1132
branch_from, overwrite, revision_id, change_reporter,
1133
local=local, show_base=show_base)
613
count = branch_to.pull(branch_from, overwrite, rev_id)
614
note('%d revision(s) pulled.' % (count,))
1135
result = branch_to.pull(
1136
branch_from, overwrite, revision_id, local=local)
617
new_rh = branch_to.revision_history()
620
from bzrlib.log import show_changed_revisions
621
show_changed_revisions(branch_to, old_rh, new_rh,
1138
result.report(self.outf)
1139
if verbose and result.old_revid != result.new_revid:
1140
log.show_branch_change(
1141
branch_to, self.outf, result.old_revno,
1143
if getattr(result, 'tag_conflicts', None):
625
1149
class cmd_push(Command):
626
"""Update a mirror of this branch.
1150
__doc__ = """Update a mirror of this branch.
628
1152
The target branch will not have its working tree populated because this
629
1153
is both expensive, and is not supported on remote file systems.
631
1155
Some smart servers or protocols *may* put the working tree in place in
638
1162
If branches have diverged, you can use 'bzr push --overwrite' to replace
639
1163
the other branch completely, discarding its unmerged changes.
641
1165
If you want to ensure you have the different changes in the other branch,
642
1166
do a merge (see bzr help merge) from the other branch, and commit that.
643
1167
After that you will be able to do a push without '--overwrite'.
645
If there is no default push location set, the first push will set it.
646
After that, you can omit the location to use the default. To change the
647
default, use --remember. The value will only be saved if the remote
648
location can be accessed.
1169
If there is no default push location set, the first push will set it (use
1170
--no-remember to avoid setting it). After that, you can omit the
1171
location to use the default. To change the default, use --remember. The
1172
value will only be saved if the remote location can be accessed.
1174
The --verbose option will display the revisions pushed using the log_format
1175
configuration option. You can use a different format by overriding it with
1176
-Olog_format=<other_format>.
651
takes_options = ['remember', 'overwrite', 'verbose',
1179
_see_also = ['pull', 'update', 'working-trees']
1180
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
652
1181
Option('create-prefix',
653
1182
help='Create the path leading up to the branch '
654
'if it does not already exist'),
656
help='branch to push from, '
657
'rather than the one containing the working directory',
1183
'if it does not already exist.'),
1184
custom_help('directory',
1185
help='Branch to push from, '
1186
'rather than the one containing the working directory.'),
661
1187
Option('use-existing-dir',
662
1188
help='By default push will fail if the target'
663
1189
' directory exists, but does not already'
664
' have a control directory. This flag will'
1190
' have a control directory. This flag will'
665
1191
' allow push to proceed.'),
1193
help='Create a stacked branch that references the public location '
1194
'of the parent branch.'),
1195
Option('stacked-on',
1196
help='Create a stacked branch that refers to another branch '
1197
'for the commit history. Only the work not present in the '
1198
'referenced branch is included in the branch created.',
1201
help='Refuse to push if there are uncommitted changes in'
1202
' the working tree, --no-strict disables the check.'),
1204
help="Don't populate the working tree, even for protocols"
1205
" that support it."),
667
1207
takes_args = ['location?']
668
1208
encoding_type = 'replace'
670
def run(self, location=None, remember=False, overwrite=False,
671
create_prefix=False, verbose=False,
672
use_existing_dir=False,
674
# FIXME: Way too big! Put this into a function called from the
1210
def run(self, location=None, remember=None, overwrite=False,
1211
create_prefix=False, verbose=False, revision=None,
1212
use_existing_dir=False, directory=None, stacked_on=None,
1213
stacked=False, strict=None, no_tree=False):
1214
from bzrlib.push import _show_push_branch
676
1216
if directory is None:
678
br_from = Branch.open_containing(directory)[0]
679
stored_loc = br_from.get_push_location()
1218
# Get the source branch
1220
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1221
# Get the tip's revision_id
1222
revision = _get_one_revision('push', revision)
1223
if revision is not None:
1224
revision_id = revision.in_history(br_from).rev_id
1227
if tree is not None and revision_id is None:
1228
tree.check_changed_or_out_of_date(
1229
strict, 'push_strict',
1230
more_error='Use --no-strict to force the push.',
1231
more_warning='Uncommitted changes will not be pushed.')
1232
# Get the stacked_on branch, if any
1233
if stacked_on is not None:
1234
stacked_on = urlutils.normalize_url(stacked_on)
1236
parent_url = br_from.get_parent()
1238
parent = Branch.open(parent_url)
1239
stacked_on = parent.get_public_branch()
1241
# I considered excluding non-http url's here, thus forcing
1242
# 'public' branches only, but that only works for some
1243
# users, so it's best to just depend on the user spotting an
1244
# error by the feedback given to them. RBC 20080227.
1245
stacked_on = parent_url
1247
raise errors.BzrCommandError(gettext(
1248
"Could not determine branch to refer to."))
1250
# Get the destination location
680
1251
if location is None:
1252
stored_loc = br_from.get_push_location()
681
1253
if stored_loc is None:
682
raise errors.BzrCommandError("No push location known or specified.")
1254
raise errors.BzrCommandError(gettext(
1255
"No push location known or specified."))
684
1257
display_url = urlutils.unescape_for_display(stored_loc,
685
1258
self.outf.encoding)
686
self.outf.write("Using saved location: %s\n" % display_url)
1259
note(gettext("Using saved push location: %s") % display_url)
687
1260
location = stored_loc
689
to_transport = transport.get_transport(location)
690
location_url = to_transport.base
695
br_to = repository_to = dir_to = None
697
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
698
except errors.NotBranchError:
699
pass # Didn't find anything
701
# If we can open a branch, use its direct repository, otherwise see
702
# if there is a repository without a branch.
704
br_to = dir_to.open_branch()
705
except errors.NotBranchError:
706
# Didn't find a branch, can we find a repository?
708
repository_to = dir_to.find_repository()
709
except errors.NoRepositoryPresent:
712
# Found a branch, so we must have found a repository
713
repository_to = br_to.repository
717
# XXX: Refactor the create_prefix/no_create_prefix code into a
718
# common helper function
720
to_transport.mkdir('.')
721
except errors.FileExists:
722
if not use_existing_dir:
723
raise errors.BzrCommandError("Target directory %s"
724
" already exists, but does not have a valid .bzr"
725
" directory. Supply --use-existing-dir to push"
726
" there anyway." % location)
727
except errors.NoSuchFile:
728
if not create_prefix:
729
raise errors.BzrCommandError("Parent directory of %s"
731
"\nYou may supply --create-prefix to create all"
732
" leading parent directories."
735
cur_transport = to_transport
736
needed = [cur_transport]
737
# Recurse upwards until we can create a directory successfully
739
new_transport = cur_transport.clone('..')
740
if new_transport.base == cur_transport.base:
741
raise errors.BzrCommandError("Failed to create path"
745
new_transport.mkdir('.')
746
except errors.NoSuchFile:
747
needed.append(new_transport)
748
cur_transport = new_transport
752
# Now we only need to create child directories
754
cur_transport = needed.pop()
755
cur_transport.mkdir('.')
757
# Now the target directory exists, but doesn't have a .bzr
758
# directory. So we need to create it, along with any work to create
759
# all of the dependent branches, etc.
760
dir_to = br_from.bzrdir.clone(location_url,
761
revision_id=br_from.last_revision())
762
br_to = dir_to.open_branch()
763
count = br_to.last_revision_info()[0]
764
# We successfully created the target, remember it
765
if br_from.get_push_location() is None or remember:
766
br_from.set_push_location(br_to.base)
767
elif repository_to is None:
768
# we have a bzrdir but no branch or repository
769
# XXX: Figure out what to do other than complain.
770
raise errors.BzrCommandError("At %s you have a valid .bzr control"
771
" directory, but not a branch or repository. This is an"
772
" unsupported configuration. Please move the target directory"
773
" out of the way and try again."
776
# We have a repository but no branch, copy the revisions, and then
778
last_revision_id = br_from.last_revision()
779
repository_to.fetch(br_from.repository,
780
revision_id=last_revision_id)
781
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
782
count = len(br_to.revision_history())
783
if br_from.get_push_location() is None or remember:
784
br_from.set_push_location(br_to.base)
785
else: # We have a valid to branch
786
# We were able to connect to the remote location, so remember it
787
# we don't need to successfully push because of possible divergence.
788
if br_from.get_push_location() is None or remember:
789
br_from.set_push_location(br_to.base)
790
old_rh = br_to.revision_history()
793
tree_to = dir_to.open_workingtree()
794
except errors.NotLocalUrl:
795
warning('This transport does not update the working '
796
'tree of: %s' % (br_to.base,))
797
count = br_from.push(br_to, overwrite)
798
except errors.NoWorkingTree:
799
count = br_from.push(br_to, overwrite)
803
count = br_from.push(tree_to.branch, overwrite)
807
except errors.DivergedBranches:
808
raise errors.BzrCommandError('These branches have diverged.'
809
' Try using "merge" and then "push".')
810
note('%d revision(s) pushed.' % (count,))
813
new_rh = br_to.revision_history()
816
from bzrlib.log import show_changed_revisions
817
show_changed_revisions(br_to, old_rh, new_rh,
1262
_show_push_branch(br_from, revision_id, location, self.outf,
1263
verbose=verbose, overwrite=overwrite, remember=remember,
1264
stacked_on=stacked_on, create_prefix=create_prefix,
1265
use_existing_dir=use_existing_dir, no_tree=no_tree)
821
1268
class cmd_branch(Command):
822
"""Create a new copy of a branch.
1269
__doc__ = """Create a new branch that is a copy of an existing branch.
824
1271
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
825
1272
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1273
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
1274
is derived from the FROM_LOCATION by stripping a leading scheme or drive
1275
identifier, if any. For example, "branch lp:foo-bar" will attempt to
827
1278
To retrieve the branch as of a particular revision, supply the --revision
828
1279
parameter, as in "branch foo/bar -r 5".
830
--basis is to speed up branching from remote branches. When specified, it
831
copies all the file-contents, inventory and revision data from the basis
832
branch before copying anything from the remote branch.
1281
The synonyms 'clone' and 'get' for this command are deprecated.
1284
_see_also = ['checkout']
834
1285
takes_args = ['from_location', 'to_location?']
835
takes_options = ['revision', 'basis']
1286
takes_options = ['revision',
1287
Option('hardlink', help='Hard-link working tree files where possible.'),
1288
Option('files-from', type=str,
1289
help="Get file contents from this tree."),
1291
help="Create a branch without a working-tree."),
1293
help="Switch the checkout in the current directory "
1294
"to the new branch."),
1296
help='Create a stacked branch referring to the source branch. '
1297
'The new branch will depend on the availability of the source '
1298
'branch for all operations.'),
1299
Option('standalone',
1300
help='Do not use a shared repository, even if available.'),
1301
Option('use-existing-dir',
1302
help='By default branch will fail if the target'
1303
' directory exists, but does not already'
1304
' have a control directory. This flag will'
1305
' allow branch to proceed.'),
1307
help="Bind new branch to from location."),
836
1309
aliases = ['get', 'clone']
838
def run(self, from_location, to_location=None, revision=None, basis=None):
841
elif len(revision) > 1:
842
raise errors.BzrCommandError(
843
'bzr branch --revision takes exactly 1 revision value')
845
br_from = Branch.open(from_location)
848
if basis is not None:
849
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
852
if len(revision) == 1 and revision[0] is not None:
853
revision_id = revision[0].in_history(br_from)[1]
855
# FIXME - wt.last_revision, fallback to branch, fall back to
856
# None or perhaps NULL_REVISION to mean copy nothing
858
revision_id = br_from.last_revision()
1311
def run(self, from_location, to_location=None, revision=None,
1312
hardlink=False, stacked=False, standalone=False, no_tree=False,
1313
use_existing_dir=False, switch=False, bind=False,
1315
from bzrlib import switch as _mod_switch
1316
from bzrlib.tag import _merge_tags_if_possible
1317
if self.invoked_as in ['get', 'clone']:
1318
ui.ui_factory.show_user_warning(
1319
'deprecated_command',
1320
deprecated_name=self.invoked_as,
1321
recommended_name='branch',
1322
deprecated_in_version='2.4')
1323
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1325
if not (hardlink or files_from):
1326
# accelerator_tree is usually slower because you have to read N
1327
# files (no readahead, lots of seeks, etc), but allow the user to
1328
# explicitly request it
1329
accelerator_tree = None
1330
if files_from is not None and files_from != from_location:
1331
accelerator_tree = WorkingTree.open(files_from)
1332
revision = _get_one_revision('branch', revision)
1333
self.add_cleanup(br_from.lock_read().unlock)
1334
if revision is not None:
1335
revision_id = revision.as_revision_id(br_from)
1337
# FIXME - wt.last_revision, fallback to branch, fall back to
1338
# None or perhaps NULL_REVISION to mean copy nothing
1340
revision_id = br_from.last_revision()
1341
if to_location is None:
1342
to_location = getattr(br_from, "name", None)
859
1343
if to_location is None:
860
to_location = os.path.basename(from_location.rstrip("/\\"))
1344
to_location = urlutils.derive_to_location(from_location)
1345
to_transport = transport.get_transport(to_location)
1347
to_transport.mkdir('.')
1348
except errors.FileExists:
1350
to_dir = controldir.ControlDir.open_from_transport(
1352
except errors.NotBranchError:
1353
if not use_existing_dir:
1354
raise errors.BzrCommandError(gettext('Target directory "%s" '
1355
'already exists.') % to_location)
863
name = os.path.basename(to_location) + '\n'
865
to_transport = transport.get_transport(to_location)
867
to_transport.mkdir('.')
868
except errors.FileExists:
869
raise errors.BzrCommandError('Target directory "%s" already'
870
' exists.' % to_location)
871
except errors.NoSuchFile:
872
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1360
to_dir.open_branch()
1361
except errors.NotBranchError:
1364
raise errors.AlreadyBranchError(to_location)
1365
except errors.NoSuchFile:
1366
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
875
1372
# preserve whatever source format we have.
876
dir = br_from.bzrdir.sprout(to_transport.base,
877
revision_id, basis_dir)
878
branch = dir.open_branch()
1373
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1374
possible_transports=[to_transport],
1375
accelerator_tree=accelerator_tree,
1376
hardlink=hardlink, stacked=stacked,
1377
force_new_repo=standalone,
1378
create_tree_if_local=not no_tree,
1379
source_branch=br_from)
1380
branch = to_dir.open_branch(
1381
possible_transports=[
1382
br_from.bzrdir.root_transport, to_transport])
879
1383
except errors.NoSuchRevision:
880
1384
to_transport.delete_tree('.')
881
msg = "The branch %s has no revision %s." % (from_location, revision[0])
882
raise errors.BzrCommandError(msg)
883
except errors.UnlistableBranch:
884
osutils.rmtree(to_location)
885
msg = "The branch %s cannot be used as a --basis" % (basis,)
886
raise errors.BzrCommandError(msg)
888
branch.control_files.put_utf8('branch-name', name)
889
note('Branched %d revision(s).' % branch.revno())
1385
msg = gettext("The branch {0} has no revision {1}.").format(
1386
from_location, revision)
1387
raise errors.BzrCommandError(msg)
1389
branch = br_from.sprout(to_dir, revision_id=revision_id)
1390
_merge_tags_if_possible(br_from, branch)
1391
# If the source branch is stacked, the new branch may
1392
# be stacked whether we asked for that explicitly or not.
1393
# We therefore need a try/except here and not just 'if stacked:'
1395
note(gettext('Created new stacked branch referring to %s.') %
1396
branch.get_stacked_on_url())
1397
except (errors.NotStacked, errors.UnstackableBranchFormat,
1398
errors.UnstackableRepositoryFormat), e:
1399
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1401
# Bind to the parent
1402
parent_branch = Branch.open(from_location)
1403
branch.bind(parent_branch)
1404
note(gettext('New branch bound to %s') % from_location)
1406
# Switch to the new branch
1407
wt, _ = WorkingTree.open_containing('.')
1408
_mod_switch.switch(wt.bzrdir, branch)
1409
note(gettext('Switched to branch: %s'),
1410
urlutils.unescape_for_display(branch.base, 'utf-8'))
1413
class cmd_branches(Command):
1414
__doc__ = """List the branches available at the current location.
1416
This command will print the names of all the branches at the current
1420
takes_args = ['location?']
1422
Option('recursive', short_name='R',
1423
help='Recursively scan for branches rather than '
1424
'just looking in the specified location.')]
1426
def run(self, location=".", recursive=False):
1428
t = transport.get_transport(location)
1429
if not t.listable():
1430
raise errors.BzrCommandError(
1431
"Can't scan this type of location.")
1432
for b in controldir.ControlDir.find_branches(t):
1433
self.outf.write("%s\n" % urlutils.unescape_for_display(
1434
urlutils.relative_url(t.base, b.base),
1435
self.outf.encoding).rstrip("/"))
1437
dir = controldir.ControlDir.open_containing(location)[0]
1438
for branch in dir.list_branches():
1439
if branch.name is None:
1440
self.outf.write(gettext(" (default)\n"))
1442
self.outf.write(" %s\n" % branch.name.encode(
1443
self.outf.encoding))
894
1446
class cmd_checkout(Command):
895
"""Create a new checkout of an existing branch.
1447
__doc__ = """Create a new checkout of an existing branch.
897
1449
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
898
1450
the branch found in '.'. This is useful if you have removed the working tree
899
1451
or if it was never created - i.e. if you pushed the branch to its current
900
1452
location using SFTP.
902
1454
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
903
1455
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
1456
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1457
is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
1458
identifier, if any. For example, "checkout lp:foo-bar" will attempt to
905
1461
To retrieve the branch as of a particular revision, supply the --revision
906
1462
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
907
1463
out of date [so you cannot commit] but it may be useful (i.e. to examine old
910
--basis is to speed up checking out from remote branches. When specified, it
911
uses the inventory and file contents from the basis branch in preference to the
912
branch being checked out.
914
See "help checkouts" for more information on checkouts.
1467
_see_also = ['checkouts', 'branch']
916
1468
takes_args = ['branch_location?', 'to_location?']
917
takes_options = ['revision', # , 'basis']
1469
takes_options = ['revision',
918
1470
Option('lightweight',
919
help="perform a lightweight checkout. Lightweight "
1471
help="Perform a lightweight checkout. Lightweight "
920
1472
"checkouts depend on access to the branch for "
921
"every operation. Normal checkouts can perform "
1473
"every operation. Normal checkouts can perform "
922
1474
"common operations like diff and status without "
923
1475
"such access, and also support local commits."
1477
Option('files-from', type=str,
1478
help="Get file contents from this tree."),
1480
help='Hard-link working tree files where possible.'
926
1483
aliases = ['co']
928
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
932
elif len(revision) > 1:
933
raise errors.BzrCommandError(
934
'bzr checkout --revision takes exactly 1 revision value')
1485
def run(self, branch_location=None, to_location=None, revision=None,
1486
lightweight=False, files_from=None, hardlink=False):
935
1487
if branch_location is None:
936
1488
branch_location = osutils.getcwd()
937
1489
to_location = branch_location
938
source = Branch.open(branch_location)
939
if len(revision) == 1 and revision[0] is not None:
940
revision_id = revision[0].in_history(source)[1]
1490
accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1492
if not (hardlink or files_from):
1493
# accelerator_tree is usually slower because you have to read N
1494
# files (no readahead, lots of seeks, etc), but allow the user to
1495
# explicitly request it
1496
accelerator_tree = None
1497
revision = _get_one_revision('checkout', revision)
1498
if files_from is not None and files_from != branch_location:
1499
accelerator_tree = WorkingTree.open(files_from)
1500
if revision is not None:
1501
revision_id = revision.as_revision_id(source)
942
1503
revision_id = None
943
1504
if to_location is None:
944
to_location = os.path.basename(branch_location.rstrip("/\\"))
945
# if the source and to_location are the same,
1505
to_location = urlutils.derive_to_location(branch_location)
1506
# if the source and to_location are the same,
946
1507
# and there is no working tree,
947
1508
# then reconstitute a branch
948
1509
if (osutils.abspath(to_location) ==
951
1512
source.bzrdir.open_workingtree()
952
1513
except errors.NoWorkingTree:
953
source.bzrdir.create_workingtree()
1514
source.bzrdir.create_workingtree(revision_id)
956
os.mkdir(to_location)
958
if e.errno == errno.EEXIST:
959
raise errors.BzrCommandError('Target directory "%s" already'
960
' exists.' % to_location)
961
if e.errno == errno.ENOENT:
962
raise errors.BzrCommandError('Parent of "%s" does not exist.'
966
source.create_checkout(to_location, revision_id, lightweight)
1516
source.create_checkout(to_location, revision_id, lightweight,
1517
accelerator_tree, hardlink)
969
1520
class cmd_renames(Command):
970
"""Show list of renamed files.
1521
__doc__ = """Show list of renamed files.
972
1523
# TODO: Option to show renames between two historical versions.
974
1525
# TODO: Only show renames under dir, rather than in the whole branch.
1526
_see_also = ['status']
975
1527
takes_args = ['dir?']
977
1529
@display_command
978
1530
def run(self, dir=u'.'):
979
1531
tree = WorkingTree.open_containing(dir)[0]
980
old_inv = tree.basis_tree().inventory
981
new_inv = tree.read_working_inventory()
982
renames = list(_mod_tree.find_renames(old_inv, new_inv))
1532
self.add_cleanup(tree.lock_read().unlock)
1533
new_inv = tree.inventory
1534
old_tree = tree.basis_tree()
1535
self.add_cleanup(old_tree.lock_read().unlock)
1536
old_inv = old_tree.inventory
1538
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1539
for f, paths, c, v, p, n, k, e in iterator:
1540
if paths[0] == paths[1]:
1544
renames.append(paths)
984
1546
for old_name, new_name in renames:
985
1547
self.outf.write("%s => %s\n" % (old_name, new_name))
988
1550
class cmd_update(Command):
989
"""Update a tree to have the latest code committed to its branch.
991
This will perform a merge into the working tree, and may generate
992
conflicts. If you have any local changes, you will still
993
need to commit them after the update for the update to be complete.
995
If you want to discard your local changes, you can just do a
996
'bzr revert' instead of 'bzr commit' after the update.
1551
__doc__ = """Update a working tree to a new revision.
1553
This will perform a merge of the destination revision (the tip of the
1554
branch, or the specified revision) into the working tree, and then make
1555
that revision the basis revision for the working tree.
1557
You can use this to visit an older revision, or to update a working tree
1558
that is out of date from its branch.
1560
If there are any uncommitted changes in the tree, they will be carried
1561
across and remain as uncommitted changes after the update. To discard
1562
these changes, use 'bzr revert'. The uncommitted changes may conflict
1563
with the changes brought in by the change in basis revision.
1565
If the tree's branch is bound to a master branch, bzr will also update
1566
the branch from the master.
1568
You cannot update just a single file or directory, because each Bazaar
1569
working tree has just a single basis revision. If you want to restore a
1570
file that has been removed locally, use 'bzr revert' instead of 'bzr
1571
update'. If you want to restore a file to its state in a previous
1572
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1573
out the old content of that file to a new location.
1575
The 'dir' argument, if given, must be the location of the root of a
1576
working tree to update. By default, the working tree that contains the
1577
current working directory is used.
1580
_see_also = ['pull', 'working-trees', 'status-flags']
998
1581
takes_args = ['dir?']
1582
takes_options = ['revision',
1584
help="Show base revision text in conflicts."),
999
1586
aliases = ['up']
1001
def run(self, dir='.'):
1002
tree = WorkingTree.open_containing(dir)[0]
1003
master = tree.branch.get_master_branch()
1588
def run(self, dir=None, revision=None, show_base=None):
1589
if revision is not None and len(revision) != 1:
1590
raise errors.BzrCommandError(gettext(
1591
"bzr update --revision takes exactly one revision"))
1593
tree = WorkingTree.open_containing('.')[0]
1595
tree, relpath = WorkingTree.open_containing(dir)
1598
raise errors.BzrCommandError(gettext(
1599
"bzr update can only update a whole tree, "
1600
"not a file or subdirectory"))
1601
branch = tree.branch
1602
possible_transports = []
1603
master = branch.get_master_branch(
1604
possible_transports=possible_transports)
1004
1605
if master is not None:
1606
branch_location = master.base
1005
1607
tree.lock_write()
1609
branch_location = tree.branch.base
1007
1610
tree.lock_tree_write()
1611
self.add_cleanup(tree.unlock)
1612
# get rid of the final '/' and be ready for display
1613
branch_location = urlutils.unescape_for_display(
1614
branch_location.rstrip('/'),
1616
existing_pending_merges = tree.get_parent_ids()[1:]
1620
# may need to fetch data into a heavyweight checkout
1621
# XXX: this may take some time, maybe we should display a
1623
old_tip = branch.update(possible_transports)
1624
if revision is not None:
1625
revision_id = revision[0].as_revision_id(branch)
1627
revision_id = branch.last_revision()
1628
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1629
revno = branch.revision_id_to_dotted_revno(revision_id)
1630
note(gettext("Tree is up to date at revision {0} of branch {1}"
1631
).format('.'.join(map(str, revno)), branch_location))
1633
view_info = _get_view_info_for_change_reporter(tree)
1634
change_reporter = delta._ChangeReporter(
1635
unversioned_filter=tree.is_ignored,
1636
view_info=view_info)
1009
existing_pending_merges = tree.get_parent_ids()[1:]
1010
last_rev = tree.last_revision()
1011
if last_rev == tree.branch.last_revision():
1012
# may be up to date, check master too.
1013
master = tree.branch.get_master_branch()
1014
if master is None or last_rev == master.last_revision():
1015
revno = tree.branch.revision_id_to_revno(last_rev)
1016
note("Tree is up to date at revision %d." % (revno,))
1018
conflicts = tree.update()
1019
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1020
note('Updated to revision %d.' % (revno,))
1021
if tree.get_parent_ids()[1:] != existing_pending_merges:
1022
note('Your local commits will now show as pending merges with '
1023
"'bzr status', and can be committed with 'bzr commit'.")
1638
conflicts = tree.update(
1640
possible_transports=possible_transports,
1641
revision=revision_id,
1643
show_base=show_base)
1644
except errors.NoSuchRevision, e:
1645
raise errors.BzrCommandError(gettext(
1646
"branch has no revision %s\n"
1647
"bzr update --revision only works"
1648
" for a revision in the branch history")
1650
revno = tree.branch.revision_id_to_dotted_revno(
1651
_mod_revision.ensure_null(tree.last_revision()))
1652
note(gettext('Updated to revision {0} of branch {1}').format(
1653
'.'.join(map(str, revno)), branch_location))
1654
parent_ids = tree.get_parent_ids()
1655
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1656
note(gettext('Your local commits will now show as pending merges with '
1657
"'bzr status', and can be committed with 'bzr commit'."))
1032
1664
class cmd_info(Command):
1033
"""Show information about a working tree, branch or repository.
1665
__doc__ = """Show information about a working tree, branch or repository.
1035
1667
This command will show all known locations and formats associated to the
1036
tree, branch or repository. Statistical information is included with
1668
tree, branch or repository.
1670
In verbose mode, statistical information is included with each report.
1671
To see extended statistic information, use a verbosity level of 2 or
1672
higher by specifying the verbose option multiple times, e.g. -vv.
1039
1674
Branches and working trees will also report any missing revisions.
1678
Display information on the format and related locations:
1682
Display the above together with extended format information and
1683
basic statistics (like the number of files in the working tree and
1684
number of revisions in the branch and repository):
1688
Display the above together with number of committers to the branch:
1692
_see_also = ['revno', 'working-trees', 'repositories']
1041
1693
takes_args = ['location?']
1042
1694
takes_options = ['verbose']
1695
encoding_type = 'replace'
1044
1697
@display_command
1045
1698
def run(self, location=None, verbose=False):
1700
noise_level = get_verbosity_level()
1046
1703
from bzrlib.info import show_bzrdir_info
1047
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1704
show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1705
verbose=noise_level, outfile=self.outf)
1051
1708
class cmd_remove(Command):
1052
"""Make a file unversioned.
1054
This makes bzr stop tracking changes to a versioned file. It does
1055
not delete the working copy.
1057
You can specify one or more files, and/or --new. If you specify --new,
1058
only 'added' files will be removed. If you specify both, then new files
1059
in the specified directories will be removed. If the directories are
1060
also new, they will also be removed.
1709
__doc__ = """Remove files or directories.
1711
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1712
delete them if they can easily be recovered using revert otherwise they
1713
will be backed up (adding an extention of the form .~#~). If no options or
1714
parameters are given Bazaar will scan for files that are being tracked by
1715
Bazaar but missing in your tree and stop tracking them for you.
1062
1717
takes_args = ['file*']
1063
takes_options = ['verbose', Option('new', help='remove newly-added files')]
1718
takes_options = ['verbose',
1719
Option('new', help='Only remove files that have never been committed.'),
1720
RegistryOption.from_kwargs('file-deletion-strategy',
1721
'The file deletion mode to be used.',
1722
title='Deletion Strategy', value_switches=True, enum_switch=False,
1723
safe='Backup changed files (default).',
1724
keep='Delete from bzr but leave the working copy.',
1725
no_backup='Don\'t backup changed files.',
1726
force='Delete all the specified files, even if they can not be '
1727
'recovered and even if they are non-empty directories. '
1728
'(deprecated, use no-backup)')]
1729
aliases = ['rm', 'del']
1065
1730
encoding_type = 'replace'
1067
def run(self, file_list, verbose=False, new=False):
1068
tree, file_list = tree_files(file_list)
1070
if file_list is None:
1071
raise errors.BzrCommandError('Specify one or more files to'
1072
' remove, or use --new.')
1732
def run(self, file_list, verbose=False, new=False,
1733
file_deletion_strategy='safe'):
1734
if file_deletion_strategy == 'force':
1735
note(gettext("(The --force option is deprecated, rather use --no-backup "
1737
file_deletion_strategy = 'no-backup'
1739
tree, file_list = WorkingTree.open_containing_paths(file_list)
1741
if file_list is not None:
1742
file_list = [f for f in file_list]
1744
self.add_cleanup(tree.lock_write().unlock)
1745
# Heuristics should probably all move into tree.remove_smart or
1074
1748
added = tree.changes_from(tree.basis_tree(),
1075
1749
specific_files=file_list).added
1076
1750
file_list = sorted([f[0] for f in added], reverse=True)
1077
1751
if len(file_list) == 0:
1078
raise errors.BzrCommandError('No matching files.')
1079
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1752
raise errors.BzrCommandError(gettext('No matching files.'))
1753
elif file_list is None:
1754
# missing files show up in iter_changes(basis) as
1755
# versioned-with-no-kind.
1757
for change in tree.iter_changes(tree.basis_tree()):
1758
# Find paths in the working tree that have no kind:
1759
if change[1][1] is not None and change[6][1] is None:
1760
missing.append(change[1][1])
1761
file_list = sorted(missing, reverse=True)
1762
file_deletion_strategy = 'keep'
1763
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1764
keep_files=file_deletion_strategy=='keep',
1765
force=(file_deletion_strategy=='no-backup'))
1082
1768
class cmd_file_id(Command):
1083
"""Print file_id of a particular file or directory.
1769
__doc__ = """Print file_id of a particular file or directory.
1085
1771
The file_id is assigned when the file is first added and remains the
1086
1772
same through all revisions where the file exists, even when it is
1493
2325
self.outf.write(tree.basedir + '\n')
2328
def _parse_limit(limitstring):
2330
return int(limitstring)
2332
msg = gettext("The limit argument must be an integer.")
2333
raise errors.BzrCommandError(msg)
2336
def _parse_levels(s):
2340
msg = gettext("The levels argument must be an integer.")
2341
raise errors.BzrCommandError(msg)
1496
2344
class cmd_log(Command):
1497
"""Show log of a branch, file, or directory.
1499
By default show the log of the branch containing the working directory.
1501
To request a range of logs, you can use the command -r begin..end
1502
-r revision requests a specific revision, -r ..end or -r begin.. are
1508
bzr log -r -10.. http://server/branch
2345
__doc__ = """Show historical log for a branch or subset of a branch.
2347
log is bzr's default tool for exploring the history of a branch.
2348
The branch to use is taken from the first parameter. If no parameters
2349
are given, the branch containing the working directory is logged.
2350
Here are some simple examples::
2352
bzr log log the current branch
2353
bzr log foo.py log a file in its branch
2354
bzr log http://server/branch log a branch on a server
2356
The filtering, ordering and information shown for each revision can
2357
be controlled as explained below. By default, all revisions are
2358
shown sorted (topologically) so that newer revisions appear before
2359
older ones and descendants always appear before ancestors. If displayed,
2360
merged revisions are shown indented under the revision in which they
2365
The log format controls how information about each revision is
2366
displayed. The standard log formats are called ``long``, ``short``
2367
and ``line``. The default is long. See ``bzr help log-formats``
2368
for more details on log formats.
2370
The following options can be used to control what information is
2373
-l N display a maximum of N revisions
2374
-n N display N levels of revisions (0 for all, 1 for collapsed)
2375
-v display a status summary (delta) for each revision
2376
-p display a diff (patch) for each revision
2377
--show-ids display revision-ids (and file-ids), not just revnos
2379
Note that the default number of levels to display is a function of the
2380
log format. If the -n option is not used, the standard log formats show
2381
just the top level (mainline).
2383
Status summaries are shown using status flags like A, M, etc. To see
2384
the changes explained using words like ``added`` and ``modified``
2385
instead, use the -vv option.
2389
To display revisions from oldest to newest, use the --forward option.
2390
In most cases, using this option will have little impact on the total
2391
time taken to produce a log, though --forward does not incrementally
2392
display revisions like --reverse does when it can.
2394
:Revision filtering:
2396
The -r option can be used to specify what revision or range of revisions
2397
to filter against. The various forms are shown below::
2399
-rX display revision X
2400
-rX.. display revision X and later
2401
-r..Y display up to and including revision Y
2402
-rX..Y display from X to Y inclusive
2404
See ``bzr help revisionspec`` for details on how to specify X and Y.
2405
Some common examples are given below::
2407
-r-1 show just the tip
2408
-r-10.. show the last 10 mainline revisions
2409
-rsubmit:.. show what's new on this branch
2410
-rancestor:path.. show changes since the common ancestor of this
2411
branch and the one at location path
2412
-rdate:yesterday.. show changes since yesterday
2414
When logging a range of revisions using -rX..Y, log starts at
2415
revision Y and searches back in history through the primary
2416
("left-hand") parents until it finds X. When logging just the
2417
top level (using -n1), an error is reported if X is not found
2418
along the way. If multi-level logging is used (-n0), X may be
2419
a nested merge revision and the log will be truncated accordingly.
2423
If parameters are given and the first one is not a branch, the log
2424
will be filtered to show only those revisions that changed the
2425
nominated files or directories.
2427
Filenames are interpreted within their historical context. To log a
2428
deleted file, specify a revision range so that the file existed at
2429
the end or start of the range.
2431
Historical context is also important when interpreting pathnames of
2432
renamed files/directories. Consider the following example:
2434
* revision 1: add tutorial.txt
2435
* revision 2: modify tutorial.txt
2436
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2440
* ``bzr log guide.txt`` will log the file added in revision 1
2442
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2444
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2445
the original file in revision 2.
2447
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2448
was no file called guide.txt in revision 2.
2450
Renames are always followed by log. By design, there is no need to
2451
explicitly ask for this (and no way to stop logging a file back
2452
until it was last renamed).
2456
The --match option can be used for finding revisions that match a
2457
regular expression in a commit message, committer, author or bug.
2458
Specifying the option several times will match any of the supplied
2459
expressions. --match-author, --match-bugs, --match-committer and
2460
--match-message can be used to only match a specific field.
2464
GUI tools and IDEs are often better at exploring history than command
2465
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2466
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2467
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2468
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2470
You may find it useful to add the aliases below to ``bazaar.conf``::
2474
top = log -l10 --line
2477
``bzr tip`` will then show the latest revision while ``bzr top``
2478
will show the last 10 mainline revisions. To see the details of a
2479
particular revision X, ``bzr show -rX``.
2481
If you are interested in looking deeper into a particular merge X,
2482
use ``bzr log -n0 -rX``.
2484
``bzr log -v`` on a branch with lots of history is currently
2485
very slow. A fix for this issue is currently under development.
2486
With or without that fix, it is recommended that a revision range
2487
be given when using the -v option.
2489
bzr has a generic full-text matching plugin, bzr-search, that can be
2490
used to find revisions matching user names, commit messages, etc.
2491
Among other features, this plugin can find all revisions containing
2492
a list of words but not others.
2494
When exploring non-mainline history on large projects with deep
2495
history, the performance of log can be greatly improved by installing
2496
the historycache plugin. This plugin buffers historical information
2497
trading disk space for faster speed.
1511
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1513
takes_args = ['location?']
1514
takes_options = [Option('forward',
1515
help='show from oldest to newest'),
1519
help='show files changed in each revision'),
1520
'show-ids', 'revision',
1524
help='show revisions whose message matches this regexp',
2499
takes_args = ['file*']
2500
_see_also = ['log-formats', 'revisionspec']
2503
help='Show from oldest to newest.'),
2505
custom_help('verbose',
2506
help='Show files changed in each revision.'),
2510
type=bzrlib.option._parse_revision_str,
2512
help='Show just the specified revision.'
2513
' See also "help revisionspec".'),
2515
RegistryOption('authors',
2516
'What names to list as authors - first, all or committer.',
2518
lazy_registry=('bzrlib.log', 'author_list_registry'),
2522
help='Number of levels to display - 0 for all, 1 for flat.',
2524
type=_parse_levels),
2526
help='Show revisions whose message matches this '
2527
'regular expression.',
2532
help='Limit the output to the first N revisions.',
2537
help='Show changes made in each revision as a patch.'),
2538
Option('include-merged',
2539
help='Show merged revisions like --levels 0 does.'),
2540
Option('include-merges', hidden=True,
2541
help='Historical alias for --include-merged.'),
2542
Option('omit-merges',
2543
help='Do not report commits with more than one parent.'),
2544
Option('exclude-common-ancestry',
2545
help='Display only the revisions that are not part'
2546
' of both ancestries (require -rX..Y).'
2548
Option('signatures',
2549
help='Show digital signature validity.'),
2552
help='Show revisions whose properties match this '
2555
ListOption('match-message',
2556
help='Show revisions whose message matches this '
2559
ListOption('match-committer',
2560
help='Show revisions whose committer matches this '
2563
ListOption('match-author',
2564
help='Show revisions whose authors match this '
2567
ListOption('match-bugs',
2568
help='Show revisions whose bugs match this '
1527
2572
encoding_type = 'replace'
1529
2574
@display_command
1530
def run(self, location=None, timezone='original',
2575
def run(self, file_list=None, timezone='original',
1532
2577
show_ids=False,
1535
2581
log_format=None,
1537
from bzrlib.log import show_log
1538
assert message is None or isinstance(message, basestring), \
1539
"invalid message argument %r" % message
2586
include_merged=None,
2588
exclude_common_ancestry=False,
2592
match_committer=None,
2596
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2598
from bzrlib.log import (
2600
make_log_request_dict,
2601
_get_info_for_log_files,
1540
2603
direction = (forward and 'forward') or 'reverse'
1545
# find the file id to log:
1547
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1551
tree = b.basis_tree()
1552
file_id = tree.path2id(fp)
2604
if symbol_versioning.deprecated_passed(include_merges):
2605
ui.ui_factory.show_user_warning(
2606
'deprecated_command_option',
2607
deprecated_name='--include-merges',
2608
recommended_name='--include-merged',
2609
deprecated_in_version='2.5',
2610
command=self.invoked_as)
2611
if include_merged is None:
2612
include_merged = include_merges
2614
raise errors.BzrCommandError(gettext(
2615
'{0} and {1} are mutually exclusive').format(
2616
'--include-merges', '--include-merged'))
2617
if include_merged is None:
2618
include_merged = False
2619
if (exclude_common_ancestry
2620
and (revision is None or len(revision) != 2)):
2621
raise errors.BzrCommandError(gettext(
2622
'--exclude-common-ancestry requires -r with two revisions'))
2627
raise errors.BzrCommandError(gettext(
2628
'{0} and {1} are mutually exclusive').format(
2629
'--levels', '--include-merged'))
2631
if change is not None:
2633
raise errors.RangeInChangeOption()
2634
if revision is not None:
2635
raise errors.BzrCommandError(gettext(
2636
'{0} and {1} are mutually exclusive').format(
2637
'--revision', '--change'))
2642
filter_by_dir = False
2644
# find the file ids to log and check for directory filtering
2645
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2646
revision, file_list, self.add_cleanup)
2647
for relpath, file_id, kind in file_info_list:
1553
2648
if file_id is None:
1554
raise errors.BzrCommandError(
1555
"Path does not have any revision history: %s" %
2649
raise errors.BzrCommandError(gettext(
2650
"Path unknown at end or start of revision range: %s") %
2652
# If the relpath is the top of the tree, we log everything
2657
file_ids.append(file_id)
2658
filter_by_dir = filter_by_dir or (
2659
kind in ['directory', 'tree-reference'])
1559
# FIXME ? log the current subdir only RBC 20060203
2662
# FIXME ? log the current subdir only RBC 20060203
1560
2663
if revision is not None \
1561
2664
and len(revision) > 0 and revision[0].get_branch():
1562
2665
location = revision[0].get_branch()
1565
dir, relpath = bzrdir.BzrDir.open_containing(location)
2668
dir, relpath = controldir.ControlDir.open_containing(location)
1566
2669
b = dir.open_branch()
1570
if revision is None:
1573
elif len(revision) == 1:
1574
rev1 = rev2 = revision[0].in_history(b).revno
1575
elif len(revision) == 2:
1576
if revision[1].get_branch() != revision[0].get_branch():
1577
# b is taken from revision[0].get_branch(), and
1578
# show_log will use its revision_history. Having
1579
# different branches will lead to weird behaviors.
1580
raise errors.BzrCommandError(
1581
"Log doesn't accept two revisions in different"
1583
if revision[0].spec is None:
1584
# missing begin-range means first revision
1587
rev1 = revision[0].in_history(b).revno
1589
if revision[1].spec is None:
1590
# missing end-range means last known revision
1593
rev2 = revision[1].in_history(b).revno
1595
raise errors.BzrCommandError(
1596
'bzr log --revision takes one or two values.')
1598
# By this point, the revision numbers are converted to the +ve
1599
# form if they were supplied in the -ve form, so we can do
1600
# this comparison in relative safety
1602
(rev2, rev1) = (rev1, rev2)
1604
if log_format is None:
1605
log_format = log.log_formatter_registry.get_default(b)
1607
lf = log_format(show_ids=show_ids, to_file=self.outf,
1608
show_timezone=timezone)
1614
direction=direction,
1615
start_revision=rev1,
2670
self.add_cleanup(b.lock_read().unlock)
2671
rev1, rev2 = _get_revision_range(revision, b, self.name())
2673
if b.get_config().validate_signatures_in_log():
2677
if not gpg.GPGStrategy.verify_signatures_available():
2678
raise errors.GpgmeNotInstalled(None)
2680
# Decide on the type of delta & diff filtering to use
2681
# TODO: add an --all-files option to make this configurable & consistent
2689
diff_type = 'partial'
2693
# Build the log formatter
2694
if log_format is None:
2695
log_format = log.log_formatter_registry.get_default(b)
2696
# Make a non-encoding output to include the diffs - bug 328007
2697
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2698
lf = log_format(show_ids=show_ids, to_file=self.outf,
2699
to_exact_file=unencoded_output,
2700
show_timezone=timezone,
2701
delta_format=get_verbosity_level(),
2703
show_advice=levels is None,
2704
author_list_handler=authors)
2706
# Choose the algorithm for doing the logging. It's annoying
2707
# having multiple code paths like this but necessary until
2708
# the underlying repository format is faster at generating
2709
# deltas or can provide everything we need from the indices.
2710
# The default algorithm - match-using-deltas - works for
2711
# multiple files and directories and is faster for small
2712
# amounts of history (200 revisions say). However, it's too
2713
# slow for logging a single file in a repository with deep
2714
# history, i.e. > 10K revisions. In the spirit of "do no
2715
# evil when adding features", we continue to use the
2716
# original algorithm - per-file-graph - for the "single
2717
# file that isn't a directory without showing a delta" case.
2718
partial_history = revision and b.repository._format.supports_chks
2719
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2720
or delta_type or partial_history)
2724
match_dict[''] = match
2726
match_dict['message'] = match_message
2728
match_dict['committer'] = match_committer
2730
match_dict['author'] = match_author
2732
match_dict['bugs'] = match_bugs
2734
# Build the LogRequest and execute it
2735
if len(file_ids) == 0:
2737
rqst = make_log_request_dict(
2738
direction=direction, specific_fileids=file_ids,
2739
start_revision=rev1, end_revision=rev2, limit=limit,
2740
message_search=message, delta_type=delta_type,
2741
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2742
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2743
signature=signatures, omit_merges=omit_merges,
2745
Logger(b, rqst).show(lf)
2748
def _get_revision_range(revisionspec_list, branch, command_name):
2749
"""Take the input of a revision option and turn it into a revision range.
2751
It returns RevisionInfo objects which can be used to obtain the rev_id's
2752
of the desired revisions. It does some user input validations.
2754
if revisionspec_list is None:
2757
elif len(revisionspec_list) == 1:
2758
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2759
elif len(revisionspec_list) == 2:
2760
start_spec = revisionspec_list[0]
2761
end_spec = revisionspec_list[1]
2762
if end_spec.get_branch() != start_spec.get_branch():
2763
# b is taken from revision[0].get_branch(), and
2764
# show_log will use its revision_history. Having
2765
# different branches will lead to weird behaviors.
2766
raise errors.BzrCommandError(gettext(
2767
"bzr %s doesn't accept two revisions in different"
2768
" branches.") % command_name)
2769
if start_spec.spec is None:
2770
# Avoid loading all the history.
2771
rev1 = RevisionInfo(branch, None, None)
2773
rev1 = start_spec.in_history(branch)
2774
# Avoid loading all of history when we know a missing
2775
# end of range means the last revision ...
2776
if end_spec.spec is None:
2777
last_revno, last_revision_id = branch.last_revision_info()
2778
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2780
rev2 = end_spec.in_history(branch)
2782
raise errors.BzrCommandError(gettext(
2783
'bzr %s --revision takes one or two values.') % command_name)
2787
def _revision_range_to_revid_range(revision_range):
2790
if revision_range[0] is not None:
2791
rev_id1 = revision_range[0].rev_id
2792
if revision_range[1] is not None:
2793
rev_id2 = revision_range[1].rev_id
2794
return rev_id1, rev_id2
1622
2796
def get_log_format(long=False, short=False, line=False, default='long'):
1623
2797
log_format = default
1642
2816
@display_command
1643
2817
def run(self, filename):
1644
2818
tree, relpath = WorkingTree.open_containing(filename)
2819
file_id = tree.path2id(relpath)
1645
2820
b = tree.branch
1646
file_id = tree.path2id(relpath)
1647
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
2821
self.add_cleanup(b.lock_read().unlock)
2822
touching_revs = log.find_touching_revisions(b, file_id)
2823
for revno, revision_id, what in touching_revs:
1648
2824
self.outf.write("%6d %s\n" % (revno, what))
1651
2827
class cmd_ls(Command):
1652
"""List files in a tree.
2828
__doc__ = """List files in a tree.
2831
_see_also = ['status', 'cat']
1655
2832
takes_args = ['path?']
1656
# TODO: Take a revision or remote path and list that tree instead.
1657
takes_options = ['verbose', 'revision',
1658
Option('non-recursive',
1659
help='don\'t recurse into sub-directories'),
1661
help='Print all paths from the root of the branch.'),
1662
Option('unknown', help='Print unknown files'),
1663
Option('versioned', help='Print versioned files'),
1664
Option('ignored', help='Print ignored files'),
1666
Option('null', help='Null separate the files'),
2836
Option('recursive', short_name='R',
2837
help='Recurse into subdirectories.'),
2839
help='Print paths relative to the root of the branch.'),
2840
Option('unknown', short_name='u',
2841
help='Print unknown files.'),
2842
Option('versioned', help='Print versioned files.',
2844
Option('ignored', short_name='i',
2845
help='Print ignored files.'),
2846
Option('kind', short_name='k',
2847
help='List entries of a particular kind: file, directory, symlink.',
1669
2853
@display_command
1670
def run(self, revision=None, verbose=False,
1671
non_recursive=False, from_root=False,
2854
def run(self, revision=None, verbose=False,
2855
recursive=False, from_root=False,
1672
2856
unknown=False, versioned=False, ignored=False,
1673
null=False, kind=None, show_ids=False, path=None):
2857
null=False, kind=None, show_ids=False, path=None, directory=None):
1675
2859
if kind and kind not in ('file', 'directory', 'symlink'):
1676
raise errors.BzrCommandError('invalid kind specified')
2860
raise errors.BzrCommandError(gettext('invalid kind specified'))
1678
2862
if verbose and null:
1679
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2863
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
1680
2864
all = not (unknown or versioned or ignored)
1682
2866
selection = {'I':ignored, '?':unknown, 'V':versioned}
1684
2868
if path is None:
1689
raise errors.BzrCommandError('cannot specify both --from-root'
2872
raise errors.BzrCommandError(gettext('cannot specify both --from-root'
1693
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2875
tree, branch, relpath = \
2876
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2878
# Calculate the prefix to use
1699
if revision is not None:
1700
tree = branch.repository.revision_tree(
1701
revision[0].in_history(branch).rev_id)
1703
tree = branch.basis_tree()
1707
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1708
if fp.startswith(relpath):
1709
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1710
if non_recursive and '/' in fp:
1712
if not all and not selection[fc]:
1714
if kind is not None and fkind != kind:
1717
kindch = entry.kind_character()
1718
outstring = '%-8s %s%s' % (fc, fp, kindch)
1719
if show_ids and fid is not None:
1720
outstring = "%-50s %s" % (outstring, fid)
1721
self.outf.write(outstring + '\n')
1723
self.outf.write(fp + '\0')
1726
self.outf.write(fid)
1727
self.outf.write('\0')
1735
self.outf.write('%-50s %s\n' % (fp, my_id))
1737
self.outf.write(fp + '\n')
2882
prefix = relpath + '/'
2883
elif fs_path != '.' and not fs_path.endswith('/'):
2884
prefix = fs_path + '/'
2886
if revision is not None or tree is None:
2887
tree = _get_one_revision_tree('ls', revision, branch=branch)
2890
if isinstance(tree, WorkingTree) and tree.supports_views():
2891
view_files = tree.views.lookup_view()
2894
view_str = views.view_display_str(view_files)
2895
note(gettext("Ignoring files outside view. View is %s") % view_str)
2897
self.add_cleanup(tree.lock_read().unlock)
2898
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2899
from_dir=relpath, recursive=recursive):
2900
# Apply additional masking
2901
if not all and not selection[fc]:
2903
if kind is not None and fkind != kind:
2908
fullpath = osutils.pathjoin(relpath, fp)
2911
views.check_path_in_view(tree, fullpath)
2912
except errors.FileOutsideView:
2917
fp = osutils.pathjoin(prefix, fp)
2918
kindch = entry.kind_character()
2919
outstring = fp + kindch
2920
ui.ui_factory.clear_term()
2922
outstring = '%-8s %s' % (fc, outstring)
2923
if show_ids and fid is not None:
2924
outstring = "%-50s %s" % (outstring, fid)
2925
self.outf.write(outstring + '\n')
2927
self.outf.write(fp + '\0')
2930
self.outf.write(fid)
2931
self.outf.write('\0')
2939
self.outf.write('%-50s %s\n' % (outstring, my_id))
2941
self.outf.write(outstring + '\n')
1742
2944
class cmd_unknowns(Command):
1743
"""List unknown files.
1745
See also: "bzr ls --unknown".
2945
__doc__ = """List unknown files.
2950
takes_options = ['directory']
1750
2952
@display_command
1752
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2953
def run(self, directory=u'.'):
2954
for f in WorkingTree.open_containing(directory)[0].unknowns():
1753
2955
self.outf.write(osutils.quotefn(f) + '\n')
1756
2958
class cmd_ignore(Command):
1757
"""Ignore specified files or patterns.
2959
__doc__ = """Ignore specified files or patterns.
2961
See ``bzr help patterns`` for details on the syntax of patterns.
2963
If a .bzrignore file does not exist, the ignore command
2964
will create one and add the specified files or patterns to the newly
2965
created file. The ignore command will also automatically add the
2966
.bzrignore file to be versioned. Creating a .bzrignore file without
2967
the use of the ignore command will require an explicit add command.
1759
2969
To remove patterns from the ignore list, edit the .bzrignore file.
1761
Trailing slashes on patterns are ignored.
1762
If the pattern contains a slash or is a regular expression, it is compared
1763
to the whole path from the branch root. Otherwise, it is compared to only
1764
the last component of the path. To match a file only in the root
1765
directory, prepend './'.
1767
Ignore patterns specifying absolute paths are not allowed.
1769
Ignore patterns may include globbing wildcards such as:
1770
? - Matches any single character except '/'
1771
* - Matches 0 or more characters except '/'
1772
/**/ - Matches 0 or more directories in a path
1773
[a-z] - Matches a single character from within a group of characters
1775
Ignore patterns may also be Python regular expressions.
1776
Regular expression ignore patterns are identified by a 'RE:' prefix
1777
followed by the regular expression. Regular expression ignore patterns
1778
may not include named or numbered groups.
1780
Note: ignore patterns containing shell wildcards must be quoted from
1784
bzr ignore ./Makefile
1785
bzr ignore '*.class'
1786
bzr ignore 'lib/**/*.o'
1787
bzr ignore 'RE:lib/.*\.o'
2970
After adding, editing or deleting that file either indirectly by
2971
using this command or directly by using an editor, be sure to commit
2974
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2975
the global ignore file can be found in the application data directory as
2976
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2977
Global ignores are not touched by this command. The global ignore file
2978
can be edited directly using an editor.
2980
Patterns prefixed with '!' are exceptions to ignore patterns and take
2981
precedence over regular ignores. Such exceptions are used to specify
2982
files that should be versioned which would otherwise be ignored.
2984
Patterns prefixed with '!!' act as regular ignore patterns, but have
2985
precedence over the '!' exception patterns.
2989
* Ignore patterns containing shell wildcards must be quoted from
2992
* Ignore patterns starting with "#" act as comments in the ignore file.
2993
To ignore patterns that begin with that character, use the "RE:" prefix.
2996
Ignore the top level Makefile::
2998
bzr ignore ./Makefile
3000
Ignore .class files in all directories...::
3002
bzr ignore "*.class"
3004
...but do not ignore "special.class"::
3006
bzr ignore "!special.class"
3008
Ignore files whose name begins with the "#" character::
3012
Ignore .o files under the lib directory::
3014
bzr ignore "lib/**/*.o"
3016
Ignore .o files under the lib directory::
3018
bzr ignore "RE:lib/.*\.o"
3020
Ignore everything but the "debian" toplevel directory::
3022
bzr ignore "RE:(?!debian/).*"
3024
Ignore everything except the "local" toplevel directory,
3025
but always ignore autosave files ending in ~, even under local/::
3028
bzr ignore "!./local"
3032
_see_also = ['status', 'ignored', 'patterns']
1789
3033
takes_args = ['name_pattern*']
1791
Option('old-default-rules',
1792
help='Out the ignore rules bzr < 0.9 always used.')
1795
def run(self, name_pattern_list=None, old_default_rules=None):
1796
from bzrlib.atomicfile import AtomicFile
1797
if old_default_rules is not None:
1798
# dump the rules and exit
1799
for pattern in ignores.OLD_DEFAULTS:
3034
takes_options = ['directory',
3035
Option('default-rules',
3036
help='Display the default ignore rules that bzr uses.')
3039
def run(self, name_pattern_list=None, default_rules=None,
3041
from bzrlib import ignores
3042
if default_rules is not None:
3043
# dump the default rules and exit
3044
for pattern in ignores.USER_DEFAULTS:
3045
self.outf.write("%s\n" % pattern)
1802
3047
if not name_pattern_list:
1803
raise errors.BzrCommandError("ignore requires at least one "
1804
"NAME_PATTERN or --old-default-rules")
1805
for name_pattern in name_pattern_list:
1806
if name_pattern[0] == '/':
1807
raise errors.BzrCommandError(
1808
"NAME_PATTERN should not be an absolute path")
1809
tree, relpath = WorkingTree.open_containing(u'.')
1810
ifn = tree.abspath('.bzrignore')
1811
if os.path.exists(ifn):
1814
igns = f.read().decode('utf-8')
1820
# TODO: If the file already uses crlf-style termination, maybe
1821
# we should use that for the newly added lines?
1823
if igns and igns[-1] != '\n':
1825
for name_pattern in name_pattern_list:
1826
igns += name_pattern.rstrip('/') + '\n'
1828
f = AtomicFile(ifn, 'wb')
1830
f.write(igns.encode('utf-8'))
1835
if not tree.path2id('.bzrignore'):
1836
tree.add(['.bzrignore'])
3048
raise errors.BzrCommandError(gettext("ignore requires at least one "
3049
"NAME_PATTERN or --default-rules."))
3050
name_pattern_list = [globbing.normalize_pattern(p)
3051
for p in name_pattern_list]
3053
bad_patterns_count = 0
3054
for p in name_pattern_list:
3055
if not globbing.Globster.is_pattern_valid(p):
3056
bad_patterns_count += 1
3057
bad_patterns += ('\n %s' % p)
3059
msg = (ngettext('Invalid ignore pattern found. %s',
3060
'Invalid ignore patterns found. %s',
3061
bad_patterns_count) % bad_patterns)
3062
ui.ui_factory.show_error(msg)
3063
raise errors.InvalidPattern('')
3064
for name_pattern in name_pattern_list:
3065
if (name_pattern[0] == '/' or
3066
(len(name_pattern) > 1 and name_pattern[1] == ':')):
3067
raise errors.BzrCommandError(gettext(
3068
"NAME_PATTERN should not be an absolute path"))
3069
tree, relpath = WorkingTree.open_containing(directory)
3070
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3071
ignored = globbing.Globster(name_pattern_list)
3073
self.add_cleanup(tree.lock_read().unlock)
3074
for entry in tree.list_files():
3078
if ignored.match(filename):
3079
matches.append(filename)
3080
if len(matches) > 0:
3081
self.outf.write(gettext("Warning: the following files are version "
3082
"controlled and match your ignore pattern:\n%s"
3083
"\nThese files will continue to be version controlled"
3084
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
1839
3087
class cmd_ignored(Command):
1840
"""List ignored files and the patterns that matched them.
1842
See also: bzr ignore"""
3088
__doc__ = """List ignored files and the patterns that matched them.
3090
List all the ignored files and the ignore pattern that caused the file to
3093
Alternatively, to list just the files::
3098
encoding_type = 'replace'
3099
_see_also = ['ignore', 'ls']
3100
takes_options = ['directory']
1843
3102
@display_command
1845
tree = WorkingTree.open_containing(u'.')[0]
1848
for path, file_class, kind, file_id, entry in tree.list_files():
1849
if file_class != 'I':
1851
## XXX: Slightly inefficient since this was already calculated
1852
pat = tree.is_ignored(path)
1853
print '%-50s %s' % (path, pat)
3103
def run(self, directory=u'.'):
3104
tree = WorkingTree.open_containing(directory)[0]
3105
self.add_cleanup(tree.lock_read().unlock)
3106
for path, file_class, kind, file_id, entry in tree.list_files():
3107
if file_class != 'I':
3109
## XXX: Slightly inefficient since this was already calculated
3110
pat = tree.is_ignored(path)
3111
self.outf.write('%-50s %s\n' % (path, pat))
1858
3114
class cmd_lookup_revision(Command):
1859
"""Lookup the revision-id from a revision-number
3115
__doc__ = """Lookup the revision-id from a revision-number
1862
3118
bzr lookup-revision 33
1865
3121
takes_args = ['revno']
3122
takes_options = ['directory']
1867
3124
@display_command
1868
def run(self, revno):
3125
def run(self, revno, directory=u'.'):
1870
3127
revno = int(revno)
1871
3128
except ValueError:
1872
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
1874
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
3129
raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3131
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3132
self.outf.write("%s\n" % revid)
1877
3135
class cmd_export(Command):
1878
"""Export past revision to destination directory.
3136
__doc__ = """Export current or past revision to a destination directory or archive.
1880
3138
If no revision is specified this exports the last committed revision.
1883
3141
given, try to find the format with the extension. If no extension
1884
3142
is found exports to a directory (equivalent to --format=dir).
1886
Root may be the top directory for tar, tgz and tbz2 formats. If none
1887
is given, the top directory will be the root name of the file.
1889
If branch is omitted then the branch containing the CWD will be used.
1891
Note: export of tree with non-ascii filenames to zip is not supported.
1893
Supported formats Autodetected by extension
1894
----------------- -------------------------
3144
If root is supplied, it will be used as the root directory inside
3145
container formats (tar, zip, etc). If it is not supplied it will default
3146
to the exported filename. The root option has no effect for 'dir' format.
3148
If branch is omitted then the branch containing the current working
3149
directory will be used.
3151
Note: Export of tree with non-ASCII filenames to zip is not supported.
3153
================= =========================
3154
Supported formats Autodetected by extension
3155
================= =========================
1897
3158
tbz2 .tar.bz2, .tbz2
1898
3159
tgz .tar.gz, .tgz
3161
================= =========================
1901
takes_args = ['dest', 'branch?']
1902
takes_options = ['revision', 'format', 'root']
1903
def run(self, dest, branch=None, revision=None, format=None, root=None):
3164
takes_args = ['dest', 'branch_or_subdir?']
3165
takes_options = ['directory',
3167
help="Type of file to export to.",
3170
Option('filters', help='Apply content filters to export the '
3171
'convenient form.'),
3174
help="Name of the root directory inside the exported file."),
3175
Option('per-file-timestamps',
3176
help='Set modification time of files to that of the last '
3177
'revision in which it was changed.'),
3178
Option('uncommitted',
3179
help='Export the working tree contents rather than that of the '
3182
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3183
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
1904
3185
from bzrlib.export import export
1907
tree = WorkingTree.open_containing(u'.')[0]
1910
b = Branch.open(branch)
1912
if revision is None:
1913
# should be tree.last_revision FIXME
1914
rev_id = b.last_revision()
1916
if len(revision) != 1:
1917
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1918
rev_id = revision[0].in_history(b).rev_id
1919
t = b.repository.revision_tree(rev_id)
3187
if branch_or_subdir is None:
3188
branch_or_subdir = directory
3190
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3192
if tree is not None:
3193
self.add_cleanup(tree.lock_read().unlock)
3197
raise errors.BzrCommandError(
3198
gettext("--uncommitted requires a working tree"))
3201
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
1921
export(t, dest, format, root)
3203
export(export_tree, dest, format, root, subdir, filtered=filters,
3204
per_file_timestamps=per_file_timestamps)
1922
3205
except errors.NoSuchExportFormat, e:
1923
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3206
raise errors.BzrCommandError(
3207
gettext('Unsupported export format: %s') % e.format)
1926
3210
class cmd_cat(Command):
1927
"""Write a file's text from a previous revision."""
1929
takes_options = ['revision', 'name-from-revision']
3211
__doc__ = """Write the contents of a file as of a given revision to standard output.
3213
If no revision is nominated, the last revision is used.
3215
Note: Take care to redirect standard output when using this command on a
3220
takes_options = ['directory',
3221
Option('name-from-revision', help='The path name in the old tree.'),
3222
Option('filters', help='Apply content filters to display the '
3223
'convenience form.'),
1930
3226
takes_args = ['filename']
1931
3227
encoding_type = 'exact'
1933
3229
@display_command
1934
def run(self, filename, revision=None, name_from_revision=False):
3230
def run(self, filename, revision=None, name_from_revision=False,
3231
filters=False, directory=None):
1935
3232
if revision is not None and len(revision) != 1:
1936
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1941
tree, relpath = WorkingTree.open_containing(filename)
1943
except (errors.NotBranchError, errors.NotLocalUrl):
1946
if revision is not None and revision[0].get_branch() is not None:
1947
b = Branch.open(revision[0].get_branch())
3233
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3234
" one revision specifier"))
3235
tree, branch, relpath = \
3236
_open_directory_or_containing_tree_or_branch(filename, directory)
3237
self.add_cleanup(branch.lock_read().unlock)
3238
return self._run(tree, branch, relpath, filename, revision,
3239
name_from_revision, filters)
3241
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
1948
3243
if tree is None:
1949
b, relpath = Branch.open_containing(filename)
1950
3244
tree = b.basis_tree()
1951
if revision is None:
1952
revision_id = b.last_revision()
1954
revision_id = revision[0].in_history(b).rev_id
3245
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3246
self.add_cleanup(rev_tree.lock_read().unlock)
1956
cur_file_id = tree.path2id(relpath)
1957
rev_tree = b.repository.revision_tree(revision_id)
1958
3248
old_file_id = rev_tree.path2id(relpath)
3250
# TODO: Split out this code to something that generically finds the
3251
# best id for a path across one or more trees; it's like
3252
# find_ids_across_trees but restricted to find just one. -- mbp
1960
3254
if name_from_revision:
3255
# Try in revision if requested
1961
3256
if old_file_id is None:
1962
raise errors.BzrCommandError("%r is not present in revision %s"
1963
% (filename, revision_id))
1965
rev_tree.print_file(old_file_id)
1966
elif cur_file_id is not None:
1967
rev_tree.print_file(cur_file_id)
1968
elif old_file_id is not None:
1969
rev_tree.print_file(old_file_id)
1971
raise errors.BzrCommandError("%r is not present in revision %s" %
1972
(filename, revision_id))
3257
raise errors.BzrCommandError(gettext(
3258
"{0!r} is not present in revision {1}").format(
3259
filename, rev_tree.get_revision_id()))
3261
actual_file_id = old_file_id
3263
cur_file_id = tree.path2id(relpath)
3264
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3265
actual_file_id = cur_file_id
3266
elif old_file_id is not None:
3267
actual_file_id = old_file_id
3269
raise errors.BzrCommandError(gettext(
3270
"{0!r} is not present in revision {1}").format(
3271
filename, rev_tree.get_revision_id()))
3273
from bzrlib.filter_tree import ContentFilterTree
3274
filter_tree = ContentFilterTree(rev_tree,
3275
rev_tree._content_filter_stack)
3276
content = filter_tree.get_file_text(actual_file_id)
3278
content = rev_tree.get_file_text(actual_file_id)
3280
self.outf.write(content)
1975
3283
class cmd_local_time_offset(Command):
1976
"""Show the offset in seconds from GMT to local time."""
3284
__doc__ = """Show the offset in seconds from GMT to local time."""
1978
3286
@display_command
1980
print osutils.local_time_offset()
3288
self.outf.write("%s\n" % osutils.local_time_offset())
1984
3292
class cmd_commit(Command):
1985
"""Commit changes into a new revision.
1987
If no arguments are given, the entire tree is committed.
1989
If selected files are specified, only changes to those files are
1990
committed. If a directory is specified then the directory and everything
1991
within it is committed.
1993
A selected-file commit may fail in some cases where the committed
1994
tree would be invalid, such as trying to commit a file in a
1995
newly-added directory that is not itself committed.
3293
__doc__ = """Commit changes into a new revision.
3295
An explanatory message needs to be given for each commit. This is
3296
often done by using the --message option (getting the message from the
3297
command line) or by using the --file option (getting the message from
3298
a file). If neither of these options is given, an editor is opened for
3299
the user to enter the message. To see the changed files in the
3300
boilerplate text loaded into the editor, use the --show-diff option.
3302
By default, the entire tree is committed and the person doing the
3303
commit is assumed to be the author. These defaults can be overridden
3308
If selected files are specified, only changes to those files are
3309
committed. If a directory is specified then the directory and
3310
everything within it is committed.
3312
When excludes are given, they take precedence over selected files.
3313
For example, to commit only changes within foo, but not changes
3316
bzr commit foo -x foo/bar
3318
A selective commit after a merge is not yet supported.
3322
If the author of the change is not the same person as the committer,
3323
you can specify the author's name using the --author option. The
3324
name should be in the same format as a committer-id, e.g.
3325
"John Doe <jdoe@example.com>". If there is more than one author of
3326
the change you can specify the option multiple times, once for each
3331
A common mistake is to forget to add a new file or directory before
3332
running the commit command. The --strict option checks for unknown
3333
files and aborts the commit if any are found. More advanced pre-commit
3334
checks can be implemented by defining hooks. See ``bzr help hooks``
3339
If you accidentially commit the wrong changes or make a spelling
3340
mistake in the commit message say, you can use the uncommit command
3341
to undo it. See ``bzr help uncommit`` for details.
3343
Hooks can also be configured to run after a commit. This allows you
3344
to trigger updates to external systems like bug trackers. The --fixes
3345
option can be used to record the association between a revision and
3346
one or more bugs. See ``bzr help bugs`` for details.
1997
# TODO: Run hooks on tree to-be-committed, and after commit.
1999
# TODO: Strict commit that fails if there are deleted files.
2000
# (what does "deleted files" mean ??)
2002
# TODO: Give better message for -s, --summary, used by tla people
2004
# XXX: verbose currently does nothing
3349
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2006
3350
takes_args = ['selected*']
2007
takes_options = ['message', 'verbose',
2009
help='commit even if nothing has changed'),
2010
Option('file', type=str,
2013
help='file containing commit message'),
2015
help="refuse to commit if there are unknown "
2016
"files in the working tree."),
2018
help="perform a local only commit in a bound "
2019
"branch. Such commits are not pushed to "
2020
"the master branch until a normal commit "
3352
ListOption('exclude', type=str, short_name='x',
3353
help="Do not consider changes made to a given path."),
3354
Option('message', type=unicode,
3356
help="Description of the new revision."),
3359
help='Commit even if nothing has changed.'),
3360
Option('file', type=str,
3363
help='Take commit message from this file.'),
3365
help="Refuse to commit if there are unknown "
3366
"files in the working tree."),
3367
Option('commit-time', type=str,
3368
help="Manually set a commit time using commit date "
3369
"format, e.g. '2009-10-10 08:00:00 +0100'."),
3370
ListOption('fixes', type=str,
3371
help="Mark a bug as being fixed by this revision "
3372
"(see \"bzr help bugs\")."),
3373
ListOption('author', type=unicode,
3374
help="Set the author's name, if it's different "
3375
"from the committer."),
3377
help="Perform a local commit in a bound "
3378
"branch. Local commits are not pushed to "
3379
"the master branch until a normal commit "
3382
Option('show-diff', short_name='p',
3383
help='When no message is supplied, show the diff along'
3384
' with the status summary in the message editor.'),
3386
help='When committing to a foreign version control '
3387
'system do not push data that can not be natively '
2024
3390
aliases = ['ci', 'checkin']
2026
def run(self, message=None, file=None, verbose=True, selected_list=None,
2027
unchanged=False, strict=False, local=False):
2028
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2029
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2031
from bzrlib.msgeditor import edit_commit_message, \
2032
make_commit_message_template
2034
# TODO: Need a blackbox test for invoking the external editor; may be
2035
# slightly problematic to run this cross-platform.
2037
# TODO: do more checks that the commit will succeed before
2038
# spending the user's valuable time typing a commit message.
2039
tree, selected_list = tree_files(selected_list)
3392
def _iter_bug_fix_urls(self, fixes, branch):
3393
default_bugtracker = None
3394
# Configure the properties for bug fixing attributes.
3395
for fixed_bug in fixes:
3396
tokens = fixed_bug.split(':')
3397
if len(tokens) == 1:
3398
if default_bugtracker is None:
3399
branch_config = branch.get_config()
3400
default_bugtracker = branch_config.get_user_option(
3402
if default_bugtracker is None:
3403
raise errors.BzrCommandError(gettext(
3404
"No tracker specified for bug %s. Use the form "
3405
"'tracker:id' or specify a default bug tracker "
3406
"using the `bugtracker` option.\nSee "
3407
"\"bzr help bugs\" for more information on this "
3408
"feature. Commit refused.") % fixed_bug)
3409
tag = default_bugtracker
3411
elif len(tokens) != 2:
3412
raise errors.BzrCommandError(gettext(
3413
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3414
"See \"bzr help bugs\" for more information on this "
3415
"feature.\nCommit refused.") % fixed_bug)
3417
tag, bug_id = tokens
3419
yield bugtracker.get_bug_url(tag, branch, bug_id)
3420
except errors.UnknownBugTrackerAbbreviation:
3421
raise errors.BzrCommandError(gettext(
3422
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3423
except errors.MalformedBugIdentifier, e:
3424
raise errors.BzrCommandError(gettext(
3425
"%s\nCommit refused.") % (str(e),))
3427
def run(self, message=None, file=None, verbose=False, selected_list=None,
3428
unchanged=False, strict=False, local=False, fixes=None,
3429
author=None, show_diff=False, exclude=None, commit_time=None,
3431
from bzrlib.errors import (
3436
from bzrlib.msgeditor import (
3437
edit_commit_message_encoded,
3438
generate_commit_message_template,
3439
make_commit_message_template_encoded,
3443
commit_stamp = offset = None
3444
if commit_time is not None:
3446
commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3447
except ValueError, e:
3448
raise errors.BzrCommandError(gettext(
3449
"Could not parse --commit-time: " + str(e)))
3453
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
2040
3454
if selected_list == ['']:
2041
3455
# workaround - commit of root of tree should be exactly the same
2042
3456
# as just default commit in that tree, and succeed even though
2043
3457
# selected-file merge commit is not done yet
2044
3458
selected_list = []
3462
bug_property = bugtracker.encode_fixes_bug_urls(
3463
self._iter_bug_fix_urls(fixes, tree.branch))
3465
properties['bugs'] = bug_property
2046
3467
if local and not tree.branch.get_bound_location():
2047
3468
raise errors.LocalRequiresBoundBranch()
3470
if message is not None:
3472
file_exists = osutils.lexists(message)
3473
except UnicodeError:
3474
# The commit message contains unicode characters that can't be
3475
# represented in the filesystem encoding, so that can't be a
3480
'The commit message is a file name: "%(f)s".\n'
3481
'(use --file "%(f)s" to take commit message from that file)'
3483
ui.ui_factory.show_warning(warning_msg)
3485
message = message.replace('\r\n', '\n')
3486
message = message.replace('\r', '\n')
3488
raise errors.BzrCommandError(gettext(
3489
"please specify either --message or --file"))
2049
3491
def get_message(commit_obj):
2050
3492
"""Callback to get commit message"""
2051
my_message = message
2052
if my_message is None and not file:
2053
template = make_commit_message_template(tree, selected_list)
2054
my_message = edit_commit_message(template)
2055
if my_message is None:
2056
raise errors.BzrCommandError("please specify a commit"
2057
" message with either --message or --file")
2058
elif my_message and file:
2059
raise errors.BzrCommandError(
2060
"please specify either --message or --file")
2062
my_message = codecs.open(file, 'rt',
2063
bzrlib.user_encoding).read()
2064
if my_message == "":
2065
raise errors.BzrCommandError("empty commit message specified")
3496
my_message = f.read().decode(osutils.get_user_encoding())
3499
elif message is not None:
3500
my_message = message
3502
# No message supplied: make one up.
3503
# text is the status of the tree
3504
text = make_commit_message_template_encoded(tree,
3505
selected_list, diff=show_diff,
3506
output_encoding=osutils.get_user_encoding())
3507
# start_message is the template generated from hooks
3508
# XXX: Warning - looks like hooks return unicode,
3509
# make_commit_message_template_encoded returns user encoding.
3510
# We probably want to be using edit_commit_message instead to
3512
my_message = set_commit_message(commit_obj)
3513
if my_message is None:
3514
start_message = generate_commit_message_template(commit_obj)
3515
my_message = edit_commit_message_encoded(text,
3516
start_message=start_message)
3517
if my_message is None:
3518
raise errors.BzrCommandError(gettext("please specify a commit"
3519
" message with either --message or --file"))
3520
if my_message == "":
3521
raise errors.BzrCommandError(gettext("Empty commit message specified."
3522
" Please specify a commit message with either"
3523
" --message or --file or leave a blank message"
3524
" with --message \"\"."))
2066
3525
return my_message
2069
reporter = ReportCommitToLog()
2071
reporter = NullCommitReporter()
3527
# The API permits a commit with a filter of [] to mean 'select nothing'
3528
# but the command line should not do that.
3529
if not selected_list:
3530
selected_list = None
2074
3532
tree.commit(message_callback=get_message,
2075
3533
specific_files=selected_list,
2076
3534
allow_pointless=unchanged, strict=strict, local=local,
3535
reporter=None, verbose=verbose, revprops=properties,
3536
authors=author, timestamp=commit_stamp,
3538
exclude=tree.safe_relpath_files(exclude),
2078
3540
except PointlessCommit:
2079
# FIXME: This should really happen before the file is read in;
2080
# perhaps prepare the commit; get the message; then actually commit
2081
raise errors.BzrCommandError("no changes to commit."
2082
" use --unchanged to commit anyhow")
3541
raise errors.BzrCommandError(gettext("No changes to commit."
3542
" Please 'bzr add' the files you want to commit, or use"
3543
" --unchanged to force an empty commit."))
2083
3544
except ConflictsInTree:
2084
raise errors.BzrCommandError('Conflicts detected in working '
3545
raise errors.BzrCommandError(gettext('Conflicts detected in working '
2085
3546
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
2087
3548
except StrictCommitFailed:
2088
raise errors.BzrCommandError("Commit refused because there are"
2089
" unknown files in the working tree.")
3549
raise errors.BzrCommandError(gettext("Commit refused because there are"
3550
" unknown files in the working tree."))
2090
3551
except errors.BoundBranchOutOfDate, e:
2091
raise errors.BzrCommandError(str(e) + "\n"
2092
'To commit to master branch, run update and then commit.\n'
2093
'You can also pass --local to commit to continue working '
3552
e.extra_help = (gettext("\n"
3553
'To commit to master branch, run update and then commit.\n'
3554
'You can also pass --local to commit to continue working '
2097
3559
class cmd_check(Command):
2098
"""Validate consistency of branch history.
2100
This command checks various invariants about the branch storage to
2101
detect data corruption or bzr bugs.
3560
__doc__ = """Validate working tree structure, branch consistency and repository history.
3562
This command checks various invariants about branch and repository storage
3563
to detect data corruption or bzr bugs.
3565
The working tree and branch checks will only give output if a problem is
3566
detected. The output fields of the repository check are:
3569
This is just the number of revisions checked. It doesn't
3573
This is just the number of versionedfiles checked. It
3574
doesn't indicate a problem.
3576
unreferenced ancestors
3577
Texts that are ancestors of other texts, but
3578
are not properly referenced by the revision ancestry. This is a
3579
subtle problem that Bazaar can work around.
3582
This is the total number of unique file contents
3583
seen in the checked revisions. It does not indicate a problem.
3586
This is the total number of repeated texts seen
3587
in the checked revisions. Texts can be repeated when their file
3588
entries are modified, but the file contents are not. It does not
3591
If no restrictions are specified, all Bazaar data that is found at the given
3592
location will be checked.
3596
Check the tree and branch at 'foo'::
3598
bzr check --tree --branch foo
3600
Check only the repository at 'bar'::
3602
bzr check --repo bar
3604
Check everything at 'baz'::
2103
takes_args = ['branch?']
2104
takes_options = ['verbose']
2106
def run(self, branch=None, verbose=False):
2107
from bzrlib.check import check
2109
tree = WorkingTree.open_containing()[0]
2110
branch = tree.branch
2112
branch = Branch.open(branch)
2113
check(branch, verbose)
3609
_see_also = ['reconcile']
3610
takes_args = ['path?']
3611
takes_options = ['verbose',
3612
Option('branch', help="Check the branch related to the"
3613
" current directory."),
3614
Option('repo', help="Check the repository related to the"
3615
" current directory."),
3616
Option('tree', help="Check the working tree related to"
3617
" the current directory.")]
3619
def run(self, path=None, verbose=False, branch=False, repo=False,
3621
from bzrlib.check import check_dwim
3624
if not branch and not repo and not tree:
3625
branch = repo = tree = True
3626
check_dwim(path, verbose, do_branch=branch, do_repo=repo, do_tree=tree)
2116
3629
class cmd_upgrade(Command):
2117
"""Upgrade branch storage to current format.
2119
The check command or bzr developers may sometimes advise you to run
2120
this command. When the default format has changed you may also be warned
2121
during other operations to upgrade.
3630
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3632
When the default format has changed after a major new release of
3633
Bazaar, you may be informed during certain operations that you
3634
should upgrade. Upgrading to a newer format may improve performance
3635
or make new features available. It may however limit interoperability
3636
with older repositories or with older versions of Bazaar.
3638
If you wish to upgrade to a particular format rather than the
3639
current default, that can be specified using the --format option.
3640
As a consequence, you can use the upgrade command this way to
3641
"downgrade" to an earlier format, though some conversions are
3642
a one way process (e.g. changing from the 1.x default to the
3643
2.x default) so downgrading is not always possible.
3645
A backup.bzr.~#~ directory is created at the start of the conversion
3646
process (where # is a number). By default, this is left there on
3647
completion. If the conversion fails, delete the new .bzr directory
3648
and rename this one back in its place. Use the --clean option to ask
3649
for the backup.bzr directory to be removed on successful conversion.
3650
Alternatively, you can delete it by hand if everything looks good
3653
If the location given is a shared repository, dependent branches
3654
are also converted provided the repository converts successfully.
3655
If the conversion of a branch fails, remaining branches are still
3658
For more information on upgrades, see the Bazaar Upgrade Guide,
3659
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3662
_see_also = ['check', 'reconcile', 'formats']
2123
3663
takes_args = ['url?']
2124
3664
takes_options = [
2125
RegistryOption('format',
2126
help='Upgrade to a specific format. See "bzr help'
2127
' formats" for details',
2128
registry=bzrdir.format_registry,
2129
converter=bzrdir.format_registry.make_bzrdir,
2130
value_switches=True, title='Branch format'),
2134
def run(self, url='.', format=None):
3665
RegistryOption('format',
3666
help='Upgrade to a specific format. See "bzr help'
3667
' formats" for details.',
3668
lazy_registry=('bzrlib.controldir', 'format_registry'),
3669
converter=lambda name: controldir.format_registry.make_bzrdir(name),
3670
value_switches=True, title='Branch format'),
3672
help='Remove the backup.bzr directory if successful.'),
3674
help="Show what would be done, but don't actually do anything."),
3677
def run(self, url='.', format=None, clean=False, dry_run=False):
2135
3678
from bzrlib.upgrade import upgrade
2137
format = bzrdir.format_registry.make_bzrdir('default')
2138
upgrade(url, format)
3679
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3681
if len(exceptions) == 1:
3682
# Compatibility with historical behavior
2141
3688
class cmd_whoami(Command):
2142
"""Show or set bzr user id.
2146
bzr whoami 'Frank Chu <fchu@example.com>'
3689
__doc__ = """Show or set bzr user id.
3692
Show the email of the current user::
3696
Set the current user::
3698
bzr whoami "Frank Chu <fchu@example.com>"
2148
takes_options = [ Option('email',
2149
help='display email address only'),
3700
takes_options = [ 'directory',
3702
help='Display email address only.'),
2150
3703
Option('branch',
2151
help='set identity for the current branch instead of '
3704
help='Set identity for the current branch instead of '
2154
3707
takes_args = ['name?']
2155
3708
encoding_type = 'replace'
2157
3710
@display_command
2158
def run(self, email=False, branch=False, name=None):
3711
def run(self, email=False, branch=False, name=None, directory=None):
2159
3712
if name is None:
2160
# use branch if we're inside one; otherwise global config
2162
c = Branch.open_containing('.')[0].get_config()
2163
except errors.NotBranchError:
2164
c = config.GlobalConfig()
3713
if directory is None:
3714
# use branch if we're inside one; otherwise global config
3716
c = Branch.open_containing(u'.')[0].get_config_stack()
3717
except errors.NotBranchError:
3718
c = _mod_config.GlobalStack()
3720
c = Branch.open(directory).get_config_stack()
3721
identity = c.get('email')
2166
self.outf.write(c.user_email() + '\n')
3723
self.outf.write(_mod_config.extract_email_address(identity)
2168
self.outf.write(c.username() + '\n')
3726
self.outf.write(identity + '\n')
3730
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
2171
3733
# display a warning if an email address isn't included in the given name.
2173
config.extract_email_address(name)
3735
_mod_config.extract_email_address(name)
2174
3736
except errors.NoEmailInUsername, e:
2175
3737
warning('"%s" does not seem to contain an email address. '
2176
3738
'This is allowed, but not recommended.', name)
2178
3740
# use global config unless --branch given
2180
c = Branch.open_containing('.')[0].get_config()
3742
if directory is None:
3743
c = Branch.open_containing(u'.')[0].get_config_stack()
3745
c = Branch.open(directory).get_config_stack()
2182
c = config.GlobalConfig()
2183
c.set_user_option('email', name)
3747
c = _mod_config.GlobalStack()
3748
c.set('email', name)
2186
3751
class cmd_nick(Command):
2187
"""Print or set the branch nickname.
2189
If unset, the tree root directory name is used as the nickname
2190
To print the current nickname, execute with no argument.
3752
__doc__ = """Print or set the branch nickname.
3754
If unset, the tree root directory name is used as the nickname.
3755
To print the current nickname, execute with no argument.
3757
Bound branches use the nickname of its master branch unless it is set
3761
_see_also = ['info']
2192
3762
takes_args = ['nickname?']
2193
def run(self, nickname=None):
2194
branch = Branch.open_containing(u'.')[0]
3763
takes_options = ['directory']
3764
def run(self, nickname=None, directory=u'.'):
3765
branch = Branch.open_containing(directory)[0]
2195
3766
if nickname is None:
2196
3767
self.printme(branch)
2252
3913
takes_args = ['testspecs*']
2253
3914
takes_options = ['verbose',
2254
Option('one', help='stop when one test fails'),
2255
Option('keep-output',
2256
help='keep output directories when tests fail'),
3916
help='Stop when one test fails.',
2258
3920
help='Use a different transport by default '
2259
3921
'throughout the test suite.',
2260
3922
type=get_transport_type),
2261
Option('benchmark', help='run the bzr bencharks.'),
3924
help='Run the benchmarks rather than selftests.',
2262
3926
Option('lsprof-timed',
2263
help='generate lsprof output for benchmarked'
3927
help='Generate lsprof output for benchmarked'
2264
3928
' sections of code.'),
2265
Option('cache-dir', type=str,
2266
help='a directory to cache intermediate'
2267
' benchmark steps'),
2268
Option('clean-output',
2269
help='clean temporary tests directories'
2270
' without running tests'),
3929
Option('lsprof-tests',
3930
help='Generate lsprof output for each test.'),
2271
3931
Option('first',
2272
help='run all tests, but run specified tests first',
3932
help='Run all tests, but run specified tests first.',
3936
help='List the tests instead of running them.'),
3937
RegistryOption('parallel',
3938
help="Run the test suite in parallel.",
3939
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3940
value_switches=False,
3942
Option('randomize', type=str, argname="SEED",
3943
help='Randomize the order of tests using the given'
3944
' seed or "now" for the current time.'),
3945
ListOption('exclude', type=str, argname="PATTERN",
3947
help='Exclude tests that match this regular'
3950
help='Output test progress via subunit.'),
3951
Option('strict', help='Fail on missing dependencies or '
3953
Option('load-list', type=str, argname='TESTLISTFILE',
3954
help='Load a test id list from a text file.'),
3955
ListOption('debugflag', type=str, short_name='E',
3956
help='Turn on a selftest debug flag.'),
3957
ListOption('starting-with', type=str, argname='TESTID',
3958
param_name='starting_with', short_name='s',
3960
'Load only the tests starting with TESTID.'),
3962
help="By default we disable fsync and fdatasync"
3963
" while running the test suite.")
2275
3965
encoding_type = 'replace'
2277
def run(self, testspecs_list=None, verbose=None, one=False,
2278
keep_output=False, transport=None, benchmark=None,
2279
lsprof_timed=None, cache_dir=None, clean_output=False,
2282
from bzrlib.tests import selftest
2283
import bzrlib.benchmarks as benchmarks
2284
from bzrlib.benchmarks import tree_creator
2287
from bzrlib.tests import clean_selftest_output
2288
clean_selftest_output()
2291
if cache_dir is not None:
2292
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2293
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2294
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
3968
Command.__init__(self)
3969
self.additional_selftest_args = {}
3971
def run(self, testspecs_list=None, verbose=False, one=False,
3972
transport=None, benchmark=None,
3974
first=False, list_only=False,
3975
randomize=None, exclude=None, strict=False,
3976
load_list=None, debugflag=None, starting_with=None, subunit=False,
3977
parallel=None, lsprof_tests=False,
3979
from bzrlib import tests
2296
3981
if testspecs_list is not None:
2297
3982
pattern = '|'.join(testspecs_list)
3987
from bzrlib.tests import SubUnitBzrRunner
3989
raise errors.BzrCommandError(gettext("subunit not available. subunit "
3990
"needs to be installed to use --subunit."))
3991
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3992
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3993
# stdout, which would corrupt the subunit stream.
3994
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3995
# following code can be deleted when it's sufficiently deployed
3996
# -- vila/mgz 20100514
3997
if (sys.platform == "win32"
3998
and getattr(sys.stdout, 'fileno', None) is not None):
4000
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4002
self.additional_selftest_args.setdefault(
4003
'suite_decorators', []).append(parallel)
2301
test_suite_factory = benchmarks.test_suite
2304
# TODO: should possibly lock the history file...
2305
benchfile = open(".perf_history", "at", buffering=1)
4005
raise errors.BzrCommandError(gettext(
4006
"--benchmark is no longer supported from bzr 2.2; "
4007
"use bzr-usertest instead"))
4008
test_suite_factory = None
4010
exclude_pattern = None
2307
test_suite_factory = None
4012
exclude_pattern = '(' + '|'.join(exclude) + ')'
4014
self._disable_fsync()
4015
selftest_kwargs = {"verbose": verbose,
4017
"stop_on_failure": one,
4018
"transport": transport,
4019
"test_suite_factory": test_suite_factory,
4020
"lsprof_timed": lsprof_timed,
4021
"lsprof_tests": lsprof_tests,
4022
"matching_tests_first": first,
4023
"list_only": list_only,
4024
"random_seed": randomize,
4025
"exclude_pattern": exclude_pattern,
4027
"load_list": load_list,
4028
"debug_flags": debugflag,
4029
"starting_with": starting_with
4031
selftest_kwargs.update(self.additional_selftest_args)
4033
# Make deprecation warnings visible, unless -Werror is set
4034
cleanup = symbol_versioning.activate_deprecation_warnings(
2312
result = selftest(verbose=verbose,
2314
stop_on_failure=one,
2315
keep_output=keep_output,
2316
transport=transport,
2317
test_suite_factory=test_suite_factory,
2318
lsprof_timed=lsprof_timed,
2319
bench_history=benchfile,
2320
matching_tests_first=first,
4037
result = tests.selftest(**selftest_kwargs)
2323
if benchfile is not None:
2326
info('tests passed')
2328
info('tests failed')
2329
4040
return int(not result)
4042
def _disable_fsync(self):
4043
"""Change the 'os' functionality to not synchronize."""
4044
self._orig_fsync = getattr(os, 'fsync', None)
4045
if self._orig_fsync is not None:
4046
os.fsync = lambda filedes: None
4047
self._orig_fdatasync = getattr(os, 'fdatasync', None)
4048
if self._orig_fdatasync is not None:
4049
os.fdatasync = lambda filedes: None
2332
4052
class cmd_version(Command):
2333
"""Show version of bzr."""
4053
__doc__ = """Show version of bzr."""
4055
encoding_type = 'replace'
4057
Option("short", help="Print just the version number."),
2335
4060
@display_command
4061
def run(self, short=False):
2337
4062
from bzrlib.version import show_version
4064
self.outf.write(bzrlib.version_string + '\n')
4066
show_version(to_file=self.outf)
2341
4069
class cmd_rocks(Command):
2342
"""Statement of optimism."""
4070
__doc__ = """Statement of optimism."""
2346
4074
@display_command
2348
print "it sure does!"
4076
self.outf.write(gettext("It sure does!\n"))
2351
4079
class cmd_find_merge_base(Command):
2352
"""Find and print a base revision for merging two branches."""
4080
__doc__ = """Find and print a base revision for merging two branches."""
2353
4081
# TODO: Options to specify revisions on either side, as if
2354
4082
# merging only part of the history.
2355
4083
takes_args = ['branch', 'other']
2358
4086
@display_command
2359
4087
def run(self, branch, other):
2360
from bzrlib.revision import MultipleRevisionSources
4088
from bzrlib.revision import ensure_null
2362
4090
branch1 = Branch.open_containing(branch)[0]
2363
4091
branch2 = Branch.open_containing(other)[0]
2365
last1 = branch1.last_revision()
2366
last2 = branch2.last_revision()
2368
source = MultipleRevisionSources(branch1.repository,
2371
base_rev_id = common_ancestor(last1, last2, source)
2373
print 'merge base is revision %s' % base_rev_id
4092
self.add_cleanup(branch1.lock_read().unlock)
4093
self.add_cleanup(branch2.lock_read().unlock)
4094
last1 = ensure_null(branch1.last_revision())
4095
last2 = ensure_null(branch2.last_revision())
4097
graph = branch1.repository.get_graph(branch2.repository)
4098
base_rev_id = graph.find_unique_lca(last1, last2)
4100
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
2376
4103
class cmd_merge(Command):
2377
"""Perform a three-way merge.
2379
The branch is the branch you will merge from. By default, it will merge
2380
the latest revision. If you specify a revision, that revision will be
2381
merged. If you specify two revisions, the first will be used as a BASE,
2382
and the second one as OTHER. Revision numbers are always relative to the
2385
By default, bzr will try to merge in all new work from the other
2386
branch, automatically determining an appropriate base. If this
2387
fails, you may need to give an explicit base.
4104
__doc__ = """Perform a three-way merge.
4106
The source of the merge can be specified either in the form of a branch,
4107
or in the form of a path to a file containing a merge directive generated
4108
with bzr send. If neither is specified, the default is the upstream branch
4109
or the branch most recently merged using --remember. The source of the
4110
merge may also be specified in the form of a path to a file in another
4111
branch: in this case, only the modifications to that file are merged into
4112
the current working tree.
4114
When merging from a branch, by default bzr will try to merge in all new
4115
work from the other branch, automatically determining an appropriate base
4116
revision. If this fails, you may need to give an explicit base.
4118
To pick a different ending revision, pass "--revision OTHER". bzr will
4119
try to merge in all new work up to and including revision OTHER.
4121
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4122
through OTHER, excluding BASE but including OTHER, will be merged. If this
4123
causes some revisions to be skipped, i.e. if the destination branch does
4124
not already contain revision BASE, such a merge is commonly referred to as
4125
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4126
cherrypicks. The changes look like a normal commit, and the history of the
4127
changes from the other branch is not stored in the commit.
4129
Revision numbers are always relative to the source branch.
2389
4131
Merge will do its best to combine the changes in two branches, but there
2390
4132
are some kinds of problems only a human can fix. When it encounters those,
2391
4133
it will mark a conflict. A conflict means that you need to fix something,
2394
4136
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
2396
If there is no default branch set, the first merge will set it. After
2397
that, you can omit the branch to use the default. To change the
2398
default, use --remember. The value will only be saved if the remote
2399
location can be accessed.
4138
If there is no default branch set, the first merge will set it (use
4139
--no-remember to avoid setting it). After that, you can omit the branch
4140
to use the default. To change the default, use --remember. The value will
4141
only be saved if the remote location can be accessed.
2401
4143
The results of the merge are placed into the destination working
2402
4144
directory, where they can be reviewed (with bzr diff), tested, and then
2403
4145
committed to record the result of the merge.
2407
To merge the latest revision from bzr.dev
2408
bzr merge ../bzr.dev
2410
To merge changes up to and including revision 82 from bzr.dev
2411
bzr merge -r 82 ../bzr.dev
2413
To merge the changes introduced by 82, without previous changes:
2414
bzr merge -r 81..82 ../bzr.dev
2416
4147
merge refuses to run if there are any uncommitted changes, unless
2419
The following merge types are available:
4148
--force is given. If --force is given, then the changes from the source
4149
will be merged with the current working tree, including any uncommitted
4150
changes in the tree. The --force option can also be used to create a
4151
merge revision which has more than two parents.
4153
If one would like to merge changes from the working tree of the other
4154
branch without merging any committed revisions, the --uncommitted option
4157
To select only some changes to merge, use "merge -i", which will prompt
4158
you to apply each diff hunk and file change, similar to "shelve".
4161
To merge all new revisions from bzr.dev::
4163
bzr merge ../bzr.dev
4165
To merge changes up to and including revision 82 from bzr.dev::
4167
bzr merge -r 82 ../bzr.dev
4169
To merge the changes introduced by 82, without previous changes::
4171
bzr merge -r 81..82 ../bzr.dev
4173
To apply a merge directive contained in /tmp/merge::
4175
bzr merge /tmp/merge
4177
To create a merge revision with three parents from two branches
4178
feature1a and feature1b:
4180
bzr merge ../feature1a
4181
bzr merge ../feature1b --force
4182
bzr commit -m 'revision with three parents'
2421
takes_args = ['branch?']
2422
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
4185
encoding_type = 'exact'
4186
_see_also = ['update', 'remerge', 'status-flags', 'send']
4187
takes_args = ['location?']
4192
help='Merge even if the destination tree has uncommitted changes.'),
2423
4196
Option('show-base', help="Show base revision text in "
2425
4198
Option('uncommitted', help='Apply uncommitted changes'
2426
' from a working copy, instead of branch changes'),
4199
' from a working copy, instead of branch changes.'),
2427
4200
Option('pull', help='If the destination is already'
2428
4201
' completely merged into the source, pull from the'
2429
' source rather than merging. When this happens,'
4202
' source rather than merging. When this happens,'
2430
4203
' you do not need to commit the result.'),
2432
help='branch to merge into, '
2433
'rather than the one containing the working directory',
4204
custom_help('directory',
4205
help='Branch to merge into, '
4206
'rather than the one containing the working directory.'),
4207
Option('preview', help='Instead of merging, show a diff of the'
4209
Option('interactive', help='Select changes interactively.',
2439
def run(self, branch=None, revision=None, force=False, merge_type=None,
2440
show_base=False, reprocess=False, remember=False,
4213
def run(self, location=None, revision=None, force=False,
4214
merge_type=None, show_base=False, reprocess=None, remember=None,
2441
4215
uncommitted=False, pull=False,
2442
4216
directory=None,
2444
4220
if merge_type is None:
2445
4221
merge_type = _mod_merge.Merge3Merger
2447
4223
if directory is None: directory = u'.'
2448
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2449
# inventory. Because merge is a mutating operation, it really
2450
# should be a lock_write() for the whole cmd_merge operation.
2451
# However, cmd_merge open's its own tree in _merge_helper, which
2452
# means if we lock here, the later lock_write() will always block.
2453
# Either the merge helper code should be updated to take a tree,
2454
# or the ChangeReporter should be updated to not require an
2455
# inventory. (What about tree.merge_from_branch?)
4224
possible_transports = []
4226
allow_pending = True
4227
verified = 'inapplicable'
2456
4229
tree = WorkingTree.open_containing(directory)[0]
4230
if tree.branch.revno() == 0:
4231
raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4232
'https://bugs.launchpad.net/bzr/+bug/308562'))
2459
change_reporter = delta.ChangeReporter(tree.inventory)
2463
if branch is not None:
4235
basis_tree = tree.revision_tree(tree.last_revision())
4236
except errors.NoSuchRevision:
4237
basis_tree = tree.basis_tree()
4239
# die as quickly as possible if there are uncommitted changes
4241
if tree.has_changes():
4242
raise errors.UncommittedChanges(tree)
4244
view_info = _get_view_info_for_change_reporter(tree)
4245
change_reporter = delta._ChangeReporter(
4246
unversioned_filter=tree.is_ignored, view_info=view_info)
4247
pb = ui.ui_factory.nested_progress_bar()
4248
self.add_cleanup(pb.finished)
4249
self.add_cleanup(tree.lock_write().unlock)
4250
if location is not None:
2465
reader = bundle.read_bundle_from_url(branch)
4252
mergeable = bundle.read_mergeable_from_url(location,
4253
possible_transports=possible_transports)
2466
4254
except errors.NotABundle:
2467
pass # Continue on considering this url a Branch
2469
conflicts = merge_bundle(reader, tree, not force, merge_type,
2470
reprocess, show_base, change_reporter)
2476
if revision is None \
2477
or len(revision) < 1 or revision[0].needs_branch():
2478
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2480
if revision is None or len(revision) < 1:
2483
other = [branch, None]
2486
other = [branch, -1]
2487
other_branch, path = Branch.open_containing(branch)
2490
raise errors.BzrCommandError('Cannot use --uncommitted and'
2491
' --revision at the same time.')
2492
branch = revision[0].get_branch() or branch
2493
if len(revision) == 1:
2495
other_branch, path = Branch.open_containing(branch)
2496
revno = revision[0].in_history(other_branch).revno
2497
other = [branch, revno]
2499
assert len(revision) == 2
2500
if None in revision:
2501
raise errors.BzrCommandError(
2502
"Merge doesn't permit empty revision specifier.")
2503
base_branch, path = Branch.open_containing(branch)
2504
branch1 = revision[1].get_branch() or branch
2505
other_branch, path1 = Branch.open_containing(branch1)
2506
if revision[0].get_branch() is not None:
2507
# then path was obtained from it, and is None.
2510
base = [branch, revision[0].in_history(base_branch).revno]
2511
other = [branch1, revision[1].in_history(other_branch).revno]
2513
if tree.branch.get_parent() is None or remember:
2514
tree.branch.set_parent(other_branch.base)
2517
interesting_files = [path]
2519
interesting_files = None
2520
pb = ui.ui_factory.nested_progress_bar()
2523
conflict_count = _merge_helper(
2524
other, base, check_clean=(not force),
2525
merge_type=merge_type,
2526
reprocess=reprocess,
2527
show_base=show_base,
2530
pb=pb, file_list=interesting_files,
2531
change_reporter=change_reporter)
2534
if conflict_count != 0:
4258
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4259
' with bundles or merge directives.'))
4261
if revision is not None:
4262
raise errors.BzrCommandError(gettext(
4263
'Cannot use -r with merge directives or bundles'))
4264
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4267
if merger is None and uncommitted:
4268
if revision is not None and len(revision) > 0:
4269
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4270
' --revision at the same time.'))
4271
merger = self.get_merger_from_uncommitted(tree, location, None)
4272
allow_pending = False
4275
merger, allow_pending = self._get_merger_from_branch(tree,
4276
location, revision, remember, possible_transports, None)
4278
merger.merge_type = merge_type
4279
merger.reprocess = reprocess
4280
merger.show_base = show_base
4281
self.sanity_check_merger(merger)
4282
if (merger.base_rev_id == merger.other_rev_id and
4283
merger.other_rev_id is not None):
4284
# check if location is a nonexistent file (and not a branch) to
4285
# disambiguate the 'Nothing to do'
4286
if merger.interesting_files:
4287
if not merger.other_tree.has_filename(
4288
merger.interesting_files[0]):
4289
note(gettext("merger: ") + str(merger))
4290
raise errors.PathsDoNotExist([location])
4291
note(gettext('Nothing to do.'))
4293
if pull and not preview:
4294
if merger.interesting_files is not None:
4295
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4296
if (merger.base_rev_id == tree.last_revision()):
4297
result = tree.pull(merger.other_branch, False,
4298
merger.other_rev_id)
4299
result.report(self.outf)
2538
except errors.AmbiguousBase, e:
2539
m = ("sorry, bzr can't determine the right merge base yet\n"
2540
"candidates are:\n "
2541
+ "\n ".join(e.bases)
2543
"please specify an explicit base with -r,\n"
2544
"and (if you want) report this to the bzr developers\n")
2547
# TODO: move up to common parent; this isn't merge-specific anymore.
2548
def _get_remembered_parent(self, tree, supplied_location, verb_string):
4301
if merger.this_basis is None:
4302
raise errors.BzrCommandError(gettext(
4303
"This branch has no commits."
4304
" (perhaps you would prefer 'bzr pull')"))
4306
return self._do_preview(merger)
4308
return self._do_interactive(merger)
4310
return self._do_merge(merger, change_reporter, allow_pending,
4313
def _get_preview(self, merger):
4314
tree_merger = merger.make_merger()
4315
tt = tree_merger.make_preview_transform()
4316
self.add_cleanup(tt.finalize)
4317
result_tree = tt.get_preview_tree()
4320
def _do_preview(self, merger):
4321
from bzrlib.diff import show_diff_trees
4322
result_tree = self._get_preview(merger)
4323
path_encoding = osutils.get_diff_header_encoding()
4324
show_diff_trees(merger.this_tree, result_tree, self.outf,
4325
old_label='', new_label='',
4326
path_encoding=path_encoding)
4328
def _do_merge(self, merger, change_reporter, allow_pending, verified):
4329
merger.change_reporter = change_reporter
4330
conflict_count = merger.do_merge()
4332
merger.set_pending()
4333
if verified == 'failed':
4334
warning('Preview patch does not match changes')
4335
if conflict_count != 0:
4340
def _do_interactive(self, merger):
4341
"""Perform an interactive merge.
4343
This works by generating a preview tree of the merge, then using
4344
Shelver to selectively remove the differences between the working tree
4345
and the preview tree.
4347
from bzrlib import shelf_ui
4348
result_tree = self._get_preview(merger)
4349
writer = bzrlib.option.diff_writer_registry.get()
4350
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
4351
reporter=shelf_ui.ApplyReporter(),
4352
diff_writer=writer(sys.stdout))
4358
def sanity_check_merger(self, merger):
4359
if (merger.show_base and
4360
not merger.merge_type is _mod_merge.Merge3Merger):
4361
raise errors.BzrCommandError(gettext("Show-base is not supported for this"
4362
" merge type. %s") % merger.merge_type)
4363
if merger.reprocess is None:
4364
if merger.show_base:
4365
merger.reprocess = False
4367
# Use reprocess if the merger supports it
4368
merger.reprocess = merger.merge_type.supports_reprocess
4369
if merger.reprocess and not merger.merge_type.supports_reprocess:
4370
raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
4371
" for merge type %s.") %
4373
if merger.reprocess and merger.show_base:
4374
raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
4377
def _get_merger_from_branch(self, tree, location, revision, remember,
4378
possible_transports, pb):
4379
"""Produce a merger from a location, assuming it refers to a branch."""
4380
from bzrlib.tag import _merge_tags_if_possible
4381
# find the branch locations
4382
other_loc, user_location = self._select_branch_location(tree, location,
4384
if revision is not None and len(revision) == 2:
4385
base_loc, _unused = self._select_branch_location(tree,
4386
location, revision, 0)
4388
base_loc = other_loc
4390
other_branch, other_path = Branch.open_containing(other_loc,
4391
possible_transports)
4392
if base_loc == other_loc:
4393
base_branch = other_branch
4395
base_branch, base_path = Branch.open_containing(base_loc,
4396
possible_transports)
4397
# Find the revision ids
4398
other_revision_id = None
4399
base_revision_id = None
4400
if revision is not None:
4401
if len(revision) >= 1:
4402
other_revision_id = revision[-1].as_revision_id(other_branch)
4403
if len(revision) == 2:
4404
base_revision_id = revision[0].as_revision_id(base_branch)
4405
if other_revision_id is None:
4406
other_revision_id = _mod_revision.ensure_null(
4407
other_branch.last_revision())
4408
# Remember where we merge from. We need to remember if:
4409
# - user specify a location (and we don't merge from the parent
4411
# - user ask to remember or there is no previous location set to merge
4412
# from and user didn't ask to *not* remember
4413
if (user_location is not None
4415
or (remember is None
4416
and tree.branch.get_submit_branch() is None)))):
4417
tree.branch.set_submit_branch(other_branch.base)
4418
# Merge tags (but don't set them in the master branch yet, the user
4419
# might revert this merge). Commit will propagate them.
4420
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
4421
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4422
other_revision_id, base_revision_id, other_branch, base_branch)
4423
if other_path != '':
4424
allow_pending = False
4425
merger.interesting_files = [other_path]
4427
allow_pending = True
4428
return merger, allow_pending
4430
def get_merger_from_uncommitted(self, tree, location, pb):
4431
"""Get a merger for uncommitted changes.
4433
:param tree: The tree the merger should apply to.
4434
:param location: The location containing uncommitted changes.
4435
:param pb: The progress bar to use for showing progress.
4437
location = self._select_branch_location(tree, location)[0]
4438
other_tree, other_path = WorkingTree.open_containing(location)
4439
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
4440
if other_path != '':
4441
merger.interesting_files = [other_path]
4444
def _select_branch_location(self, tree, user_location, revision=None,
4446
"""Select a branch location, according to possible inputs.
4448
If provided, branches from ``revision`` are preferred. (Both
4449
``revision`` and ``index`` must be supplied.)
4451
Otherwise, the ``location`` parameter is used. If it is None, then the
4452
``submit`` or ``parent`` location is used, and a note is printed.
4454
:param tree: The working tree to select a branch for merging into
4455
:param location: The location entered by the user
4456
:param revision: The revision parameter to the command
4457
:param index: The index to use for the revision parameter. Negative
4458
indices are permitted.
4459
:return: (selected_location, user_location). The default location
4460
will be the user-entered location.
4462
if (revision is not None and index is not None
4463
and revision[index] is not None):
4464
branch = revision[index].get_branch()
4465
if branch is not None:
4466
return branch, branch
4467
if user_location is None:
4468
location = self._get_remembered(tree, 'Merging from')
4470
location = user_location
4471
return location, user_location
4473
def _get_remembered(self, tree, verb_string):
2549
4474
"""Use tree.branch's parent if none was supplied.
2551
4476
Report if the remembered location was used.
2553
if supplied_location is not None:
2554
return supplied_location
2555
stored_location = tree.branch.get_parent()
4478
stored_location = tree.branch.get_submit_branch()
4479
stored_location_type = "submit"
4480
if stored_location is None:
4481
stored_location = tree.branch.get_parent()
4482
stored_location_type = "parent"
2556
4483
mutter("%s", stored_location)
2557
4484
if stored_location is None:
2558
raise errors.BzrCommandError("No location specified or remembered")
2559
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2560
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
4485
raise errors.BzrCommandError(gettext("No location specified or remembered"))
4486
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4487
note(gettext("{0} remembered {1} location {2}").format(verb_string,
4488
stored_location_type, display_url))
2561
4489
return stored_location
2564
4492
class cmd_remerge(Command):
4493
__doc__ = """Redo a merge.
2567
4495
Use this if you want to try a different merge technique while resolving
2568
conflicts. Some merge techniques are better than others, and remerge
4496
conflicts. Some merge techniques are better than others, and remerge
2569
4497
lets you try different ones on different files.
2571
4499
The options for remerge have the same meaning and defaults as the ones for
2572
4500
merge. The difference is that remerge can (only) be run when there is a
2573
4501
pending merge, and it lets you specify particular files.
2576
$ bzr remerge --show-base
2577
4504
Re-do the merge of all conflicted files, and show the base text in
2578
conflict regions, in addition to the usual THIS and OTHER texts.
2580
$ bzr remerge --merge-type weave --reprocess foobar
4505
conflict regions, in addition to the usual THIS and OTHER texts::
4507
bzr remerge --show-base
2581
4509
Re-do the merge of "foobar", using the weave merge algorithm, with
2582
additional processing to reduce the size of conflict regions.
2584
The following merge types are available:"""
4510
additional processing to reduce the size of conflict regions::
4512
bzr remerge --merge-type weave --reprocess foobar
2585
4514
takes_args = ['file*']
2586
takes_options = ['merge-type', 'reprocess',
2587
Option('show-base', help="Show base revision text in "
4519
help="Show base revision text in conflicts."),
2590
4522
def run(self, file_list=None, merge_type=None, show_base=False,
2591
4523
reprocess=False):
4524
from bzrlib.conflicts import restore
2592
4525
if merge_type is None:
2593
4526
merge_type = _mod_merge.Merge3Merger
2594
tree, file_list = tree_files(file_list)
4527
tree, file_list = WorkingTree.open_containing_paths(file_list)
4528
self.add_cleanup(tree.lock_write().unlock)
4529
parents = tree.get_parent_ids()
4530
if len(parents) != 2:
4531
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4532
" merges. Not cherrypicking or"
4534
repository = tree.branch.repository
4535
interesting_ids = None
4537
conflicts = tree.conflicts()
4538
if file_list is not None:
4539
interesting_ids = set()
4540
for filename in file_list:
4541
file_id = tree.path2id(filename)
4543
raise errors.NotVersionedError(filename)
4544
interesting_ids.add(file_id)
4545
if tree.kind(file_id) != "directory":
4548
for name, ie in tree.inventory.iter_entries(file_id):
4549
interesting_ids.add(ie.file_id)
4550
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4552
# Remerge only supports resolving contents conflicts
4553
allowed_conflicts = ('text conflict', 'contents conflict')
4554
restore_files = [c.path for c in conflicts
4555
if c.typestring in allowed_conflicts]
4556
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4557
tree.set_conflicts(ConflictList(new_conflicts))
4558
if file_list is not None:
4559
restore_files = file_list
4560
for filename in restore_files:
4562
restore(tree.abspath(filename))
4563
except errors.NotConflicted:
4565
# Disable pending merges, because the file texts we are remerging
4566
# have not had those merges performed. If we use the wrong parents
4567
# list, we imply that the working tree text has seen and rejected
4568
# all the changes from the other tree, when in fact those changes
4569
# have not yet been seen.
4570
tree.set_parent_ids(parents[:1])
2597
parents = tree.get_parent_ids()
2598
if len(parents) != 2:
2599
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2600
" merges. Not cherrypicking or"
2602
repository = tree.branch.repository
2603
base_revision = common_ancestor(parents[0],
2604
parents[1], repository)
2605
base_tree = repository.revision_tree(base_revision)
2606
other_tree = repository.revision_tree(parents[1])
2607
interesting_ids = None
2609
conflicts = tree.conflicts()
2610
if file_list is not None:
2611
interesting_ids = set()
2612
for filename in file_list:
2613
file_id = tree.path2id(filename)
2615
raise errors.NotVersionedError(filename)
2616
interesting_ids.add(file_id)
2617
if tree.kind(file_id) != "directory":
2620
for name, ie in tree.inventory.iter_entries(file_id):
2621
interesting_ids.add(ie.file_id)
2622
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2624
# Remerge only supports resolving contents conflicts
2625
allowed_conflicts = ('text conflict', 'contents conflict')
2626
restore_files = [c.path for c in conflicts
2627
if c.typestring in allowed_conflicts]
2628
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2629
tree.set_conflicts(ConflictList(new_conflicts))
2630
if file_list is not None:
2631
restore_files = file_list
2632
for filename in restore_files:
2634
restore(tree.abspath(filename))
2635
except errors.NotConflicted:
2637
conflicts = _mod_merge.merge_inner(
2638
tree.branch, other_tree, base_tree,
2640
interesting_ids=interesting_ids,
2641
other_rev_id=parents[1],
2642
merge_type=merge_type,
2643
show_base=show_base,
2644
reprocess=reprocess)
4572
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4573
merger.interesting_ids = interesting_ids
4574
merger.merge_type = merge_type
4575
merger.show_base = show_base
4576
merger.reprocess = reprocess
4577
conflicts = merger.do_merge()
4579
tree.set_parent_ids(parents)
2647
4580
if conflicts > 0:
2729
4687
class cmd_shell_complete(Command):
2730
"""Show appropriate completions for context.
4688
__doc__ = """Show appropriate completions for context.
2732
4690
For a list of all available commands, say 'bzr shell-complete'.
2734
4692
takes_args = ['context?']
2735
4693
aliases = ['s-c']
2738
4696
@display_command
2739
4697
def run(self, context=None):
2740
4698
import shellcomplete
2741
4699
shellcomplete.shellcomplete(context)
2744
class cmd_fetch(Command):
2745
"""Copy in history from another branch but don't merge it.
2747
This is an internal method used for pull and merge.
2750
takes_args = ['from_branch', 'to_branch']
2751
def run(self, from_branch, to_branch):
2752
from bzrlib.fetch import Fetcher
2753
from_b = Branch.open(from_branch)
2754
to_b = Branch.open(to_branch)
2755
Fetcher(to_b, from_b)
2758
4702
class cmd_missing(Command):
2759
"""Show unmerged/unpulled revisions between two branches.
4703
__doc__ = """Show unmerged/unpulled revisions between two branches.
2761
4705
OTHER_BRANCH may be local or remote.
4707
To filter on a range of revisions, you can use the command -r begin..end
4708
-r revision requests a specific revision, -r ..end or -r begin.. are
4712
1 - some missing revisions
4713
0 - no missing revisions
4717
Determine the missing revisions between this and the branch at the
4718
remembered pull location::
4722
Determine the missing revisions between this and another branch::
4724
bzr missing http://server/branch
4726
Determine the missing revisions up to a specific revision on the other
4729
bzr missing -r ..-10
4731
Determine the missing revisions up to a specific revision on this
4734
bzr missing --my-revision ..-10
4737
_see_also = ['merge', 'pull']
2763
4738
takes_args = ['other_branch?']
2764
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2766
'Display changes in the local branch only'),
2767
Option('theirs-only',
2768
'Display changes in the remote branch only'),
4741
Option('reverse', 'Reverse the order of revisions.'),
4743
'Display changes in the local branch only.'),
4744
Option('this' , 'Same as --mine-only.'),
4745
Option('theirs-only',
4746
'Display changes in the remote branch only.'),
4747
Option('other', 'Same as --theirs-only.'),
4751
custom_help('revision',
4752
help='Filter on other branch revisions (inclusive). '
4753
'See "help revisionspec" for details.'),
4754
Option('my-revision',
4755
type=_parse_revision_str,
4756
help='Filter on local branch revisions (inclusive). '
4757
'See "help revisionspec" for details.'),
4758
Option('include-merged',
4759
'Show all revisions in addition to the mainline ones.'),
4760
Option('include-merges', hidden=True,
4761
help='Historical alias for --include-merged.'),
2773
4763
encoding_type = 'replace'
2775
4765
@display_command
2776
4766
def run(self, other_branch=None, reverse=False, mine_only=False,
2777
theirs_only=False, log_format=None, long=False, short=False, line=False,
2778
show_ids=False, verbose=False):
2779
from bzrlib.missing import find_unmerged, iter_log_data
2780
from bzrlib.log import log_formatter
2781
local_branch = Branch.open_containing(u".")[0]
4768
log_format=None, long=False, short=False, line=False,
4769
show_ids=False, verbose=False, this=False, other=False,
4770
include_merged=None, revision=None, my_revision=None,
4772
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4773
from bzrlib.missing import find_unmerged, iter_log_revisions
4778
if symbol_versioning.deprecated_passed(include_merges):
4779
ui.ui_factory.show_user_warning(
4780
'deprecated_command_option',
4781
deprecated_name='--include-merges',
4782
recommended_name='--include-merged',
4783
deprecated_in_version='2.5',
4784
command=self.invoked_as)
4785
if include_merged is None:
4786
include_merged = include_merges
4788
raise errors.BzrCommandError(gettext(
4789
'{0} and {1} are mutually exclusive').format(
4790
'--include-merges', '--include-merged'))
4791
if include_merged is None:
4792
include_merged = False
4797
# TODO: We should probably check that we don't have mine-only and
4798
# theirs-only set, but it gets complicated because we also have
4799
# this and other which could be used.
4806
local_branch = Branch.open_containing(directory)[0]
4807
self.add_cleanup(local_branch.lock_read().unlock)
2782
4809
parent = local_branch.get_parent()
2783
4810
if other_branch is None:
2784
4811
other_branch = parent
2785
4812
if other_branch is None:
2786
raise errors.BzrCommandError("No peer location known or specified.")
4813
raise errors.BzrCommandError(gettext("No peer location known"
2787
4815
display_url = urlutils.unescape_for_display(parent,
2788
4816
self.outf.encoding)
2789
print "Using last location: " + display_url
4817
message(gettext("Using saved parent location: {0}\n").format(
2791
4820
remote_branch = Branch.open(other_branch)
2792
4821
if remote_branch.base == local_branch.base:
2793
4822
remote_branch = local_branch
2794
local_branch.lock_read()
2796
remote_branch.lock_read()
2798
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2799
if (log_format is None):
2800
log_format = log.log_formatter_registry.get_default(
2802
lf = log_format(to_file=self.outf,
2804
show_timezone='original')
2805
if reverse is False:
2806
local_extra.reverse()
2807
remote_extra.reverse()
2808
if local_extra and not theirs_only:
2809
print "You have %d extra revision(s):" % len(local_extra)
2810
for data in iter_log_data(local_extra, local_branch.repository,
2813
printed_local = True
2815
printed_local = False
2816
if remote_extra and not mine_only:
2817
if printed_local is True:
2819
print "You are missing %d revision(s):" % len(remote_extra)
2820
for data in iter_log_data(remote_extra, remote_branch.repository,
2823
if not remote_extra and not local_extra:
2825
print "Branches are up to date."
2829
remote_branch.unlock()
2831
local_branch.unlock()
4824
self.add_cleanup(remote_branch.lock_read().unlock)
4826
local_revid_range = _revision_range_to_revid_range(
4827
_get_revision_range(my_revision, local_branch,
4830
remote_revid_range = _revision_range_to_revid_range(
4831
_get_revision_range(revision,
4832
remote_branch, self.name()))
4834
local_extra, remote_extra = find_unmerged(
4835
local_branch, remote_branch, restrict,
4836
backward=not reverse,
4837
include_merged=include_merged,
4838
local_revid_range=local_revid_range,
4839
remote_revid_range=remote_revid_range)
4841
if log_format is None:
4842
registry = log.log_formatter_registry
4843
log_format = registry.get_default(local_branch)
4844
lf = log_format(to_file=self.outf,
4846
show_timezone='original')
4849
if local_extra and not theirs_only:
4850
message(ngettext("You have %d extra revision:\n",
4851
"You have %d extra revisions:\n",
4854
for revision in iter_log_revisions(local_extra,
4855
local_branch.repository,
4857
lf.log_revision(revision)
4858
printed_local = True
4861
printed_local = False
4863
if remote_extra and not mine_only:
4864
if printed_local is True:
4866
message(ngettext("You are missing %d revision:\n",
4867
"You are missing %d revisions:\n",
4868
len(remote_extra)) %
4870
for revision in iter_log_revisions(remote_extra,
4871
remote_branch.repository,
4873
lf.log_revision(revision)
4876
if mine_only and not local_extra:
4877
# We checked local, and found nothing extra
4878
message(gettext('This branch has no new revisions.\n'))
4879
elif theirs_only and not remote_extra:
4880
# We checked remote, and found nothing extra
4881
message(gettext('Other branch has no new revisions.\n'))
4882
elif not (mine_only or theirs_only or local_extra or
4884
# We checked both branches, and neither one had extra
4886
message(gettext("Branches are up to date.\n"))
2832
4888
if not status_code and parent is None and other_branch is not None:
2833
local_branch.lock_write()
2835
# handle race conditions - a parent might be set while we run.
2836
if local_branch.get_parent() is None:
2837
local_branch.set_parent(remote_branch.base)
2839
local_branch.unlock()
4889
self.add_cleanup(local_branch.lock_write().unlock)
4890
# handle race conditions - a parent might be set while we run.
4891
if local_branch.get_parent() is None:
4892
local_branch.set_parent(remote_branch.base)
2840
4893
return status_code
4896
class cmd_pack(Command):
4897
__doc__ = """Compress the data within a repository.
4899
This operation compresses the data within a bazaar repository. As
4900
bazaar supports automatic packing of repository, this operation is
4901
normally not required to be done manually.
4903
During the pack operation, bazaar takes a backup of existing repository
4904
data, i.e. pack files. This backup is eventually removed by bazaar
4905
automatically when it is safe to do so. To save disk space by removing
4906
the backed up pack files, the --clean-obsolete-packs option may be
4909
Warning: If you use --clean-obsolete-packs and your machine crashes
4910
during or immediately after repacking, you may be left with a state
4911
where the deletion has been written to disk but the new packs have not
4912
been. In this case the repository may be unusable.
4915
_see_also = ['repositories']
4916
takes_args = ['branch_or_repo?']
4918
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4921
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4922
dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4924
branch = dir.open_branch()
4925
repository = branch.repository
4926
except errors.NotBranchError:
4927
repository = dir.open_repository()
4928
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
2843
4931
class cmd_plugins(Command):
4932
__doc__ = """List the installed plugins.
4934
This command displays the list of installed plugins including
4935
version of plugin and a short description of each.
4937
--verbose shows the path where each plugin is located.
4939
A plugin is an external component for Bazaar that extends the
4940
revision control system, by adding or replacing code in Bazaar.
4941
Plugins can do a variety of things, including overriding commands,
4942
adding new commands, providing additional network transports and
4943
customizing log output.
4945
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4946
for further information on plugins including where to find them and how to
4947
install them. Instructions are also provided there on how to write new
4948
plugins using the Python programming language.
4950
takes_options = ['verbose']
2846
4952
@display_command
2848
import bzrlib.plugin
2849
from inspect import getdoc
2850
for name, plugin in bzrlib.plugin.all_plugins().items():
2851
if getattr(plugin, '__path__', None) is not None:
2852
print plugin.__path__[0]
2853
elif getattr(plugin, '__file__', None) is not None:
2854
print plugin.__file__
2860
print '\t', d.split('\n')[0]
4953
def run(self, verbose=False):
4954
from bzrlib import plugin
4955
# Don't give writelines a generator as some codecs don't like that
4956
self.outf.writelines(
4957
list(plugin.describe_plugins(show_paths=verbose)))
2863
4960
class cmd_testament(Command):
2864
"""Show testament (signing-form) of a revision."""
2865
takes_options = ['revision',
2866
Option('long', help='Produce long-format testament'),
2867
Option('strict', help='Produce a strict-format'
4961
__doc__ = """Show testament (signing-form) of a revision."""
4964
Option('long', help='Produce long-format testament.'),
4966
help='Produce a strict-format testament.')]
2869
4967
takes_args = ['branch?']
2870
4968
@display_command
2871
4969
def run(self, branch=u'.', revision=None, long=False, strict=False):
3145
5336
class cmd_serve(Command):
3146
"""Run the bzr server."""
5337
__doc__ = """Run the bzr server."""
3148
5339
aliases = ['server']
3150
5341
takes_options = [
3152
help='serve on stdin/out for use from inetd or sshd'),
5343
help='Serve on stdin/out for use from inetd or sshd.'),
5344
RegistryOption('protocol',
5345
help="Protocol to serve.",
5346
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5347
value_switches=True),
3154
help='listen for connections on nominated port of the form '
3155
'[hostname:]portnumber. Passing 0 as the port number will '
3156
'result in a dynamically allocated port.',
5349
help='Listen for connections on nominated port of the form '
5350
'[hostname:]portnumber. Passing 0 as the port number will '
5351
'result in a dynamically allocated port. The default port '
5352
'depends on the protocol.',
3159
help='serve contents of directory',
5354
custom_help('directory',
5355
help='Serve contents of this directory.'),
3161
5356
Option('allow-writes',
3162
help='By default the server is a readonly server. Supplying '
5357
help='By default the server is a readonly server. Supplying '
3163
5358
'--allow-writes enables write access to the contents of '
3164
'the served directory and below. '
5359
'the served directory and below. Note that ``bzr serve`` '
5360
'does not perform authentication, so unless some form of '
5361
'external authentication is arranged supplying this '
5362
'option leads to global uncontrolled write access to your '
5365
Option('client-timeout', type=float,
5366
help='Override the default idle client timeout (5min).'),
3168
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3169
from bzrlib.transport import smart
3170
from bzrlib.transport import get_transport
5369
def get_host_and_port(self, port):
5370
"""Return the host and port to run the smart server on.
5372
If 'port' is None, None will be returned for the host and port.
5374
If 'port' has a colon in it, the string before the colon will be
5375
interpreted as the host.
5377
:param port: A string of the port to run the server on.
5378
:return: A tuple of (host, port), where 'host' is a host name or IP,
5379
and port is an integer TCP/IP port.
5382
if port is not None:
5384
host, port = port.split(':')
5388
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5389
protocol=None, client_timeout=None):
5390
from bzrlib import transport
3171
5391
if directory is None:
3172
5392
directory = os.getcwd()
3173
url = urlutils.local_path_to_url(directory)
5393
if protocol is None:
5394
protocol = transport.transport_server_registry.get()
5395
host, port = self.get_host_and_port(port)
5396
url = transport.location_to_url(directory)
3174
5397
if not allow_writes:
3175
5398
url = 'readonly+' + url
3176
t = get_transport(url)
3178
server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
3179
elif port is not None:
3181
host, port = port.split(':')
3184
server = smart.SmartTCPServer(t, host=host, port=int(port))
3185
print 'listening on port: ', server.port
3188
raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
3192
# command-line interpretation helper for merge-related commands
3193
def _merge_helper(other_revision, base_revision,
3194
check_clean=True, ignore_zero=False,
3195
this_dir=None, backup_files=False,
3197
file_list=None, show_base=False, reprocess=False,
3200
change_reporter=None):
3201
"""Merge changes into a tree.
3204
list(path, revno) Base for three-way merge.
3205
If [None, None] then a base will be automatically determined.
3207
list(path, revno) Other revision for three-way merge.
3209
Directory to merge changes into; '.' by default.
3211
If true, this_dir must have no uncommitted changes before the
3213
ignore_zero - If true, suppress the "zero conflicts" message when
3214
there are no conflicts; should be set when doing something we expect
3215
to complete perfectly.
3216
file_list - If supplied, merge only changes to selected files.
3218
All available ancestors of other_revision and base_revision are
3219
automatically pulled into the branch.
3221
The revno may be -1 to indicate the last revision on the branch, which is
3224
This function is intended for use from the command line; programmatic
3225
clients might prefer to call merge.merge_inner(), which has less magic
3228
# Loading it late, so that we don't always have to import bzrlib.merge
3229
if merge_type is None:
3230
merge_type = _mod_merge.Merge3Merger
3231
if this_dir is None:
3233
this_tree = WorkingTree.open_containing(this_dir)[0]
3234
if show_base and not merge_type is _mod_merge.Merge3Merger:
3235
raise errors.BzrCommandError("Show-base is not supported for this merge"
3236
" type. %s" % merge_type)
3237
if reprocess and not merge_type.supports_reprocess:
3238
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3239
" type %s." % merge_type)
3240
if reprocess and show_base:
3241
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3242
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3243
# only want to take out a lock_tree_write() if we don't have to pull
3244
# any ancestry. But merge might fetch ancestry in the middle, in
3245
# which case we would need a lock_write().
3246
# Because we cannot upgrade locks, for now we live with the fact that
3247
# the tree will be locked multiple times during a merge. (Maybe
3248
# read-only some of the time, but it means things will get read
3251
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3252
pb=pb, change_reporter=change_reporter)
3253
merger.pp = ProgressPhase("Merge phase", 5, pb)
3254
merger.pp.next_phase()
3255
merger.check_basis(check_clean)
3256
merger.set_other(other_revision)
3257
merger.pp.next_phase()
3258
merger.set_base(base_revision)
3259
if merger.base_rev_id == merger.other_rev_id:
3260
note('Nothing to do.')
3262
if file_list is None:
3263
if pull and merger.base_rev_id == merger.this_rev_id:
3264
count = merger.this_tree.pull(merger.this_branch,
3265
False, merger.other_rev_id)
3266
note('%d revision(s) pulled.' % (count,))
3268
merger.backup_files = backup_files
3269
merger.merge_type = merge_type
3270
merger.set_interesting_files(file_list)
3271
merger.show_base = show_base
3272
merger.reprocess = reprocess
3273
conflicts = merger.do_merge()
3274
if file_list is None:
3275
merger.set_pending()
3282
merge = _merge_helper
3285
# these get imported and then picked up by the scan for cmd_*
3286
# TODO: Some more consistent way to split command definitions across files;
3287
# we do need to load at least some information about them to know of
3288
# aliases. ideally we would avoid loading the implementation until the
3289
# details were needed.
3290
from bzrlib.cmd_version_info import cmd_version_info
3291
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
3292
from bzrlib.bundle.commands import cmd_bundle_revisions
3293
from bzrlib.sign_my_commits import cmd_sign_my_commits
3294
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
3295
cmd_weave_plan_merge, cmd_weave_merge_text
5399
t = transport.get_transport_from_url(url)
5401
protocol(t, host, port, inet, client_timeout)
5402
except TypeError, e:
5403
# We use symbol_versioning.deprecated_in just so that people
5404
# grepping can find it here.
5405
# symbol_versioning.deprecated_in((2, 5, 0))
5406
symbol_versioning.warn(
5407
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5408
'Most likely it needs to be updated to support a'
5409
' "timeout" parameter (added in bzr 2.5.0)'
5410
% (e, protocol.__module__, protocol),
5412
protocol(t, host, port, inet)
5415
class cmd_join(Command):
5416
__doc__ = """Combine a tree into its containing tree.
5418
This command requires the target tree to be in a rich-root format.
5420
The TREE argument should be an independent tree, inside another tree, but
5421
not part of it. (Such trees can be produced by "bzr split", but also by
5422
running "bzr branch" with the target inside a tree.)
5424
The result is a combined tree, with the subtree no longer an independent
5425
part. This is marked as a merge of the subtree into the containing tree,
5426
and all history is preserved.
5429
_see_also = ['split']
5430
takes_args = ['tree']
5432
Option('reference', help='Join by reference.', hidden=True),
5435
def run(self, tree, reference=False):
5436
sub_tree = WorkingTree.open(tree)
5437
parent_dir = osutils.dirname(sub_tree.basedir)
5438
containing_tree = WorkingTree.open_containing(parent_dir)[0]
5439
repo = containing_tree.branch.repository
5440
if not repo.supports_rich_root():
5441
raise errors.BzrCommandError(gettext(
5442
"Can't join trees because %s doesn't support rich root data.\n"
5443
"You can use bzr upgrade on the repository.")
5447
containing_tree.add_reference(sub_tree)
5448
except errors.BadReferenceTarget, e:
5449
# XXX: Would be better to just raise a nicely printable
5450
# exception from the real origin. Also below. mbp 20070306
5451
raise errors.BzrCommandError(
5452
gettext("Cannot join {0}. {1}").format(tree, e.reason))
5455
containing_tree.subsume(sub_tree)
5456
except errors.BadSubsumeSource, e:
5457
raise errors.BzrCommandError(
5458
gettext("Cannot join {0}. {1}").format(tree, e.reason))
5461
class cmd_split(Command):
5462
__doc__ = """Split a subdirectory of a tree into a separate tree.
5464
This command will produce a target tree in a format that supports
5465
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
5466
converted into earlier formats like 'dirstate-tags'.
5468
The TREE argument should be a subdirectory of a working tree. That
5469
subdirectory will be converted into an independent tree, with its own
5470
branch. Commits in the top-level tree will not apply to the new subtree.
5473
_see_also = ['join']
5474
takes_args = ['tree']
5476
def run(self, tree):
5477
containing_tree, subdir = WorkingTree.open_containing(tree)
5478
sub_id = containing_tree.path2id(subdir)
5480
raise errors.NotVersionedError(subdir)
5482
containing_tree.extract(sub_id)
5483
except errors.RootNotRich:
5484
raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
5487
class cmd_merge_directive(Command):
5488
__doc__ = """Generate a merge directive for auto-merge tools.
5490
A directive requests a merge to be performed, and also provides all the
5491
information necessary to do so. This means it must either include a
5492
revision bundle, or the location of a branch containing the desired
5495
A submit branch (the location to merge into) must be supplied the first
5496
time the command is issued. After it has been supplied once, it will
5497
be remembered as the default.
5499
A public branch is optional if a revision bundle is supplied, but required
5500
if --diff or --plain is specified. It will be remembered as the default
5501
after the first use.
5504
takes_args = ['submit_branch?', 'public_branch?']
5508
_see_also = ['send']
5512
RegistryOption.from_kwargs('patch-type',
5513
'The type of patch to include in the directive.',
5515
value_switches=True,
5517
bundle='Bazaar revision bundle (default).',
5518
diff='Normal unified diff.',
5519
plain='No patch, just directive.'),
5520
Option('sign', help='GPG-sign the directive.'), 'revision',
5521
Option('mail-to', type=str,
5522
help='Instead of printing the directive, email to this address.'),
5523
Option('message', type=str, short_name='m',
5524
help='Message to use when committing this merge.')
5527
encoding_type = 'exact'
5529
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5530
sign=False, revision=None, mail_to=None, message=None,
5532
from bzrlib.revision import ensure_null, NULL_REVISION
5533
include_patch, include_bundle = {
5534
'plain': (False, False),
5535
'diff': (True, False),
5536
'bundle': (True, True),
5538
branch = Branch.open(directory)
5539
stored_submit_branch = branch.get_submit_branch()
5540
if submit_branch is None:
5541
submit_branch = stored_submit_branch
5543
if stored_submit_branch is None:
5544
branch.set_submit_branch(submit_branch)
5545
if submit_branch is None:
5546
submit_branch = branch.get_parent()
5547
if submit_branch is None:
5548
raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5550
stored_public_branch = branch.get_public_branch()
5551
if public_branch is None:
5552
public_branch = stored_public_branch
5553
elif stored_public_branch is None:
5554
branch.set_public_branch(public_branch)
5555
if not include_bundle and public_branch is None:
5556
raise errors.BzrCommandError(gettext('No public branch specified or'
5558
base_revision_id = None
5559
if revision is not None:
5560
if len(revision) > 2:
5561
raise errors.BzrCommandError(gettext('bzr merge-directive takes '
5562
'at most two one revision identifiers'))
5563
revision_id = revision[-1].as_revision_id(branch)
5564
if len(revision) == 2:
5565
base_revision_id = revision[0].as_revision_id(branch)
5567
revision_id = branch.last_revision()
5568
revision_id = ensure_null(revision_id)
5569
if revision_id == NULL_REVISION:
5570
raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5571
directive = merge_directive.MergeDirective2.from_objects(
5572
branch.repository, revision_id, time.time(),
5573
osutils.local_time_offset(), submit_branch,
5574
public_branch=public_branch, include_patch=include_patch,
5575
include_bundle=include_bundle, message=message,
5576
base_revision_id=base_revision_id)
5579
self.outf.write(directive.to_signed(branch))
5581
self.outf.writelines(directive.to_lines())
5583
message = directive.to_email(mail_to, branch, sign)
5584
s = SMTPConnection(branch.get_config_stack())
5585
s.send_email(message)
5588
class cmd_send(Command):
5589
__doc__ = """Mail or create a merge-directive for submitting changes.
5591
A merge directive provides many things needed for requesting merges:
5593
* A machine-readable description of the merge to perform
5595
* An optional patch that is a preview of the changes requested
5597
* An optional bundle of revision data, so that the changes can be applied
5598
directly from the merge directive, without retrieving data from a
5601
`bzr send` creates a compact data set that, when applied using bzr
5602
merge, has the same effect as merging from the source branch.
5604
By default the merge directive is self-contained and can be applied to any
5605
branch containing submit_branch in its ancestory without needing access to
5608
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5609
revisions, but only a structured request to merge from the
5610
public_location. In that case the public_branch is needed and it must be
5611
up-to-date and accessible to the recipient. The public_branch is always
5612
included if known, so that people can check it later.
5614
The submit branch defaults to the parent of the source branch, but can be
5615
overridden. Both submit branch and public branch will be remembered in
5616
branch.conf the first time they are used for a particular branch. The
5617
source branch defaults to that containing the working directory, but can
5618
be changed using --from.
5620
Both the submit branch and the public branch follow the usual behavior with
5621
respect to --remember: If there is no default location set, the first send
5622
will set it (use --no-remember to avoid setting it). After that, you can
5623
omit the location to use the default. To change the default, use
5624
--remember. The value will only be saved if the location can be accessed.
5626
In order to calculate those changes, bzr must analyse the submit branch.
5627
Therefore it is most efficient for the submit branch to be a local mirror.
5628
If a public location is known for the submit_branch, that location is used
5629
in the merge directive.
5631
The default behaviour is to send the merge directive by mail, unless -o is
5632
given, in which case it is sent to a file.
5634
Mail is sent using your preferred mail program. This should be transparent
5635
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5636
If the preferred client can't be found (or used), your editor will be used.
5638
To use a specific mail program, set the mail_client configuration option.
5639
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5640
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5641
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5642
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5645
If mail is being sent, a to address is required. This can be supplied
5646
either on the commandline, by setting the submit_to configuration
5647
option in the branch itself or the child_submit_to configuration option
5648
in the submit branch.
5650
Two formats are currently supported: "4" uses revision bundle format 4 and
5651
merge directive format 2. It is significantly faster and smaller than
5652
older formats. It is compatible with Bazaar 0.19 and later. It is the
5653
default. "0.9" uses revision bundle format 0.9 and merge directive
5654
format 1. It is compatible with Bazaar 0.12 - 0.18.
5656
The merge directives created by bzr send may be applied using bzr merge or
5657
bzr pull by specifying a file containing a merge directive as the location.
5659
bzr send makes extensive use of public locations to map local locations into
5660
URLs that can be used by other people. See `bzr help configuration` to
5661
set them, and use `bzr info` to display them.
5664
encoding_type = 'exact'
5666
_see_also = ['merge', 'pull']
5668
takes_args = ['submit_branch?', 'public_branch?']
5672
help='Do not include a bundle in the merge directive.'),
5673
Option('no-patch', help='Do not include a preview patch in the merge'
5676
help='Remember submit and public branch.'),
5678
help='Branch to generate the submission from, '
5679
'rather than the one containing the working directory.',
5682
Option('output', short_name='o',
5683
help='Write merge directive to this file or directory; '
5684
'use - for stdout.',
5687
help='Refuse to send if there are uncommitted changes in'
5688
' the working tree, --no-strict disables the check.'),
5689
Option('mail-to', help='Mail the request to this address.',
5693
Option('body', help='Body for the email.', type=unicode),
5694
RegistryOption('format',
5695
help='Use the specified output format.',
5696
lazy_registry=('bzrlib.send', 'format_registry')),
5699
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5700
no_patch=False, revision=None, remember=None, output=None,
5701
format=None, mail_to=None, message=None, body=None,
5702
strict=None, **kwargs):
5703
from bzrlib.send import send
5704
return send(submit_branch, revision, public_branch, remember,
5705
format, no_bundle, no_patch, output,
5706
kwargs.get('from', '.'), mail_to, message, body,
5711
class cmd_bundle_revisions(cmd_send):
5712
__doc__ = """Create a merge-directive for submitting changes.
5714
A merge directive provides many things needed for requesting merges:
5716
* A machine-readable description of the merge to perform
5718
* An optional patch that is a preview of the changes requested
5720
* An optional bundle of revision data, so that the changes can be applied
5721
directly from the merge directive, without retrieving data from a
5724
If --no-bundle is specified, then public_branch is needed (and must be
5725
up-to-date), so that the receiver can perform the merge using the
5726
public_branch. The public_branch is always included if known, so that
5727
people can check it later.
5729
The submit branch defaults to the parent, but can be overridden. Both
5730
submit branch and public branch will be remembered if supplied.
5732
If a public_branch is known for the submit_branch, that public submit
5733
branch is used in the merge instructions. This means that a local mirror
5734
can be used as your actual submit branch, once you have set public_branch
5737
Two formats are currently supported: "4" uses revision bundle format 4 and
5738
merge directive format 2. It is significantly faster and smaller than
5739
older formats. It is compatible with Bazaar 0.19 and later. It is the
5740
default. "0.9" uses revision bundle format 0.9 and merge directive
5741
format 1. It is compatible with Bazaar 0.12 - 0.18.
5746
help='Do not include a bundle in the merge directive.'),
5747
Option('no-patch', help='Do not include a preview patch in the merge'
5750
help='Remember submit and public branch.'),
5752
help='Branch to generate the submission from, '
5753
'rather than the one containing the working directory.',
5756
Option('output', short_name='o', help='Write directive to this file.',
5759
help='Refuse to bundle revisions if there are uncommitted'
5760
' changes in the working tree, --no-strict disables the check.'),
5762
RegistryOption('format',
5763
help='Use the specified output format.',
5764
lazy_registry=('bzrlib.send', 'format_registry')),
5766
aliases = ['bundle']
5768
_see_also = ['send', 'merge']
5772
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5773
no_patch=False, revision=None, remember=False, output=None,
5774
format=None, strict=None, **kwargs):
5777
from bzrlib.send import send
5778
return send(submit_branch, revision, public_branch, remember,
5779
format, no_bundle, no_patch, output,
5780
kwargs.get('from', '.'), None, None, None,
5781
self.outf, strict=strict)
5784
class cmd_tag(Command):
5785
__doc__ = """Create, remove or modify a tag naming a revision.
5787
Tags give human-meaningful names to revisions. Commands that take a -r
5788
(--revision) option can be given -rtag:X, where X is any previously
5791
Tags are stored in the branch. Tags are copied from one branch to another
5792
along when you branch, push, pull or merge.
5794
It is an error to give a tag name that already exists unless you pass
5795
--force, in which case the tag is moved to point to the new revision.
5797
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5798
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5800
If no tag name is specified it will be determined through the
5801
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5802
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5806
_see_also = ['commit', 'tags']
5807
takes_args = ['tag_name?']
5810
help='Delete this tag rather than placing it.',
5812
custom_help('directory',
5813
help='Branch in which to place the tag.'),
5815
help='Replace existing tags.',
5820
def run(self, tag_name=None,
5826
branch, relpath = Branch.open_containing(directory)
5827
self.add_cleanup(branch.lock_write().unlock)
5829
if tag_name is None:
5830
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5831
branch.tags.delete_tag(tag_name)
5832
note(gettext('Deleted tag %s.') % tag_name)
5835
if len(revision) != 1:
5836
raise errors.BzrCommandError(gettext(
5837
"Tags can only be placed on a single revision, "
5839
revision_id = revision[0].as_revision_id(branch)
5841
revision_id = branch.last_revision()
5842
if tag_name is None:
5843
tag_name = branch.automatic_tag_name(revision_id)
5844
if tag_name is None:
5845
raise errors.BzrCommandError(gettext(
5846
"Please specify a tag name."))
5848
existing_target = branch.tags.lookup_tag(tag_name)
5849
except errors.NoSuchTag:
5850
existing_target = None
5851
if not force and existing_target not in (None, revision_id):
5852
raise errors.TagAlreadyExists(tag_name)
5853
if existing_target == revision_id:
5854
note(gettext('Tag %s already exists for that revision.') % tag_name)
5856
branch.tags.set_tag(tag_name, revision_id)
5857
if existing_target is None:
5858
note(gettext('Created tag %s.') % tag_name)
5860
note(gettext('Updated tag %s.') % tag_name)
5863
class cmd_tags(Command):
5864
__doc__ = """List tags.
5866
This command shows a table of tag names and the revisions they reference.
5871
custom_help('directory',
5872
help='Branch whose tags should be displayed.'),
5873
RegistryOption('sort',
5874
'Sort tags by different criteria.', title='Sorting',
5875
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5882
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5883
from bzrlib.tag import tag_sort_methods
5884
branch, relpath = Branch.open_containing(directory)
5886
tags = branch.tags.get_tag_dict().items()
5890
self.add_cleanup(branch.lock_read().unlock)
5892
# Restrict to the specified range
5893
tags = self._tags_for_range(branch, revision)
5895
sort = tag_sort_methods.get()
5898
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5899
for index, (tag, revid) in enumerate(tags):
5901
revno = branch.revision_id_to_dotted_revno(revid)
5902
if isinstance(revno, tuple):
5903
revno = '.'.join(map(str, revno))
5904
except (errors.NoSuchRevision,
5905
errors.GhostRevisionsHaveNoRevno,
5906
errors.UnsupportedOperation):
5907
# Bad tag data/merges can lead to tagged revisions
5908
# which are not in this branch. Fail gracefully ...
5910
tags[index] = (tag, revno)
5912
for tag, revspec in tags:
5913
self.outf.write('%-20s %s\n' % (tag, revspec))
5915
def _tags_for_range(self, branch, revision):
5917
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5918
revid1, revid2 = rev1.rev_id, rev2.rev_id
5919
# _get_revision_range will always set revid2 if it's not specified.
5920
# If revid1 is None, it means we want to start from the branch
5921
# origin which is always a valid ancestor. If revid1 == revid2, the
5922
# ancestry check is useless.
5923
if revid1 and revid1 != revid2:
5924
# FIXME: We really want to use the same graph than
5925
# branch.iter_merge_sorted_revisions below, but this is not
5926
# easily available -- vila 2011-09-23
5927
if branch.repository.get_graph().is_ancestor(revid2, revid1):
5928
# We don't want to output anything in this case...
5930
# only show revisions between revid1 and revid2 (inclusive)
5931
tagged_revids = branch.tags.get_reverse_tag_dict()
5933
for r in branch.iter_merge_sorted_revisions(
5934
start_revision_id=revid2, stop_revision_id=revid1,
5935
stop_rule='include'):
5936
revid_tags = tagged_revids.get(r[0], None)
5938
found.extend([(tag, r[0]) for tag in revid_tags])
5942
class cmd_reconfigure(Command):
5943
__doc__ = """Reconfigure the type of a bzr directory.
5945
A target configuration must be specified.
5947
For checkouts, the bind-to location will be auto-detected if not specified.
5948
The order of preference is
5949
1. For a lightweight checkout, the current bound location.
5950
2. For branches that used to be checkouts, the previously-bound location.
5951
3. The push location.
5952
4. The parent location.
5953
If none of these is available, --bind-to must be specified.
5956
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5957
takes_args = ['location?']
5959
RegistryOption.from_kwargs(
5962
help='The relation between branch and tree.',
5963
value_switches=True, enum_switch=False,
5964
branch='Reconfigure to be an unbound branch with no working tree.',
5965
tree='Reconfigure to be an unbound branch with a working tree.',
5966
checkout='Reconfigure to be a bound branch with a working tree.',
5967
lightweight_checkout='Reconfigure to be a lightweight'
5968
' checkout (with no local history).',
5970
RegistryOption.from_kwargs(
5972
title='Repository type',
5973
help='Location fo the repository.',
5974
value_switches=True, enum_switch=False,
5975
standalone='Reconfigure to be a standalone branch '
5976
'(i.e. stop using shared repository).',
5977
use_shared='Reconfigure to use a shared repository.',
5979
RegistryOption.from_kwargs(
5981
title='Trees in Repository',
5982
help='Whether new branches in the repository have trees.',
5983
value_switches=True, enum_switch=False,
5984
with_trees='Reconfigure repository to create '
5985
'working trees on branches by default.',
5986
with_no_trees='Reconfigure repository to not create '
5987
'working trees on branches by default.'
5989
Option('bind-to', help='Branch to bind checkout to.', type=str),
5991
help='Perform reconfiguration even if local changes'
5993
Option('stacked-on',
5994
help='Reconfigure a branch to be stacked on another branch.',
5998
help='Reconfigure a branch to be unstacked. This '
5999
'may require copying substantial data into it.',
6003
def run(self, location=None, bind_to=None, force=False,
6004
tree_type=None, repository_type=None, repository_trees=None,
6005
stacked_on=None, unstacked=None):
6006
directory = controldir.ControlDir.open(location)
6007
if stacked_on and unstacked:
6008
raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
6009
elif stacked_on is not None:
6010
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
6012
reconfigure.ReconfigureUnstacked().apply(directory)
6013
# At the moment you can use --stacked-on and a different
6014
# reconfiguration shape at the same time; there seems no good reason
6016
if (tree_type is None and
6017
repository_type is None and
6018
repository_trees is None):
6019
if stacked_on or unstacked:
6022
raise errors.BzrCommandError(gettext('No target configuration '
6024
reconfiguration = None
6025
if tree_type == 'branch':
6026
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6027
elif tree_type == 'tree':
6028
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6029
elif tree_type == 'checkout':
6030
reconfiguration = reconfigure.Reconfigure.to_checkout(
6032
elif tree_type == 'lightweight-checkout':
6033
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6036
reconfiguration.apply(force)
6037
reconfiguration = None
6038
if repository_type == 'use-shared':
6039
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6040
elif repository_type == 'standalone':
6041
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6043
reconfiguration.apply(force)
6044
reconfiguration = None
6045
if repository_trees == 'with-trees':
6046
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6048
elif repository_trees == 'with-no-trees':
6049
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6052
reconfiguration.apply(force)
6053
reconfiguration = None
6056
class cmd_switch(Command):
6057
__doc__ = """Set the branch of a checkout and update.
6059
For lightweight checkouts, this changes the branch being referenced.
6060
For heavyweight checkouts, this checks that there are no local commits
6061
versus the current bound branch, then it makes the local branch a mirror
6062
of the new location and binds to it.
6064
In both cases, the working tree is updated and uncommitted changes
6065
are merged. The user can commit or revert these as they desire.
6067
Pending merges need to be committed or reverted before using switch.
6069
The path to the branch to switch to can be specified relative to the parent
6070
directory of the current branch. For example, if you are currently in a
6071
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
6074
Bound branches use the nickname of its master branch unless it is set
6075
locally, in which case switching will update the local nickname to be
6079
takes_args = ['to_location?']
6080
takes_options = ['directory',
6082
help='Switch even if local commits will be lost.'),
6084
Option('create-branch', short_name='b',
6085
help='Create the target branch from this one before'
6086
' switching to it.'),
6089
def run(self, to_location=None, force=False, create_branch=False,
6090
revision=None, directory=u'.'):
6091
from bzrlib import switch
6092
tree_location = directory
6093
revision = _get_one_revision('switch', revision)
6094
control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6095
if to_location is None:
6096
if revision is None:
6097
raise errors.BzrCommandError(gettext('You must supply either a'
6098
' revision or a location'))
6099
to_location = tree_location
6101
branch = control_dir.open_branch()
6102
had_explicit_nick = branch.get_config().has_explicit_nickname()
6103
except errors.NotBranchError:
6105
had_explicit_nick = False
6108
raise errors.BzrCommandError(gettext('cannot create branch without'
6110
to_location = directory_service.directories.dereference(
6112
if '/' not in to_location and '\\' not in to_location:
6113
# This path is meant to be relative to the existing branch
6114
this_url = self._get_branch_location(control_dir)
6115
# Perhaps the target control dir supports colocated branches?
6117
root = controldir.ControlDir.open(this_url,
6118
possible_transports=[control_dir.user_transport])
6119
except errors.NotBranchError:
6122
colocated = root._format.colocated_branches
6124
to_location = urlutils.join_segment_parameters(this_url,
6125
{"branch": urlutils.escape(to_location)})
6127
to_location = urlutils.join(
6128
this_url, '..', urlutils.escape(to_location))
6129
to_branch = branch.bzrdir.sprout(to_location,
6130
possible_transports=[branch.bzrdir.root_transport],
6131
source_branch=branch).open_branch()
6133
# Perhaps it's a colocated branch?
6135
to_branch = control_dir.open_branch(to_location)
6136
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6138
to_branch = Branch.open(to_location)
6139
except errors.NotBranchError:
6140
this_url = self._get_branch_location(control_dir)
6141
to_branch = Branch.open(
6143
this_url, '..', urlutils.escape(to_location)))
6144
if revision is not None:
6145
revision = revision.as_revision_id(to_branch)
6146
switch.switch(control_dir, to_branch, force, revision_id=revision)
6147
if had_explicit_nick:
6148
branch = control_dir.open_branch() #get the new branch!
6149
branch.nick = to_branch.nick
6150
note(gettext('Switched to branch: %s'),
6151
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6153
def _get_branch_location(self, control_dir):
6154
"""Return location of branch for this control dir."""
6156
this_branch = control_dir.open_branch()
6157
# This may be a heavy checkout, where we want the master branch
6158
master_location = this_branch.get_bound_location()
6159
if master_location is not None:
6160
return master_location
6161
# If not, use a local sibling
6162
return this_branch.base
6163
except errors.NotBranchError:
6164
format = control_dir.find_branch_format()
6165
if getattr(format, 'get_reference', None) is not None:
6166
return format.get_reference(control_dir)
6168
return control_dir.root_transport.base
6171
class cmd_view(Command):
6172
__doc__ = """Manage filtered views.
6174
Views provide a mask over the tree so that users can focus on
6175
a subset of a tree when doing their work. After creating a view,
6176
commands that support a list of files - status, diff, commit, etc -
6177
effectively have that list of files implicitly given each time.
6178
An explicit list of files can still be given but those files
6179
must be within the current view.
6181
In most cases, a view has a short life-span: it is created to make
6182
a selected change and is deleted once that change is committed.
6183
At other times, you may wish to create one or more named views
6184
and switch between them.
6186
To disable the current view without deleting it, you can switch to
6187
the pseudo view called ``off``. This can be useful when you need
6188
to see the whole tree for an operation or two (e.g. merge) but
6189
want to switch back to your view after that.
6192
To define the current view::
6194
bzr view file1 dir1 ...
6196
To list the current view::
6200
To delete the current view::
6204
To disable the current view without deleting it::
6206
bzr view --switch off
6208
To define a named view and switch to it::
6210
bzr view --name view-name file1 dir1 ...
6212
To list a named view::
6214
bzr view --name view-name
6216
To delete a named view::
6218
bzr view --name view-name --delete
6220
To switch to a named view::
6222
bzr view --switch view-name
6224
To list all views defined::
6228
To delete all views::
6230
bzr view --delete --all
6234
takes_args = ['file*']
6237
help='Apply list or delete action to all views.',
6240
help='Delete the view.',
6243
help='Name of the view to define, list or delete.',
6247
help='Name of the view to switch to.',
6252
def run(self, file_list,
6258
tree, file_list = WorkingTree.open_containing_paths(file_list,
6260
current_view, view_dict = tree.views.get_view_info()
6265
raise errors.BzrCommandError(gettext(
6266
"Both --delete and a file list specified"))
6268
raise errors.BzrCommandError(gettext(
6269
"Both --delete and --switch specified"))
6271
tree.views.set_view_info(None, {})
6272
self.outf.write(gettext("Deleted all views.\n"))
6274
raise errors.BzrCommandError(gettext("No current view to delete"))
6276
tree.views.delete_view(name)
6277
self.outf.write(gettext("Deleted '%s' view.\n") % name)
6280
raise errors.BzrCommandError(gettext(
6281
"Both --switch and a file list specified"))
6283
raise errors.BzrCommandError(gettext(
6284
"Both --switch and --all specified"))
6285
elif switch == 'off':
6286
if current_view is None:
6287
raise errors.BzrCommandError(gettext("No current view to disable"))
6288
tree.views.set_view_info(None, view_dict)
6289
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
6291
tree.views.set_view_info(switch, view_dict)
6292
view_str = views.view_display_str(tree.views.lookup_view())
6293
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6296
self.outf.write(gettext('Views defined:\n'))
6297
for view in sorted(view_dict):
6298
if view == current_view:
6302
view_str = views.view_display_str(view_dict[view])
6303
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6305
self.outf.write(gettext('No views defined.\n'))
6308
# No name given and no current view set
6311
raise errors.BzrCommandError(gettext(
6312
"Cannot change the 'off' pseudo view"))
6313
tree.views.set_view(name, sorted(file_list))
6314
view_str = views.view_display_str(tree.views.lookup_view())
6315
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6319
# No name given and no current view set
6320
self.outf.write(gettext('No current view.\n'))
6322
view_str = views.view_display_str(tree.views.lookup_view(name))
6323
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6326
class cmd_hooks(Command):
6327
__doc__ = """Show hooks."""
6332
for hook_key in sorted(hooks.known_hooks.keys()):
6333
some_hooks = hooks.known_hooks_key_to_object(hook_key)
6334
self.outf.write("%s:\n" % type(some_hooks).__name__)
6335
for hook_name, hook_point in sorted(some_hooks.items()):
6336
self.outf.write(" %s:\n" % (hook_name,))
6337
found_hooks = list(hook_point)
6339
for hook in found_hooks:
6340
self.outf.write(" %s\n" %
6341
(some_hooks.get_hook_name(hook),))
6343
self.outf.write(gettext(" <no hooks installed>\n"))
6346
class cmd_remove_branch(Command):
6347
__doc__ = """Remove a branch.
6349
This will remove the branch from the specified location but
6350
will keep any working tree or repository in place.
6354
Remove the branch at repo/trunk::
6356
bzr remove-branch repo/trunk
6360
takes_args = ["location?"]
6362
aliases = ["rmbranch"]
6364
def run(self, location=None):
6365
if location is None:
6367
branch = Branch.open_containing(location)[0]
6368
branch.bzrdir.destroy_branch()
6371
class cmd_shelve(Command):
6372
__doc__ = """Temporarily set aside some changes from the current tree.
6374
Shelve allows you to temporarily put changes you've made "on the shelf",
6375
ie. out of the way, until a later time when you can bring them back from
6376
the shelf with the 'unshelve' command. The changes are stored alongside
6377
your working tree, and so they aren't propagated along with your branch nor
6378
will they survive its deletion.
6380
If shelve --list is specified, previously-shelved changes are listed.
6382
Shelve is intended to help separate several sets of changes that have
6383
been inappropriately mingled. If you just want to get rid of all changes
6384
and you don't need to restore them later, use revert. If you want to
6385
shelve all text changes at once, use shelve --all.
6387
If filenames are specified, only the changes to those files will be
6388
shelved. Other files will be left untouched.
6390
If a revision is specified, changes since that revision will be shelved.
6392
You can put multiple items on the shelf, and by default, 'unshelve' will
6393
restore the most recently shelved changes.
6395
For complicated changes, it is possible to edit the changes in a separate
6396
editor program to decide what the file remaining in the working copy
6397
should look like. To do this, add the configuration option
6399
change_editor = PROGRAM @new_path @old_path
6401
where @new_path is replaced with the path of the new version of the
6402
file and @old_path is replaced with the path of the old version of
6403
the file. The PROGRAM should save the new file with the desired
6404
contents of the file in the working tree.
6408
takes_args = ['file*']
6413
Option('all', help='Shelve all changes.'),
6415
RegistryOption('writer', 'Method to use for writing diffs.',
6416
bzrlib.option.diff_writer_registry,
6417
value_switches=True, enum_switch=False),
6419
Option('list', help='List shelved changes.'),
6421
help='Destroy removed changes instead of shelving them.'),
6423
_see_also = ['unshelve', 'configuration']
6425
def run(self, revision=None, all=False, file_list=None, message=None,
6426
writer=None, list=False, destroy=False, directory=None):
6428
return self.run_for_list(directory=directory)
6429
from bzrlib.shelf_ui import Shelver
6431
writer = bzrlib.option.diff_writer_registry.get()
6433
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6434
file_list, message, destroy=destroy, directory=directory)
6439
except errors.UserAbort:
6442
def run_for_list(self, directory=None):
6443
if directory is None:
6445
tree = WorkingTree.open_containing(directory)[0]
6446
self.add_cleanup(tree.lock_read().unlock)
6447
manager = tree.get_shelf_manager()
6448
shelves = manager.active_shelves()
6449
if len(shelves) == 0:
6450
note(gettext('No shelved changes.'))
6452
for shelf_id in reversed(shelves):
6453
message = manager.get_metadata(shelf_id).get('message')
6455
message = '<no message>'
6456
self.outf.write('%3d: %s\n' % (shelf_id, message))
6460
class cmd_unshelve(Command):
6461
__doc__ = """Restore shelved changes.
6463
By default, the most recently shelved changes are restored. However if you
6464
specify a shelf by id those changes will be restored instead. This works
6465
best when the changes don't depend on each other.
6468
takes_args = ['shelf_id?']
6471
RegistryOption.from_kwargs(
6472
'action', help="The action to perform.",
6473
enum_switch=False, value_switches=True,
6474
apply="Apply changes and remove from the shelf.",
6475
dry_run="Show changes, but do not apply or remove them.",
6476
preview="Instead of unshelving the changes, show the diff that "
6477
"would result from unshelving.",
6478
delete_only="Delete changes without applying them.",
6479
keep="Apply changes but don't delete them.",
6482
_see_also = ['shelve']
6484
def run(self, shelf_id=None, action='apply', directory=u'.'):
6485
from bzrlib.shelf_ui import Unshelver
6486
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
6490
unshelver.tree.unlock()
6493
class cmd_clean_tree(Command):
6494
__doc__ = """Remove unwanted files from working tree.
6496
By default, only unknown files, not ignored files, are deleted. Versioned
6497
files are never deleted.
6499
Another class is 'detritus', which includes files emitted by bzr during
6500
normal operations and selftests. (The value of these files decreases with
6503
If no options are specified, unknown files are deleted. Otherwise, option
6504
flags are respected, and may be combined.
6506
To check what clean-tree will do, use --dry-run.
6508
takes_options = ['directory',
6509
Option('ignored', help='Delete all ignored files.'),
6510
Option('detritus', help='Delete conflict files, merge and revert'
6511
' backups, and failed selftest dirs.'),
6513
help='Delete files unknown to bzr (default).'),
6514
Option('dry-run', help='Show files to delete instead of'
6516
Option('force', help='Do not prompt before deleting.')]
6517
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6518
force=False, directory=u'.'):
6519
from bzrlib.clean_tree import clean_tree
6520
if not (unknown or ignored or detritus):
6524
clean_tree(directory, unknown=unknown, ignored=ignored,
6525
detritus=detritus, dry_run=dry_run, no_prompt=force)
6528
class cmd_reference(Command):
6529
__doc__ = """list, view and set branch locations for nested trees.
6531
If no arguments are provided, lists the branch locations for nested trees.
6532
If one argument is provided, display the branch location for that tree.
6533
If two arguments are provided, set the branch location for that tree.
6538
takes_args = ['path?', 'location?']
6540
def run(self, path=None, location=None):
6542
if path is not None:
6544
tree, branch, relpath =(
6545
controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6546
if path is not None:
6549
tree = branch.basis_tree()
6551
info = branch._get_all_reference_info().iteritems()
6552
self._display_reference_info(tree, branch, info)
6554
file_id = tree.path2id(path)
6556
raise errors.NotVersionedError(path)
6557
if location is None:
6558
info = [(file_id, branch.get_reference_info(file_id))]
6559
self._display_reference_info(tree, branch, info)
6561
branch.set_reference_info(file_id, path, location)
6563
def _display_reference_info(self, tree, branch, info):
6565
for file_id, (path, location) in info:
6567
path = tree.id2path(file_id)
6568
except errors.NoSuchId:
6570
ref_list.append((path, location))
6571
for path, location in sorted(ref_list):
6572
self.outf.write('%s %s\n' % (path, location))
6575
class cmd_export_pot(Command):
6576
__doc__ = """Export command helps and error messages in po format."""
6579
takes_options = [Option('plugin',
6580
help='Export help text from named command '\
6581
'(defaults to all built in commands).',
6583
Option('include-duplicates',
6584
help='Output multiple copies of the same msgid '
6585
'string if it appears more than once.'),
6588
def run(self, plugin=None, include_duplicates=False):
6589
from bzrlib.export_pot import export_pot
6590
export_pot(self.outf, plugin, include_duplicates)
6593
def _register_lazy_builtins():
6594
# register lazy builtins from other modules; called at startup and should
6595
# be only called once.
6596
for (name, aliases, module_name) in [
6597
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6598
('cmd_config', [], 'bzrlib.config'),
6599
('cmd_dpush', [], 'bzrlib.foreign'),
6600
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6601
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6602
('cmd_conflicts', [], 'bzrlib.conflicts'),
6603
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6604
('cmd_verify_signatures', [],
6605
'bzrlib.commit_signature_commands'),
6606
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6608
builtin_command_registry.register_lazy(name, aliases, module_name)