133
228
Text has changed since the previous revision.
136
Nothing about this file has changed since the previous revision.
137
Only shown with --all.
231
File kind has been changed (e.g. from file to directory).
140
234
Not versioned and not matching an ignore pattern.
142
To see ignored files use 'bzr ignored'. For details in the
236
Additionally for directories, symlinks and files with a changed
237
executable bit, Bazaar indicates their type using a trailing
238
character: '/', '@' or '*' respectively. These decorations can be
239
disabled using the '--no-classify' option.
241
To see ignored files use 'bzr ignored'. For details on the
143
242
changes to file texts, use 'bzr diff'.
244
Note that --short or -S gives status flags for each item, similar
245
to Subversion's status command. To get output similar to svn -q,
145
248
If no arguments are specified, the status of the entire working
146
249
directory is shown. Otherwise, only the status of the specified
147
250
files or directories is reported. If a directory is given, status
148
251
is reported for everything inside that directory.
150
If a revision argument is given, the status is calculated against
151
that revision, or between two revisions if two are provided.
253
Before merges are committed, the pending merge tip revisions are
254
shown. To see all pending merge revisions, use the -v option.
255
To skip the display of pending merge information altogether, use
256
the no-pending option or specify a file/directory.
258
To compare the working directory to a specific revision, pass a
259
single revision to the revision argument.
261
To see which files have changed in a specific revision, or between
262
two revisions, pass a revision range to the revision argument.
263
This will produce the same results as calling 'bzr diff --summarize'.
154
266
# TODO: --no-recurse, --recurse options
156
268
takes_args = ['file*']
157
takes_options = ['all', 'show-ids', 'revision']
269
takes_options = ['show-ids', 'revision', 'change', 'verbose',
270
Option('short', help='Use short status indicators.',
272
Option('versioned', help='Only show versioned files.',
274
Option('no-pending', help='Don\'t show pending merges.',
276
Option('no-classify',
277
help='Do not mark object type using indicator.',
158
280
aliases = ['st', 'stat']
160
282
encoding_type = 'replace'
283
_see_also = ['diff', 'revert', 'status-flags']
163
def run(self, all=False, show_ids=False, file_list=None, revision=None):
286
def run(self, show_ids=False, file_list=None, revision=None, short=False,
287
versioned=False, no_pending=False, verbose=False,
164
289
from bzrlib.status import show_tree_status
166
tree, file_list = tree_files(file_list)
168
show_tree_status(tree, show_unchanged=all, show_ids=show_ids,
169
specific_files=file_list, revision=revision,
291
if revision and len(revision) > 2:
292
raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
293
' one or two revision specifiers'))
295
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
296
# Avoid asking for specific files when that is not needed.
297
if relfile_list == ['']:
299
# Don't disable pending merges for full trees other than '.'.
300
if file_list == ['.']:
302
# A specific path within a tree was given.
303
elif relfile_list is not None:
305
show_tree_status(tree, show_ids=show_ids,
306
specific_files=relfile_list, revision=revision,
307
to_file=self.outf, short=short, versioned=versioned,
308
show_pending=(not no_pending), verbose=verbose,
309
classify=not no_classify)
173
312
class cmd_cat_revision(Command):
174
"""Write out metadata for a revision.
313
__doc__ = """Write out metadata for a revision.
176
315
The revision to print can either be specified by a specific
177
316
revision identifier, or you can use --revision.
181
320
takes_args = ['revision_id?']
182
takes_options = ['revision']
321
takes_options = ['directory', 'revision']
183
322
# cat-revision is more for frontends so should be exact
184
323
encoding = 'strict'
325
def print_revision(self, revisions, revid):
326
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
327
record = stream.next()
328
if record.storage_kind == 'absent':
329
raise errors.NoSuchRevision(revisions, revid)
330
revtext = record.get_bytes_as('fulltext')
331
self.outf.write(revtext.decode('utf-8'))
187
def run(self, revision_id=None, revision=None):
334
def run(self, revision_id=None, revision=None, directory=u'.'):
189
335
if revision_id is not None and revision is not None:
190
raise BzrCommandError('You can only supply one of revision_id or --revision')
336
raise errors.BzrCommandError(gettext('You can only supply one of'
337
' revision_id or --revision'))
191
338
if revision_id is None and revision is None:
192
raise BzrCommandError('You must supply either --revision or a revision_id')
193
b = WorkingTree.open_containing(u'.')[0].branch
195
# TODO: jam 20060112 should cat-revision always output utf-8?
196
if revision_id is not None:
197
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
198
elif revision is not None:
201
raise BzrCommandError('You cannot specify a NULL revision.')
202
revno, rev_id = rev.in_history(b)
203
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
339
raise errors.BzrCommandError(gettext('You must supply either'
340
' --revision or a revision_id'))
342
b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
344
revisions = b.repository.revisions
345
if revisions is None:
346
raise errors.BzrCommandError(gettext('Repository %r does not support '
347
'access to raw revision texts'))
349
b.repository.lock_read()
351
# TODO: jam 20060112 should cat-revision always output utf-8?
352
if revision_id is not None:
353
revision_id = osutils.safe_revision_id(revision_id, warn=False)
355
self.print_revision(revisions, revision_id)
356
except errors.NoSuchRevision:
357
msg = gettext("The repository {0} contains no revision {1}.").format(
358
b.repository.base, revision_id)
359
raise errors.BzrCommandError(msg)
360
elif revision is not None:
363
raise errors.BzrCommandError(
364
gettext('You cannot specify a NULL revision.'))
365
rev_id = rev.as_revision_id(b)
366
self.print_revision(revisions, rev_id)
368
b.repository.unlock()
371
class cmd_dump_btree(Command):
372
__doc__ = """Dump the contents of a btree index file to stdout.
374
PATH is a btree index file, it can be any URL. This includes things like
375
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
377
By default, the tuples stored in the index file will be displayed. With
378
--raw, we will uncompress the pages, but otherwise display the raw bytes
382
# TODO: Do we want to dump the internal nodes as well?
383
# TODO: It would be nice to be able to dump the un-parsed information,
384
# rather than only going through iter_all_entries. However, this is
385
# good enough for a start
387
encoding_type = 'exact'
388
takes_args = ['path']
389
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
390
' rather than the parsed tuples.'),
393
def run(self, path, raw=False):
394
dirname, basename = osutils.split(path)
395
t = transport.get_transport(dirname)
397
self._dump_raw_bytes(t, basename)
399
self._dump_entries(t, basename)
401
def _get_index_and_bytes(self, trans, basename):
402
"""Create a BTreeGraphIndex and raw bytes."""
403
bt = btree_index.BTreeGraphIndex(trans, basename, None)
404
bytes = trans.get_bytes(basename)
405
bt._file = cStringIO.StringIO(bytes)
406
bt._size = len(bytes)
409
def _dump_raw_bytes(self, trans, basename):
412
# We need to parse at least the root node.
413
# This is because the first page of every row starts with an
414
# uncompressed header.
415
bt, bytes = self._get_index_and_bytes(trans, basename)
416
for page_idx, page_start in enumerate(xrange(0, len(bytes),
417
btree_index._PAGE_SIZE)):
418
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
419
page_bytes = bytes[page_start:page_end]
421
self.outf.write('Root node:\n')
422
header_end, data = bt._parse_header_from_bytes(page_bytes)
423
self.outf.write(page_bytes[:header_end])
425
self.outf.write('\nPage %d\n' % (page_idx,))
426
if len(page_bytes) == 0:
427
self.outf.write('(empty)\n');
429
decomp_bytes = zlib.decompress(page_bytes)
430
self.outf.write(decomp_bytes)
431
self.outf.write('\n')
433
def _dump_entries(self, trans, basename):
435
st = trans.stat(basename)
436
except errors.TransportNotPossible:
437
# We can't stat, so we'll fake it because we have to do the 'get()'
439
bt, _ = self._get_index_and_bytes(trans, basename)
441
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
442
for node in bt.iter_all_entries():
443
# Node is made up of:
444
# (index, key, value, [references])
448
refs_as_tuples = None
450
refs_as_tuples = static_tuple.as_tuples(refs)
451
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
452
self.outf.write('%s\n' % (as_tuple,))
455
class cmd_remove_tree(Command):
456
__doc__ = """Remove the working tree from a given branch/checkout.
458
Since a lightweight checkout is little more than a working tree
459
this will refuse to run against one.
461
To re-create the working tree, use "bzr checkout".
463
_see_also = ['checkout', 'working-trees']
464
takes_args = ['location*']
467
help='Remove the working tree even if it has '
468
'uncommitted or shelved changes.'),
471
def run(self, location_list, force=False):
472
if not location_list:
475
for location in location_list:
476
d = bzrdir.BzrDir.open(location)
479
working = d.open_workingtree()
480
except errors.NoWorkingTree:
481
raise errors.BzrCommandError(gettext("No working tree to remove"))
482
except errors.NotLocalUrl:
483
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
484
" of a remote path"))
486
if (working.has_changes()):
487
raise errors.UncommittedChanges(working)
488
if working.get_shelf_manager().last_shelf() is not None:
489
raise errors.ShelvedChanges(working)
491
if working.user_url != working.branch.user_url:
492
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
493
" from a lightweight checkout"))
495
d.destroy_workingtree()
498
class cmd_repair_workingtree(Command):
499
__doc__ = """Reset the working tree state file.
501
This is not meant to be used normally, but more as a way to recover from
502
filesystem corruption, etc. This rebuilds the working inventory back to a
503
'known good' state. Any new modifications (adding a file, renaming, etc)
504
will be lost, though modified files will still be detected as such.
506
Most users will want something more like "bzr revert" or "bzr update"
507
unless the state file has become corrupted.
509
By default this attempts to recover the current state by looking at the
510
headers of the state file. If the state file is too corrupted to even do
511
that, you can supply --revision to force the state of the tree.
514
takes_options = ['revision', 'directory',
516
help='Reset the tree even if it doesn\'t appear to be'
521
def run(self, revision=None, directory='.', force=False):
522
tree, _ = WorkingTree.open_containing(directory)
523
self.add_cleanup(tree.lock_tree_write().unlock)
527
except errors.BzrError:
528
pass # There seems to be a real error here, so we'll reset
531
raise errors.BzrCommandError(gettext(
532
'The tree does not appear to be corrupt. You probably'
533
' want "bzr revert" instead. Use "--force" if you are'
534
' sure you want to reset the working tree.'))
538
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
540
tree.reset_state(revision_ids)
541
except errors.BzrError, e:
542
if revision_ids is None:
543
extra = (gettext(', the header appears corrupt, try passing -r -1'
544
' to set the state to the last commit'))
547
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
206
550
class cmd_revno(Command):
207
"""Show current revision number.
551
__doc__ = """Show current revision number.
209
553
This is equal to the number of revisions on this branch.
212
557
takes_args = ['location?']
559
Option('tree', help='Show revno of working tree'),
215
def run(self, location=u'.'):
216
self.outf.write(str(Branch.open_containing(location)[0].revno()))
217
self.outf.write('\n')
563
def run(self, tree=False, location=u'.'):
566
wt = WorkingTree.open_containing(location)[0]
567
self.add_cleanup(wt.lock_read().unlock)
568
except (errors.NoWorkingTree, errors.NotLocalUrl):
569
raise errors.NoWorkingTree(location)
570
revid = wt.last_revision()
572
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
573
except errors.NoSuchRevision:
575
revno = ".".join(str(n) for n in revno_t)
577
b = Branch.open_containing(location)[0]
578
self.add_cleanup(b.lock_read().unlock)
581
self.outf.write(str(revno) + '\n')
220
584
class cmd_revision_info(Command):
221
"""Show revision number and revision id for a given revision identifier.
585
__doc__ = """Show revision number and revision id for a given revision identifier.
224
588
takes_args = ['revision_info*']
225
takes_options = ['revision']
591
custom_help('directory',
592
help='Branch to examine, '
593
'rather than the one containing the working directory.'),
594
Option('tree', help='Show revno of working tree'),
228
def run(self, revision=None, revision_info_list=[]):
598
def run(self, revision=None, directory=u'.', tree=False,
599
revision_info_list=[]):
602
wt = WorkingTree.open_containing(directory)[0]
604
self.add_cleanup(wt.lock_read().unlock)
605
except (errors.NoWorkingTree, errors.NotLocalUrl):
607
b = Branch.open_containing(directory)[0]
608
self.add_cleanup(b.lock_read().unlock)
231
610
if revision is not None:
232
revs.extend(revision)
611
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
233
612
if revision_info_list is not None:
234
for rev in revision_info_list:
235
revs.append(RevisionSpec(rev))
237
raise BzrCommandError('You must supply a revision identifier')
239
b = WorkingTree.open_containing(u'.')[0].branch
242
revinfo = rev.in_history(b)
243
if revinfo.revno is None:
244
print ' %s' % revinfo.rev_id
613
for rev_str in revision_info_list:
614
rev_spec = RevisionSpec.from_string(rev_str)
615
revision_ids.append(rev_spec.as_revision_id(b))
616
# No arguments supplied, default to the last revision
617
if len(revision_ids) == 0:
620
raise errors.NoWorkingTree(directory)
621
revision_ids.append(wt.last_revision())
246
print '%4d %s' % (revinfo.revno, revinfo.rev_id)
623
revision_ids.append(b.last_revision())
627
for revision_id in revision_ids:
629
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
630
revno = '.'.join(str(i) for i in dotted_revno)
631
except errors.NoSuchRevision:
633
maxlen = max(maxlen, len(revno))
634
revinfos.append([revno, revision_id])
638
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
249
641
class cmd_add(Command):
250
"""Add specified files or directories.
642
__doc__ = """Add specified files or directories.
252
644
In non-recursive mode, all the named items are added, regardless
253
645
of whether they were previously ignored. A warning is given if
367
828
class cmd_mv(Command):
368
"""Move or rename a file.
829
__doc__ = """Move or rename a file.
371
832
bzr mv OLDNAME NEWNAME
372
834
bzr mv SOURCE... DESTINATION
374
836
If the last argument is a versioned directory, all the other names
375
837
are moved into it. Otherwise, there must be exactly two arguments
376
and the file is changed to a new name, which must not already exist.
838
and the file is changed to a new name.
840
If OLDNAME does not exist on the filesystem but is versioned and
841
NEWNAME does exist on the filesystem but is not versioned, mv
842
assumes that the file has been manually moved and only updates
843
its internal inventory to reflect that change.
844
The same is valid when moving many SOURCE files to a DESTINATION.
378
846
Files cannot be moved between branches.
381
849
takes_args = ['names*']
850
takes_options = [Option("after", help="Move only the bzr identifier"
851
" of the file, because the file has already been moved."),
852
Option('auto', help='Automatically guess renames.'),
853
Option('dry-run', help='Avoid making changes when guessing renames.'),
382
855
aliases = ['move', 'rename']
383
856
encoding_type = 'replace'
385
def run(self, names_list):
858
def run(self, names_list, after=False, auto=False, dry_run=False):
860
return self.run_auto(names_list, after, dry_run)
862
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
863
if names_list is None:
386
865
if len(names_list) < 2:
387
raise BzrCommandError("missing file argument")
388
tree, rel_names = tree_files(names_list)
390
if os.path.isdir(names_list[-1]):
866
raise errors.BzrCommandError(gettext("missing file argument"))
867
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
868
self.add_cleanup(tree.lock_tree_write().unlock)
869
self._run(tree, names_list, rel_names, after)
871
def run_auto(self, names_list, after, dry_run):
872
if names_list is not None and len(names_list) > 1:
873
raise errors.BzrCommandError(gettext('Only one path may be specified to'
876
raise errors.BzrCommandError(gettext('--after cannot be specified with'
878
work_tree, file_list = WorkingTree.open_containing_paths(
879
names_list, default_directory='.')
880
self.add_cleanup(work_tree.lock_tree_write().unlock)
881
rename_map.RenameMap.guess_renames(work_tree, dry_run)
883
def _run(self, tree, names_list, rel_names, after):
884
into_existing = osutils.isdir(names_list[-1])
885
if into_existing and len(names_list) == 2:
887
# a. case-insensitive filesystem and change case of dir
888
# b. move directory after the fact (if the source used to be
889
# a directory, but now doesn't exist in the working tree
890
# and the target is an existing directory, just rename it)
891
if (not tree.case_sensitive
892
and rel_names[0].lower() == rel_names[1].lower()):
893
into_existing = False
896
# 'fix' the case of a potential 'from'
897
from_id = tree.path2id(
898
tree.get_canonical_inventory_path(rel_names[0]))
899
if (not osutils.lexists(names_list[0]) and
900
from_id and inv.get_file_kind(from_id) == "directory"):
901
into_existing = False
391
904
# move into existing directory
392
for pair in tree.move(rel_names[:-1], rel_names[-1]):
393
self.outf.write("%s => %s\n" % pair)
905
# All entries reference existing inventory items, so fix them up
906
# for cicp file-systems.
907
rel_names = tree.get_canonical_inventory_paths(rel_names)
908
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
910
self.outf.write("%s => %s\n" % (src, dest))
395
912
if len(names_list) != 2:
396
raise BzrCommandError('to mv multiple files the destination '
397
'must be a versioned directory')
398
tree.rename_one(rel_names[0], rel_names[1])
399
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
913
raise errors.BzrCommandError(gettext('to mv multiple files the'
914
' destination must be a versioned'
917
# for cicp file-systems: the src references an existing inventory
919
src = tree.get_canonical_inventory_path(rel_names[0])
920
# Find the canonical version of the destination: In all cases, the
921
# parent of the target must be in the inventory, so we fetch the
922
# canonical version from there (we do not always *use* the
923
# canonicalized tail portion - we may be attempting to rename the
925
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
926
dest_parent = osutils.dirname(canon_dest)
927
spec_tail = osutils.basename(rel_names[1])
928
# For a CICP file-system, we need to avoid creating 2 inventory
929
# entries that differ only by case. So regardless of the case
930
# we *want* to use (ie, specified by the user or the file-system),
931
# we must always choose to use the case of any existing inventory
932
# items. The only exception to this is when we are attempting a
933
# case-only rename (ie, canonical versions of src and dest are
935
dest_id = tree.path2id(canon_dest)
936
if dest_id is None or tree.path2id(src) == dest_id:
937
# No existing item we care about, so work out what case we
938
# are actually going to use.
940
# If 'after' is specified, the tail must refer to a file on disk.
942
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
944
# pathjoin with an empty tail adds a slash, which breaks
946
dest_parent_fq = tree.basedir
948
dest_tail = osutils.canonical_relpath(
950
osutils.pathjoin(dest_parent_fq, spec_tail))
952
# not 'after', so case as specified is used
953
dest_tail = spec_tail
955
# Use the existing item so 'mv' fails with AlreadyVersioned.
956
dest_tail = os.path.basename(canon_dest)
957
dest = osutils.pathjoin(dest_parent, dest_tail)
958
mutter("attempting to move %s => %s", src, dest)
959
tree.rename_one(src, dest, after=after)
961
self.outf.write("%s => %s\n" % (src, dest))
402
964
class cmd_pull(Command):
403
"""Turn this branch into a mirror of another branch.
965
__doc__ = """Turn this branch into a mirror of another branch.
405
This command only works on branches that have not diverged. Branches are
406
considered diverged if the destination branch's most recent commit is one
407
that has not been merged (directly or indirectly) into the parent.
967
By default, this command only works on branches that have not diverged.
968
Branches are considered diverged if the destination branch's most recent
969
commit is one that has not been merged (directly or indirectly) into the
409
972
If branches have diverged, you can use 'bzr merge' to integrate the changes
410
973
from one into the other. Once one branch has merged, the other should
411
974
be able to pull it again.
413
If branches have diverged, you can use 'bzr merge' to pull the text changes
414
from one into the other. Once one branch has merged, the other should
415
be able to pull it again.
417
If you want to forget your local changes and just update your branch to
418
match the remote one, use pull --overwrite.
420
If there is no default location set, the first pull will set it. After
421
that, you can omit the location to use the default. To change the
422
default, use --remember.
976
If you want to replace your local changes and just want your branch to
977
match the remote one, use pull --overwrite. This will work even if the two
978
branches have diverged.
980
If there is no default location set, the first pull will set it (use
981
--no-remember to avoid setting it). After that, you can omit the
982
location to use the default. To change the default, use --remember. The
983
value will only be saved if the remote location can be accessed.
985
Note: The location can be specified either in the form of a branch,
986
or in the form of a path to a file containing a merge directive generated
425
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
990
_see_also = ['push', 'update', 'status-flags', 'send']
991
takes_options = ['remember', 'overwrite', 'revision',
992
custom_help('verbose',
993
help='Show logs of pulled revisions.'),
994
custom_help('directory',
995
help='Branch to pull into, '
996
'rather than the one containing the working directory.'),
998
help="Perform a local pull in a bound "
999
"branch. Local pulls are not applied to "
1000
"the master branch."
1003
help="Show base revision text in conflicts.")
426
1005
takes_args = ['location?']
427
1006
encoding_type = 'replace'
429
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
1008
def run(self, location=None, remember=None, overwrite=False,
1009
revision=None, verbose=False,
1010
directory=None, local=False,
430
1012
# FIXME: too much stuff is in the command class
1015
if directory is None:
432
tree_to = WorkingTree.open_containing(u'.')[0]
1018
tree_to = WorkingTree.open_containing(directory)[0]
433
1019
branch_to = tree_to.branch
434
except NoWorkingTree:
1020
self.add_cleanup(tree_to.lock_write().unlock)
1021
except errors.NoWorkingTree:
436
branch_to = Branch.open_containing(u'.')[0]
1023
branch_to = Branch.open_containing(directory)[0]
1024
self.add_cleanup(branch_to.lock_write().unlock)
1026
if tree_to is None and show_base:
1027
raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1029
if local and not branch_to.get_bound_location():
1030
raise errors.LocalRequiresBoundBranch()
1032
possible_transports = []
1033
if location is not None:
1035
mergeable = bundle.read_mergeable_from_url(location,
1036
possible_transports=possible_transports)
1037
except errors.NotABundle:
437
1040
stored_loc = branch_to.get_parent()
438
1041
if location is None:
439
1042
if stored_loc is None:
440
raise BzrCommandError("No pull location known or specified.")
1043
raise errors.BzrCommandError(gettext("No pull location known or"
442
1046
display_url = urlutils.unescape_for_display(stored_loc,
443
1047
self.outf.encoding)
444
self.outf.write("Using saved location: %s\n" % display_url)
1049
self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
445
1050
location = stored_loc
447
branch_from = Branch.open(location)
449
if branch_to.get_parent() is None or remember:
450
branch_to.set_parent(branch_from.base)
454
elif len(revision) == 1:
455
rev_id = revision[0].in_history(branch_from).rev_id
1052
revision = _get_one_revision('pull', revision)
1053
if mergeable is not None:
1054
if revision is not None:
1055
raise errors.BzrCommandError(gettext(
1056
'Cannot use -r with merge directives or bundles'))
1057
mergeable.install_revisions(branch_to.repository)
1058
base_revision_id, revision_id, verified = \
1059
mergeable.get_merge_request(branch_to.repository)
1060
branch_from = branch_to
457
raise BzrCommandError('bzr pull --revision takes one value.')
459
old_rh = branch_to.revision_history()
1062
branch_from = Branch.open(location,
1063
possible_transports=possible_transports)
1064
self.add_cleanup(branch_from.lock_read().unlock)
1065
# Remembers if asked explicitly or no previous location is set
1067
or (remember is None and branch_to.get_parent() is None)):
1068
branch_to.set_parent(branch_from.base)
1070
if revision is not None:
1071
revision_id = revision.as_revision_id(branch_from)
460
1073
if tree_to is not None:
461
count = tree_to.pull(branch_from, overwrite, rev_id)
1074
view_info = _get_view_info_for_change_reporter(tree_to)
1075
change_reporter = delta._ChangeReporter(
1076
unversioned_filter=tree_to.is_ignored,
1077
view_info=view_info)
1078
result = tree_to.pull(
1079
branch_from, overwrite, revision_id, change_reporter,
1080
local=local, show_base=show_base)
463
count = branch_to.pull(branch_from, overwrite, rev_id)
464
note('%d revision(s) pulled.' % (count,))
1082
result = branch_to.pull(
1083
branch_from, overwrite, revision_id, local=local)
467
new_rh = branch_to.revision_history()
470
from bzrlib.log import show_changed_revisions
471
show_changed_revisions(branch_to, old_rh, new_rh,
1085
result.report(self.outf)
1086
if verbose and result.old_revid != result.new_revid:
1087
log.show_branch_change(
1088
branch_to, self.outf, result.old_revno,
1090
if getattr(result, 'tag_conflicts', None):
475
1096
class cmd_push(Command):
476
"""Update a mirror of this branch.
1097
__doc__ = """Update a mirror of this branch.
478
1099
The target branch will not have its working tree populated because this
479
1100
is both expensive, and is not supported on remote file systems.
481
1102
Some smart servers or protocols *may* put the working tree in place in
488
1109
If branches have diverged, you can use 'bzr push --overwrite' to replace
489
1110
the other branch completely, discarding its unmerged changes.
491
1112
If you want to ensure you have the different changes in the other branch,
492
1113
do a merge (see bzr help merge) from the other branch, and commit that.
493
1114
After that you will be able to do a push without '--overwrite'.
495
If there is no default push location set, the first push will set it.
496
After that, you can omit the location to use the default. To change the
497
default, use --remember.
1116
If there is no default push location set, the first push will set it (use
1117
--no-remember to avoid setting it). After that, you can omit the
1118
location to use the default. To change the default, use --remember. The
1119
value will only be saved if the remote location can be accessed.
500
takes_options = ['remember', 'overwrite', 'verbose',
501
Option('create-prefix',
502
help='Create the path leading up to the branch '
503
'if it does not already exist')]
1122
_see_also = ['pull', 'update', 'working-trees']
1123
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1124
Option('create-prefix',
1125
help='Create the path leading up to the branch '
1126
'if it does not already exist.'),
1127
custom_help('directory',
1128
help='Branch to push from, '
1129
'rather than the one containing the working directory.'),
1130
Option('use-existing-dir',
1131
help='By default push will fail if the target'
1132
' directory exists, but does not already'
1133
' have a control directory. This flag will'
1134
' allow push to proceed.'),
1136
help='Create a stacked branch that references the public location '
1137
'of the parent branch.'),
1138
Option('stacked-on',
1139
help='Create a stacked branch that refers to another branch '
1140
'for the commit history. Only the work not present in the '
1141
'referenced branch is included in the branch created.',
1144
help='Refuse to push if there are uncommitted changes in'
1145
' the working tree, --no-strict disables the check.'),
1147
help="Don't populate the working tree, even for protocols"
1148
" that support it."),
504
1150
takes_args = ['location?']
505
1151
encoding_type = 'replace'
507
def run(self, location=None, remember=False, overwrite=False,
508
create_prefix=False, verbose=False):
509
# FIXME: Way too big! Put this into a function called from the
511
from bzrlib.transport import get_transport
513
br_from = Branch.open_containing('.')[0]
514
stored_loc = br_from.get_push_location()
1153
def run(self, location=None, remember=None, overwrite=False,
1154
create_prefix=False, verbose=False, revision=None,
1155
use_existing_dir=False, directory=None, stacked_on=None,
1156
stacked=False, strict=None, no_tree=False):
1157
from bzrlib.push import _show_push_branch
1159
if directory is None:
1161
# Get the source branch
1163
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1164
# Get the tip's revision_id
1165
revision = _get_one_revision('push', revision)
1166
if revision is not None:
1167
revision_id = revision.in_history(br_from).rev_id
1170
if tree is not None and revision_id is None:
1171
tree.check_changed_or_out_of_date(
1172
strict, 'push_strict',
1173
more_error='Use --no-strict to force the push.',
1174
more_warning='Uncommitted changes will not be pushed.')
1175
# Get the stacked_on branch, if any
1176
if stacked_on is not None:
1177
stacked_on = urlutils.normalize_url(stacked_on)
1179
parent_url = br_from.get_parent()
1181
parent = Branch.open(parent_url)
1182
stacked_on = parent.get_public_branch()
1184
# I considered excluding non-http url's here, thus forcing
1185
# 'public' branches only, but that only works for some
1186
# users, so it's best to just depend on the user spotting an
1187
# error by the feedback given to them. RBC 20080227.
1188
stacked_on = parent_url
1190
raise errors.BzrCommandError(gettext(
1191
"Could not determine branch to refer to."))
1193
# Get the destination location
515
1194
if location is None:
1195
stored_loc = br_from.get_push_location()
516
1196
if stored_loc is None:
517
raise BzrCommandError("No push location known or specified.")
1197
raise errors.BzrCommandError(gettext(
1198
"No push location known or specified."))
519
1200
display_url = urlutils.unescape_for_display(stored_loc,
520
1201
self.outf.encoding)
521
self.outf.write("Using saved location: %s" % display_url)
1202
note(gettext("Using saved push location: %s") % display_url)
522
1203
location = stored_loc
524
transport = get_transport(location)
525
location_url = transport.base
526
if br_from.get_push_location() is None or remember:
527
br_from.set_push_location(location_url)
531
dir_to = bzrlib.bzrdir.BzrDir.open(location_url)
532
br_to = dir_to.open_branch()
533
except NotBranchError:
535
transport = transport.clone('..')
536
if not create_prefix:
538
relurl = transport.relpath(location_url)
539
mutter('creating directory %s => %s', location_url, relurl)
540
transport.mkdir(relurl)
542
raise BzrCommandError("Parent directory of %s "
543
"does not exist." % location)
545
current = transport.base
546
needed = [(transport, transport.relpath(location_url))]
549
transport, relpath = needed[-1]
550
transport.mkdir(relpath)
553
new_transport = transport.clone('..')
554
needed.append((new_transport,
555
new_transport.relpath(transport.base)))
556
if new_transport.base == transport.base:
557
raise BzrCommandError("Could not create "
559
dir_to = br_from.bzrdir.clone(location_url,
560
revision_id=br_from.last_revision())
561
br_to = dir_to.open_branch()
562
count = len(br_to.revision_history())
564
old_rh = br_to.revision_history()
567
tree_to = dir_to.open_workingtree()
568
except errors.NotLocalUrl:
569
warning('This transport does not update the working '
570
'tree of: %s' % (br_to.base,))
571
count = br_to.pull(br_from, overwrite)
572
except NoWorkingTree:
573
count = br_to.pull(br_from, overwrite)
575
count = tree_to.pull(br_from, overwrite)
576
except DivergedBranches:
577
raise BzrCommandError("These branches have diverged."
578
" Try a merge then push with overwrite.")
579
note('%d revision(s) pushed.' % (count,))
582
new_rh = br_to.revision_history()
585
from bzrlib.log import show_changed_revisions
586
show_changed_revisions(br_to, old_rh, new_rh,
1205
_show_push_branch(br_from, revision_id, location, self.outf,
1206
verbose=verbose, overwrite=overwrite, remember=remember,
1207
stacked_on=stacked_on, create_prefix=create_prefix,
1208
use_existing_dir=use_existing_dir, no_tree=no_tree)
590
1211
class cmd_branch(Command):
591
"""Create a new copy of a branch.
1212
__doc__ = """Create a new branch that is a copy of an existing branch.
593
1214
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
594
1215
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1216
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
1217
is derived from the FROM_LOCATION by stripping a leading scheme or drive
1218
identifier, if any. For example, "branch lp:foo-bar" will attempt to
596
1221
To retrieve the branch as of a particular revision, supply the --revision
597
1222
parameter, as in "branch foo/bar -r 5".
599
--basis is to speed up branching from remote branches. When specified, it
600
copies all the file-contents, inventory and revision data from the basis
601
branch before copying anything from the remote branch.
1224
The synonyms 'clone' and 'get' for this command are deprecated.
1227
_see_also = ['checkout']
603
1228
takes_args = ['from_location', 'to_location?']
604
takes_options = ['revision', 'basis']
1229
takes_options = ['revision',
1230
Option('hardlink', help='Hard-link working tree files where possible.'),
1231
Option('files-from', type=str,
1232
help="Get file contents from this tree."),
1234
help="Create a branch without a working-tree."),
1236
help="Switch the checkout in the current directory "
1237
"to the new branch."),
1239
help='Create a stacked branch referring to the source branch. '
1240
'The new branch will depend on the availability of the source '
1241
'branch for all operations.'),
1242
Option('standalone',
1243
help='Do not use a shared repository, even if available.'),
1244
Option('use-existing-dir',
1245
help='By default branch will fail if the target'
1246
' directory exists, but does not already'
1247
' have a control directory. This flag will'
1248
' allow branch to proceed.'),
1250
help="Bind new branch to from location."),
605
1252
aliases = ['get', 'clone']
607
def run(self, from_location, to_location=None, revision=None, basis=None):
608
from bzrlib.transport import get_transport
609
from bzrlib.osutils import rmtree
612
elif len(revision) > 1:
613
raise BzrCommandError(
614
'bzr branch --revision takes exactly 1 revision value')
616
br_from = Branch.open(from_location)
618
if e.errno == errno.ENOENT:
619
raise BzrCommandError('Source location "%s" does not'
620
' exist.' % to_location)
625
if basis is not None:
626
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
629
if len(revision) == 1 and revision[0] is not None:
630
revision_id = revision[0].in_history(br_from)[1]
632
# FIXME - wt.last_revision, fallback to branch, fall back to
633
# None or perhaps NULL_REVISION to mean copy nothing
635
revision_id = br_from.last_revision()
636
if to_location is None:
637
to_location = os.path.basename(from_location.rstrip("/\\"))
640
name = os.path.basename(to_location) + '\n'
642
to_transport = get_transport(to_location)
644
to_transport.mkdir('.')
645
except bzrlib.errors.FileExists:
646
raise BzrCommandError('Target directory "%s" already'
647
' exists.' % to_location)
648
except bzrlib.errors.NoSuchFile:
649
raise BzrCommandError('Parent of "%s" does not exist.' %
652
# preserve whatever source format we have.
653
dir = br_from.bzrdir.sprout(to_transport.base,
654
revision_id, basis_dir)
655
branch = dir.open_branch()
656
except bzrlib.errors.NoSuchRevision:
657
to_transport.delete_tree('.')
658
msg = "The branch %s has no revision %s." % (from_location, revision[0])
659
raise BzrCommandError(msg)
660
except bzrlib.errors.UnlistableBranch:
662
msg = "The branch %s cannot be used as a --basis" % (basis,)
663
raise BzrCommandError(msg)
665
branch.control_files.put_utf8('branch-name', name)
666
note('Branched %d revision(s).' % branch.revno())
1254
def run(self, from_location, to_location=None, revision=None,
1255
hardlink=False, stacked=False, standalone=False, no_tree=False,
1256
use_existing_dir=False, switch=False, bind=False,
1258
from bzrlib import switch as _mod_switch
1259
from bzrlib.tag import _merge_tags_if_possible
1260
if self.invoked_as in ['get', 'clone']:
1261
ui.ui_factory.show_user_warning(
1262
'deprecated_command',
1263
deprecated_name=self.invoked_as,
1264
recommended_name='branch',
1265
deprecated_in_version='2.4')
1266
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1268
if not (hardlink or files_from):
1269
# accelerator_tree is usually slower because you have to read N
1270
# files (no readahead, lots of seeks, etc), but allow the user to
1271
# explicitly request it
1272
accelerator_tree = None
1273
if files_from is not None and files_from != from_location:
1274
accelerator_tree = WorkingTree.open(files_from)
1275
revision = _get_one_revision('branch', revision)
1276
self.add_cleanup(br_from.lock_read().unlock)
1277
if revision is not None:
1278
revision_id = revision.as_revision_id(br_from)
1280
# FIXME - wt.last_revision, fallback to branch, fall back to
1281
# None or perhaps NULL_REVISION to mean copy nothing
1283
revision_id = br_from.last_revision()
1284
if to_location is None:
1285
to_location = urlutils.derive_to_location(from_location)
1286
to_transport = transport.get_transport(to_location)
1288
to_transport.mkdir('.')
1289
except errors.FileExists:
1290
if not use_existing_dir:
1291
raise errors.BzrCommandError(gettext('Target directory "%s" '
1292
'already exists.') % to_location)
1295
bzrdir.BzrDir.open_from_transport(to_transport)
1296
except errors.NotBranchError:
1299
raise errors.AlreadyBranchError(to_location)
1300
except errors.NoSuchFile:
1301
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1304
# preserve whatever source format we have.
1305
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1306
possible_transports=[to_transport],
1307
accelerator_tree=accelerator_tree,
1308
hardlink=hardlink, stacked=stacked,
1309
force_new_repo=standalone,
1310
create_tree_if_local=not no_tree,
1311
source_branch=br_from)
1312
branch = dir.open_branch()
1313
except errors.NoSuchRevision:
1314
to_transport.delete_tree('.')
1315
msg = gettext("The branch {0} has no revision {1}.").format(
1316
from_location, revision)
1317
raise errors.BzrCommandError(msg)
1318
_merge_tags_if_possible(br_from, branch)
1319
# If the source branch is stacked, the new branch may
1320
# be stacked whether we asked for that explicitly or not.
1321
# We therefore need a try/except here and not just 'if stacked:'
1323
note(gettext('Created new stacked branch referring to %s.') %
1324
branch.get_stacked_on_url())
1325
except (errors.NotStacked, errors.UnstackableBranchFormat,
1326
errors.UnstackableRepositoryFormat), e:
1327
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1329
# Bind to the parent
1330
parent_branch = Branch.open(from_location)
1331
branch.bind(parent_branch)
1332
note(gettext('New branch bound to %s') % from_location)
1334
# Switch to the new branch
1335
wt, _ = WorkingTree.open_containing('.')
1336
_mod_switch.switch(wt.bzrdir, branch)
1337
note(gettext('Switched to branch: %s'),
1338
urlutils.unescape_for_display(branch.base, 'utf-8'))
1341
class cmd_branches(Command):
1342
__doc__ = """List the branches available at the current location.
1344
This command will print the names of all the branches at the current location.
1347
takes_args = ['location?']
1349
def run(self, location="."):
1350
dir = bzrdir.BzrDir.open_containing(location)[0]
1351
for branch in dir.list_branches():
1352
if branch.name is None:
1353
self.outf.write(gettext(" (default)\n"))
1355
self.outf.write(" %s\n" % branch.name.encode(self.outf.encoding))
671
1358
class cmd_checkout(Command):
672
"""Create a new checkout of an existing branch.
1359
__doc__ = """Create a new checkout of an existing branch.
674
1361
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
675
1362
the branch found in '.'. This is useful if you have removed the working tree
676
1363
or if it was never created - i.e. if you pushed the branch to its current
677
1364
location using SFTP.
679
1366
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
680
1367
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
1368
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1369
is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
1370
identifier, if any. For example, "checkout lp:foo-bar" will attempt to
682
1373
To retrieve the branch as of a particular revision, supply the --revision
683
1374
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
684
1375
out of date [so you cannot commit] but it may be useful (i.e. to examine old
687
--basis is to speed up checking out from remote branches. When specified, it
688
uses the inventory and file contents from the basis branch in preference to the
689
branch being checked out.
1379
_see_also = ['checkouts', 'branch']
691
1380
takes_args = ['branch_location?', 'to_location?']
692
takes_options = ['revision', # , 'basis']
1381
takes_options = ['revision',
693
1382
Option('lightweight',
694
help="perform a lightweight checkout. Lightweight "
1383
help="Perform a lightweight checkout. Lightweight "
695
1384
"checkouts depend on access to the branch for "
696
"every operation. Normal checkouts can perform "
1385
"every operation. Normal checkouts can perform "
697
1386
"common operations like diff and status without "
698
1387
"such access, and also support local commits."
1389
Option('files-from', type=str,
1390
help="Get file contents from this tree."),
1392
help='Hard-link working tree files where possible.'
702
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
706
elif len(revision) > 1:
707
raise BzrCommandError(
708
'bzr checkout --revision takes exactly 1 revision value')
1397
def run(self, branch_location=None, to_location=None, revision=None,
1398
lightweight=False, files_from=None, hardlink=False):
709
1399
if branch_location is None:
710
branch_location = bzrlib.osutils.getcwd()
1400
branch_location = osutils.getcwd()
711
1401
to_location = branch_location
712
source = Branch.open(branch_location)
713
if len(revision) == 1 and revision[0] is not None:
714
revision_id = revision[0].in_history(source)[1]
1402
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1404
if not (hardlink or files_from):
1405
# accelerator_tree is usually slower because you have to read N
1406
# files (no readahead, lots of seeks, etc), but allow the user to
1407
# explicitly request it
1408
accelerator_tree = None
1409
revision = _get_one_revision('checkout', revision)
1410
if files_from is not None and files_from != branch_location:
1411
accelerator_tree = WorkingTree.open(files_from)
1412
if revision is not None:
1413
revision_id = revision.as_revision_id(source)
716
1415
revision_id = None
717
1416
if to_location is None:
718
to_location = os.path.basename(branch_location.rstrip("/\\"))
719
# if the source and to_location are the same,
1417
to_location = urlutils.derive_to_location(branch_location)
1418
# if the source and to_location are the same,
720
1419
# and there is no working tree,
721
1420
# then reconstitute a branch
722
if (bzrlib.osutils.abspath(to_location) ==
723
bzrlib.osutils.abspath(branch_location)):
1421
if (osutils.abspath(to_location) ==
1422
osutils.abspath(branch_location)):
725
1424
source.bzrdir.open_workingtree()
726
1425
except errors.NoWorkingTree:
727
source.bzrdir.create_workingtree()
1426
source.bzrdir.create_workingtree(revision_id)
730
os.mkdir(to_location)
732
if e.errno == errno.EEXIST:
733
raise BzrCommandError('Target directory "%s" already'
734
' exists.' % to_location)
735
if e.errno == errno.ENOENT:
736
raise BzrCommandError('Parent of "%s" does not exist.' %
740
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
741
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
744
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
745
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
747
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
748
to_location, force_new_tree=False)
749
checkout = checkout_branch.bzrdir
750
checkout_branch.bind(source)
751
if revision_id is not None:
752
rh = checkout_branch.revision_history()
753
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
754
checkout.create_workingtree(revision_id)
756
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
1428
source.create_checkout(to_location, revision_id, lightweight,
1429
accelerator_tree, hardlink)
759
1432
class cmd_renames(Command):
760
"""Show list of renamed files.
1433
__doc__ = """Show list of renamed files.
762
1435
# TODO: Option to show renames between two historical versions.
764
1437
# TODO: Only show renames under dir, rather than in the whole branch.
1438
_see_also = ['status']
765
1439
takes_args = ['dir?']
767
1441
@display_command
768
1442
def run(self, dir=u'.'):
769
1443
tree = WorkingTree.open_containing(dir)[0]
770
old_inv = tree.basis_tree().inventory
771
new_inv = tree.read_working_inventory()
773
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
1444
self.add_cleanup(tree.lock_read().unlock)
1445
new_inv = tree.inventory
1446
old_tree = tree.basis_tree()
1447
self.add_cleanup(old_tree.lock_read().unlock)
1448
old_inv = old_tree.inventory
1450
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1451
for f, paths, c, v, p, n, k, e in iterator:
1452
if paths[0] == paths[1]:
1456
renames.append(paths)
775
1458
for old_name, new_name in renames:
776
1459
self.outf.write("%s => %s\n" % (old_name, new_name))
779
1462
class cmd_update(Command):
780
"""Update a tree to have the latest code committed to its branch.
1463
__doc__ = """Update a tree to have the latest code committed to its branch.
782
1465
This will perform a merge into the working tree, and may generate
783
conflicts. If you have any local changes, you will still
1466
conflicts. If you have any local changes, you will still
784
1467
need to commit them after the update for the update to be complete.
786
If you want to discard your local changes, you can just do a
1469
If you want to discard your local changes, you can just do a
787
1470
'bzr revert' instead of 'bzr commit' after the update.
1472
If you want to restore a file that has been removed locally, use
1473
'bzr revert' instead of 'bzr update'.
1475
If the tree's branch is bound to a master branch, it will also update
1476
the branch from the master.
1479
_see_also = ['pull', 'working-trees', 'status-flags']
789
1480
takes_args = ['dir?']
1481
takes_options = ['revision',
1483
help="Show base revision text in conflicts."),
791
def run(self, dir='.'):
1487
def run(self, dir='.', revision=None, show_base=None):
1488
if revision is not None and len(revision) != 1:
1489
raise errors.BzrCommandError(gettext(
1490
"bzr update --revision takes exactly one revision"))
792
1491
tree = WorkingTree.open_containing(dir)[0]
1492
branch = tree.branch
1493
possible_transports = []
1494
master = branch.get_master_branch(
1495
possible_transports=possible_transports)
1496
if master is not None:
1497
branch_location = master.base
1500
branch_location = tree.branch.base
1501
tree.lock_tree_write()
1502
self.add_cleanup(tree.unlock)
1503
# get rid of the final '/' and be ready for display
1504
branch_location = urlutils.unescape_for_display(
1505
branch_location.rstrip('/'),
1507
existing_pending_merges = tree.get_parent_ids()[1:]
1511
# may need to fetch data into a heavyweight checkout
1512
# XXX: this may take some time, maybe we should display a
1514
old_tip = branch.update(possible_transports)
1515
if revision is not None:
1516
revision_id = revision[0].as_revision_id(branch)
1518
revision_id = branch.last_revision()
1519
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1520
revno = branch.revision_id_to_dotted_revno(revision_id)
1521
note(gettext("Tree is up to date at revision {0} of branch {1}"
1522
).format('.'.join(map(str, revno)), branch_location))
1524
view_info = _get_view_info_for_change_reporter(tree)
1525
change_reporter = delta._ChangeReporter(
1526
unversioned_filter=tree.is_ignored,
1527
view_info=view_info)
795
if tree.last_revision() == tree.branch.last_revision():
796
# may be up to date, check master too.
797
master = tree.branch.get_master_branch()
798
if master is None or master.last_revision == tree.last_revision():
799
note("Tree is up to date.")
801
conflicts = tree.update()
802
note('Updated to revision %d.' %
803
(tree.branch.revision_id_to_revno(tree.last_revision()),))
1529
conflicts = tree.update(
1531
possible_transports=possible_transports,
1532
revision=revision_id,
1534
show_base=show_base)
1535
except errors.NoSuchRevision, e:
1536
raise errors.BzrCommandError(gettext(
1537
"branch has no revision %s\n"
1538
"bzr update --revision only works"
1539
" for a revision in the branch history")
1541
revno = tree.branch.revision_id_to_dotted_revno(
1542
_mod_revision.ensure_null(tree.last_revision()))
1543
note(gettext('Updated to revision {0} of branch {1}').format(
1544
'.'.join(map(str, revno)), branch_location))
1545
parent_ids = tree.get_parent_ids()
1546
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1547
note(gettext('Your local commits will now show as pending merges with '
1548
"'bzr status', and can be committed with 'bzr commit'."))
812
1555
class cmd_info(Command):
813
"""Show information about a working tree, branch or repository.
1556
__doc__ = """Show information about a working tree, branch or repository.
815
1558
This command will show all known locations and formats associated to the
816
tree, branch or repository. Statistical information is included with
1559
tree, branch or repository.
1561
In verbose mode, statistical information is included with each report.
1562
To see extended statistic information, use a verbosity level of 2 or
1563
higher by specifying the verbose option multiple times, e.g. -vv.
819
1565
Branches and working trees will also report any missing revisions.
1569
Display information on the format and related locations:
1573
Display the above together with extended format information and
1574
basic statistics (like the number of files in the working tree and
1575
number of revisions in the branch and repository):
1579
Display the above together with number of committers to the branch:
1583
_see_also = ['revno', 'working-trees', 'repositories']
821
1584
takes_args = ['location?']
822
1585
takes_options = ['verbose']
1586
encoding_type = 'replace'
824
1588
@display_command
825
1589
def run(self, location=None, verbose=False):
1591
noise_level = get_verbosity_level()
826
1594
from bzrlib.info import show_bzrdir_info
827
1595
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1596
verbose=noise_level, outfile=self.outf)
831
1599
class cmd_remove(Command):
832
"""Make a file unversioned.
834
This makes bzr stop tracking changes to a versioned file. It does
835
not delete the working copy.
837
You can specify one or more files, and/or --new. If you specify --new,
838
only 'added' files will be removed. If you specify both, then new files
839
in the specified directories will be removed. If the directories are
840
also new, they will also be removed.
1600
__doc__ = """Remove files or directories.
1602
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1603
delete them if they can easily be recovered using revert otherwise they
1604
will be backed up (adding an extention of the form .~#~). If no options or
1605
parameters are given Bazaar will scan for files that are being tracked by
1606
Bazaar but missing in your tree and stop tracking them for you.
842
1608
takes_args = ['file*']
843
takes_options = ['verbose', Option('new', help='remove newly-added files')]
1609
takes_options = ['verbose',
1610
Option('new', help='Only remove files that have never been committed.'),
1611
RegistryOption.from_kwargs('file-deletion-strategy',
1612
'The file deletion mode to be used.',
1613
title='Deletion Strategy', value_switches=True, enum_switch=False,
1614
safe='Backup changed files (default).',
1615
keep='Delete from bzr but leave the working copy.',
1616
no_backup='Don\'t backup changed files.',
1617
force='Delete all the specified files, even if they can not be '
1618
'recovered and even if they are non-empty directories. '
1619
'(deprecated, use no-backup)')]
1620
aliases = ['rm', 'del']
845
1621
encoding_type = 'replace'
847
def run(self, file_list, verbose=False, new=False):
848
tree, file_list = tree_files(file_list)
850
if file_list is None:
851
raise BzrCommandError('Specify one or more files to remove, or'
854
from bzrlib.delta import compare_trees
855
added = [compare_trees(tree.basis_tree(), tree,
856
specific_files=file_list).added]
857
file_list = sorted([f[0] for f in added[0]], reverse=True)
1623
def run(self, file_list, verbose=False, new=False,
1624
file_deletion_strategy='safe'):
1625
if file_deletion_strategy == 'force':
1626
note(gettext("(The --force option is deprecated, rather use --no-backup "
1628
file_deletion_strategy = 'no-backup'
1630
tree, file_list = WorkingTree.open_containing_paths(file_list)
1632
if file_list is not None:
1633
file_list = [f for f in file_list]
1635
self.add_cleanup(tree.lock_write().unlock)
1636
# Heuristics should probably all move into tree.remove_smart or
1639
added = tree.changes_from(tree.basis_tree(),
1640
specific_files=file_list).added
1641
file_list = sorted([f[0] for f in added], reverse=True)
858
1642
if len(file_list) == 0:
859
raise BzrCommandError('No matching files.')
860
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1643
raise errors.BzrCommandError(gettext('No matching files.'))
1644
elif file_list is None:
1645
# missing files show up in iter_changes(basis) as
1646
# versioned-with-no-kind.
1648
for change in tree.iter_changes(tree.basis_tree()):
1649
# Find paths in the working tree that have no kind:
1650
if change[1][1] is not None and change[6][1] is None:
1651
missing.append(change[1][1])
1652
file_list = sorted(missing, reverse=True)
1653
file_deletion_strategy = 'keep'
1654
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1655
keep_files=file_deletion_strategy=='keep',
1656
force=(file_deletion_strategy=='no-backup'))
863
1659
class cmd_file_id(Command):
864
"""Print file_id of a particular file or directory.
1660
__doc__ = """Print file_id of a particular file or directory.
866
1662
The file_id is assigned when the file is first added and remains the
867
1663
same through all revisions where the file exists, even when it is
915
1713
id which was not present in very early bzr versions is represented
916
1714
correctly in both branches.
918
At the same time it is run it may recompress data resulting in
1716
At the same time it is run it may recompress data resulting in
919
1717
a potential saving in disk space or performance gain.
921
1719
The branch *MUST* be on a listable system such as local disk or sftp.
1722
_see_also = ['check']
923
1723
takes_args = ['branch?']
1725
Option('canonicalize-chks',
1726
help='Make sure CHKs are in canonical form (repairs '
925
def run(self, branch="."):
1731
def run(self, branch=".", canonicalize_chks=False):
926
1732
from bzrlib.reconcile import reconcile
927
dir = bzrlib.bzrdir.BzrDir.open(branch)
1733
dir = bzrdir.BzrDir.open(branch)
1734
reconcile(dir, canonicalize_chks=canonicalize_chks)
931
1737
class cmd_revision_history(Command):
932
"""Display list of revision ids on this branch."""
1738
__doc__ = """Display the list of revision ids on a branch."""
1741
takes_args = ['location?']
935
1745
@display_command
937
branch = WorkingTree.open_containing(u'.')[0].branch
938
for patchid in branch.revision_history():
939
self.outf.write(patchid)
1746
def run(self, location="."):
1747
branch = Branch.open_containing(location)[0]
1748
for revid in branch.revision_history():
1749
self.outf.write(revid)
940
1750
self.outf.write('\n')
943
1753
class cmd_ancestry(Command):
944
"""List all revisions merged into this branch."""
1754
__doc__ = """List all revisions merged into this branch."""
1756
_see_also = ['log', 'revision-history']
1757
takes_args = ['location?']
947
1761
@display_command
949
tree = WorkingTree.open_containing(u'.')[0]
951
# FIXME. should be tree.last_revision
952
revision_ids = b.repository.get_ancestry(b.last_revision())
953
assert revision_ids[0] == None
955
for revision_id in revision_ids:
1762
def run(self, location="."):
1764
wt = WorkingTree.open_containing(location)[0]
1765
except errors.NoWorkingTree:
1766
b = Branch.open(location)
1767
last_revision = b.last_revision()
1770
last_revision = wt.last_revision()
1772
self.add_cleanup(b.repository.lock_read().unlock)
1773
graph = b.repository.get_graph()
1774
revisions = [revid for revid, parents in
1775
graph.iter_ancestry([last_revision])]
1776
for revision_id in reversed(revisions):
1777
if _mod_revision.is_null(revision_id):
956
1779
self.outf.write(revision_id + '\n')
959
1782
class cmd_init(Command):
960
"""Make a directory into a versioned branch.
1783
__doc__ = """Make a directory into a versioned branch.
962
1785
Use this to create an empty branch, or before importing an
963
1786
existing project.
965
If there is a repository in a parent directory of the location, then
1788
If there is a repository in a parent directory of the location, then
966
1789
the history of the branch will be stored in the repository. Otherwise
967
init creates a standalone branch which carries its own history in
1790
init creates a standalone branch which carries its own history
1791
in the .bzr directory.
970
1793
If there is already a branch at the location but it has no working tree,
971
1794
the tree can be populated with 'bzr checkout'.
973
Recipe for importing a tree of files:
1796
Recipe for importing a tree of files::
978
bzr commit -m 'imported project'
1802
bzr commit -m "imported project"
1805
_see_also = ['init-repository', 'branch', 'checkout']
980
1806
takes_args = ['location?']
981
1807
takes_options = [
983
help='Specify a format for this branch. Current'
984
' formats are: default, knit, metaweave and'
985
' weave. Default is knit; metaweave and'
986
' weave are deprecated',
987
type=get_format_type),
989
def run(self, location=None, format=None):
990
from bzrlib.branch import Branch
1808
Option('create-prefix',
1809
help='Create the path leading up to the branch '
1810
'if it does not already exist.'),
1811
RegistryOption('format',
1812
help='Specify a format for this branch. '
1813
'See "help formats".',
1814
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1815
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1816
value_switches=True,
1817
title="Branch format",
1819
Option('append-revisions-only',
1820
help='Never change revnos or the existing log.'
1821
' Append revisions to it only.'),
1823
'Create a branch without a working tree.')
1825
def run(self, location=None, format=None, append_revisions_only=False,
1826
create_prefix=False, no_tree=False):
991
1827
if format is None:
992
format = get_format_type('default')
1828
format = bzrdir.format_registry.make_bzrdir('default')
993
1829
if location is None:
996
# The path has to exist to initialize a
997
# branch inside of it.
998
# Just using os.mkdir, since I don't
999
# believe that we want to create a bunch of
1000
# locations if the user supplies an extended path
1001
if not os.path.exists(location):
1004
existing_bzrdir = bzrdir.BzrDir.open(location)
1005
except NotBranchError:
1832
to_transport = transport.get_transport(location)
1834
# The path has to exist to initialize a
1835
# branch inside of it.
1836
# Just using os.mkdir, since I don't
1837
# believe that we want to create a bunch of
1838
# locations if the user supplies an extended path
1840
to_transport.ensure_base()
1841
except errors.NoSuchFile:
1842
if not create_prefix:
1843
raise errors.BzrCommandError(gettext("Parent directory of %s"
1845
"\nYou may supply --create-prefix to create all"
1846
" leading parent directories.")
1848
to_transport.create_prefix()
1851
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1852
except errors.NotBranchError:
1006
1853
# really a NotBzrDir error...
1007
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1854
create_branch = bzrdir.BzrDir.create_branch_convenience
1856
force_new_tree = False
1858
force_new_tree = None
1859
branch = create_branch(to_transport.base, format=format,
1860
possible_transports=[to_transport],
1861
force_new_tree=force_new_tree)
1862
a_bzrdir = branch.bzrdir
1009
if existing_bzrdir.has_branch():
1010
if existing_bzrdir.has_workingtree():
1011
raise errors.AlreadyBranchError(location)
1013
raise errors.BranchExistsWithoutWorkingTree(location)
1015
existing_bzrdir.create_branch()
1016
existing_bzrdir.create_workingtree()
1864
from bzrlib.transport.local import LocalTransport
1865
if a_bzrdir.has_branch():
1866
if (isinstance(to_transport, LocalTransport)
1867
and not a_bzrdir.has_workingtree()):
1868
raise errors.BranchExistsWithoutWorkingTree(location)
1869
raise errors.AlreadyBranchError(location)
1870
branch = a_bzrdir.create_branch()
1872
a_bzrdir.create_workingtree()
1873
if append_revisions_only:
1875
branch.set_append_revisions_only(True)
1876
except errors.UpgradeRequired:
1877
raise errors.BzrCommandError(gettext('This branch format cannot be set'
1878
' to append-revisions-only. Try --default.'))
1880
from bzrlib.info import describe_layout, describe_format
1882
tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
1883
except (errors.NoWorkingTree, errors.NotLocalUrl):
1885
repository = branch.repository
1886
layout = describe_layout(repository, branch, tree).lower()
1887
format = describe_format(a_bzrdir, repository, branch, tree)
1888
self.outf.write(gettext("Created a {0} (format: {1})\n").format(
1890
if repository.is_shared():
1891
#XXX: maybe this can be refactored into transport.path_or_url()
1892
url = repository.bzrdir.root_transport.external_url()
1894
url = urlutils.local_path_from_url(url)
1895
except errors.InvalidURL:
1897
self.outf.write(gettext("Using shared repository: %s\n") % url)
1019
1900
class cmd_init_repository(Command):
1020
"""Create a shared repository to hold branches.
1022
New branches created under the repository directory will store their revisions
1023
in the repository, not in the branch directory, if the branch format supports
1029
bzr checkout --lightweight repo/trunk trunk-checkout
1901
__doc__ = """Create a shared repository for branches to share storage space.
1903
New branches created under the repository directory will store their
1904
revisions in the repository, not in the branch directory. For branches
1905
with shared history, this reduces the amount of storage needed and
1906
speeds up the creation of new branches.
1908
If the --no-trees option is given then the branches in the repository
1909
will not have working trees by default. They will still exist as
1910
directories on disk, but they will not have separate copies of the
1911
files at a certain revision. This can be useful for repositories that
1912
store branches which are interacted with through checkouts or remote
1913
branches, such as on a server.
1916
Create a shared repository holding just branches::
1918
bzr init-repo --no-trees repo
1921
Make a lightweight checkout elsewhere::
1923
bzr checkout --lightweight repo/trunk trunk-checkout
1033
takes_args = ["location"]
1034
takes_options = [Option('format',
1035
help='Specify a format for this repository.'
1036
' Current formats are: default, knit,'
1037
' metaweave and weave. Default is knit;'
1038
' metaweave and weave are deprecated',
1039
type=get_format_type),
1041
help='Allows branches in repository to have'
1928
_see_also = ['init', 'branch', 'checkout', 'repositories']
1929
takes_args = ["location"]
1930
takes_options = [RegistryOption('format',
1931
help='Specify a format for this repository. See'
1932
' "bzr help formats" for details.',
1933
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1934
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1935
value_switches=True, title='Repository format'),
1937
help='Branches in the repository will default to'
1938
' not having a working tree.'),
1043
1940
aliases = ["init-repo"]
1044
def run(self, location, format=None, trees=False):
1045
from bzrlib.transport import get_transport
1942
def run(self, location, format=None, no_trees=False):
1046
1943
if format is None:
1047
format = get_format_type('default')
1048
transport = get_transport(location)
1049
if not transport.has('.'):
1051
newdir = format.initialize_on_transport(transport)
1944
format = bzrdir.format_registry.make_bzrdir('default')
1946
if location is None:
1949
to_transport = transport.get_transport(location)
1950
to_transport.ensure_base()
1952
newdir = format.initialize_on_transport(to_transport)
1052
1953
repo = newdir.create_repository(shared=True)
1053
repo.set_make_working_trees(trees)
1954
repo.set_make_working_trees(not no_trees)
1956
from bzrlib.info import show_bzrdir_info
1957
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
1056
1960
class cmd_diff(Command):
1057
"""Show differences in working tree.
1059
If files are listed, only the changes in those files are listed.
1060
Otherwise, all changes for the tree are listed.
1961
__doc__ = """Show differences in the working tree, between revisions or branches.
1963
If no arguments are given, all changes for the current tree are listed.
1964
If files are given, only the changes in those files are listed.
1965
Remote and multiple branches can be compared by using the --old and
1966
--new options. If not provided, the default for both is derived from
1967
the first argument, if any, or the current tree if no arguments are
1062
1970
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1063
1971
produces patches suitable for "patch -p1".
1069
bzr diff --diff-prefix old/:new/
1070
bzr diff bzr.mine bzr.dev
1973
Note that when using the -r argument with a range of revisions, the
1974
differences are computed between the two specified revisions. That
1975
is, the command does not show the changes introduced by the first
1976
revision in the range. This differs from the interpretation of
1977
revision ranges used by "bzr log" which includes the first revision
1982
2 - unrepresentable changes
1987
Shows the difference in the working tree versus the last commit::
1991
Difference between the working tree and revision 1::
1995
Difference between revision 3 and revision 1::
1999
Difference between revision 3 and revision 1 for branch xxx::
2003
The changes introduced by revision 2 (equivalent to -r1..2)::
2007
To see the changes introduced by revision X::
2011
Note that in the case of a merge, the -c option shows the changes
2012
compared to the left hand parent. To see the changes against
2013
another parent, use::
2015
bzr diff -r<chosen_parent>..X
2017
The changes between the current revision and the previous revision
2018
(equivalent to -c-1 and -r-2..-1)
2022
Show just the differences for file NEWS::
2026
Show the differences in working tree xxx for file NEWS::
2030
Show the differences from branch xxx to this working tree:
2034
Show the differences between two branches for file NEWS::
2036
bzr diff --old xxx --new yyy NEWS
2038
Same as 'bzr diff' but prefix paths with old/ and new/::
2040
bzr diff --prefix old/:new/
2042
Show the differences using a custom diff program with options::
2044
bzr diff --using /usr/bin/diff --diff-options -wu
1073
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1074
# or a graphical diff.
1076
# TODO: Python difflib is not exactly the same as unidiff; should
1077
# either fix it up or prefer to use an external diff.
1079
# TODO: Selected-file diff is inefficient and doesn't show you
1082
# TODO: This probably handles non-Unix newlines poorly.
2046
_see_also = ['status']
1084
2047
takes_args = ['file*']
1085
takes_options = ['revision', 'diff-options', 'prefix']
2049
Option('diff-options', type=str,
2050
help='Pass these options to the external diff program.'),
2051
Option('prefix', type=str,
2053
help='Set prefixes added to old and new filenames, as '
2054
'two values separated by a colon. (eg "old/:new/").'),
2056
help='Branch/tree to compare from.',
2060
help='Branch/tree to compare to.',
2066
help='Use this command to compare files.',
2069
RegistryOption('format',
2071
help='Diff format to use.',
2072
lazy_registry=('bzrlib.diff', 'format_registry'),
2073
title='Diff format'),
1086
2075
aliases = ['di', 'dif']
1087
2076
encoding_type = 'exact'
1089
2078
@display_command
1090
2079
def run(self, revision=None, file_list=None, diff_options=None,
1092
from bzrlib.diff import diff_cmd_helper, show_diff_trees
2080
prefix=None, old=None, new=None, using=None, format=None):
2081
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
1094
2084
if (prefix is None) or (prefix == '0'):
1095
2085
# diff -p0 format
1210
2212
self.outf.write(tree.basedir + '\n')
2215
def _parse_limit(limitstring):
2217
return int(limitstring)
2219
msg = gettext("The limit argument must be an integer.")
2220
raise errors.BzrCommandError(msg)
2223
def _parse_levels(s):
2227
msg = gettext("The levels argument must be an integer.")
2228
raise errors.BzrCommandError(msg)
1213
2231
class cmd_log(Command):
1214
"""Show log of a branch, file, or directory.
1216
By default show the log of the branch containing the working directory.
1218
To request a range of logs, you can use the command -r begin..end
1219
-r revision requests a specific revision, -r ..end or -r begin.. are
1225
bzr log -r -10.. http://server/branch
2232
__doc__ = """Show historical log for a branch or subset of a branch.
2234
log is bzr's default tool for exploring the history of a branch.
2235
The branch to use is taken from the first parameter. If no parameters
2236
are given, the branch containing the working directory is logged.
2237
Here are some simple examples::
2239
bzr log log the current branch
2240
bzr log foo.py log a file in its branch
2241
bzr log http://server/branch log a branch on a server
2243
The filtering, ordering and information shown for each revision can
2244
be controlled as explained below. By default, all revisions are
2245
shown sorted (topologically) so that newer revisions appear before
2246
older ones and descendants always appear before ancestors. If displayed,
2247
merged revisions are shown indented under the revision in which they
2252
The log format controls how information about each revision is
2253
displayed. The standard log formats are called ``long``, ``short``
2254
and ``line``. The default is long. See ``bzr help log-formats``
2255
for more details on log formats.
2257
The following options can be used to control what information is
2260
-l N display a maximum of N revisions
2261
-n N display N levels of revisions (0 for all, 1 for collapsed)
2262
-v display a status summary (delta) for each revision
2263
-p display a diff (patch) for each revision
2264
--show-ids display revision-ids (and file-ids), not just revnos
2266
Note that the default number of levels to display is a function of the
2267
log format. If the -n option is not used, the standard log formats show
2268
just the top level (mainline).
2270
Status summaries are shown using status flags like A, M, etc. To see
2271
the changes explained using words like ``added`` and ``modified``
2272
instead, use the -vv option.
2276
To display revisions from oldest to newest, use the --forward option.
2277
In most cases, using this option will have little impact on the total
2278
time taken to produce a log, though --forward does not incrementally
2279
display revisions like --reverse does when it can.
2281
:Revision filtering:
2283
The -r option can be used to specify what revision or range of revisions
2284
to filter against. The various forms are shown below::
2286
-rX display revision X
2287
-rX.. display revision X and later
2288
-r..Y display up to and including revision Y
2289
-rX..Y display from X to Y inclusive
2291
See ``bzr help revisionspec`` for details on how to specify X and Y.
2292
Some common examples are given below::
2294
-r-1 show just the tip
2295
-r-10.. show the last 10 mainline revisions
2296
-rsubmit:.. show what's new on this branch
2297
-rancestor:path.. show changes since the common ancestor of this
2298
branch and the one at location path
2299
-rdate:yesterday.. show changes since yesterday
2301
When logging a range of revisions using -rX..Y, log starts at
2302
revision Y and searches back in history through the primary
2303
("left-hand") parents until it finds X. When logging just the
2304
top level (using -n1), an error is reported if X is not found
2305
along the way. If multi-level logging is used (-n0), X may be
2306
a nested merge revision and the log will be truncated accordingly.
2310
If parameters are given and the first one is not a branch, the log
2311
will be filtered to show only those revisions that changed the
2312
nominated files or directories.
2314
Filenames are interpreted within their historical context. To log a
2315
deleted file, specify a revision range so that the file existed at
2316
the end or start of the range.
2318
Historical context is also important when interpreting pathnames of
2319
renamed files/directories. Consider the following example:
2321
* revision 1: add tutorial.txt
2322
* revision 2: modify tutorial.txt
2323
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2327
* ``bzr log guide.txt`` will log the file added in revision 1
2329
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2331
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2332
the original file in revision 2.
2334
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2335
was no file called guide.txt in revision 2.
2337
Renames are always followed by log. By design, there is no need to
2338
explicitly ask for this (and no way to stop logging a file back
2339
until it was last renamed).
2343
The --match option can be used for finding revisions that match a
2344
regular expression in a commit message, committer, author or bug.
2345
Specifying the option several times will match any of the supplied
2346
expressions. --match-author, --match-bugs, --match-committer and
2347
--match-message can be used to only match a specific field.
2351
GUI tools and IDEs are often better at exploring history than command
2352
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2353
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2354
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2355
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2357
You may find it useful to add the aliases below to ``bazaar.conf``::
2361
top = log -l10 --line
2364
``bzr tip`` will then show the latest revision while ``bzr top``
2365
will show the last 10 mainline revisions. To see the details of a
2366
particular revision X, ``bzr show -rX``.
2368
If you are interested in looking deeper into a particular merge X,
2369
use ``bzr log -n0 -rX``.
2371
``bzr log -v`` on a branch with lots of history is currently
2372
very slow. A fix for this issue is currently under development.
2373
With or without that fix, it is recommended that a revision range
2374
be given when using the -v option.
2376
bzr has a generic full-text matching plugin, bzr-search, that can be
2377
used to find revisions matching user names, commit messages, etc.
2378
Among other features, this plugin can find all revisions containing
2379
a list of words but not others.
2381
When exploring non-mainline history on large projects with deep
2382
history, the performance of log can be greatly improved by installing
2383
the historycache plugin. This plugin buffers historical information
2384
trading disk space for faster speed.
1228
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1230
takes_args = ['location?']
1231
takes_options = [Option('forward',
1232
help='show from oldest to newest'),
1235
help='show files changed in each revision'),
1236
'show-ids', 'revision',
1240
help='show revisions whose message matches this regexp',
2386
takes_args = ['file*']
2387
_see_also = ['log-formats', 'revisionspec']
2390
help='Show from oldest to newest.'),
2392
custom_help('verbose',
2393
help='Show files changed in each revision.'),
2397
type=bzrlib.option._parse_revision_str,
2399
help='Show just the specified revision.'
2400
' See also "help revisionspec".'),
2402
RegistryOption('authors',
2403
'What names to list as authors - first, all or committer.',
2405
lazy_registry=('bzrlib.log', 'author_list_registry'),
2409
help='Number of levels to display - 0 for all, 1 for flat.',
2411
type=_parse_levels),
2413
help='Show revisions whose message matches this '
2414
'regular expression.',
2419
help='Limit the output to the first N revisions.',
2424
help='Show changes made in each revision as a patch.'),
2425
Option('include-merged',
2426
help='Show merged revisions like --levels 0 does.'),
2427
Option('include-merges', hidden=True,
2428
help='Historical alias for --include-merged.'),
2429
Option('omit-merges',
2430
help='Do not report commits with more than one parent.'),
2431
Option('exclude-common-ancestry',
2432
help='Display only the revisions that are not part'
2433
' of both ancestries (require -rX..Y)'
2435
Option('signatures',
2436
help='Show digital signature validity'),
2439
help='Show revisions whose properties match this '
2442
ListOption('match-message',
2443
help='Show revisions whose message matches this '
2446
ListOption('match-committer',
2447
help='Show revisions whose committer matches this '
2450
ListOption('match-author',
2451
help='Show revisions whose authors match this '
2454
ListOption('match-bugs',
2455
help='Show revisions whose bugs match this '
1244
2459
encoding_type = 'replace'
1246
2461
@display_command
1247
def run(self, location=None, timezone='original',
2462
def run(self, file_list=None, timezone='original',
1249
2464
show_ids=False,
1252
2468
log_format=None,
1257
from bzrlib.log import log_formatter, show_log
1258
assert message is None or isinstance(message, basestring), \
1259
"invalid message argument %r" % message
2473
include_merged=None,
2475
exclude_common_ancestry=False,
2479
match_committer=None,
2483
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2485
from bzrlib.log import (
2487
make_log_request_dict,
2488
_get_info_for_log_files,
1260
2490
direction = (forward and 'forward') or 'reverse'
1265
# find the file id to log:
1267
dir, fp = bzrdir.BzrDir.open_containing(location)
1268
b = dir.open_branch()
1272
inv = dir.open_workingtree().inventory
1273
except (errors.NotBranchError, errors.NotLocalUrl):
1274
# either no tree, or is remote.
1275
inv = b.basis_tree().inventory
1276
file_id = inv.path2id(fp)
1279
# FIXME ? log the current subdir only RBC 20060203
1280
dir, relpath = bzrdir.BzrDir.open_containing('.')
1281
b = dir.open_branch()
1283
if revision is None:
1286
elif len(revision) == 1:
1287
rev1 = rev2 = revision[0].in_history(b).revno
1288
elif len(revision) == 2:
1289
if revision[0].spec is None:
1290
# missing begin-range means first revision
1293
rev1 = revision[0].in_history(b).revno
1295
if revision[1].spec is None:
1296
# missing end-range means last known revision
1299
rev2 = revision[1].in_history(b).revno
1301
raise BzrCommandError('bzr log --revision takes one or two values.')
1303
# By this point, the revision numbers are converted to the +ve
1304
# form if they were supplied in the -ve form, so we can do
1305
# this comparison in relative safety
1307
(rev2, rev1) = (rev1, rev2)
1309
if (log_format == None):
1310
default = bzrlib.config.BranchConfig(b).log_format()
1311
log_format = get_log_format(long=long, short=short, line=line, default=default)
1312
lf = log_formatter(log_format,
1315
show_timezone=timezone)
1321
direction=direction,
1322
start_revision=rev1,
2491
if symbol_versioning.deprecated_passed(include_merges):
2492
ui.ui_factory.show_user_warning(
2493
'deprecated_command_option',
2494
deprecated_name='--include-merges',
2495
recommended_name='--include-merged',
2496
deprecated_in_version='2.5',
2497
command=self.invoked_as)
2498
if include_merged is None:
2499
include_merged = include_merges
2501
raise errors.BzrCommandError(gettext(
2502
'{0} and {1} are mutually exclusive').format(
2503
'--include-merges', '--include-merged'))
2504
if include_merged is None:
2505
include_merged = False
2506
if (exclude_common_ancestry
2507
and (revision is None or len(revision) != 2)):
2508
raise errors.BzrCommandError(gettext(
2509
'--exclude-common-ancestry requires -r with two revisions'))
2514
raise errors.BzrCommandError(gettext(
2515
'{0} and {1} are mutually exclusive').format(
2516
'--levels', '--include-merged'))
2518
if change is not None:
2520
raise errors.RangeInChangeOption()
2521
if revision is not None:
2522
raise errors.BzrCommandError(gettext(
2523
'{0} and {1} are mutually exclusive').format(
2524
'--revision', '--change'))
2529
filter_by_dir = False
2531
# find the file ids to log and check for directory filtering
2532
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2533
revision, file_list, self.add_cleanup)
2534
for relpath, file_id, kind in file_info_list:
2536
raise errors.BzrCommandError(gettext(
2537
"Path unknown at end or start of revision range: %s") %
2539
# If the relpath is the top of the tree, we log everything
2544
file_ids.append(file_id)
2545
filter_by_dir = filter_by_dir or (
2546
kind in ['directory', 'tree-reference'])
2549
# FIXME ? log the current subdir only RBC 20060203
2550
if revision is not None \
2551
and len(revision) > 0 and revision[0].get_branch():
2552
location = revision[0].get_branch()
2555
dir, relpath = bzrdir.BzrDir.open_containing(location)
2556
b = dir.open_branch()
2557
self.add_cleanup(b.lock_read().unlock)
2558
rev1, rev2 = _get_revision_range(revision, b, self.name())
2560
if b.get_config().validate_signatures_in_log():
2564
if not gpg.GPGStrategy.verify_signatures_available():
2565
raise errors.GpgmeNotInstalled(None)
2567
# Decide on the type of delta & diff filtering to use
2568
# TODO: add an --all-files option to make this configurable & consistent
2576
diff_type = 'partial'
2580
# Build the log formatter
2581
if log_format is None:
2582
log_format = log.log_formatter_registry.get_default(b)
2583
# Make a non-encoding output to include the diffs - bug 328007
2584
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2585
lf = log_format(show_ids=show_ids, to_file=self.outf,
2586
to_exact_file=unencoded_output,
2587
show_timezone=timezone,
2588
delta_format=get_verbosity_level(),
2590
show_advice=levels is None,
2591
author_list_handler=authors)
2593
# Choose the algorithm for doing the logging. It's annoying
2594
# having multiple code paths like this but necessary until
2595
# the underlying repository format is faster at generating
2596
# deltas or can provide everything we need from the indices.
2597
# The default algorithm - match-using-deltas - works for
2598
# multiple files and directories and is faster for small
2599
# amounts of history (200 revisions say). However, it's too
2600
# slow for logging a single file in a repository with deep
2601
# history, i.e. > 10K revisions. In the spirit of "do no
2602
# evil when adding features", we continue to use the
2603
# original algorithm - per-file-graph - for the "single
2604
# file that isn't a directory without showing a delta" case.
2605
partial_history = revision and b.repository._format.supports_chks
2606
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2607
or delta_type or partial_history)
2611
match_dict[''] = match
2613
match_dict['message'] = match_message
2615
match_dict['committer'] = match_committer
2617
match_dict['author'] = match_author
2619
match_dict['bugs'] = match_bugs
2621
# Build the LogRequest and execute it
2622
if len(file_ids) == 0:
2624
rqst = make_log_request_dict(
2625
direction=direction, specific_fileids=file_ids,
2626
start_revision=rev1, end_revision=rev2, limit=limit,
2627
message_search=message, delta_type=delta_type,
2628
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2629
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2630
signature=signatures, omit_merges=omit_merges,
2632
Logger(b, rqst).show(lf)
2635
def _get_revision_range(revisionspec_list, branch, command_name):
2636
"""Take the input of a revision option and turn it into a revision range.
2638
It returns RevisionInfo objects which can be used to obtain the rev_id's
2639
of the desired revisions. It does some user input validations.
2641
if revisionspec_list is None:
2644
elif len(revisionspec_list) == 1:
2645
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2646
elif len(revisionspec_list) == 2:
2647
start_spec = revisionspec_list[0]
2648
end_spec = revisionspec_list[1]
2649
if end_spec.get_branch() != start_spec.get_branch():
2650
# b is taken from revision[0].get_branch(), and
2651
# show_log will use its revision_history. Having
2652
# different branches will lead to weird behaviors.
2653
raise errors.BzrCommandError(gettext(
2654
"bzr %s doesn't accept two revisions in different"
2655
" branches.") % command_name)
2656
if start_spec.spec is None:
2657
# Avoid loading all the history.
2658
rev1 = RevisionInfo(branch, None, None)
2660
rev1 = start_spec.in_history(branch)
2661
# Avoid loading all of history when we know a missing
2662
# end of range means the last revision ...
2663
if end_spec.spec is None:
2664
last_revno, last_revision_id = branch.last_revision_info()
2665
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2667
rev2 = end_spec.in_history(branch)
2669
raise errors.BzrCommandError(gettext(
2670
'bzr %s --revision takes one or two values.') % command_name)
2674
def _revision_range_to_revid_range(revision_range):
2677
if revision_range[0] is not None:
2678
rev_id1 = revision_range[0].rev_id
2679
if revision_range[1] is not None:
2680
rev_id2 = revision_range[1].rev_id
2681
return rev_id1, rev_id2
1327
2683
def get_log_format(long=False, short=False, line=False, default='long'):
1328
2684
log_format = default
1347
2703
@display_command
1348
2704
def run(self, filename):
1349
2705
tree, relpath = WorkingTree.open_containing(filename)
2706
file_id = tree.path2id(relpath)
1350
2707
b = tree.branch
1351
inv = tree.read_working_inventory()
1352
file_id = inv.path2id(relpath)
1353
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
2708
self.add_cleanup(b.lock_read().unlock)
2709
touching_revs = log.find_touching_revisions(b, file_id)
2710
for revno, revision_id, what in touching_revs:
1354
2711
self.outf.write("%6d %s\n" % (revno, what))
1357
2714
class cmd_ls(Command):
1358
"""List files in a tree.
2715
__doc__ = """List files in a tree.
1360
# TODO: Take a revision or remote path and list that tree instead.
1362
takes_options = ['verbose', 'revision',
1363
Option('non-recursive',
1364
help='don\'t recurse into sub-directories'),
1366
help='Print all paths from the root of the branch.'),
1367
Option('unknown', help='Print unknown files'),
1368
Option('versioned', help='Print versioned files'),
1369
Option('ignored', help='Print ignored files'),
1371
Option('null', help='Null separate the files'),
2718
_see_also = ['status', 'cat']
2719
takes_args = ['path?']
2723
Option('recursive', short_name='R',
2724
help='Recurse into subdirectories.'),
2726
help='Print paths relative to the root of the branch.'),
2727
Option('unknown', short_name='u',
2728
help='Print unknown files.'),
2729
Option('versioned', help='Print versioned files.',
2731
Option('ignored', short_name='i',
2732
help='Print ignored files.'),
2733
Option('kind', short_name='k',
2734
help='List entries of a particular kind: file, directory, symlink.',
1373
2740
@display_command
1374
def run(self, revision=None, verbose=False,
1375
non_recursive=False, from_root=False,
2741
def run(self, revision=None, verbose=False,
2742
recursive=False, from_root=False,
1376
2743
unknown=False, versioned=False, ignored=False,
2744
null=False, kind=None, show_ids=False, path=None, directory=None):
2746
if kind and kind not in ('file', 'directory', 'symlink'):
2747
raise errors.BzrCommandError(gettext('invalid kind specified'))
1379
2749
if verbose and null:
1380
raise BzrCommandError('Cannot set both --verbose and --null')
2750
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
1381
2751
all = not (unknown or versioned or ignored)
1383
2753
selection = {'I':ignored, '?':unknown, 'V':versioned}
1385
tree, relpath = WorkingTree.open_containing(u'.')
2759
raise errors.BzrCommandError(gettext('cannot specify both --from-root'
2762
tree, branch, relpath = \
2763
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2765
# Calculate the prefix to use
1390
if revision is not None:
1391
tree = tree.branch.repository.revision_tree(
1392
revision[0].in_history(tree.branch).rev_id)
1394
for fp, fc, kind, fid, entry in tree.list_files():
1395
if fp.startswith(relpath):
1396
fp = fp[len(relpath):]
1397
if non_recursive and '/' in fp:
1399
if not all and not selection[fc]:
1402
kindch = entry.kind_character()
1403
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1405
self.outf.write(fp + '\0')
2769
prefix = relpath + '/'
2770
elif fs_path != '.' and not fs_path.endswith('/'):
2771
prefix = fs_path + '/'
2773
if revision is not None or tree is None:
2774
tree = _get_one_revision_tree('ls', revision, branch=branch)
2777
if isinstance(tree, WorkingTree) and tree.supports_views():
2778
view_files = tree.views.lookup_view()
2781
view_str = views.view_display_str(view_files)
2782
note(gettext("Ignoring files outside view. View is %s") % view_str)
2784
self.add_cleanup(tree.lock_read().unlock)
2785
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2786
from_dir=relpath, recursive=recursive):
2787
# Apply additional masking
2788
if not all and not selection[fc]:
2790
if kind is not None and fkind != kind:
2795
fullpath = osutils.pathjoin(relpath, fp)
2798
views.check_path_in_view(tree, fullpath)
2799
except errors.FileOutsideView:
2804
fp = osutils.pathjoin(prefix, fp)
2805
kindch = entry.kind_character()
2806
outstring = fp + kindch
2807
ui.ui_factory.clear_term()
2809
outstring = '%-8s %s' % (fc, outstring)
2810
if show_ids and fid is not None:
2811
outstring = "%-50s %s" % (outstring, fid)
2812
self.outf.write(outstring + '\n')
2814
self.outf.write(fp + '\0')
2817
self.outf.write(fid)
2818
self.outf.write('\0')
2826
self.outf.write('%-50s %s\n' % (outstring, my_id))
1408
self.outf.write(fp + '\n')
2828
self.outf.write(outstring + '\n')
1411
2831
class cmd_unknowns(Command):
1412
"""List unknown files."""
2832
__doc__ = """List unknown files.
2837
takes_options = ['directory']
1413
2839
@display_command
1415
from bzrlib.osutils import quotefn
1416
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1417
self.outf.write(quotefn(f) + '\n')
2840
def run(self, directory=u'.'):
2841
for f in WorkingTree.open_containing(directory)[0].unknowns():
2842
self.outf.write(osutils.quotefn(f) + '\n')
1420
2845
class cmd_ignore(Command):
1421
"""Ignore a command or pattern.
2846
__doc__ = """Ignore specified files or patterns.
2848
See ``bzr help patterns`` for details on the syntax of patterns.
2850
If a .bzrignore file does not exist, the ignore command
2851
will create one and add the specified files or patterns to the newly
2852
created file. The ignore command will also automatically add the
2853
.bzrignore file to be versioned. Creating a .bzrignore file without
2854
the use of the ignore command will require an explicit add command.
1423
2856
To remove patterns from the ignore list, edit the .bzrignore file.
1425
If the pattern contains a slash, it is compared to the whole path
1426
from the branch root. Otherwise, it is compared to only the last
1427
component of the path. To match a file only in the root directory,
1430
Ignore patterns are case-insensitive on case-insensitive systems.
1432
Note: wildcards must be quoted from the shell on Unix.
1435
bzr ignore ./Makefile
1436
bzr ignore '*.class'
2857
After adding, editing or deleting that file either indirectly by
2858
using this command or directly by using an editor, be sure to commit
2861
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2862
the global ignore file can be found in the application data directory as
2863
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2864
Global ignores are not touched by this command. The global ignore file
2865
can be edited directly using an editor.
2867
Patterns prefixed with '!' are exceptions to ignore patterns and take
2868
precedence over regular ignores. Such exceptions are used to specify
2869
files that should be versioned which would otherwise be ignored.
2871
Patterns prefixed with '!!' act as regular ignore patterns, but have
2872
precedence over the '!' exception patterns.
2876
* Ignore patterns containing shell wildcards must be quoted from
2879
* Ignore patterns starting with "#" act as comments in the ignore file.
2880
To ignore patterns that begin with that character, use the "RE:" prefix.
2883
Ignore the top level Makefile::
2885
bzr ignore ./Makefile
2887
Ignore .class files in all directories...::
2889
bzr ignore "*.class"
2891
...but do not ignore "special.class"::
2893
bzr ignore "!special.class"
2895
Ignore files whose name begins with the "#" character::
2899
Ignore .o files under the lib directory::
2901
bzr ignore "lib/**/*.o"
2903
Ignore .o files under the lib directory::
2905
bzr ignore "RE:lib/.*\.o"
2907
Ignore everything but the "debian" toplevel directory::
2909
bzr ignore "RE:(?!debian/).*"
2911
Ignore everything except the "local" toplevel directory,
2912
but always ignore autosave files ending in ~, even under local/::
2915
bzr ignore "!./local"
1438
# TODO: Complain if the filename is absolute
1439
takes_args = ['name_pattern']
1441
def run(self, name_pattern):
1442
from bzrlib.atomicfile import AtomicFile
1445
tree, relpath = WorkingTree.open_containing(u'.')
1446
ifn = tree.abspath('.bzrignore')
1448
if os.path.exists(ifn):
1451
igns = f.read().decode('utf-8')
1457
# TODO: If the file already uses crlf-style termination, maybe
1458
# we should use that for the newly added lines?
1460
if igns and igns[-1] != '\n':
1462
igns += name_pattern + '\n'
1464
f = AtomicFile(ifn, 'wt')
1466
f.write(igns.encode('utf-8'))
1471
inv = tree.inventory
1472
if inv.path2id('.bzrignore'):
1473
mutter('.bzrignore is already versioned')
1475
mutter('need to make new .bzrignore file versioned')
1476
tree.add(['.bzrignore'])
2919
_see_also = ['status', 'ignored', 'patterns']
2920
takes_args = ['name_pattern*']
2921
takes_options = ['directory',
2922
Option('default-rules',
2923
help='Display the default ignore rules that bzr uses.')
2926
def run(self, name_pattern_list=None, default_rules=None,
2928
from bzrlib import ignores
2929
if default_rules is not None:
2930
# dump the default rules and exit
2931
for pattern in ignores.USER_DEFAULTS:
2932
self.outf.write("%s\n" % pattern)
2934
if not name_pattern_list:
2935
raise errors.BzrCommandError(gettext("ignore requires at least one "
2936
"NAME_PATTERN or --default-rules."))
2937
name_pattern_list = [globbing.normalize_pattern(p)
2938
for p in name_pattern_list]
2940
bad_patterns_count = 0
2941
for p in name_pattern_list:
2942
if not globbing.Globster.is_pattern_valid(p):
2943
bad_patterns_count += 1
2944
bad_patterns += ('\n %s' % p)
2946
msg = (ngettext('Invalid ignore pattern found. %s',
2947
'Invalid ignore patterns found. %s',
2948
bad_patterns_count) % bad_patterns)
2949
ui.ui_factory.show_error(msg)
2950
raise errors.InvalidPattern('')
2951
for name_pattern in name_pattern_list:
2952
if (name_pattern[0] == '/' or
2953
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2954
raise errors.BzrCommandError(gettext(
2955
"NAME_PATTERN should not be an absolute path"))
2956
tree, relpath = WorkingTree.open_containing(directory)
2957
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2958
ignored = globbing.Globster(name_pattern_list)
2960
self.add_cleanup(tree.lock_read().unlock)
2961
for entry in tree.list_files():
2965
if ignored.match(filename):
2966
matches.append(filename)
2967
if len(matches) > 0:
2968
self.outf.write(gettext("Warning: the following files are version "
2969
"controlled and match your ignore pattern:\n%s"
2970
"\nThese files will continue to be version controlled"
2971
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
1479
2974
class cmd_ignored(Command):
1480
"""List ignored files and the patterns that matched them.
1482
See also: bzr ignore"""
2975
__doc__ = """List ignored files and the patterns that matched them.
2977
List all the ignored files and the ignore pattern that caused the file to
2980
Alternatively, to list just the files::
2985
encoding_type = 'replace'
2986
_see_also = ['ignore', 'ls']
2987
takes_options = ['directory']
1483
2989
@display_command
1485
tree = WorkingTree.open_containing(u'.')[0]
2990
def run(self, directory=u'.'):
2991
tree = WorkingTree.open_containing(directory)[0]
2992
self.add_cleanup(tree.lock_read().unlock)
1486
2993
for path, file_class, kind, file_id, entry in tree.list_files():
1487
2994
if file_class != 'I':
1489
2996
## XXX: Slightly inefficient since this was already calculated
1490
2997
pat = tree.is_ignored(path)
1491
print '%-50s %s' % (path, pat)
2998
self.outf.write('%-50s %s\n' % (path, pat))
1494
3001
class cmd_lookup_revision(Command):
1495
"""Lookup the revision-id from a revision-number
3002
__doc__ = """Lookup the revision-id from a revision-number
1498
3005
bzr lookup-revision 33
1501
3008
takes_args = ['revno']
3009
takes_options = ['directory']
1503
3011
@display_command
1504
def run(self, revno):
3012
def run(self, revno, directory=u'.'):
1506
3014
revno = int(revno)
1507
3015
except ValueError:
1508
raise BzrCommandError("not a valid revision-number: %r" % revno)
1510
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
3016
raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3018
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3019
self.outf.write("%s\n" % revid)
1513
3022
class cmd_export(Command):
1514
"""Export past revision to destination directory.
3023
__doc__ = """Export current or past revision to a destination directory or archive.
1516
3025
If no revision is specified this exports the last committed revision.
1519
3028
given, try to find the format with the extension. If no extension
1520
3029
is found exports to a directory (equivalent to --format=dir).
1522
Root may be the top directory for tar, tgz and tbz2 formats. If none
1523
is given, the top directory will be the root name of the file.
1525
Note: export of tree with non-ascii filenames to zip is not supported.
1527
Supported formats Autodetected by extension
1528
----------------- -------------------------
3031
If root is supplied, it will be used as the root directory inside
3032
container formats (tar, zip, etc). If it is not supplied it will default
3033
to the exported filename. The root option has no effect for 'dir' format.
3035
If branch is omitted then the branch containing the current working
3036
directory will be used.
3038
Note: Export of tree with non-ASCII filenames to zip is not supported.
3040
================= =========================
3041
Supported formats Autodetected by extension
3042
================= =========================
1531
3045
tbz2 .tar.bz2, .tbz2
1532
3046
tgz .tar.gz, .tgz
3048
================= =========================
1535
takes_args = ['dest']
1536
takes_options = ['revision', 'format', 'root']
1537
def run(self, dest, revision=None, format=None, root=None):
3051
takes_args = ['dest', 'branch_or_subdir?']
3052
takes_options = ['directory',
3054
help="Type of file to export to.",
3057
Option('filters', help='Apply content filters to export the '
3058
'convenient form.'),
3061
help="Name of the root directory inside the exported file."),
3062
Option('per-file-timestamps',
3063
help='Set modification time of files to that of the last '
3064
'revision in which it was changed.'),
3066
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3067
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
1539
3068
from bzrlib.export import export
1540
tree = WorkingTree.open_containing(u'.')[0]
1542
if revision is None:
1543
# should be tree.last_revision FIXME
1544
rev_id = b.last_revision()
3070
if branch_or_subdir is None:
3071
tree = WorkingTree.open_containing(directory)[0]
1546
if len(revision) != 1:
1547
raise BzrError('bzr export --revision takes exactly 1 argument')
1548
rev_id = revision[0].in_history(b).rev_id
1549
t = b.repository.revision_tree(rev_id)
3075
b, subdir = Branch.open_containing(branch_or_subdir)
3078
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
1551
export(t, dest, format, root)
3080
export(rev_tree, dest, format, root, subdir, filtered=filters,
3081
per_file_timestamps=per_file_timestamps)
1552
3082
except errors.NoSuchExportFormat, e:
1553
raise BzrCommandError('Unsupported export format: %s' % e.format)
3083
raise errors.BzrCommandError(gettext('Unsupported export format: %s') % e.format)
1556
3086
class cmd_cat(Command):
1557
"""Write a file's text from a previous revision."""
1559
takes_options = ['revision']
3087
__doc__ = """Write the contents of a file as of a given revision to standard output.
3089
If no revision is nominated, the last revision is used.
3091
Note: Take care to redirect standard output when using this command on a
3096
takes_options = ['directory',
3097
Option('name-from-revision', help='The path name in the old tree.'),
3098
Option('filters', help='Apply content filters to display the '
3099
'convenience form.'),
1560
3102
takes_args = ['filename']
3103
encoding_type = 'exact'
1562
3105
@display_command
1563
def run(self, filename, revision=None):
3106
def run(self, filename, revision=None, name_from_revision=False,
3107
filters=False, directory=None):
1564
3108
if revision is not None and len(revision) != 1:
1565
raise BzrCommandError("bzr cat --revision takes exactly one number")
1568
tree, relpath = WorkingTree.open_containing(filename)
1570
except NotBranchError:
3109
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3110
" one revision specifier"))
3111
tree, branch, relpath = \
3112
_open_directory_or_containing_tree_or_branch(filename, directory)
3113
self.add_cleanup(branch.lock_read().unlock)
3114
return self._run(tree, branch, relpath, filename, revision,
3115
name_from_revision, filters)
3117
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
1573
3119
if tree is None:
1574
b, relpath = Branch.open_containing(filename)
1575
if revision is None:
1576
revision_id = b.last_revision()
1578
revision_id = revision[0].in_history(b).rev_id
1579
b.print_file(relpath, revision_id)
3120
tree = b.basis_tree()
3121
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3122
self.add_cleanup(rev_tree.lock_read().unlock)
3124
old_file_id = rev_tree.path2id(relpath)
3126
# TODO: Split out this code to something that generically finds the
3127
# best id for a path across one or more trees; it's like
3128
# find_ids_across_trees but restricted to find just one. -- mbp
3130
if name_from_revision:
3131
# Try in revision if requested
3132
if old_file_id is None:
3133
raise errors.BzrCommandError(gettext(
3134
"{0!r} is not present in revision {1}").format(
3135
filename, rev_tree.get_revision_id()))
3137
actual_file_id = old_file_id
3139
cur_file_id = tree.path2id(relpath)
3140
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3141
actual_file_id = cur_file_id
3142
elif old_file_id is not None:
3143
actual_file_id = old_file_id
3145
raise errors.BzrCommandError(gettext(
3146
"{0!r} is not present in revision {1}").format(
3147
filename, rev_tree.get_revision_id()))
3149
from bzrlib.filter_tree import ContentFilterTree
3150
filter_tree = ContentFilterTree(rev_tree,
3151
rev_tree._content_filter_stack)
3152
content = filter_tree.get_file_text(actual_file_id)
3154
content = rev_tree.get_file_text(actual_file_id)
3156
self.outf.write(content)
1582
3159
class cmd_local_time_offset(Command):
1583
"""Show the offset in seconds from GMT to local time."""
3160
__doc__ = """Show the offset in seconds from GMT to local time."""
1585
3162
@display_command
1587
print bzrlib.osutils.local_time_offset()
3164
self.outf.write("%s\n" % osutils.local_time_offset())
1591
3168
class cmd_commit(Command):
1592
"""Commit changes into a new revision.
1594
If no arguments are given, the entire tree is committed.
1596
If selected files are specified, only changes to those files are
1597
committed. If a directory is specified then the directory and everything
1598
within it is committed.
1600
A selected-file commit may fail in some cases where the committed
1601
tree would be invalid, such as trying to commit a file in a
1602
newly-added directory that is not itself committed.
3169
__doc__ = """Commit changes into a new revision.
3171
An explanatory message needs to be given for each commit. This is
3172
often done by using the --message option (getting the message from the
3173
command line) or by using the --file option (getting the message from
3174
a file). If neither of these options is given, an editor is opened for
3175
the user to enter the message. To see the changed files in the
3176
boilerplate text loaded into the editor, use the --show-diff option.
3178
By default, the entire tree is committed and the person doing the
3179
commit is assumed to be the author. These defaults can be overridden
3184
If selected files are specified, only changes to those files are
3185
committed. If a directory is specified then the directory and
3186
everything within it is committed.
3188
When excludes are given, they take precedence over selected files.
3189
For example, to commit only changes within foo, but not changes
3192
bzr commit foo -x foo/bar
3194
A selective commit after a merge is not yet supported.
3198
If the author of the change is not the same person as the committer,
3199
you can specify the author's name using the --author option. The
3200
name should be in the same format as a committer-id, e.g.
3201
"John Doe <jdoe@example.com>". If there is more than one author of
3202
the change you can specify the option multiple times, once for each
3207
A common mistake is to forget to add a new file or directory before
3208
running the commit command. The --strict option checks for unknown
3209
files and aborts the commit if any are found. More advanced pre-commit
3210
checks can be implemented by defining hooks. See ``bzr help hooks``
3215
If you accidentially commit the wrong changes or make a spelling
3216
mistake in the commit message say, you can use the uncommit command
3217
to undo it. See ``bzr help uncommit`` for details.
3219
Hooks can also be configured to run after a commit. This allows you
3220
to trigger updates to external systems like bug trackers. The --fixes
3221
option can be used to record the association between a revision and
3222
one or more bugs. See ``bzr help bugs`` for details.
1604
# TODO: Run hooks on tree to-be-committed, and after commit.
1606
# TODO: Strict commit that fails if there are deleted files.
1607
# (what does "deleted files" mean ??)
1609
# TODO: Give better message for -s, --summary, used by tla people
1611
# XXX: verbose currently does nothing
3225
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
1613
3226
takes_args = ['selected*']
1614
takes_options = ['message', 'verbose',
1616
help='commit even if nothing has changed'),
1617
Option('file', type=str,
1619
help='file containing commit message'),
1621
help="refuse to commit if there are unknown "
1622
"files in the working tree."),
1624
help="perform a local only commit in a bound "
1625
"branch. Such commits are not pushed to "
1626
"the master branch until a normal commit "
3228
ListOption('exclude', type=str, short_name='x',
3229
help="Do not consider changes made to a given path."),
3230
Option('message', type=unicode,
3232
help="Description of the new revision."),
3235
help='Commit even if nothing has changed.'),
3236
Option('file', type=str,
3239
help='Take commit message from this file.'),
3241
help="Refuse to commit if there are unknown "
3242
"files in the working tree."),
3243
Option('commit-time', type=str,
3244
help="Manually set a commit time using commit date "
3245
"format, e.g. '2009-10-10 08:00:00 +0100'."),
3246
ListOption('fixes', type=str,
3247
help="Mark a bug as being fixed by this revision "
3248
"(see \"bzr help bugs\")."),
3249
ListOption('author', type=unicode,
3250
help="Set the author's name, if it's different "
3251
"from the committer."),
3253
help="Perform a local commit in a bound "
3254
"branch. Local commits are not pushed to "
3255
"the master branch until a normal commit "
3258
Option('show-diff', short_name='p',
3259
help='When no message is supplied, show the diff along'
3260
' with the status summary in the message editor.'),
3262
help='When committing to a foreign version control '
3263
'system do not push data that can not be natively '
1630
3266
aliases = ['ci', 'checkin']
1632
def run(self, message=None, file=None, verbose=True, selected_list=None,
1633
unchanged=False, strict=False, local=False):
1634
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
1635
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1637
from bzrlib.msgeditor import edit_commit_message, \
1638
make_commit_message_template
1639
from tempfile import TemporaryFile
1641
# TODO: Need a blackbox test for invoking the external editor; may be
1642
# slightly problematic to run this cross-platform.
1644
# TODO: do more checks that the commit will succeed before
1645
# spending the user's valuable time typing a commit message.
1647
# TODO: if the commit *does* happen to fail, then save the commit
1648
# message to a temporary file where it can be recovered
1649
tree, selected_list = tree_files(selected_list)
3268
def _iter_bug_fix_urls(self, fixes, branch):
3269
default_bugtracker = None
3270
# Configure the properties for bug fixing attributes.
3271
for fixed_bug in fixes:
3272
tokens = fixed_bug.split(':')
3273
if len(tokens) == 1:
3274
if default_bugtracker is None:
3275
branch_config = branch.get_config()
3276
default_bugtracker = branch_config.get_user_option(
3278
if default_bugtracker is None:
3279
raise errors.BzrCommandError(gettext(
3280
"No tracker specified for bug %s. Use the form "
3281
"'tracker:id' or specify a default bug tracker "
3282
"using the `bugtracker` option.\nSee "
3283
"\"bzr help bugs\" for more information on this "
3284
"feature. Commit refused.") % fixed_bug)
3285
tag = default_bugtracker
3287
elif len(tokens) != 2:
3288
raise errors.BzrCommandError(gettext(
3289
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3290
"See \"bzr help bugs\" for more information on this "
3291
"feature.\nCommit refused.") % fixed_bug)
3293
tag, bug_id = tokens
3295
yield bugtracker.get_bug_url(tag, branch, bug_id)
3296
except errors.UnknownBugTrackerAbbreviation:
3297
raise errors.BzrCommandError(gettext(
3298
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3299
except errors.MalformedBugIdentifier, e:
3300
raise errors.BzrCommandError(gettext(
3301
"%s\nCommit refused.") % (str(e),))
3303
def run(self, message=None, file=None, verbose=False, selected_list=None,
3304
unchanged=False, strict=False, local=False, fixes=None,
3305
author=None, show_diff=False, exclude=None, commit_time=None,
3307
from bzrlib.errors import (
3312
from bzrlib.msgeditor import (
3313
edit_commit_message_encoded,
3314
generate_commit_message_template,
3315
make_commit_message_template_encoded,
3319
commit_stamp = offset = None
3320
if commit_time is not None:
3322
commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3323
except ValueError, e:
3324
raise errors.BzrCommandError(gettext(
3325
"Could not parse --commit-time: " + str(e)))
3329
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
1650
3330
if selected_list == ['']:
1651
3331
# workaround - commit of root of tree should be exactly the same
1652
3332
# as just default commit in that tree, and succeed even though
1653
3333
# selected-file merge commit is not done yet
1654
3334
selected_list = []
3338
bug_property = bugtracker.encode_fixes_bug_urls(
3339
self._iter_bug_fix_urls(fixes, tree.branch))
3341
properties['bugs'] = bug_property
1656
3343
if local and not tree.branch.get_bound_location():
1657
3344
raise errors.LocalRequiresBoundBranch()
1658
if message is None and not file:
1659
template = make_commit_message_template(tree, selected_list)
1660
message = edit_commit_message(template)
1662
raise BzrCommandError("please specify a commit message"
1663
" with either --message or --file")
1664
elif message and file:
1665
raise BzrCommandError("please specify either --message or --file")
1668
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1671
raise BzrCommandError("empty commit message specified")
1674
reporter = ReportCommitToLog()
1676
reporter = NullCommitReporter()
3346
if message is not None:
3348
file_exists = osutils.lexists(message)
3349
except UnicodeError:
3350
# The commit message contains unicode characters that can't be
3351
# represented in the filesystem encoding, so that can't be a
3356
'The commit message is a file name: "%(f)s".\n'
3357
'(use --file "%(f)s" to take commit message from that file)'
3359
ui.ui_factory.show_warning(warning_msg)
3361
message = message.replace('\r\n', '\n')
3362
message = message.replace('\r', '\n')
3364
raise errors.BzrCommandError(gettext(
3365
"please specify either --message or --file"))
3367
def get_message(commit_obj):
3368
"""Callback to get commit message"""
3372
my_message = f.read().decode(osutils.get_user_encoding())
3375
elif message is not None:
3376
my_message = message
3378
# No message supplied: make one up.
3379
# text is the status of the tree
3380
text = make_commit_message_template_encoded(tree,
3381
selected_list, diff=show_diff,
3382
output_encoding=osutils.get_user_encoding())
3383
# start_message is the template generated from hooks
3384
# XXX: Warning - looks like hooks return unicode,
3385
# make_commit_message_template_encoded returns user encoding.
3386
# We probably want to be using edit_commit_message instead to
3388
my_message = set_commit_message(commit_obj)
3389
if my_message is None:
3390
start_message = generate_commit_message_template(commit_obj)
3391
my_message = edit_commit_message_encoded(text,
3392
start_message=start_message)
3393
if my_message is None:
3394
raise errors.BzrCommandError(gettext("please specify a commit"
3395
" message with either --message or --file"))
3396
if my_message == "":
3397
raise errors.BzrCommandError(gettext("Empty commit message specified."
3398
" Please specify a commit message with either"
3399
" --message or --file or leave a blank message"
3400
" with --message \"\"."))
3403
# The API permits a commit with a filter of [] to mean 'select nothing'
3404
# but the command line should not do that.
3405
if not selected_list:
3406
selected_list = None
1679
tree.commit(message, specific_files=selected_list,
3408
tree.commit(message_callback=get_message,
3409
specific_files=selected_list,
1680
3410
allow_pointless=unchanged, strict=strict, local=local,
3411
reporter=None, verbose=verbose, revprops=properties,
3412
authors=author, timestamp=commit_stamp,
3414
exclude=tree.safe_relpath_files(exclude),
1682
3416
except PointlessCommit:
1683
# FIXME: This should really happen before the file is read in;
1684
# perhaps prepare the commit; get the message; then actually commit
1685
raise BzrCommandError("no changes to commit",
1686
["use --unchanged to commit anyhow"])
3417
raise errors.BzrCommandError(gettext("No changes to commit."
3418
" Please 'bzr add' the files you want to commit, or use"
3419
" --unchanged to force an empty commit."))
1687
3420
except ConflictsInTree:
1688
raise BzrCommandError("Conflicts detected in working tree. "
1689
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
3421
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3422
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1690
3424
except StrictCommitFailed:
1691
raise BzrCommandError("Commit refused because there are unknown "
1692
"files in the working tree.")
3425
raise errors.BzrCommandError(gettext("Commit refused because there are"
3426
" unknown files in the working tree."))
1693
3427
except errors.BoundBranchOutOfDate, e:
1694
raise BzrCommandError(str(e)
1695
+ ' Either unbind, update, or'
1696
' pass --local to commit.')
3428
e.extra_help = (gettext("\n"
3429
'To commit to master branch, run update and then commit.\n'
3430
'You can also pass --local to commit to continue working '
1699
3435
class cmd_check(Command):
1700
"""Validate consistency of branch history.
1702
This command checks various invariants about the branch storage to
1703
detect data corruption or bzr bugs.
3436
__doc__ = """Validate working tree structure, branch consistency and repository history.
3438
This command checks various invariants about branch and repository storage
3439
to detect data corruption or bzr bugs.
3441
The working tree and branch checks will only give output if a problem is
3442
detected. The output fields of the repository check are:
3445
This is just the number of revisions checked. It doesn't
3449
This is just the number of versionedfiles checked. It
3450
doesn't indicate a problem.
3452
unreferenced ancestors
3453
Texts that are ancestors of other texts, but
3454
are not properly referenced by the revision ancestry. This is a
3455
subtle problem that Bazaar can work around.
3458
This is the total number of unique file contents
3459
seen in the checked revisions. It does not indicate a problem.
3462
This is the total number of repeated texts seen
3463
in the checked revisions. Texts can be repeated when their file
3464
entries are modified, but the file contents are not. It does not
3467
If no restrictions are specified, all Bazaar data that is found at the given
3468
location will be checked.
3472
Check the tree and branch at 'foo'::
3474
bzr check --tree --branch foo
3476
Check only the repository at 'bar'::
3478
bzr check --repo bar
3480
Check everything at 'baz'::
1705
takes_args = ['branch?']
1706
takes_options = ['verbose']
1708
def run(self, branch=None, verbose=False):
1709
from bzrlib.check import check
1711
tree = WorkingTree.open_containing()[0]
1712
branch = tree.branch
1714
branch = Branch.open(branch)
1715
check(branch, verbose)
1718
class cmd_scan_cache(Command):
1721
from bzrlib.hashcache import HashCache
1727
print '%6d stats' % c.stat_count
1728
print '%6d in hashcache' % len(c._cache)
1729
print '%6d files removed from cache' % c.removed_count
1730
print '%6d hashes updated' % c.update_count
1731
print '%6d files changed too recently to cache' % c.danger_count
3485
_see_also = ['reconcile']
3486
takes_args = ['path?']
3487
takes_options = ['verbose',
3488
Option('branch', help="Check the branch related to the"
3489
" current directory."),
3490
Option('repo', help="Check the repository related to the"
3491
" current directory."),
3492
Option('tree', help="Check the working tree related to"
3493
" the current directory.")]
3495
def run(self, path=None, verbose=False, branch=False, repo=False,
3497
from bzrlib.check import check_dwim
3500
if not branch and not repo and not tree:
3501
branch = repo = tree = True
3502
check_dwim(path, verbose, do_branch=branch, do_repo=repo, do_tree=tree)
1737
3505
class cmd_upgrade(Command):
1738
"""Upgrade branch storage to current format.
1740
The check command or bzr developers may sometimes advise you to run
1741
this command. When the default format has changed you may also be warned
1742
during other operations to upgrade.
3506
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3508
When the default format has changed after a major new release of
3509
Bazaar, you may be informed during certain operations that you
3510
should upgrade. Upgrading to a newer format may improve performance
3511
or make new features available. It may however limit interoperability
3512
with older repositories or with older versions of Bazaar.
3514
If you wish to upgrade to a particular format rather than the
3515
current default, that can be specified using the --format option.
3516
As a consequence, you can use the upgrade command this way to
3517
"downgrade" to an earlier format, though some conversions are
3518
a one way process (e.g. changing from the 1.x default to the
3519
2.x default) so downgrading is not always possible.
3521
A backup.bzr.~#~ directory is created at the start of the conversion
3522
process (where # is a number). By default, this is left there on
3523
completion. If the conversion fails, delete the new .bzr directory
3524
and rename this one back in its place. Use the --clean option to ask
3525
for the backup.bzr directory to be removed on successful conversion.
3526
Alternatively, you can delete it by hand if everything looks good
3529
If the location given is a shared repository, dependent branches
3530
are also converted provided the repository converts successfully.
3531
If the conversion of a branch fails, remaining branches are still
3534
For more information on upgrades, see the Bazaar Upgrade Guide,
3535
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3538
_see_also = ['check', 'reconcile', 'formats']
1744
3539
takes_args = ['url?']
1745
3540
takes_options = [
1747
help='Upgrade to a specific format. Current formats'
1748
' are: default, knit, metaweave and weave.'
1749
' Default is knit; metaweave and weave are'
1751
type=get_format_type),
1755
def run(self, url='.', format=None):
3541
RegistryOption('format',
3542
help='Upgrade to a specific format. See "bzr help'
3543
' formats" for details.',
3544
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3545
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3546
value_switches=True, title='Branch format'),
3548
help='Remove the backup.bzr directory if successful.'),
3550
help="Show what would be done, but don't actually do anything."),
3553
def run(self, url='.', format=None, clean=False, dry_run=False):
1756
3554
from bzrlib.upgrade import upgrade
1758
format = get_format_type('default')
1759
upgrade(url, format)
3555
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3557
if len(exceptions) == 1:
3558
# Compatibility with historical behavior
1762
3564
class cmd_whoami(Command):
1763
"""Show bzr user id."""
1764
takes_options = ['email']
3565
__doc__ = """Show or set bzr user id.
3568
Show the email of the current user::
3572
Set the current user::
3574
bzr whoami "Frank Chu <fchu@example.com>"
3576
takes_options = [ 'directory',
3578
help='Display email address only.'),
3580
help='Set identity for the current branch instead of '
3583
takes_args = ['name?']
3584
encoding_type = 'replace'
1766
3586
@display_command
1767
def run(self, email=False):
1769
b = WorkingTree.open_containing(u'.')[0].branch
1770
config = bzrlib.config.BranchConfig(b)
1771
except NotBranchError:
1772
config = bzrlib.config.GlobalConfig()
3587
def run(self, email=False, branch=False, name=None, directory=None):
3589
if directory is None:
3590
# use branch if we're inside one; otherwise global config
3592
c = Branch.open_containing(u'.')[0].get_config()
3593
except errors.NotBranchError:
3594
c = _mod_config.GlobalConfig()
3596
c = Branch.open(directory).get_config()
3598
self.outf.write(c.user_email() + '\n')
3600
self.outf.write(c.username() + '\n')
1775
print config.user_email()
3604
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3607
# display a warning if an email address isn't included in the given name.
3609
_mod_config.extract_email_address(name)
3610
except errors.NoEmailInUsername, e:
3611
warning('"%s" does not seem to contain an email address. '
3612
'This is allowed, but not recommended.', name)
3614
# use global config unless --branch given
3616
if directory is None:
3617
c = Branch.open_containing(u'.')[0].get_config()
3619
c = Branch.open(directory).get_config()
1777
print config.username()
3621
c = _mod_config.GlobalConfig()
3622
c.set_user_option('email', name)
1780
3625
class cmd_nick(Command):
1781
"""Print or set the branch nickname.
1783
If unset, the tree root directory name is used as the nickname
1784
To print the current nickname, execute with no argument.
3626
__doc__ = """Print or set the branch nickname.
3628
If unset, the tree root directory name is used as the nickname.
3629
To print the current nickname, execute with no argument.
3631
Bound branches use the nickname of its master branch unless it is set
3635
_see_also = ['info']
1786
3636
takes_args = ['nickname?']
1787
def run(self, nickname=None):
1788
branch = Branch.open_containing(u'.')[0]
3637
takes_options = ['directory']
3638
def run(self, nickname=None, directory=u'.'):
3639
branch = Branch.open_containing(directory)[0]
1789
3640
if nickname is None:
1790
3641
self.printme(branch)
1794
3645
@display_command
1795
3646
def printme(self, branch):
3647
self.outf.write('%s\n' % branch.nick)
3650
class cmd_alias(Command):
3651
__doc__ = """Set/unset and display aliases.
3654
Show the current aliases::
3658
Show the alias specified for 'll'::
3662
Set an alias for 'll'::
3664
bzr alias ll="log --line -r-10..-1"
3666
To remove an alias for 'll'::
3668
bzr alias --remove ll
3671
takes_args = ['name?']
3673
Option('remove', help='Remove the alias.'),
3676
def run(self, name=None, remove=False):
3678
self.remove_alias(name)
3680
self.print_aliases()
3682
equal_pos = name.find('=')
3684
self.print_alias(name)
3686
self.set_alias(name[:equal_pos], name[equal_pos+1:])
3688
def remove_alias(self, alias_name):
3689
if alias_name is None:
3690
raise errors.BzrCommandError(gettext(
3691
'bzr alias --remove expects an alias to remove.'))
3692
# If alias is not found, print something like:
3693
# unalias: foo: not found
3694
c = _mod_config.GlobalConfig()
3695
c.unset_alias(alias_name)
3698
def print_aliases(self):
3699
"""Print out the defined aliases in a similar format to bash."""
3700
aliases = _mod_config.GlobalConfig().get_aliases()
3701
for key, value in sorted(aliases.iteritems()):
3702
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3705
def print_alias(self, alias_name):
3706
from bzrlib.commands import get_alias
3707
alias = get_alias(alias_name)
3709
self.outf.write("bzr alias: %s: not found\n" % alias_name)
3712
'bzr alias %s="%s"\n' % (alias_name, ' '.join(alias)))
3714
def set_alias(self, alias_name, alias_command):
3715
"""Save the alias in the global config."""
3716
c = _mod_config.GlobalConfig()
3717
c.set_alias(alias_name, alias_command)
1799
3720
class cmd_selftest(Command):
1800
"""Run internal test suite.
1802
This creates temporary test directories in the working directory,
1803
but not existing data is affected. These directories are deleted
1804
if the tests pass, or left behind to help in debugging if they
1805
fail and --keep-output is specified.
1807
If arguments are given, they are regular expressions that say
1808
which tests should run.
3721
__doc__ = """Run internal test suite.
3723
If arguments are given, they are regular expressions that say which tests
3724
should run. Tests matching any expression are run, and other tests are
3727
Alternatively if --first is given, matching tests are run first and then
3728
all other tests are run. This is useful if you have been working in a
3729
particular area, but want to make sure nothing else was broken.
3731
If --exclude is given, tests that match that regular expression are
3732
excluded, regardless of whether they match --first or not.
3734
To help catch accidential dependencies between tests, the --randomize
3735
option is useful. In most cases, the argument used is the word 'now'.
3736
Note that the seed used for the random number generator is displayed
3737
when this option is used. The seed can be explicitly passed as the
3738
argument to this option if required. This enables reproduction of the
3739
actual ordering used if and when an order sensitive problem is encountered.
3741
If --list-only is given, the tests that would be run are listed. This is
3742
useful when combined with --first, --exclude and/or --randomize to
3743
understand their impact. The test harness reports "Listed nn tests in ..."
3744
instead of "Ran nn tests in ..." when list mode is enabled.
1810
3746
If the global option '--no-plugins' is given, plugins are not loaded
1811
3747
before running the selftests. This has two effects: features provided or
1812
3748
modified by plugins will not be tested, and tests provided by plugins will
1817
bzr --no-plugins selftest -v
3751
Tests that need working space on disk use a common temporary directory,
3752
typically inside $TMPDIR or /tmp.
3754
If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
3755
into a pdb postmortem session.
3757
The --coverage=DIRNAME global option produces a report with covered code
3761
Run only tests relating to 'ignore'::
3765
Disable plugins and list tests as they're run::
3767
bzr --no-plugins selftest -v
1819
# TODO: --list should give a list of all available tests
1821
3769
# NB: this is used from the class without creating an instance, which is
1822
3770
# why it does not have a self parameter.
1823
3771
def get_transport_type(typestring):
1824
3772
"""Parse and return a transport specifier."""
1825
3773
if typestring == "sftp":
1826
from bzrlib.transport.sftp import SFTPAbsoluteServer
1827
return SFTPAbsoluteServer
1828
if typestring == "memory":
1829
from bzrlib.transport.memory import MemoryServer
1831
if typestring == "fakenfs":
1832
from bzrlib.transport.fakenfs import FakeNFSServer
1833
return FakeNFSServer
3774
from bzrlib.tests import stub_sftp
3775
return stub_sftp.SFTPAbsoluteServer
3776
elif typestring == "memory":
3777
from bzrlib.tests import test_server
3778
return memory.MemoryServer
3779
elif typestring == "fakenfs":
3780
from bzrlib.tests import test_server
3781
return test_server.FakeNFSServer
1834
3782
msg = "No known transport type %s. Supported types are: sftp\n" %\
1836
raise BzrCommandError(msg)
3784
raise errors.BzrCommandError(msg)
1839
3787
takes_args = ['testspecs*']
1840
3788
takes_options = ['verbose',
1841
Option('one', help='stop when one test fails'),
1842
Option('keep-output',
1843
help='keep output directories when tests fail'),
3790
help='Stop when one test fails.',
1845
3794
help='Use a different transport by default '
1846
3795
'throughout the test suite.',
1847
3796
type=get_transport_type),
1848
Option('benchmark', help='run the bzr bencharks.'),
3798
help='Run the benchmarks rather than selftests.',
1849
3800
Option('lsprof-timed',
1850
help='generate lsprof output for benchmarked'
3801
help='Generate lsprof output for benchmarked'
1851
3802
' sections of code.'),
3803
Option('lsprof-tests',
3804
help='Generate lsprof output for each test.'),
3806
help='Run all tests, but run specified tests first.',
3810
help='List the tests instead of running them.'),
3811
RegistryOption('parallel',
3812
help="Run the test suite in parallel.",
3813
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3814
value_switches=False,
3816
Option('randomize', type=str, argname="SEED",
3817
help='Randomize the order of tests using the given'
3818
' seed or "now" for the current time.'),
3819
ListOption('exclude', type=str, argname="PATTERN",
3821
help='Exclude tests that match this regular'
3824
help='Output test progress via subunit.'),
3825
Option('strict', help='Fail on missing dependencies or '
3827
Option('load-list', type=str, argname='TESTLISTFILE',
3828
help='Load a test id list from a text file.'),
3829
ListOption('debugflag', type=str, short_name='E',
3830
help='Turn on a selftest debug flag.'),
3831
ListOption('starting-with', type=str, argname='TESTID',
3832
param_name='starting_with', short_name='s',
3834
'Load only the tests starting with TESTID.'),
3836
help="By default we disable fsync and fdatasync"
3837
" while running the test suite.")
1854
def run(self, testspecs_list=None, verbose=None, one=False,
1855
keep_output=False, transport=None, benchmark=None,
1858
from bzrlib.tests import selftest
1859
import bzrlib.benchmarks as benchmarks
1860
# we don't want progress meters from the tests to go to the
1861
# real output; and we don't want log messages cluttering up
1863
save_ui = bzrlib.ui.ui_factory
1864
print '%10s: %s' % ('bzr', bzrlib.osutils.realpath(sys.argv[0]))
1865
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1867
bzrlib.trace.info('running tests...')
3839
encoding_type = 'replace'
3842
Command.__init__(self)
3843
self.additional_selftest_args = {}
3845
def run(self, testspecs_list=None, verbose=False, one=False,
3846
transport=None, benchmark=None,
3848
first=False, list_only=False,
3849
randomize=None, exclude=None, strict=False,
3850
load_list=None, debugflag=None, starting_with=None, subunit=False,
3851
parallel=None, lsprof_tests=False,
3853
from bzrlib import tests
3855
if testspecs_list is not None:
3856
pattern = '|'.join(testspecs_list)
3861
from bzrlib.tests import SubUnitBzrRunner
3863
raise errors.BzrCommandError(gettext("subunit not available. subunit "
3864
"needs to be installed to use --subunit."))
3865
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3866
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3867
# stdout, which would corrupt the subunit stream.
3868
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3869
# following code can be deleted when it's sufficiently deployed
3870
# -- vila/mgz 20100514
3871
if (sys.platform == "win32"
3872
and getattr(sys.stdout, 'fileno', None) is not None):
3874
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3876
self.additional_selftest_args.setdefault(
3877
'suite_decorators', []).append(parallel)
3879
raise errors.BzrCommandError(gettext(
3880
"--benchmark is no longer supported from bzr 2.2; "
3881
"use bzr-usertest instead"))
3882
test_suite_factory = None
3884
exclude_pattern = None
3886
exclude_pattern = '(' + '|'.join(exclude) + ')'
3888
self._disable_fsync()
3889
selftest_kwargs = {"verbose": verbose,
3891
"stop_on_failure": one,
3892
"transport": transport,
3893
"test_suite_factory": test_suite_factory,
3894
"lsprof_timed": lsprof_timed,
3895
"lsprof_tests": lsprof_tests,
3896
"matching_tests_first": first,
3897
"list_only": list_only,
3898
"random_seed": randomize,
3899
"exclude_pattern": exclude_pattern,
3901
"load_list": load_list,
3902
"debug_flags": debugflag,
3903
"starting_with": starting_with
3905
selftest_kwargs.update(self.additional_selftest_args)
3907
# Make deprecation warnings visible, unless -Werror is set
3908
cleanup = symbol_versioning.activate_deprecation_warnings(
1869
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1870
if testspecs_list is not None:
1871
pattern = '|'.join(testspecs_list)
1875
test_suite_factory = benchmarks.test_suite
1879
test_suite_factory = None
1882
result = selftest(verbose=verbose,
1884
stop_on_failure=one,
1885
keep_output=keep_output,
1886
transport=transport,
1887
test_suite_factory=test_suite_factory,
1888
lsprof_timed=lsprof_timed)
1890
bzrlib.trace.info('tests passed')
1892
bzrlib.trace.info('tests failed')
1893
return int(not result)
3911
result = tests.selftest(**selftest_kwargs)
1895
bzrlib.ui.ui_factory = save_ui
1898
def _get_bzr_branch():
1899
"""If bzr is run from a branch, return Branch or None"""
1900
import bzrlib.errors
1901
from bzrlib.branch import Branch
1902
from bzrlib.osutils import abspath
1903
from os.path import dirname
1906
branch = Branch.open(dirname(abspath(dirname(__file__))))
1908
except bzrlib.errors.BzrError:
1913
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1914
# is bzrlib itself in a branch?
1915
branch = _get_bzr_branch()
1917
rh = branch.revision_history()
1919
print " bzr checkout, revision %d" % (revno,)
1920
print " nick: %s" % (branch.nick,)
1922
print " revid: %s" % (rh[-1],)
1923
print "Using python interpreter:", sys.executable
1925
print "Using python standard library:", os.path.dirname(site.__file__)
1926
print "Using bzrlib:",
1927
if len(bzrlib.__path__) > 1:
1928
# print repr, which is a good enough way of making it clear it's
1929
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1930
print repr(bzrlib.__path__)
1932
print bzrlib.__path__[0]
1935
print bzrlib.__copyright__
1936
print "http://bazaar-vcs.org/"
1938
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
1939
print "you may use, modify and redistribute it under the terms of the GNU"
1940
print "General Public License version 2 or later."
3914
return int(not result)
3916
def _disable_fsync(self):
3917
"""Change the 'os' functionality to not synchronize."""
3918
self._orig_fsync = getattr(os, 'fsync', None)
3919
if self._orig_fsync is not None:
3920
os.fsync = lambda filedes: None
3921
self._orig_fdatasync = getattr(os, 'fdatasync', None)
3922
if self._orig_fdatasync is not None:
3923
os.fdatasync = lambda filedes: None
1943
3926
class cmd_version(Command):
1944
"""Show version of bzr."""
3927
__doc__ = """Show version of bzr."""
3929
encoding_type = 'replace'
3931
Option("short", help="Print just the version number."),
1945
3934
@display_command
3935
def run(self, short=False):
3936
from bzrlib.version import show_version
3938
self.outf.write(bzrlib.version_string + '\n')
3940
show_version(to_file=self.outf)
1949
3943
class cmd_rocks(Command):
1950
"""Statement of optimism."""
3944
__doc__ = """Statement of optimism."""
1952
3948
@display_command
1954
print "it sure does!"
3950
self.outf.write(gettext("It sure does!\n"))
1957
3953
class cmd_find_merge_base(Command):
1958
"""Find and print a base revision for merging two branches.
3954
__doc__ = """Find and print a base revision for merging two branches."""
1960
3955
# TODO: Options to specify revisions on either side, as if
1961
3956
# merging only part of the history.
1962
3957
takes_args = ['branch', 'other']
1965
3960
@display_command
1966
3961
def run(self, branch, other):
1967
from bzrlib.revision import common_ancestor, MultipleRevisionSources
3962
from bzrlib.revision import ensure_null
1969
3964
branch1 = Branch.open_containing(branch)[0]
1970
3965
branch2 = Branch.open_containing(other)[0]
1972
history_1 = branch1.revision_history()
1973
history_2 = branch2.revision_history()
1975
last1 = branch1.last_revision()
1976
last2 = branch2.last_revision()
1978
source = MultipleRevisionSources(branch1.repository,
1981
base_rev_id = common_ancestor(last1, last2, source)
1983
print 'merge base is revision %s' % base_rev_id
1987
if base_revno is None:
1988
raise bzrlib.errors.UnrelatedBranches()
1990
print ' r%-6d in %s' % (base_revno, branch)
1992
other_revno = branch2.revision_id_to_revno(base_revid)
1994
print ' r%-6d in %s' % (other_revno, other)
3966
self.add_cleanup(branch1.lock_read().unlock)
3967
self.add_cleanup(branch2.lock_read().unlock)
3968
last1 = ensure_null(branch1.last_revision())
3969
last2 = ensure_null(branch2.last_revision())
3971
graph = branch1.repository.get_graph(branch2.repository)
3972
base_rev_id = graph.find_unique_lca(last1, last2)
3974
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
1998
3977
class cmd_merge(Command):
1999
"""Perform a three-way merge.
2001
The branch is the branch you will merge from. By default, it will
2002
merge the latest revision. If you specify a revision, that
2003
revision will be merged. If you specify two revisions, the first
2004
will be used as a BASE, and the second one as OTHER. Revision
2005
numbers are always relative to the specified branch.
2007
By default, bzr will try to merge in all new work from the other
2008
branch, automatically determining an appropriate base. If this
2009
fails, you may need to give an explicit base.
3978
__doc__ = """Perform a three-way merge.
3980
The source of the merge can be specified either in the form of a branch,
3981
or in the form of a path to a file containing a merge directive generated
3982
with bzr send. If neither is specified, the default is the upstream branch
3983
or the branch most recently merged using --remember. The source of the
3984
merge may also be specified in the form of a path to a file in another
3985
branch: in this case, only the modifications to that file are merged into
3986
the current working tree.
3988
When merging from a branch, by default bzr will try to merge in all new
3989
work from the other branch, automatically determining an appropriate base
3990
revision. If this fails, you may need to give an explicit base.
3992
To pick a different ending revision, pass "--revision OTHER". bzr will
3993
try to merge in all new work up to and including revision OTHER.
3995
If you specify two values, "--revision BASE..OTHER", only revisions BASE
3996
through OTHER, excluding BASE but including OTHER, will be merged. If this
3997
causes some revisions to be skipped, i.e. if the destination branch does
3998
not already contain revision BASE, such a merge is commonly referred to as
3999
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4000
cherrypicks. The changes look like a normal commit, and the history of the
4001
changes from the other branch is not stored in the commit.
4003
Revision numbers are always relative to the source branch.
2011
4005
Merge will do its best to combine the changes in two branches, but there
2012
4006
are some kinds of problems only a human can fix. When it encounters those,
2013
4007
it will mark a conflict. A conflict means that you need to fix something,
2016
4010
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
2018
If there is no default branch set, the first merge will set it. After
2019
that, you can omit the branch to use the default. To change the
2020
default, use --remember.
2024
To merge the latest revision from bzr.dev
2025
bzr merge ../bzr.dev
2027
To merge changes up to and including revision 82 from bzr.dev
2028
bzr merge -r 82 ../bzr.dev
2030
To merge the changes introduced by 82, without previous changes:
2031
bzr merge -r 81..82 ../bzr.dev
4012
If there is no default branch set, the first merge will set it (use
4013
--no-remember to avoid setting it). After that, you can omit the branch
4014
to use the default. To change the default, use --remember. The value will
4015
only be saved if the remote location can be accessed.
4017
The results of the merge are placed into the destination working
4018
directory, where they can be reviewed (with bzr diff), tested, and then
4019
committed to record the result of the merge.
2033
4021
merge refuses to run if there are any uncommitted changes, unless
2036
The following merge types are available:
4022
--force is given. If --force is given, then the changes from the source
4023
will be merged with the current working tree, including any uncommitted
4024
changes in the tree. The --force option can also be used to create a
4025
merge revision which has more than two parents.
4027
If one would like to merge changes from the working tree of the other
4028
branch without merging any committed revisions, the --uncommitted option
4031
To select only some changes to merge, use "merge -i", which will prompt
4032
you to apply each diff hunk and file change, similar to "shelve".
4035
To merge all new revisions from bzr.dev::
4037
bzr merge ../bzr.dev
4039
To merge changes up to and including revision 82 from bzr.dev::
4041
bzr merge -r 82 ../bzr.dev
4043
To merge the changes introduced by 82, without previous changes::
4045
bzr merge -r 81..82 ../bzr.dev
4047
To apply a merge directive contained in /tmp/merge::
4049
bzr merge /tmp/merge
4051
To create a merge revision with three parents from two branches
4052
feature1a and feature1b:
4054
bzr merge ../feature1a
4055
bzr merge ../feature1b --force
4056
bzr commit -m 'revision with three parents'
2038
takes_args = ['branch?']
2039
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2040
Option('show-base', help="Show base revision text in "
2044
from merge import merge_type_help
2045
from inspect import getdoc
2046
return getdoc(self) + '\n' + merge_type_help()
2048
def run(self, branch=None, revision=None, force=False, merge_type=None,
2049
show_base=False, reprocess=False, remember=False):
4059
encoding_type = 'exact'
4060
_see_also = ['update', 'remerge', 'status-flags', 'send']
4061
takes_args = ['location?']
4066
help='Merge even if the destination tree has uncommitted changes.'),
4070
Option('show-base', help="Show base revision text in "
4072
Option('uncommitted', help='Apply uncommitted changes'
4073
' from a working copy, instead of branch changes.'),
4074
Option('pull', help='If the destination is already'
4075
' completely merged into the source, pull from the'
4076
' source rather than merging. When this happens,'
4077
' you do not need to commit the result.'),
4078
custom_help('directory',
4079
help='Branch to merge into, '
4080
'rather than the one containing the working directory.'),
4081
Option('preview', help='Instead of merging, show a diff of the'
4083
Option('interactive', help='Select changes interactively.',
4087
def run(self, location=None, revision=None, force=False,
4088
merge_type=None, show_base=False, reprocess=None, remember=None,
4089
uncommitted=False, pull=False,
2050
4094
if merge_type is None:
2051
merge_type = Merge3Merger
2053
tree = WorkingTree.open_containing(u'.')[0]
4095
merge_type = _mod_merge.Merge3Merger
4097
if directory is None: directory = u'.'
4098
possible_transports = []
4100
allow_pending = True
4101
verified = 'inapplicable'
4103
tree = WorkingTree.open_containing(directory)[0]
4104
if tree.branch.revno() == 0:
4105
raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4106
'https://bugs.launchpad.net/bzr/+bug/308562'))
4109
basis_tree = tree.revision_tree(tree.last_revision())
4110
except errors.NoSuchRevision:
4111
basis_tree = tree.basis_tree()
4113
# die as quickly as possible if there are uncommitted changes
4115
if tree.has_changes():
4116
raise errors.UncommittedChanges(tree)
4118
view_info = _get_view_info_for_change_reporter(tree)
4119
change_reporter = delta._ChangeReporter(
4120
unversioned_filter=tree.is_ignored, view_info=view_info)
4121
pb = ui.ui_factory.nested_progress_bar()
4122
self.add_cleanup(pb.finished)
4123
self.add_cleanup(tree.lock_write().unlock)
4124
if location is not None:
4126
mergeable = bundle.read_mergeable_from_url(location,
4127
possible_transports=possible_transports)
4128
except errors.NotABundle:
4132
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4133
' with bundles or merge directives.'))
4135
if revision is not None:
4136
raise errors.BzrCommandError(gettext(
4137
'Cannot use -r with merge directives or bundles'))
4138
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4141
if merger is None and uncommitted:
4142
if revision is not None and len(revision) > 0:
4143
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4144
' --revision at the same time.'))
4145
merger = self.get_merger_from_uncommitted(tree, location, None)
4146
allow_pending = False
4149
merger, allow_pending = self._get_merger_from_branch(tree,
4150
location, revision, remember, possible_transports, None)
4152
merger.merge_type = merge_type
4153
merger.reprocess = reprocess
4154
merger.show_base = show_base
4155
self.sanity_check_merger(merger)
4156
if (merger.base_rev_id == merger.other_rev_id and
4157
merger.other_rev_id is not None):
4158
# check if location is a nonexistent file (and not a branch) to
4159
# disambiguate the 'Nothing to do'
4160
if merger.interesting_files:
4161
if not merger.other_tree.has_filename(
4162
merger.interesting_files[0]):
4163
note(gettext("merger: ") + str(merger))
4164
raise errors.PathsDoNotExist([location])
4165
note(gettext('Nothing to do.'))
4167
if pull and not preview:
4168
if merger.interesting_files is not None:
4169
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4170
if (merger.base_rev_id == tree.last_revision()):
4171
result = tree.pull(merger.other_branch, False,
4172
merger.other_rev_id)
4173
result.report(self.outf)
4175
if merger.this_basis is None:
4176
raise errors.BzrCommandError(gettext(
4177
"This branch has no commits."
4178
" (perhaps you would prefer 'bzr pull')"))
4180
return self._do_preview(merger)
4182
return self._do_interactive(merger)
4184
return self._do_merge(merger, change_reporter, allow_pending,
4187
def _get_preview(self, merger):
4188
tree_merger = merger.make_merger()
4189
tt = tree_merger.make_preview_transform()
4190
self.add_cleanup(tt.finalize)
4191
result_tree = tt.get_preview_tree()
4194
def _do_preview(self, merger):
4195
from bzrlib.diff import show_diff_trees
4196
result_tree = self._get_preview(merger)
4197
path_encoding = osutils.get_diff_header_encoding()
4198
show_diff_trees(merger.this_tree, result_tree, self.outf,
4199
old_label='', new_label='',
4200
path_encoding=path_encoding)
4202
def _do_merge(self, merger, change_reporter, allow_pending, verified):
4203
merger.change_reporter = change_reporter
4204
conflict_count = merger.do_merge()
4206
merger.set_pending()
4207
if verified == 'failed':
4208
warning('Preview patch does not match changes')
4209
if conflict_count != 0:
4214
def _do_interactive(self, merger):
4215
"""Perform an interactive merge.
4217
This works by generating a preview tree of the merge, then using
4218
Shelver to selectively remove the differences between the working tree
4219
and the preview tree.
4221
from bzrlib import shelf_ui
4222
result_tree = self._get_preview(merger)
4223
writer = bzrlib.option.diff_writer_registry.get()
4224
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
4225
reporter=shelf_ui.ApplyReporter(),
4226
diff_writer=writer(sys.stdout))
4232
def sanity_check_merger(self, merger):
4233
if (merger.show_base and
4234
not merger.merge_type is _mod_merge.Merge3Merger):
4235
raise errors.BzrCommandError(gettext("Show-base is not supported for this"
4236
" merge type. %s") % merger.merge_type)
4237
if merger.reprocess is None:
4238
if merger.show_base:
4239
merger.reprocess = False
4241
# Use reprocess if the merger supports it
4242
merger.reprocess = merger.merge_type.supports_reprocess
4243
if merger.reprocess and not merger.merge_type.supports_reprocess:
4244
raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
4245
" for merge type %s.") %
4247
if merger.reprocess and merger.show_base:
4248
raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
4251
def _get_merger_from_branch(self, tree, location, revision, remember,
4252
possible_transports, pb):
4253
"""Produce a merger from a location, assuming it refers to a branch."""
4254
from bzrlib.tag import _merge_tags_if_possible
4255
# find the branch locations
4256
other_loc, user_location = self._select_branch_location(tree, location,
4258
if revision is not None and len(revision) == 2:
4259
base_loc, _unused = self._select_branch_location(tree,
4260
location, revision, 0)
4262
base_loc = other_loc
4264
other_branch, other_path = Branch.open_containing(other_loc,
4265
possible_transports)
4266
if base_loc == other_loc:
4267
base_branch = other_branch
4269
base_branch, base_path = Branch.open_containing(base_loc,
4270
possible_transports)
4271
# Find the revision ids
4272
other_revision_id = None
4273
base_revision_id = None
4274
if revision is not None:
4275
if len(revision) >= 1:
4276
other_revision_id = revision[-1].as_revision_id(other_branch)
4277
if len(revision) == 2:
4278
base_revision_id = revision[0].as_revision_id(base_branch)
4279
if other_revision_id is None:
4280
other_revision_id = _mod_revision.ensure_null(
4281
other_branch.last_revision())
4282
# Remember where we merge from. We need to remember if:
4283
# - user specify a location (and we don't merge from the parent
4285
# - user ask to remember or there is no previous location set to merge
4286
# from and user didn't ask to *not* remember
4287
if (user_location is not None
4289
or (remember is None
4290
and tree.branch.get_submit_branch() is None)))):
4291
tree.branch.set_submit_branch(other_branch.base)
4292
# Merge tags (but don't set them in the master branch yet, the user
4293
# might revert this merge). Commit will propagate them.
4294
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
4295
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4296
other_revision_id, base_revision_id, other_branch, base_branch)
4297
if other_path != '':
4298
allow_pending = False
4299
merger.interesting_files = [other_path]
4301
allow_pending = True
4302
return merger, allow_pending
4304
def get_merger_from_uncommitted(self, tree, location, pb):
4305
"""Get a merger for uncommitted changes.
4307
:param tree: The tree the merger should apply to.
4308
:param location: The location containing uncommitted changes.
4309
:param pb: The progress bar to use for showing progress.
4311
location = self._select_branch_location(tree, location)[0]
4312
other_tree, other_path = WorkingTree.open_containing(location)
4313
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
4314
if other_path != '':
4315
merger.interesting_files = [other_path]
4318
def _select_branch_location(self, tree, user_location, revision=None,
4320
"""Select a branch location, according to possible inputs.
4322
If provided, branches from ``revision`` are preferred. (Both
4323
``revision`` and ``index`` must be supplied.)
4325
Otherwise, the ``location`` parameter is used. If it is None, then the
4326
``submit`` or ``parent`` location is used, and a note is printed.
4328
:param tree: The working tree to select a branch for merging into
4329
:param location: The location entered by the user
4330
:param revision: The revision parameter to the command
4331
:param index: The index to use for the revision parameter. Negative
4332
indices are permitted.
4333
:return: (selected_location, user_location). The default location
4334
will be the user-entered location.
4336
if (revision is not None and index is not None
4337
and revision[index] is not None):
4338
branch = revision[index].get_branch()
2056
4339
if branch is not None:
2057
reader = BundleReader(file(branch, 'rb'))
2061
if e.errno not in (errno.ENOENT, errno.EISDIR):
2066
if reader is not None:
2067
conflicts = merge_bundle(reader, tree, not force, merge_type,
2068
reprocess, show_base)
2074
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2076
if revision is None or len(revision) < 1:
2078
other = [branch, -1]
2079
other_branch, path = Branch.open_containing(branch)
2081
if len(revision) == 1:
2083
other_branch, path = Branch.open_containing(branch)
2084
revno = revision[0].in_history(other_branch).revno
2085
other = [branch, revno]
2087
assert len(revision) == 2
2088
if None in revision:
2089
raise BzrCommandError(
2090
"Merge doesn't permit that revision specifier.")
2091
other_branch, path = Branch.open_containing(branch)
2093
base = [branch, revision[0].in_history(other_branch).revno]
2094
other = [branch, revision[1].in_history(other_branch).revno]
2096
if tree.branch.get_parent() is None or remember:
2097
tree.branch.set_parent(other_branch.base)
2100
interesting_files = [path]
2102
interesting_files = None
2103
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2106
conflict_count = merge(other, base, check_clean=(not force),
2107
merge_type=merge_type,
2108
reprocess=reprocess,
2109
show_base=show_base,
2110
pb=pb, file_list=interesting_files)
2113
if conflict_count != 0:
2117
except bzrlib.errors.AmbiguousBase, e:
2118
m = ("sorry, bzr can't determine the right merge base yet\n"
2119
"candidates are:\n "
2120
+ "\n ".join(e.bases)
2122
"please specify an explicit base with -r,\n"
2123
"and (if you want) report this to the bzr developers\n")
2126
# TODO: move up to common parent; this isn't merge-specific anymore.
2127
def _get_remembered_parent(self, tree, supplied_location, verb_string):
4340
return branch, branch
4341
if user_location is None:
4342
location = self._get_remembered(tree, 'Merging from')
4344
location = user_location
4345
return location, user_location
4347
def _get_remembered(self, tree, verb_string):
2128
4348
"""Use tree.branch's parent if none was supplied.
2130
4350
Report if the remembered location was used.
2132
if supplied_location is not None:
2133
return supplied_location
2134
stored_location = tree.branch.get_parent()
4352
stored_location = tree.branch.get_submit_branch()
4353
stored_location_type = "submit"
4354
if stored_location is None:
4355
stored_location = tree.branch.get_parent()
4356
stored_location_type = "parent"
2135
4357
mutter("%s", stored_location)
2136
4358
if stored_location is None:
2137
raise BzrCommandError("No location specified or remembered")
2138
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2139
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
4359
raise errors.BzrCommandError(gettext("No location specified or remembered"))
4360
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4361
note(gettext("{0} remembered {1} location {2}").format(verb_string,
4362
stored_location_type, display_url))
2140
4363
return stored_location
2143
4366
class cmd_remerge(Command):
4367
__doc__ = """Redo a merge.
2146
4369
Use this if you want to try a different merge technique while resolving
2147
conflicts. Some merge techniques are better than others, and remerge
4370
conflicts. Some merge techniques are better than others, and remerge
2148
4371
lets you try different ones on different files.
2150
4373
The options for remerge have the same meaning and defaults as the ones for
2151
4374
merge. The difference is that remerge can (only) be run when there is a
2152
4375
pending merge, and it lets you specify particular files.
2155
$ bzr remerge --show-base
2156
4378
Re-do the merge of all conflicted files, and show the base text in
2157
conflict regions, in addition to the usual THIS and OTHER texts.
2159
$ bzr remerge --merge-type weave --reprocess foobar
4379
conflict regions, in addition to the usual THIS and OTHER texts::
4381
bzr remerge --show-base
2160
4383
Re-do the merge of "foobar", using the weave merge algorithm, with
2161
additional processing to reduce the size of conflict regions.
2163
The following merge types are available:"""
4384
additional processing to reduce the size of conflict regions::
4386
bzr remerge --merge-type weave --reprocess foobar
2164
4388
takes_args = ['file*']
2165
takes_options = ['merge-type', 'reprocess',
2166
Option('show-base', help="Show base revision text in "
2170
from merge import merge_type_help
2171
from inspect import getdoc
2172
return getdoc(self) + '\n' + merge_type_help()
4393
help="Show base revision text in conflicts."),
2174
4396
def run(self, file_list=None, merge_type=None, show_base=False,
2175
4397
reprocess=False):
2176
from bzrlib.merge import merge_inner, transform_tree
4398
from bzrlib.conflicts import restore
2177
4399
if merge_type is None:
2178
merge_type = Merge3Merger
2179
tree, file_list = tree_files(file_list)
4400
merge_type = _mod_merge.Merge3Merger
4401
tree, file_list = WorkingTree.open_containing_paths(file_list)
4402
self.add_cleanup(tree.lock_write().unlock)
4403
parents = tree.get_parent_ids()
4404
if len(parents) != 2:
4405
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4406
" merges. Not cherrypicking or"
4408
repository = tree.branch.repository
4409
interesting_ids = None
4411
conflicts = tree.conflicts()
4412
if file_list is not None:
4413
interesting_ids = set()
4414
for filename in file_list:
4415
file_id = tree.path2id(filename)
4417
raise errors.NotVersionedError(filename)
4418
interesting_ids.add(file_id)
4419
if tree.kind(file_id) != "directory":
4422
for name, ie in tree.inventory.iter_entries(file_id):
4423
interesting_ids.add(ie.file_id)
4424
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4426
# Remerge only supports resolving contents conflicts
4427
allowed_conflicts = ('text conflict', 'contents conflict')
4428
restore_files = [c.path for c in conflicts
4429
if c.typestring in allowed_conflicts]
4430
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4431
tree.set_conflicts(ConflictList(new_conflicts))
4432
if file_list is not None:
4433
restore_files = file_list
4434
for filename in restore_files:
4436
restore(tree.abspath(filename))
4437
except errors.NotConflicted:
4439
# Disable pending merges, because the file texts we are remerging
4440
# have not had those merges performed. If we use the wrong parents
4441
# list, we imply that the working tree text has seen and rejected
4442
# all the changes from the other tree, when in fact those changes
4443
# have not yet been seen.
4444
tree.set_parent_ids(parents[:1])
2182
pending_merges = tree.pending_merges()
2183
if len(pending_merges) != 1:
2184
raise BzrCommandError("Sorry, remerge only works after normal"
2185
+ " merges. Not cherrypicking or"
2187
repository = tree.branch.repository
2188
base_revision = common_ancestor(tree.branch.last_revision(),
2189
pending_merges[0], repository)
2190
base_tree = repository.revision_tree(base_revision)
2191
other_tree = repository.revision_tree(pending_merges[0])
2192
interesting_ids = None
2193
if file_list is not None:
2194
interesting_ids = set()
2195
for filename in file_list:
2196
file_id = tree.path2id(filename)
2198
raise NotVersionedError(filename)
2199
interesting_ids.add(file_id)
2200
if tree.kind(file_id) != "directory":
2203
for name, ie in tree.inventory.iter_entries(file_id):
2204
interesting_ids.add(ie.file_id)
2205
transform_tree(tree, tree.basis_tree(), interesting_ids)
2206
if file_list is None:
2207
restore_files = list(tree.iter_conflicts())
2209
restore_files = file_list
2210
for filename in restore_files:
2212
restore(tree.abspath(filename))
2213
except NotConflicted:
2215
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2217
interesting_ids = interesting_ids,
2218
other_rev_id=pending_merges[0],
2219
merge_type=merge_type,
2220
show_base=show_base,
2221
reprocess=reprocess)
4446
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4447
merger.interesting_ids = interesting_ids
4448
merger.merge_type = merge_type
4449
merger.show_base = show_base
4450
merger.reprocess = reprocess
4451
conflicts = merger.do_merge()
4453
tree.set_parent_ids(parents)
2224
4454
if conflicts > 0:
2229
4460
class cmd_revert(Command):
2230
"""Reverse all changes since the last commit.
2232
Only versioned files are affected. Specify filenames to revert only
2233
those files. By default, any files that are changed will be backed up
2234
first. Backup files have a '~' appended to their name.
4461
__doc__ = """Revert files to a previous revision.
4463
Giving a list of files will revert only those files. Otherwise, all files
4464
will be reverted. If the revision is not specified with '--revision', the
4465
last committed revision is used.
4467
To remove only some changes, without reverting to a prior version, use
4468
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4469
will remove the changes introduced by the second last commit (-2), without
4470
affecting the changes introduced by the last commit (-1). To remove
4471
certain changes on a hunk-by-hunk basis, see the shelve command.
4473
By default, any files that have been manually changed will be backed up
4474
first. (Files changed only by merge are not backed up.) Backup files have
4475
'.~#~' appended to their name, where # is a number.
4477
When you provide files, you can use their current pathname or the pathname
4478
from the target revision. So you can use revert to "undelete" a file by
4479
name. If you name a directory, all the contents of that directory will be
4482
If you have newly added files since the target revision, they will be
4483
removed. If the files to be removed have been changed, backups will be
4484
created as above. Directories containing unknown files will not be
4487
The working tree contains a list of revisions that have been merged but
4488
not yet committed. These revisions will be included as additional parents
4489
of the next commit. Normally, using revert clears that list as well as
4490
reverting the files. If any files are specified, revert leaves the list
4491
of uncommitted merges alone and reverts only the files. Use ``bzr revert
4492
.`` in the tree root to revert all files but keep the recorded merges,
4493
and ``bzr revert --forget-merges`` to clear the pending merge list without
4494
reverting any files.
4496
Using "bzr revert --forget-merges", it is possible to apply all of the
4497
changes from a branch in a single revision. To do this, perform the merge
4498
as desired. Then doing revert with the "--forget-merges" option will keep
4499
the content of the tree as it was, but it will clear the list of pending
4500
merges. The next commit will then contain all of the changes that are
4501
present in the other branch, but without any other parent revisions.
4502
Because this technique forgets where these changes originated, it may
4503
cause additional conflicts on later merges involving the same source and
2236
takes_options = ['revision', 'no-backup']
4507
_see_also = ['cat', 'export', 'merge', 'shelve']
4510
Option('no-backup', "Do not save backups of reverted files."),
4511
Option('forget-merges',
4512
'Remove pending merge marker, without changing any files.'),
2237
4514
takes_args = ['file*']
2238
aliases = ['merge-revert']
2240
def run(self, revision=None, no_backup=False, file_list=None):
2241
from bzrlib.commands import parse_spec
2242
if file_list is not None:
2243
if len(file_list) == 0:
2244
raise BzrCommandError("No files specified")
2248
tree, file_list = tree_files(file_list)
2249
if revision is None:
2250
# FIXME should be tree.last_revision
2251
rev_id = tree.last_revision()
2252
elif len(revision) != 1:
2253
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2255
rev_id = revision[0].in_history(tree.branch).rev_id
2256
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2258
tree.revert(file_list,
2259
tree.branch.repository.revision_tree(rev_id),
4516
def run(self, revision=None, no_backup=False, file_list=None,
4517
forget_merges=None):
4518
tree, file_list = WorkingTree.open_containing_paths(file_list)
4519
self.add_cleanup(tree.lock_tree_write().unlock)
4521
tree.set_parent_ids(tree.get_parent_ids()[:1])
4523
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4526
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4527
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4528
tree.revert(file_list, rev_tree, not no_backup, None,
4529
report_changes=True)
2265
4532
class cmd_assert_fail(Command):
2266
"""Test reporting of assertion failures"""
4533
__doc__ = """Test reporting of assertion failures"""
4534
# intended just for use in testing
2269
assert False, "always fails"
4539
raise AssertionError("always fails")
2272
4542
class cmd_help(Command):
2273
"""Show help on a command or other topic.
4543
__doc__ = """Show help on a command or other topic.
2275
For a list of all available commands, say 'bzr help commands'."""
2276
takes_options = [Option('long', 'show help on all commands')]
4546
_see_also = ['topics']
4548
Option('long', 'Show help on all commands.'),
2277
4550
takes_args = ['topic?']
2278
4551
aliases = ['?', '--help', '-?', '-h']
2280
4553
@display_command
2281
4554
def run(self, topic=None, long=False):
2283
4556
if topic is None and long:
2284
4557
topic = "commands"
4558
bzrlib.help.help(topic)
2288
4561
class cmd_shell_complete(Command):
2289
"""Show appropriate completions for context.
4562
__doc__ = """Show appropriate completions for context.
2291
For a list of all available commands, say 'bzr shell-complete'."""
4564
For a list of all available commands, say 'bzr shell-complete'.
2292
4566
takes_args = ['context?']
2293
4567
aliases = ['s-c']
2296
4570
@display_command
2297
4571
def run(self, context=None):
2298
4572
import shellcomplete
2299
4573
shellcomplete.shellcomplete(context)
2302
class cmd_fetch(Command):
2303
"""Copy in history from another branch but don't merge it.
2305
This is an internal method used for pull and merge."""
2307
takes_args = ['from_branch', 'to_branch']
2308
def run(self, from_branch, to_branch):
2309
from bzrlib.fetch import Fetcher
2310
from bzrlib.branch import Branch
2311
from_b = Branch.open(from_branch)
2312
to_b = Branch.open(to_branch)
2313
Fetcher(to_b, from_b)
2316
4576
class cmd_missing(Command):
2317
"""Show unmerged/unpulled revisions between two branches.
2319
OTHER_BRANCH may be local or remote."""
4577
__doc__ = """Show unmerged/unpulled revisions between two branches.
4579
OTHER_BRANCH may be local or remote.
4581
To filter on a range of revisions, you can use the command -r begin..end
4582
-r revision requests a specific revision, -r ..end or -r begin.. are
4586
1 - some missing revisions
4587
0 - no missing revisions
4591
Determine the missing revisions between this and the branch at the
4592
remembered pull location::
4596
Determine the missing revisions between this and another branch::
4598
bzr missing http://server/branch
4600
Determine the missing revisions up to a specific revision on the other
4603
bzr missing -r ..-10
4605
Determine the missing revisions up to a specific revision on this
4608
bzr missing --my-revision ..-10
4611
_see_also = ['merge', 'pull']
2320
4612
takes_args = ['other_branch?']
2321
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2323
'Display changes in the local branch only'),
2324
Option('theirs-only',
2325
'Display changes in the remote branch only'),
4615
Option('reverse', 'Reverse the order of revisions.'),
4617
'Display changes in the local branch only.'),
4618
Option('this' , 'Same as --mine-only.'),
4619
Option('theirs-only',
4620
'Display changes in the remote branch only.'),
4621
Option('other', 'Same as --theirs-only.'),
4625
custom_help('revision',
4626
help='Filter on other branch revisions (inclusive). '
4627
'See "help revisionspec" for details.'),
4628
Option('my-revision',
4629
type=_parse_revision_str,
4630
help='Filter on local branch revisions (inclusive). '
4631
'See "help revisionspec" for details.'),
4632
Option('include-merged',
4633
'Show all revisions in addition to the mainline ones.'),
4634
Option('include-merges', hidden=True,
4635
help='Historical alias for --include-merged.'),
4637
encoding_type = 'replace'
2334
4640
def run(self, other_branch=None, reverse=False, mine_only=False,
2335
theirs_only=False, log_format=None, long=False, short=False, line=False,
2336
show_ids=False, verbose=False):
2337
from bzrlib.missing import find_unmerged, iter_log_data
2338
from bzrlib.log import log_formatter
2339
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
4642
log_format=None, long=False, short=False, line=False,
4643
show_ids=False, verbose=False, this=False, other=False,
4644
include_merged=None, revision=None, my_revision=None,
4646
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4647
from bzrlib.missing import find_unmerged, iter_log_revisions
4652
if symbol_versioning.deprecated_passed(include_merges):
4653
ui.ui_factory.show_user_warning(
4654
'deprecated_command_option',
4655
deprecated_name='--include-merges',
4656
recommended_name='--include-merged',
4657
deprecated_in_version='2.5',
4658
command=self.invoked_as)
4659
if include_merged is None:
4660
include_merged = include_merges
4662
raise errors.BzrCommandError(gettext(
4663
'{0} and {1} are mutually exclusive').format(
4664
'--include-merges', '--include-merged'))
4665
if include_merged is None:
4666
include_merged = False
4671
# TODO: We should probably check that we don't have mine-only and
4672
# theirs-only set, but it gets complicated because we also have
4673
# this and other which could be used.
4680
local_branch = Branch.open_containing(directory)[0]
4681
self.add_cleanup(local_branch.lock_read().unlock)
2340
4683
parent = local_branch.get_parent()
2341
4684
if other_branch is None:
2342
4685
other_branch = parent
2343
4686
if other_branch is None:
2344
raise BzrCommandError("No missing location known or specified.")
2345
print "Using last location: " + local_branch.get_parent()
2346
remote_branch = bzrlib.branch.Branch.open(other_branch)
4687
raise errors.BzrCommandError(gettext("No peer location known"
4689
display_url = urlutils.unescape_for_display(parent,
4691
message(gettext("Using saved parent location: {0}\n").format(
4694
remote_branch = Branch.open(other_branch)
2347
4695
if remote_branch.base == local_branch.base:
2348
4696
remote_branch = local_branch
2349
local_branch.lock_read()
2351
remote_branch.lock_read()
2353
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2354
if (log_format == None):
2355
default = bzrlib.config.BranchConfig(local_branch).log_format()
2356
log_format = get_log_format(long=long, short=short, line=line, default=default)
2357
lf = log_formatter(log_format, sys.stdout,
2359
show_timezone='original')
2360
if reverse is False:
2361
local_extra.reverse()
2362
remote_extra.reverse()
2363
if local_extra and not theirs_only:
2364
print "You have %d extra revision(s):" % len(local_extra)
2365
for data in iter_log_data(local_extra, local_branch.repository,
2368
printed_local = True
2370
printed_local = False
2371
if remote_extra and not mine_only:
2372
if printed_local is True:
2374
print "You are missing %d revision(s):" % len(remote_extra)
2375
for data in iter_log_data(remote_extra, remote_branch.repository,
2378
if not remote_extra and not local_extra:
2380
print "Branches are up to date."
2384
remote_branch.unlock()
2386
local_branch.unlock()
4698
self.add_cleanup(remote_branch.lock_read().unlock)
4700
local_revid_range = _revision_range_to_revid_range(
4701
_get_revision_range(my_revision, local_branch,
4704
remote_revid_range = _revision_range_to_revid_range(
4705
_get_revision_range(revision,
4706
remote_branch, self.name()))
4708
local_extra, remote_extra = find_unmerged(
4709
local_branch, remote_branch, restrict,
4710
backward=not reverse,
4711
include_merged=include_merged,
4712
local_revid_range=local_revid_range,
4713
remote_revid_range=remote_revid_range)
4715
if log_format is None:
4716
registry = log.log_formatter_registry
4717
log_format = registry.get_default(local_branch)
4718
lf = log_format(to_file=self.outf,
4720
show_timezone='original')
4723
if local_extra and not theirs_only:
4724
message(ngettext("You have %d extra revision:\n",
4725
"You have %d extra revisions:\n",
4728
for revision in iter_log_revisions(local_extra,
4729
local_branch.repository,
4731
lf.log_revision(revision)
4732
printed_local = True
4735
printed_local = False
4737
if remote_extra and not mine_only:
4738
if printed_local is True:
4740
message(ngettext("You are missing %d revision:\n",
4741
"You are missing %d revisions:\n",
4742
len(remote_extra)) %
4744
for revision in iter_log_revisions(remote_extra,
4745
remote_branch.repository,
4747
lf.log_revision(revision)
4750
if mine_only and not local_extra:
4751
# We checked local, and found nothing extra
4752
message(gettext('This branch has no new revisions.\n'))
4753
elif theirs_only and not remote_extra:
4754
# We checked remote, and found nothing extra
4755
message(gettext('Other branch has no new revisions.\n'))
4756
elif not (mine_only or theirs_only or local_extra or
4758
# We checked both branches, and neither one had extra
4760
message(gettext("Branches are up to date.\n"))
2387
4762
if not status_code and parent is None and other_branch is not None:
2388
local_branch.lock_write()
2390
# handle race conditions - a parent might be set while we run.
2391
if local_branch.get_parent() is None:
2392
local_branch.set_parent(remote_branch.base)
2394
local_branch.unlock()
4763
self.add_cleanup(local_branch.lock_write().unlock)
4764
# handle race conditions - a parent might be set while we run.
4765
if local_branch.get_parent() is None:
4766
local_branch.set_parent(remote_branch.base)
2395
4767
return status_code
4770
class cmd_pack(Command):
4771
__doc__ = """Compress the data within a repository.
4773
This operation compresses the data within a bazaar repository. As
4774
bazaar supports automatic packing of repository, this operation is
4775
normally not required to be done manually.
4777
During the pack operation, bazaar takes a backup of existing repository
4778
data, i.e. pack files. This backup is eventually removed by bazaar
4779
automatically when it is safe to do so. To save disk space by removing
4780
the backed up pack files, the --clean-obsolete-packs option may be
4783
Warning: If you use --clean-obsolete-packs and your machine crashes
4784
during or immediately after repacking, you may be left with a state
4785
where the deletion has been written to disk but the new packs have not
4786
been. In this case the repository may be unusable.
4789
_see_also = ['repositories']
4790
takes_args = ['branch_or_repo?']
4792
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4795
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4796
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4798
branch = dir.open_branch()
4799
repository = branch.repository
4800
except errors.NotBranchError:
4801
repository = dir.open_repository()
4802
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
2398
4805
class cmd_plugins(Command):
4806
__doc__ = """List the installed plugins.
4808
This command displays the list of installed plugins including
4809
version of plugin and a short description of each.
4811
--verbose shows the path where each plugin is located.
4813
A plugin is an external component for Bazaar that extends the
4814
revision control system, by adding or replacing code in Bazaar.
4815
Plugins can do a variety of things, including overriding commands,
4816
adding new commands, providing additional network transports and
4817
customizing log output.
4819
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4820
for further information on plugins including where to find them and how to
4821
install them. Instructions are also provided there on how to write new
4822
plugins using the Python programming language.
4824
takes_options = ['verbose']
2401
4826
@display_command
2403
import bzrlib.plugin
2404
from inspect import getdoc
2405
for name, plugin in bzrlib.plugin.all_plugins().items():
2406
if hasattr(plugin, '__path__'):
2407
print plugin.__path__[0]
2408
elif hasattr(plugin, '__file__'):
2409
print plugin.__file__
2415
print '\t', d.split('\n')[0]
4827
def run(self, verbose=False):
4828
from bzrlib import plugin
4829
# Don't give writelines a generator as some codecs don't like that
4830
self.outf.writelines(
4831
list(plugin.describe_plugins(show_paths=verbose)))
2418
4834
class cmd_testament(Command):
2419
"""Show testament (signing-form) of a revision."""
2420
takes_options = ['revision', 'long']
4835
__doc__ = """Show testament (signing-form) of a revision."""
4838
Option('long', help='Produce long-format testament.'),
4840
help='Produce a strict-format testament.')]
2421
4841
takes_args = ['branch?']
2422
4842
@display_command
2423
def run(self, branch=u'.', revision=None, long=False):
2424
from bzrlib.testament import Testament
2425
b = WorkingTree.open_containing(branch)[0].branch
2428
if revision is None:
2429
rev_id = b.last_revision()
2431
rev_id = revision[0].in_history(b).rev_id
2432
t = Testament.from_revision(b.repository, rev_id)
2434
sys.stdout.writelines(t.as_text_lines())
2436
sys.stdout.write(t.as_short_text())
4843
def run(self, branch=u'.', revision=None, long=False, strict=False):
4844
from bzrlib.testament import Testament, StrictTestament
4846
testament_class = StrictTestament
4848
testament_class = Testament
4850
b = Branch.open_containing(branch)[0]
4852
b = Branch.open(branch)
4853
self.add_cleanup(b.lock_read().unlock)
4854
if revision is None:
4855
rev_id = b.last_revision()
4857
rev_id = revision[0].as_revision_id(b)
4858
t = testament_class.from_revision(b.repository, rev_id)
4860
sys.stdout.writelines(t.as_text_lines())
4862
sys.stdout.write(t.as_short_text())
2441
4865
class cmd_annotate(Command):
2442
"""Show the origin of each line in a file.
4866
__doc__ = """Show the origin of each line in a file.
2444
4868
This prints out the given file with an annotation on the left side
2445
4869
indicating which revision, author and date introduced the change.
2447
If the origin is the same for a run of consecutive lines, it is
4871
If the origin is the same for a run of consecutive lines, it is
2448
4872
shown only at the top, unless the --all option is given.
2450
4874
# TODO: annotate directories; showing when each file was last changed
2451
# TODO: if the working copy is modified, show annotations on that
4875
# TODO: if the working copy is modified, show annotations on that
2452
4876
# with new uncommitted lines marked
2453
aliases = ['blame', 'praise']
4877
aliases = ['ann', 'blame', 'praise']
2454
4878
takes_args = ['filename']
2455
takes_options = [Option('all', help='show annotations on all lines'),
2456
Option('long', help='show date in annotations'),
4879
takes_options = [Option('all', help='Show annotations on all lines.'),
4880
Option('long', help='Show commit date in annotations.'),
4885
encoding_type = 'exact'
2460
4887
@display_command
2461
def run(self, filename, all=False, long=False, revision=None):
2462
from bzrlib.annotate import annotate_file
2463
tree, relpath = WorkingTree.open_containing(filename)
2464
branch = tree.branch
2467
if revision is None:
2468
revision_id = branch.last_revision()
2469
elif len(revision) != 1:
2470
raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2472
revision_id = revision[0].in_history(branch).rev_id
2473
file_id = tree.inventory.path2id(relpath)
2474
tree = branch.repository.revision_tree(revision_id)
2475
file_version = tree.inventory[file_id].revision
2476
annotate_file(branch, file_version, file_id, long, all, sys.stdout)
4888
def run(self, filename, all=False, long=False, revision=None,
4889
show_ids=False, directory=None):
4890
from bzrlib.annotate import (
4893
wt, branch, relpath = \
4894
_open_directory_or_containing_tree_or_branch(filename, directory)
4896
self.add_cleanup(wt.lock_read().unlock)
4898
self.add_cleanup(branch.lock_read().unlock)
4899
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4900
self.add_cleanup(tree.lock_read().unlock)
4901
if wt is not None and revision is None:
4902
file_id = wt.path2id(relpath)
4904
file_id = tree.path2id(relpath)
4906
raise errors.NotVersionedError(filename)
4907
if wt is not None and revision is None:
4908
# If there is a tree and we're not annotating historical
4909
# versions, annotate the working tree's content.
4910
annotate_file_tree(wt, file_id, self.outf, long, all,
4913
annotate_file_tree(tree, file_id, self.outf, long, all,
4914
show_ids=show_ids, branch=branch)
2481
4917
class cmd_re_sign(Command):
2482
"""Create a digital signature for an existing revision."""
4918
__doc__ = """Create a digital signature for an existing revision."""
2483
4919
# TODO be able to replace existing ones.
2485
4921
hidden = True # is this right ?
2486
4922
takes_args = ['revision_id*']
2487
takes_options = ['revision']
2489
def run(self, revision_id_list=None, revision=None):
2490
import bzrlib.config as config
2491
import bzrlib.gpg as gpg
4923
takes_options = ['directory', 'revision']
4925
def run(self, revision_id_list=None, revision=None, directory=u'.'):
2492
4926
if revision_id_list is not None and revision is not None:
2493
raise BzrCommandError('You can only supply one of revision_id or --revision')
4927
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
2494
4928
if revision_id_list is None and revision is None:
2495
raise BzrCommandError('You must supply either --revision or a revision_id')
2496
b = WorkingTree.open_containing(u'.')[0].branch
2497
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
4929
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4930
b = WorkingTree.open_containing(directory)[0].branch
4931
self.add_cleanup(b.lock_write().unlock)
4932
return self._run(b, revision_id_list, revision)
4934
def _run(self, b, revision_id_list, revision):
4935
import bzrlib.gpg as gpg
4936
gpg_strategy = gpg.GPGStrategy(b.get_config())
2498
4937
if revision_id_list is not None:
2499
for revision_id in revision_id_list:
2500
b.repository.sign_revision(revision_id, gpg_strategy)
4938
b.repository.start_write_group()
4940
for revision_id in revision_id_list:
4941
b.repository.sign_revision(revision_id, gpg_strategy)
4943
b.repository.abort_write_group()
4946
b.repository.commit_write_group()
2501
4947
elif revision is not None:
2502
4948
if len(revision) == 1:
2503
4949
revno, rev_id = revision[0].in_history(b)
2504
b.repository.sign_revision(rev_id, gpg_strategy)
4950
b.repository.start_write_group()
4952
b.repository.sign_revision(rev_id, gpg_strategy)
4954
b.repository.abort_write_group()
4957
b.repository.commit_write_group()
2505
4958
elif len(revision) == 2:
2506
4959
# are they both on rh- if so we can walk between them
2507
4960
# might be nice to have a range helper for arbitrary
2595
5085
b = control.open_branch()
5087
if tree is not None:
5088
self.add_cleanup(tree.lock_write().unlock)
5090
self.add_cleanup(b.lock_write().unlock)
5091
return self._run(b, tree, dry_run, verbose, revision, force,
5094
def _run(self, b, tree, dry_run, verbose, revision, force, local,
5096
from bzrlib.log import log_formatter, show_log
5097
from bzrlib.uncommit import uncommit
5099
last_revno, last_rev_id = b.last_revision_info()
2597
5102
if revision is None:
2599
rev_id = b.last_revision()
5104
rev_id = last_rev_id
2601
revno, rev_id = revision[0].in_history(b)
2603
print 'No revisions to uncommit.'
2605
for r in range(revno, b.revno()+1):
2606
rev_id = b.get_rev_id(r)
2607
lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2608
lf.show(r, b.repository.get_revision(rev_id), None)
5106
# 'bzr uncommit -r 10' actually means uncommit
5107
# so that the final tree is at revno 10.
5108
# but bzrlib.uncommit.uncommit() actually uncommits
5109
# the revisions that are supplied.
5110
# So we need to offset it by one
5111
revno = revision[0].in_history(b).revno + 1
5112
if revno <= last_revno:
5113
rev_id = b.get_rev_id(revno)
5115
if rev_id is None or _mod_revision.is_null(rev_id):
5116
self.outf.write(gettext('No revisions to uncommit.\n'))
5119
lf = log_formatter('short',
5121
show_timezone='original')
5126
direction='forward',
5127
start_revision=revno,
5128
end_revision=last_revno)
2611
print 'Dry-run, pretending to remove the above revisions.'
2613
val = raw_input('Press <enter> to continue')
5131
self.outf.write(gettext('Dry-run, pretending to remove'
5132
' the above revisions.\n'))
2615
print 'The above revision(s) will be removed.'
2617
val = raw_input('Are you sure [y/N]? ')
2618
if val.lower() not in ('y', 'yes'):
5134
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5137
if not ui.ui_factory.confirm_action(
5138
gettext(u'Uncommit these revisions'),
5139
'bzrlib.builtins.uncommit',
5141
self.outf.write(gettext('Canceled\n'))
5144
mutter('Uncommitting from {%s} to {%s}',
5145
last_rev_id, rev_id)
2622
5146
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5147
revno=revno, local=local, keep_tags=keep_tags)
5148
self.outf.write(gettext('You can restore the old tip by running:\n'
5149
' bzr pull . -r revid:%s\n') % last_rev_id)
2626
5152
class cmd_break_lock(Command):
2627
"""Break a dead lock on a repository, branch or working directory.
5153
__doc__ = """Break a dead lock.
5155
This command breaks a lock on a repository, branch, working directory or
2629
5158
CAUTION: Locks should only be broken when you are sure that the process
2630
5159
holding the lock has been stopped.
2632
You can get information on what locks are open via the 'bzr info' command.
5161
You can get information on what locks are open via the 'bzr info
5162
[location]' command.
5166
bzr break-lock bzr+ssh://example.com/bzr/foo
5167
bzr break-lock --conf ~/.bazaar
2637
5170
takes_args = ['location?']
5173
help='LOCATION is the directory where the config lock is.'),
5175
help='Do not ask for confirmation before breaking the lock.'),
2639
def run(self, location=None, show=False):
5178
def run(self, location=None, config=False, force=False):
2640
5179
if location is None:
2641
5180
location = u'.'
2642
control, relpath = bzrdir.BzrDir.open_containing(location)
2644
control.break_lock()
2645
except NotImplementedError:
5182
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5184
{'bzrlib.lockdir.break': True})
5186
conf = _mod_config.LockableConfig(file_name=location)
5189
control, relpath = bzrdir.BzrDir.open_containing(location)
5191
control.break_lock()
5192
except NotImplementedError:
5196
class cmd_wait_until_signalled(Command):
5197
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5199
This just prints a line to signal when it is ready, then blocks on stdin.
5205
sys.stdout.write("running\n")
5207
sys.stdin.readline()
5210
class cmd_serve(Command):
5211
__doc__ = """Run the bzr server."""
5213
aliases = ['server']
5217
help='Serve on stdin/out for use from inetd or sshd.'),
5218
RegistryOption('protocol',
5219
help="Protocol to serve.",
5220
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5221
value_switches=True),
5223
help='Listen for connections on nominated port of the form '
5224
'[hostname:]portnumber. Passing 0 as the port number will '
5225
'result in a dynamically allocated port. The default port '
5226
'depends on the protocol.',
5228
custom_help('directory',
5229
help='Serve contents of this directory.'),
5230
Option('allow-writes',
5231
help='By default the server is a readonly server. Supplying '
5232
'--allow-writes enables write access to the contents of '
5233
'the served directory and below. Note that ``bzr serve`` '
5234
'does not perform authentication, so unless some form of '
5235
'external authentication is arranged supplying this '
5236
'option leads to global uncontrolled write access to your '
5241
def get_host_and_port(self, port):
5242
"""Return the host and port to run the smart server on.
5244
If 'port' is None, None will be returned for the host and port.
5246
If 'port' has a colon in it, the string before the colon will be
5247
interpreted as the host.
5249
:param port: A string of the port to run the server on.
5250
:return: A tuple of (host, port), where 'host' is a host name or IP,
5251
and port is an integer TCP/IP port.
5254
if port is not None:
5256
host, port = port.split(':')
5260
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5262
from bzrlib import transport
5263
if directory is None:
5264
directory = os.getcwd()
5265
if protocol is None:
5266
protocol = transport.transport_server_registry.get()
5267
host, port = self.get_host_and_port(port)
5268
url = urlutils.local_path_to_url(directory)
5269
if not allow_writes:
5270
url = 'readonly+' + url
5271
t = transport.get_transport(url)
5272
protocol(t, host, port, inet)
5275
class cmd_join(Command):
5276
__doc__ = """Combine a tree into its containing tree.
5278
This command requires the target tree to be in a rich-root format.
5280
The TREE argument should be an independent tree, inside another tree, but
5281
not part of it. (Such trees can be produced by "bzr split", but also by
5282
running "bzr branch" with the target inside a tree.)
5284
The result is a combined tree, with the subtree no longer an independent
5285
part. This is marked as a merge of the subtree into the containing tree,
5286
and all history is preserved.
5289
_see_also = ['split']
5290
takes_args = ['tree']
5292
Option('reference', help='Join by reference.', hidden=True),
5295
def run(self, tree, reference=False):
5296
sub_tree = WorkingTree.open(tree)
5297
parent_dir = osutils.dirname(sub_tree.basedir)
5298
containing_tree = WorkingTree.open_containing(parent_dir)[0]
5299
repo = containing_tree.branch.repository
5300
if not repo.supports_rich_root():
5301
raise errors.BzrCommandError(gettext(
5302
"Can't join trees because %s doesn't support rich root data.\n"
5303
"You can use bzr upgrade on the repository.")
5307
containing_tree.add_reference(sub_tree)
5308
except errors.BadReferenceTarget, e:
5309
# XXX: Would be better to just raise a nicely printable
5310
# exception from the real origin. Also below. mbp 20070306
5311
raise errors.BzrCommandError(
5312
gettext("Cannot join {0}. {1}").format(tree, e.reason))
5315
containing_tree.subsume(sub_tree)
5316
except errors.BadSubsumeSource, e:
5317
raise errors.BzrCommandError(
5318
gettext("Cannot join {0}. {1}").format(tree, e.reason))
5321
class cmd_split(Command):
5322
__doc__ = """Split a subdirectory of a tree into a separate tree.
5324
This command will produce a target tree in a format that supports
5325
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
5326
converted into earlier formats like 'dirstate-tags'.
5328
The TREE argument should be a subdirectory of a working tree. That
5329
subdirectory will be converted into an independent tree, with its own
5330
branch. Commits in the top-level tree will not apply to the new subtree.
5333
_see_also = ['join']
5334
takes_args = ['tree']
5336
def run(self, tree):
5337
containing_tree, subdir = WorkingTree.open_containing(tree)
5338
sub_id = containing_tree.path2id(subdir)
5340
raise errors.NotVersionedError(subdir)
5342
containing_tree.extract(sub_id)
5343
except errors.RootNotRich:
5344
raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
5347
class cmd_merge_directive(Command):
5348
__doc__ = """Generate a merge directive for auto-merge tools.
5350
A directive requests a merge to be performed, and also provides all the
5351
information necessary to do so. This means it must either include a
5352
revision bundle, or the location of a branch containing the desired
5355
A submit branch (the location to merge into) must be supplied the first
5356
time the command is issued. After it has been supplied once, it will
5357
be remembered as the default.
5359
A public branch is optional if a revision bundle is supplied, but required
5360
if --diff or --plain is specified. It will be remembered as the default
5361
after the first use.
5364
takes_args = ['submit_branch?', 'public_branch?']
5368
_see_also = ['send']
5372
RegistryOption.from_kwargs('patch-type',
5373
'The type of patch to include in the directive.',
5375
value_switches=True,
5377
bundle='Bazaar revision bundle (default).',
5378
diff='Normal unified diff.',
5379
plain='No patch, just directive.'),
5380
Option('sign', help='GPG-sign the directive.'), 'revision',
5381
Option('mail-to', type=str,
5382
help='Instead of printing the directive, email to this address.'),
5383
Option('message', type=str, short_name='m',
5384
help='Message to use when committing this merge.')
5387
encoding_type = 'exact'
5389
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5390
sign=False, revision=None, mail_to=None, message=None,
5392
from bzrlib.revision import ensure_null, NULL_REVISION
5393
include_patch, include_bundle = {
5394
'plain': (False, False),
5395
'diff': (True, False),
5396
'bundle': (True, True),
5398
branch = Branch.open(directory)
5399
stored_submit_branch = branch.get_submit_branch()
5400
if submit_branch is None:
5401
submit_branch = stored_submit_branch
5403
if stored_submit_branch is None:
5404
branch.set_submit_branch(submit_branch)
5405
if submit_branch is None:
5406
submit_branch = branch.get_parent()
5407
if submit_branch is None:
5408
raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5410
stored_public_branch = branch.get_public_branch()
5411
if public_branch is None:
5412
public_branch = stored_public_branch
5413
elif stored_public_branch is None:
5414
branch.set_public_branch(public_branch)
5415
if not include_bundle and public_branch is None:
5416
raise errors.BzrCommandError(gettext('No public branch specified or'
5418
base_revision_id = None
5419
if revision is not None:
5420
if len(revision) > 2:
5421
raise errors.BzrCommandError(gettext('bzr merge-directive takes '
5422
'at most two one revision identifiers'))
5423
revision_id = revision[-1].as_revision_id(branch)
5424
if len(revision) == 2:
5425
base_revision_id = revision[0].as_revision_id(branch)
5427
revision_id = branch.last_revision()
5428
revision_id = ensure_null(revision_id)
5429
if revision_id == NULL_REVISION:
5430
raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5431
directive = merge_directive.MergeDirective2.from_objects(
5432
branch.repository, revision_id, time.time(),
5433
osutils.local_time_offset(), submit_branch,
5434
public_branch=public_branch, include_patch=include_patch,
5435
include_bundle=include_bundle, message=message,
5436
base_revision_id=base_revision_id)
5439
self.outf.write(directive.to_signed(branch))
5441
self.outf.writelines(directive.to_lines())
5443
message = directive.to_email(mail_to, branch, sign)
5444
s = SMTPConnection(branch.get_config())
5445
s.send_email(message)
5448
class cmd_send(Command):
5449
__doc__ = """Mail or create a merge-directive for submitting changes.
5451
A merge directive provides many things needed for requesting merges:
5453
* A machine-readable description of the merge to perform
5455
* An optional patch that is a preview of the changes requested
5457
* An optional bundle of revision data, so that the changes can be applied
5458
directly from the merge directive, without retrieving data from a
5461
`bzr send` creates a compact data set that, when applied using bzr
5462
merge, has the same effect as merging from the source branch.
5464
By default the merge directive is self-contained and can be applied to any
5465
branch containing submit_branch in its ancestory without needing access to
5468
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5469
revisions, but only a structured request to merge from the
5470
public_location. In that case the public_branch is needed and it must be
5471
up-to-date and accessible to the recipient. The public_branch is always
5472
included if known, so that people can check it later.
5474
The submit branch defaults to the parent of the source branch, but can be
5475
overridden. Both submit branch and public branch will be remembered in
5476
branch.conf the first time they are used for a particular branch. The
5477
source branch defaults to that containing the working directory, but can
5478
be changed using --from.
5480
Both the submit branch and the public branch follow the usual behavior with
5481
respect to --remember: If there is no default location set, the first send
5482
will set it (use --no-remember to avoid setting it). After that, you can
5483
omit the location to use the default. To change the default, use
5484
--remember. The value will only be saved if the location can be accessed.
5486
In order to calculate those changes, bzr must analyse the submit branch.
5487
Therefore it is most efficient for the submit branch to be a local mirror.
5488
If a public location is known for the submit_branch, that location is used
5489
in the merge directive.
5491
The default behaviour is to send the merge directive by mail, unless -o is
5492
given, in which case it is sent to a file.
5494
Mail is sent using your preferred mail program. This should be transparent
5495
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5496
If the preferred client can't be found (or used), your editor will be used.
5498
To use a specific mail program, set the mail_client configuration option.
5499
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5500
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5501
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5502
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5505
If mail is being sent, a to address is required. This can be supplied
5506
either on the commandline, by setting the submit_to configuration
5507
option in the branch itself or the child_submit_to configuration option
5508
in the submit branch.
5510
Two formats are currently supported: "4" uses revision bundle format 4 and
5511
merge directive format 2. It is significantly faster and smaller than
5512
older formats. It is compatible with Bazaar 0.19 and later. It is the
5513
default. "0.9" uses revision bundle format 0.9 and merge directive
5514
format 1. It is compatible with Bazaar 0.12 - 0.18.
5516
The merge directives created by bzr send may be applied using bzr merge or
5517
bzr pull by specifying a file containing a merge directive as the location.
5519
bzr send makes extensive use of public locations to map local locations into
5520
URLs that can be used by other people. See `bzr help configuration` to
5521
set them, and use `bzr info` to display them.
5524
encoding_type = 'exact'
5526
_see_also = ['merge', 'pull']
5528
takes_args = ['submit_branch?', 'public_branch?']
5532
help='Do not include a bundle in the merge directive.'),
5533
Option('no-patch', help='Do not include a preview patch in the merge'
5536
help='Remember submit and public branch.'),
5538
help='Branch to generate the submission from, '
5539
'rather than the one containing the working directory.',
5542
Option('output', short_name='o',
5543
help='Write merge directive to this file or directory; '
5544
'use - for stdout.',
5547
help='Refuse to send if there are uncommitted changes in'
5548
' the working tree, --no-strict disables the check.'),
5549
Option('mail-to', help='Mail the request to this address.',
5553
Option('body', help='Body for the email.', type=unicode),
5554
RegistryOption('format',
5555
help='Use the specified output format.',
5556
lazy_registry=('bzrlib.send', 'format_registry')),
5559
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5560
no_patch=False, revision=None, remember=None, output=None,
5561
format=None, mail_to=None, message=None, body=None,
5562
strict=None, **kwargs):
5563
from bzrlib.send import send
5564
return send(submit_branch, revision, public_branch, remember,
5565
format, no_bundle, no_patch, output,
5566
kwargs.get('from', '.'), mail_to, message, body,
5571
class cmd_bundle_revisions(cmd_send):
5572
__doc__ = """Create a merge-directive for submitting changes.
5574
A merge directive provides many things needed for requesting merges:
5576
* A machine-readable description of the merge to perform
5578
* An optional patch that is a preview of the changes requested
5580
* An optional bundle of revision data, so that the changes can be applied
5581
directly from the merge directive, without retrieving data from a
5584
If --no-bundle is specified, then public_branch is needed (and must be
5585
up-to-date), so that the receiver can perform the merge using the
5586
public_branch. The public_branch is always included if known, so that
5587
people can check it later.
5589
The submit branch defaults to the parent, but can be overridden. Both
5590
submit branch and public branch will be remembered if supplied.
5592
If a public_branch is known for the submit_branch, that public submit
5593
branch is used in the merge instructions. This means that a local mirror
5594
can be used as your actual submit branch, once you have set public_branch
5597
Two formats are currently supported: "4" uses revision bundle format 4 and
5598
merge directive format 2. It is significantly faster and smaller than
5599
older formats. It is compatible with Bazaar 0.19 and later. It is the
5600
default. "0.9" uses revision bundle format 0.9 and merge directive
5601
format 1. It is compatible with Bazaar 0.12 - 0.18.
5606
help='Do not include a bundle in the merge directive.'),
5607
Option('no-patch', help='Do not include a preview patch in the merge'
5610
help='Remember submit and public branch.'),
5612
help='Branch to generate the submission from, '
5613
'rather than the one containing the working directory.',
5616
Option('output', short_name='o', help='Write directive to this file.',
5619
help='Refuse to bundle revisions if there are uncommitted'
5620
' changes in the working tree, --no-strict disables the check.'),
5622
RegistryOption('format',
5623
help='Use the specified output format.',
5624
lazy_registry=('bzrlib.send', 'format_registry')),
5626
aliases = ['bundle']
5628
_see_also = ['send', 'merge']
5632
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5633
no_patch=False, revision=None, remember=False, output=None,
5634
format=None, strict=None, **kwargs):
5637
from bzrlib.send import send
5638
return send(submit_branch, revision, public_branch, remember,
5639
format, no_bundle, no_patch, output,
5640
kwargs.get('from', '.'), None, None, None,
5641
self.outf, strict=strict)
5644
class cmd_tag(Command):
5645
__doc__ = """Create, remove or modify a tag naming a revision.
5647
Tags give human-meaningful names to revisions. Commands that take a -r
5648
(--revision) option can be given -rtag:X, where X is any previously
5651
Tags are stored in the branch. Tags are copied from one branch to another
5652
along when you branch, push, pull or merge.
5654
It is an error to give a tag name that already exists unless you pass
5655
--force, in which case the tag is moved to point to the new revision.
5657
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5658
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5660
If no tag name is specified it will be determined through the
5661
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5662
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5666
_see_also = ['commit', 'tags']
5667
takes_args = ['tag_name?']
5670
help='Delete this tag rather than placing it.',
5672
custom_help('directory',
5673
help='Branch in which to place the tag.'),
5675
help='Replace existing tags.',
5680
def run(self, tag_name=None,
5686
branch, relpath = Branch.open_containing(directory)
5687
self.add_cleanup(branch.lock_write().unlock)
5689
if tag_name is None:
5690
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5691
branch.tags.delete_tag(tag_name)
5692
note(gettext('Deleted tag %s.') % tag_name)
5695
if len(revision) != 1:
5696
raise errors.BzrCommandError(gettext(
5697
"Tags can only be placed on a single revision, "
5699
revision_id = revision[0].as_revision_id(branch)
5701
revision_id = branch.last_revision()
5702
if tag_name is None:
5703
tag_name = branch.automatic_tag_name(revision_id)
5704
if tag_name is None:
5705
raise errors.BzrCommandError(gettext(
5706
"Please specify a tag name."))
5708
existing_target = branch.tags.lookup_tag(tag_name)
5709
except errors.NoSuchTag:
5710
existing_target = None
5711
if not force and existing_target not in (None, revision_id):
5712
raise errors.TagAlreadyExists(tag_name)
5713
if existing_target == revision_id:
5714
note(gettext('Tag %s already exists for that revision.') % tag_name)
5716
branch.tags.set_tag(tag_name, revision_id)
5717
if existing_target is None:
5718
note(gettext('Created tag %s.') % tag_name)
5720
note(gettext('Updated tag %s.') % tag_name)
5723
class cmd_tags(Command):
5724
__doc__ = """List tags.
5726
This command shows a table of tag names and the revisions they reference.
5731
custom_help('directory',
5732
help='Branch whose tags should be displayed.'),
5733
RegistryOption('sort',
5734
'Sort tags by different criteria.', title='Sorting',
5735
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5742
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5743
from bzrlib.tag import tag_sort_methods
5744
branch, relpath = Branch.open_containing(directory)
5746
tags = branch.tags.get_tag_dict().items()
5750
self.add_cleanup(branch.lock_read().unlock)
5752
graph = branch.repository.get_graph()
5753
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5754
revid1, revid2 = rev1.rev_id, rev2.rev_id
5755
# only show revisions between revid1 and revid2 (inclusive)
5756
tags = [(tag, revid) for tag, revid in tags if
5757
graph.is_between(revid, revid1, revid2)]
5759
sort = tag_sort_methods.get()
5762
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5763
for index, (tag, revid) in enumerate(tags):
5765
revno = branch.revision_id_to_dotted_revno(revid)
5766
if isinstance(revno, tuple):
5767
revno = '.'.join(map(str, revno))
5768
except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
5769
# Bad tag data/merges can lead to tagged revisions
5770
# which are not in this branch. Fail gracefully ...
5772
tags[index] = (tag, revno)
5774
for tag, revspec in tags:
5775
self.outf.write('%-20s %s\n' % (tag, revspec))
5778
class cmd_reconfigure(Command):
5779
__doc__ = """Reconfigure the type of a bzr directory.
5781
A target configuration must be specified.
5783
For checkouts, the bind-to location will be auto-detected if not specified.
5784
The order of preference is
5785
1. For a lightweight checkout, the current bound location.
5786
2. For branches that used to be checkouts, the previously-bound location.
5787
3. The push location.
5788
4. The parent location.
5789
If none of these is available, --bind-to must be specified.
5792
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5793
takes_args = ['location?']
5795
RegistryOption.from_kwargs(
5798
help='The relation between branch and tree.',
5799
value_switches=True, enum_switch=False,
5800
branch='Reconfigure to be an unbound branch with no working tree.',
5801
tree='Reconfigure to be an unbound branch with a working tree.',
5802
checkout='Reconfigure to be a bound branch with a working tree.',
5803
lightweight_checkout='Reconfigure to be a lightweight'
5804
' checkout (with no local history).',
5806
RegistryOption.from_kwargs(
5808
title='Repository type',
5809
help='Location fo the repository.',
5810
value_switches=True, enum_switch=False,
5811
standalone='Reconfigure to be a standalone branch '
5812
'(i.e. stop using shared repository).',
5813
use_shared='Reconfigure to use a shared repository.',
5815
RegistryOption.from_kwargs(
5817
title='Trees in Repository',
5818
help='Whether new branches in the repository have trees.',
5819
value_switches=True, enum_switch=False,
5820
with_trees='Reconfigure repository to create '
5821
'working trees on branches by default.',
5822
with_no_trees='Reconfigure repository to not create '
5823
'working trees on branches by default.'
5825
Option('bind-to', help='Branch to bind checkout to.', type=str),
5827
help='Perform reconfiguration even if local changes'
5829
Option('stacked-on',
5830
help='Reconfigure a branch to be stacked on another branch.',
5834
help='Reconfigure a branch to be unstacked. This '
5835
'may require copying substantial data into it.',
5839
def run(self, location=None, bind_to=None, force=False,
5840
tree_type=None, repository_type=None, repository_trees=None,
5841
stacked_on=None, unstacked=None):
5842
directory = bzrdir.BzrDir.open(location)
5843
if stacked_on and unstacked:
5844
raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5845
elif stacked_on is not None:
5846
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5848
reconfigure.ReconfigureUnstacked().apply(directory)
5849
# At the moment you can use --stacked-on and a different
5850
# reconfiguration shape at the same time; there seems no good reason
5852
if (tree_type is None and
5853
repository_type is None and
5854
repository_trees is None):
5855
if stacked_on or unstacked:
5858
raise errors.BzrCommandError(gettext('No target configuration '
5860
reconfiguration = None
5861
if tree_type == 'branch':
5862
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5863
elif tree_type == 'tree':
5864
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5865
elif tree_type == 'checkout':
5866
reconfiguration = reconfigure.Reconfigure.to_checkout(
5868
elif tree_type == 'lightweight-checkout':
5869
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5872
reconfiguration.apply(force)
5873
reconfiguration = None
5874
if repository_type == 'use-shared':
5875
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5876
elif repository_type == 'standalone':
5877
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5879
reconfiguration.apply(force)
5880
reconfiguration = None
5881
if repository_trees == 'with-trees':
5882
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5884
elif repository_trees == 'with-no-trees':
5885
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5888
reconfiguration.apply(force)
5889
reconfiguration = None
5892
class cmd_switch(Command):
5893
__doc__ = """Set the branch of a checkout and update.
5895
For lightweight checkouts, this changes the branch being referenced.
5896
For heavyweight checkouts, this checks that there are no local commits
5897
versus the current bound branch, then it makes the local branch a mirror
5898
of the new location and binds to it.
5900
In both cases, the working tree is updated and uncommitted changes
5901
are merged. The user can commit or revert these as they desire.
5903
Pending merges need to be committed or reverted before using switch.
5905
The path to the branch to switch to can be specified relative to the parent
5906
directory of the current branch. For example, if you are currently in a
5907
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5910
Bound branches use the nickname of its master branch unless it is set
5911
locally, in which case switching will update the local nickname to be
5915
takes_args = ['to_location?']
5916
takes_options = ['directory',
5918
help='Switch even if local commits will be lost.'),
5920
Option('create-branch', short_name='b',
5921
help='Create the target branch from this one before'
5922
' switching to it.'),
5925
def run(self, to_location=None, force=False, create_branch=False,
5926
revision=None, directory=u'.'):
5927
from bzrlib import switch
5928
tree_location = directory
5929
revision = _get_one_revision('switch', revision)
5930
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5931
if to_location is None:
5932
if revision is None:
5933
raise errors.BzrCommandError(gettext('You must supply either a'
5934
' revision or a location'))
5935
to_location = tree_location
5937
branch = control_dir.open_branch()
5938
had_explicit_nick = branch.get_config().has_explicit_nickname()
5939
except errors.NotBranchError:
5941
had_explicit_nick = False
5944
raise errors.BzrCommandError(gettext('cannot create branch without'
5946
to_location = directory_service.directories.dereference(
5948
if '/' not in to_location and '\\' not in to_location:
5949
# This path is meant to be relative to the existing branch
5950
this_url = self._get_branch_location(control_dir)
5951
to_location = urlutils.join(this_url, '..', to_location)
5952
to_branch = branch.bzrdir.sprout(to_location,
5953
possible_transports=[branch.bzrdir.root_transport],
5954
source_branch=branch).open_branch()
5957
to_branch = Branch.open(to_location)
5958
except errors.NotBranchError:
5959
this_url = self._get_branch_location(control_dir)
5960
to_branch = Branch.open(
5961
urlutils.join(this_url, '..', to_location))
5962
if revision is not None:
5963
revision = revision.as_revision_id(to_branch)
5964
switch.switch(control_dir, to_branch, force, revision_id=revision)
5965
if had_explicit_nick:
5966
branch = control_dir.open_branch() #get the new branch!
5967
branch.nick = to_branch.nick
5968
note(gettext('Switched to branch: %s'),
5969
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5971
def _get_branch_location(self, control_dir):
5972
"""Return location of branch for this control dir."""
5974
this_branch = control_dir.open_branch()
5975
# This may be a heavy checkout, where we want the master branch
5976
master_location = this_branch.get_bound_location()
5977
if master_location is not None:
5978
return master_location
5979
# If not, use a local sibling
5980
return this_branch.base
5981
except errors.NotBranchError:
5982
format = control_dir.find_branch_format()
5983
if getattr(format, 'get_reference', None) is not None:
5984
return format.get_reference(control_dir)
5986
return control_dir.root_transport.base
5989
class cmd_view(Command):
5990
__doc__ = """Manage filtered views.
5992
Views provide a mask over the tree so that users can focus on
5993
a subset of a tree when doing their work. After creating a view,
5994
commands that support a list of files - status, diff, commit, etc -
5995
effectively have that list of files implicitly given each time.
5996
An explicit list of files can still be given but those files
5997
must be within the current view.
5999
In most cases, a view has a short life-span: it is created to make
6000
a selected change and is deleted once that change is committed.
6001
At other times, you may wish to create one or more named views
6002
and switch between them.
6004
To disable the current view without deleting it, you can switch to
6005
the pseudo view called ``off``. This can be useful when you need
6006
to see the whole tree for an operation or two (e.g. merge) but
6007
want to switch back to your view after that.
6010
To define the current view::
6012
bzr view file1 dir1 ...
6014
To list the current view::
6018
To delete the current view::
6022
To disable the current view without deleting it::
6024
bzr view --switch off
6026
To define a named view and switch to it::
6028
bzr view --name view-name file1 dir1 ...
6030
To list a named view::
6032
bzr view --name view-name
6034
To delete a named view::
6036
bzr view --name view-name --delete
6038
To switch to a named view::
6040
bzr view --switch view-name
6042
To list all views defined::
6046
To delete all views::
6048
bzr view --delete --all
6052
takes_args = ['file*']
6055
help='Apply list or delete action to all views.',
6058
help='Delete the view.',
6061
help='Name of the view to define, list or delete.',
6065
help='Name of the view to switch to.',
6070
def run(self, file_list,
6076
tree, file_list = WorkingTree.open_containing_paths(file_list,
6078
current_view, view_dict = tree.views.get_view_info()
6083
raise errors.BzrCommandError(gettext(
6084
"Both --delete and a file list specified"))
6086
raise errors.BzrCommandError(gettext(
6087
"Both --delete and --switch specified"))
6089
tree.views.set_view_info(None, {})
6090
self.outf.write(gettext("Deleted all views.\n"))
6092
raise errors.BzrCommandError(gettext("No current view to delete"))
6094
tree.views.delete_view(name)
6095
self.outf.write(gettext("Deleted '%s' view.\n") % name)
6098
raise errors.BzrCommandError(gettext(
6099
"Both --switch and a file list specified"))
6101
raise errors.BzrCommandError(gettext(
6102
"Both --switch and --all specified"))
6103
elif switch == 'off':
6104
if current_view is None:
6105
raise errors.BzrCommandError(gettext("No current view to disable"))
6106
tree.views.set_view_info(None, view_dict)
6107
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
6109
tree.views.set_view_info(switch, view_dict)
6110
view_str = views.view_display_str(tree.views.lookup_view())
6111
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6114
self.outf.write(gettext('Views defined:\n'))
6115
for view in sorted(view_dict):
6116
if view == current_view:
6120
view_str = views.view_display_str(view_dict[view])
6121
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6123
self.outf.write(gettext('No views defined.\n'))
6126
# No name given and no current view set
6129
raise errors.BzrCommandError(gettext(
6130
"Cannot change the 'off' pseudo view"))
6131
tree.views.set_view(name, sorted(file_list))
6132
view_str = views.view_display_str(tree.views.lookup_view())
6133
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6137
# No name given and no current view set
6138
self.outf.write(gettext('No current view.\n'))
6140
view_str = views.view_display_str(tree.views.lookup_view(name))
6141
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6144
class cmd_hooks(Command):
6145
__doc__ = """Show hooks."""
6150
for hook_key in sorted(hooks.known_hooks.keys()):
6151
some_hooks = hooks.known_hooks_key_to_object(hook_key)
6152
self.outf.write("%s:\n" % type(some_hooks).__name__)
6153
for hook_name, hook_point in sorted(some_hooks.items()):
6154
self.outf.write(" %s:\n" % (hook_name,))
6155
found_hooks = list(hook_point)
6157
for hook in found_hooks:
6158
self.outf.write(" %s\n" %
6159
(some_hooks.get_hook_name(hook),))
6161
self.outf.write(gettext(" <no hooks installed>\n"))
6164
class cmd_remove_branch(Command):
6165
__doc__ = """Remove a branch.
6167
This will remove the branch from the specified location but
6168
will keep any working tree or repository in place.
6172
Remove the branch at repo/trunk::
6174
bzr remove-branch repo/trunk
6178
takes_args = ["location?"]
6180
aliases = ["rmbranch"]
6182
def run(self, location=None):
6183
if location is None:
6185
branch = Branch.open_containing(location)[0]
6186
branch.bzrdir.destroy_branch()
6189
class cmd_shelve(Command):
6190
__doc__ = """Temporarily set aside some changes from the current tree.
6192
Shelve allows you to temporarily put changes you've made "on the shelf",
6193
ie. out of the way, until a later time when you can bring them back from
6194
the shelf with the 'unshelve' command. The changes are stored alongside
6195
your working tree, and so they aren't propagated along with your branch nor
6196
will they survive its deletion.
6198
If shelve --list is specified, previously-shelved changes are listed.
6200
Shelve is intended to help separate several sets of changes that have
6201
been inappropriately mingled. If you just want to get rid of all changes
6202
and you don't need to restore them later, use revert. If you want to
6203
shelve all text changes at once, use shelve --all.
6205
If filenames are specified, only the changes to those files will be
6206
shelved. Other files will be left untouched.
6208
If a revision is specified, changes since that revision will be shelved.
6210
You can put multiple items on the shelf, and by default, 'unshelve' will
6211
restore the most recently shelved changes.
6213
For complicated changes, it is possible to edit the changes in a separate
6214
editor program to decide what the file remaining in the working copy
6215
should look like. To do this, add the configuration option
6217
change_editor = PROGRAM @new_path @old_path
6219
where @new_path is replaced with the path of the new version of the
6220
file and @old_path is replaced with the path of the old version of
6221
the file. The PROGRAM should save the new file with the desired
6222
contents of the file in the working tree.
2650
# command-line interpretation helper for merge-related commands
2651
def merge(other_revision, base_revision,
2652
check_clean=True, ignore_zero=False,
2653
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2654
file_list=None, show_base=False, reprocess=False,
2655
pb=DummyProgress()):
2656
"""Merge changes into a tree.
2659
list(path, revno) Base for three-way merge.
2660
If [None, None] then a base will be automatically determined.
2662
list(path, revno) Other revision for three-way merge.
2664
Directory to merge changes into; '.' by default.
2666
If true, this_dir must have no uncommitted changes before the
2668
ignore_zero - If true, suppress the "zero conflicts" message when
2669
there are no conflicts; should be set when doing something we expect
2670
to complete perfectly.
2671
file_list - If supplied, merge only changes to selected files.
2673
All available ancestors of other_revision and base_revision are
2674
automatically pulled into the branch.
2676
The revno may be -1 to indicate the last revision on the branch, which is
2679
This function is intended for use from the command line; programmatic
2680
clients might prefer to call merge.merge_inner(), which has less magic
2683
from bzrlib.merge import Merger
2684
if this_dir is None:
2686
this_tree = WorkingTree.open_containing(this_dir)[0]
2687
if show_base and not merge_type is Merge3Merger:
2688
raise BzrCommandError("Show-base is not supported for this merge"
2689
" type. %s" % merge_type)
2690
if reprocess and not merge_type.supports_reprocess:
2691
raise BzrCommandError("Conflict reduction is not supported for merge"
2692
" type %s." % merge_type)
2693
if reprocess and show_base:
2694
raise BzrCommandError("Cannot do conflict reduction and show base.")
2696
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2697
merger.pp = ProgressPhase("Merge phase", 5, pb)
2698
merger.pp.next_phase()
2699
merger.check_basis(check_clean)
2700
merger.set_other(other_revision)
2701
merger.pp.next_phase()
2702
merger.set_base(base_revision)
2703
if merger.base_rev_id == merger.other_rev_id:
2704
note('Nothing to do.')
2706
merger.backup_files = backup_files
2707
merger.merge_type = merge_type
2708
merger.set_interesting_files(file_list)
2709
merger.show_base = show_base
2710
merger.reprocess = reprocess
2711
conflicts = merger.do_merge()
2712
if file_list is None:
2713
merger.set_pending()
2719
# these get imported and then picked up by the scan for cmd_*
2720
# TODO: Some more consistent way to split command definitions across files;
2721
# we do need to load at least some information about them to know of
2722
# aliases. ideally we would avoid loading the implementation until the
2723
# details were needed.
2724
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2725
from bzrlib.bundle.commands import cmd_bundle_revisions
2726
from bzrlib.sign_my_commits import cmd_sign_my_commits
2727
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
2728
cmd_weave_plan_merge, cmd_weave_merge_text
6226
takes_args = ['file*']
6231
Option('all', help='Shelve all changes.'),
6233
RegistryOption('writer', 'Method to use for writing diffs.',
6234
bzrlib.option.diff_writer_registry,
6235
value_switches=True, enum_switch=False),
6237
Option('list', help='List shelved changes.'),
6239
help='Destroy removed changes instead of shelving them.'),
6241
_see_also = ['unshelve', 'configuration']
6243
def run(self, revision=None, all=False, file_list=None, message=None,
6244
writer=None, list=False, destroy=False, directory=None):
6246
return self.run_for_list(directory=directory)
6247
from bzrlib.shelf_ui import Shelver
6249
writer = bzrlib.option.diff_writer_registry.get()
6251
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6252
file_list, message, destroy=destroy, directory=directory)
6257
except errors.UserAbort:
6260
def run_for_list(self, directory=None):
6261
if directory is None:
6263
tree = WorkingTree.open_containing(directory)[0]
6264
self.add_cleanup(tree.lock_read().unlock)
6265
manager = tree.get_shelf_manager()
6266
shelves = manager.active_shelves()
6267
if len(shelves) == 0:
6268
note(gettext('No shelved changes.'))
6270
for shelf_id in reversed(shelves):
6271
message = manager.get_metadata(shelf_id).get('message')
6273
message = '<no message>'
6274
self.outf.write('%3d: %s\n' % (shelf_id, message))
6278
class cmd_unshelve(Command):
6279
__doc__ = """Restore shelved changes.
6281
By default, the most recently shelved changes are restored. However if you
6282
specify a shelf by id those changes will be restored instead. This works
6283
best when the changes don't depend on each other.
6286
takes_args = ['shelf_id?']
6289
RegistryOption.from_kwargs(
6290
'action', help="The action to perform.",
6291
enum_switch=False, value_switches=True,
6292
apply="Apply changes and remove from the shelf.",
6293
dry_run="Show changes, but do not apply or remove them.",
6294
preview="Instead of unshelving the changes, show the diff that "
6295
"would result from unshelving.",
6296
delete_only="Delete changes without applying them.",
6297
keep="Apply changes but don't delete them.",
6300
_see_also = ['shelve']
6302
def run(self, shelf_id=None, action='apply', directory=u'.'):
6303
from bzrlib.shelf_ui import Unshelver
6304
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
6308
unshelver.tree.unlock()
6311
class cmd_clean_tree(Command):
6312
__doc__ = """Remove unwanted files from working tree.
6314
By default, only unknown files, not ignored files, are deleted. Versioned
6315
files are never deleted.
6317
Another class is 'detritus', which includes files emitted by bzr during
6318
normal operations and selftests. (The value of these files decreases with
6321
If no options are specified, unknown files are deleted. Otherwise, option
6322
flags are respected, and may be combined.
6324
To check what clean-tree will do, use --dry-run.
6326
takes_options = ['directory',
6327
Option('ignored', help='Delete all ignored files.'),
6328
Option('detritus', help='Delete conflict files, merge and revert'
6329
' backups, and failed selftest dirs.'),
6331
help='Delete files unknown to bzr (default).'),
6332
Option('dry-run', help='Show files to delete instead of'
6334
Option('force', help='Do not prompt before deleting.')]
6335
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6336
force=False, directory=u'.'):
6337
from bzrlib.clean_tree import clean_tree
6338
if not (unknown or ignored or detritus):
6342
clean_tree(directory, unknown=unknown, ignored=ignored,
6343
detritus=detritus, dry_run=dry_run, no_prompt=force)
6346
class cmd_reference(Command):
6347
__doc__ = """list, view and set branch locations for nested trees.
6349
If no arguments are provided, lists the branch locations for nested trees.
6350
If one argument is provided, display the branch location for that tree.
6351
If two arguments are provided, set the branch location for that tree.
6356
takes_args = ['path?', 'location?']
6358
def run(self, path=None, location=None):
6360
if path is not None:
6362
tree, branch, relpath =(
6363
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
6364
if path is not None:
6367
tree = branch.basis_tree()
6369
info = branch._get_all_reference_info().iteritems()
6370
self._display_reference_info(tree, branch, info)
6372
file_id = tree.path2id(path)
6374
raise errors.NotVersionedError(path)
6375
if location is None:
6376
info = [(file_id, branch.get_reference_info(file_id))]
6377
self._display_reference_info(tree, branch, info)
6379
branch.set_reference_info(file_id, path, location)
6381
def _display_reference_info(self, tree, branch, info):
6383
for file_id, (path, location) in info:
6385
path = tree.id2path(file_id)
6386
except errors.NoSuchId:
6388
ref_list.append((path, location))
6389
for path, location in sorted(ref_list):
6390
self.outf.write('%s %s\n' % (path, location))
6393
class cmd_export_pot(Command):
6394
__doc__ = """Export command helps and error messages in po format."""
6399
from bzrlib.export_pot import export_pot
6400
export_pot(self.outf)
6403
def _register_lazy_builtins():
6404
# register lazy builtins from other modules; called at startup and should
6405
# be only called once.
6406
for (name, aliases, module_name) in [
6407
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6408
('cmd_config', [], 'bzrlib.config'),
6409
('cmd_dpush', [], 'bzrlib.foreign'),
6410
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6411
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6412
('cmd_conflicts', [], 'bzrlib.conflicts'),
6413
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6414
('cmd_verify_signatures', [],
6415
'bzrlib.commit_signature_commands'),
6416
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6418
builtin_command_registry.register_lazy(name, aliases, module_name)