171
156
:return: workingtree, [relative_paths]
173
return WorkingTree.open_containing_paths(
174
file_list, default_directory='.',
158
if file_list is None or len(file_list) == 0:
159
tree = WorkingTree.open_containing(default_branch)[0]
160
if tree.supports_views() and apply_view:
161
view_files = tree.views.lookup_view()
163
file_list = view_files
164
view_str = views.view_display_str(view_files)
165
note("Ignoring files outside view. View is %s" % view_str)
166
return tree, file_list
167
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
168
return tree, safe_relpath_files(tree, file_list, canonicalize,
169
apply_view=apply_view)
172
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
173
"""Convert file_list into a list of relpaths in tree.
175
:param tree: A tree to operate on.
176
:param file_list: A list of user provided paths or None.
177
:param apply_view: if True and a view is set, apply it or check that
178
specified files are within it
179
:return: A list of relative paths.
180
:raises errors.PathNotChild: When a provided path is in a different tree
183
if file_list is None:
185
if tree.supports_views() and apply_view:
186
view_files = tree.views.lookup_view()
190
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
191
# doesn't - fix that up here before we enter the loop.
193
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
196
for filename in file_list:
198
relpath = fixer(osutils.dereference_path(filename))
199
if view_files and not osutils.is_inside_any(view_files, relpath):
200
raise errors.FileOutsideView(filename, view_files)
201
new_list.append(relpath)
202
except errors.PathNotChild:
203
raise errors.FileInWrongBranch(tree.branch, filename)
179
207
def _get_view_info_for_change_reporter(tree):
306
322
takes_args = ['revision_id?']
307
takes_options = ['directory', 'revision']
323
takes_options = ['revision']
308
324
# cat-revision is more for frontends so should be exact
309
325
encoding = 'strict'
311
def print_revision(self, revisions, revid):
312
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
313
record = stream.next()
314
if record.storage_kind == 'absent':
315
raise errors.NoSuchRevision(revisions, revid)
316
revtext = record.get_bytes_as('fulltext')
317
self.outf.write(revtext.decode('utf-8'))
320
def run(self, revision_id=None, revision=None, directory=u'.'):
328
def run(self, revision_id=None, revision=None):
321
329
if revision_id is not None and revision is not None:
322
330
raise errors.BzrCommandError('You can only supply one of'
323
331
' revision_id or --revision')
324
332
if revision_id is None and revision is None:
325
333
raise errors.BzrCommandError('You must supply either'
326
334
' --revision or a revision_id')
327
b = WorkingTree.open_containing(directory)[0].branch
329
revisions = b.repository.revisions
330
if revisions is None:
331
raise errors.BzrCommandError('Repository %r does not support '
332
'access to raw revision texts')
334
b.repository.lock_read()
336
# TODO: jam 20060112 should cat-revision always output utf-8?
337
if revision_id is not None:
338
revision_id = osutils.safe_revision_id(revision_id, warn=False)
340
self.print_revision(revisions, revision_id)
341
except errors.NoSuchRevision:
342
msg = "The repository %s contains no revision %s." % (
343
b.repository.base, revision_id)
344
raise errors.BzrCommandError(msg)
345
elif revision is not None:
348
raise errors.BzrCommandError(
349
'You cannot specify a NULL revision.')
350
rev_id = rev.as_revision_id(b)
351
self.print_revision(revisions, rev_id)
353
b.repository.unlock()
335
b = WorkingTree.open_containing(u'.')[0].branch
337
# TODO: jam 20060112 should cat-revision always output utf-8?
338
if revision_id is not None:
339
revision_id = osutils.safe_revision_id(revision_id, warn=False)
341
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
342
except errors.NoSuchRevision:
343
msg = "The repository %s contains no revision %s." % (b.repository.base,
345
raise errors.BzrCommandError(msg)
346
elif revision is not None:
349
raise errors.BzrCommandError('You cannot specify a NULL'
351
rev_id = rev.as_revision_id(b)
352
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
356
355
class cmd_dump_btree(Command):
357
__doc__ = """Dump the contents of a btree index file to stdout.
356
"""Dump the contents of a btree index file to stdout.
359
358
PATH is a btree index file, it can be any URL. This includes things like
360
359
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
443
435
To re-create the working tree, use "bzr checkout".
445
437
_see_also = ['checkout', 'working-trees']
446
takes_args = ['location*']
438
takes_args = ['location?']
447
439
takes_options = [
449
441
help='Remove the working tree even if it has '
450
'uncommitted or shelved changes.'),
442
'uncommitted changes.'),
453
def run(self, location_list, force=False):
454
if not location_list:
457
for location in location_list:
458
d = bzrdir.BzrDir.open(location)
461
working = d.open_workingtree()
462
except errors.NoWorkingTree:
463
raise errors.BzrCommandError("No working tree to remove")
464
except errors.NotLocalUrl:
465
raise errors.BzrCommandError("You cannot remove the working tree"
468
if (working.has_changes()):
469
raise errors.UncommittedChanges(working)
470
if working.get_shelf_manager().last_shelf() is not None:
471
raise errors.ShelvedChanges(working)
473
if working.user_url != working.branch.user_url:
474
raise errors.BzrCommandError("You cannot remove the working tree"
475
" from a lightweight checkout")
477
d.destroy_workingtree()
445
def run(self, location='.', force=False):
446
d = bzrdir.BzrDir.open(location)
449
working = d.open_workingtree()
450
except errors.NoWorkingTree:
451
raise errors.BzrCommandError("No working tree to remove")
452
except errors.NotLocalUrl:
453
raise errors.BzrCommandError("You cannot remove the working tree of a "
456
changes = working.changes_from(working.basis_tree())
457
if changes.has_changed():
458
raise errors.UncommittedChanges(working)
460
working_path = working.bzrdir.root_transport.base
461
branch_path = working.branch.bzrdir.root_transport.base
462
if working_path != branch_path:
463
raise errors.BzrCommandError("You cannot remove the working tree from "
464
"a lightweight checkout")
466
d.destroy_workingtree()
480
469
class cmd_revno(Command):
481
__doc__ = """Show current revision number.
470
"""Show current revision number.
483
472
This is equal to the number of revisions on this branch.
486
475
_see_also = ['info']
487
476
takes_args = ['location?']
489
Option('tree', help='Show revno of working tree'),
493
def run(self, tree=False, location=u'.'):
496
wt = WorkingTree.open_containing(location)[0]
497
self.add_cleanup(wt.lock_read().unlock)
498
except (errors.NoWorkingTree, errors.NotLocalUrl):
499
raise errors.NoWorkingTree(location)
500
revid = wt.last_revision()
502
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
503
except errors.NoSuchRevision:
505
revno = ".".join(str(n) for n in revno_t)
507
b = Branch.open_containing(location)[0]
508
self.add_cleanup(b.lock_read().unlock)
511
self.outf.write(str(revno) + '\n')
479
def run(self, location=u'.'):
480
self.outf.write(str(Branch.open_containing(location)[0].revno()))
481
self.outf.write('\n')
514
484
class cmd_revision_info(Command):
515
__doc__ = """Show revision number and revision id for a given revision identifier.
485
"""Show revision number and revision id for a given revision identifier.
518
488
takes_args = ['revision_info*']
519
489
takes_options = [
521
custom_help('directory',
522
492
help='Branch to examine, '
523
'rather than the one containing the working directory.'),
524
Option('tree', help='Show revno of working tree'),
493
'rather than the one containing the working directory.',
528
def run(self, revision=None, directory=u'.', tree=False,
529
revision_info_list=[]):
500
def run(self, revision=None, directory=u'.', revision_info_list=[]):
532
wt = WorkingTree.open_containing(directory)[0]
534
self.add_cleanup(wt.lock_read().unlock)
535
except (errors.NoWorkingTree, errors.NotLocalUrl):
537
b = Branch.open_containing(directory)[0]
538
self.add_cleanup(b.lock_read().unlock)
540
503
if revision is not None:
541
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
504
revs.extend(revision)
542
505
if revision_info_list is not None:
543
for rev_str in revision_info_list:
544
rev_spec = RevisionSpec.from_string(rev_str)
545
revision_ids.append(rev_spec.as_revision_id(b))
546
# No arguments supplied, default to the last revision
547
if len(revision_ids) == 0:
550
raise errors.NoWorkingTree(directory)
551
revision_ids.append(wt.last_revision())
553
revision_ids.append(b.last_revision())
557
for revision_id in revision_ids:
506
for rev in revision_info_list:
507
revs.append(RevisionSpec.from_string(rev))
509
b = Branch.open_containing(directory)[0]
512
revs.append(RevisionSpec.from_string('-1'))
515
revision_id = rev.as_revision_id(b)
559
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
560
revno = '.'.join(str(i) for i in dotted_revno)
517
revno = '%4d' % (b.revision_id_to_revno(revision_id))
561
518
except errors.NoSuchRevision:
563
maxlen = max(maxlen, len(revno))
564
revinfos.append([revno, revision_id])
568
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
519
dotted_map = b.get_revision_id_to_revno_map()
520
revno = '.'.join(str(i) for i in dotted_map[revision_id])
521
print '%s %s' % (revno, revision_id)
571
524
class cmd_add(Command):
572
__doc__ = """Add specified files or directories.
525
"""Add specified files or directories.
574
527
In non-recursive mode, all the named items are added, regardless
575
528
of whether they were previously ignored. A warning is given if
640
590
should_print=(not is_quiet()))
643
self.add_cleanup(base_tree.lock_read().unlock)
644
tree, file_list = tree_files_for_add(file_list)
645
added, ignored = tree.smart_add(file_list, not
646
no_recurse, action=action, save=not dry_run)
593
base_tree.lock_read()
595
file_list = self._maybe_expand_globs(file_list)
596
tree, file_list = tree_files_for_add(file_list)
597
added, ignored = tree.smart_add(file_list, not
598
no_recurse, action=action, save=not dry_run)
600
if base_tree is not None:
648
602
if len(ignored) > 0:
650
604
for glob in sorted(ignored.keys()):
651
605
for path in ignored[glob]:
652
606
self.outf.write("ignored %s matching \"%s\"\n"
610
for glob, paths in ignored.items():
611
match_len += len(paths)
612
self.outf.write("ignored %d file(s).\n" % match_len)
613
self.outf.write("If you wish to add ignored files, "
614
"please add them explicitly by name. "
615
"(\"bzr ignored\" gives a list)\n")
656
618
class cmd_mkdir(Command):
657
__doc__ = """Create a new versioned directory.
619
"""Create a new versioned directory.
659
621
This is equivalent to creating the directory and then adding it.
717
674
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
719
676
revision = _get_one_revision('inventory', revision)
720
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
721
self.add_cleanup(work_tree.lock_read().unlock)
722
if revision is not None:
723
tree = revision.as_tree(work_tree.branch)
725
extra_trees = [work_tree]
726
self.add_cleanup(tree.lock_read().unlock)
731
if file_list is not None:
732
file_ids = tree.paths2ids(file_list, trees=extra_trees,
733
require_versioned=True)
734
# find_ids_across_trees may include some paths that don't
736
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
737
for file_id in file_ids if file_id in tree)
739
entries = tree.inventory.entries()
677
work_tree, file_list = tree_files(file_list)
678
work_tree.lock_read()
680
if revision is not None:
681
tree = revision.as_tree(work_tree.branch)
683
extra_trees = [work_tree]
689
if file_list is not None:
690
file_ids = tree.paths2ids(file_list, trees=extra_trees,
691
require_versioned=True)
692
# find_ids_across_trees may include some paths that don't
694
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
695
for file_id in file_ids if file_id in tree)
697
entries = tree.inventory.entries()
700
if tree is not work_tree:
742
703
for path, entry in entries:
743
704
if kind and kind != entry.kind:
881
846
dest = osutils.pathjoin(dest_parent, dest_tail)
882
847
mutter("attempting to move %s => %s", src, dest)
883
848
tree.rename_one(src, dest, after=after)
885
self.outf.write("%s => %s\n" % (src, dest))
849
self.outf.write("%s => %s\n" % (src, dest))
888
852
class cmd_pull(Command):
889
__doc__ = """Turn this branch into a mirror of another branch.
853
"""Turn this branch into a mirror of another branch.
891
By default, this command only works on branches that have not diverged.
892
Branches are considered diverged if the destination branch's most recent
893
commit is one that has not been merged (directly or indirectly) into the
855
This command only works on branches that have not diverged. Branches are
856
considered diverged if the destination branch's most recent commit is one
857
that has not been merged (directly or indirectly) into the parent.
896
859
If branches have diverged, you can use 'bzr merge' to integrate the changes
897
860
from one into the other. Once one branch has merged, the other should
898
861
be able to pull it again.
900
If you want to replace your local changes and just want your branch to
901
match the remote one, use pull --overwrite. This will work even if the two
902
branches have diverged.
863
If you want to forget your local changes and just update your branch to
864
match the remote one, use pull --overwrite.
904
866
If there is no default location set, the first pull will set it. After
905
867
that, you can omit the location to use the default. To change the
987
949
if revision is not None:
988
950
revision_id = revision.as_revision_id(branch_from)
990
if tree_to is not None:
991
view_info = _get_view_info_for_change_reporter(tree_to)
992
change_reporter = delta._ChangeReporter(
993
unversioned_filter=tree_to.is_ignored,
995
result = tree_to.pull(
996
branch_from, overwrite, revision_id, change_reporter,
997
possible_transports=possible_transports, local=local)
999
result = branch_to.pull(
1000
branch_from, overwrite, revision_id, local=local)
952
branch_to.lock_write()
954
if tree_to is not None:
955
view_info = _get_view_info_for_change_reporter(tree_to)
956
change_reporter = delta._ChangeReporter(
957
unversioned_filter=tree_to.is_ignored, view_info=view_info)
958
result = tree_to.pull(branch_from, overwrite, revision_id,
960
possible_transports=possible_transports,
963
result = branch_to.pull(branch_from, overwrite, revision_id,
1002
result.report(self.outf)
1003
if verbose and result.old_revid != result.new_revid:
1004
log.show_branch_change(
1005
branch_to, self.outf, result.old_revno,
966
result.report(self.outf)
967
if verbose and result.old_revid != result.new_revid:
968
log.show_branch_change(branch_to, self.outf, result.old_revno,
1009
974
class cmd_push(Command):
1010
__doc__ = """Update a mirror of this branch.
975
"""Update a mirror of this branch.
1012
977
The target branch will not have its working tree populated because this
1013
978
is both expensive, and is not supported on remote file systems.
1135
1094
_see_also = ['checkout']
1136
1095
takes_args = ['from_location', 'to_location?']
1137
takes_options = ['revision',
1138
Option('hardlink', help='Hard-link working tree files where possible.'),
1139
Option('files-from', type=str,
1140
help="Get file contents from this tree."),
1096
takes_options = ['revision', Option('hardlink',
1097
help='Hard-link working tree files where possible.'),
1141
1098
Option('no-tree',
1142
1099
help="Create a branch without a working-tree."),
1144
help="Switch the checkout in the current directory "
1145
"to the new branch."),
1146
1100
Option('stacked',
1147
1101
help='Create a stacked branch referring to the source branch. '
1148
1102
'The new branch will depend on the availability of the source '
1149
1103
'branch for all operations.'),
1150
1104
Option('standalone',
1151
1105
help='Do not use a shared repository, even if available.'),
1152
Option('use-existing-dir',
1153
help='By default branch will fail if the target'
1154
' directory exists, but does not already'
1155
' have a control directory. This flag will'
1156
' allow branch to proceed.'),
1158
help="Bind new branch to from location."),
1160
1107
aliases = ['get', 'clone']
1162
1109
def run(self, from_location, to_location=None, revision=None,
1163
hardlink=False, stacked=False, standalone=False, no_tree=False,
1164
use_existing_dir=False, switch=False, bind=False,
1166
from bzrlib import switch as _mod_switch
1110
hardlink=False, stacked=False, standalone=False, no_tree=False):
1167
1111
from bzrlib.tag import _merge_tags_if_possible
1168
1113
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1170
if not (hardlink or files_from):
1171
# accelerator_tree is usually slower because you have to read N
1172
# files (no readahead, lots of seeks, etc), but allow the user to
1173
# explicitly request it
1174
accelerator_tree = None
1175
if files_from is not None and files_from != from_location:
1176
accelerator_tree = WorkingTree.open(files_from)
1177
1115
revision = _get_one_revision('branch', revision)
1178
self.add_cleanup(br_from.lock_read().unlock)
1179
if revision is not None:
1180
revision_id = revision.as_revision_id(br_from)
1182
# FIXME - wt.last_revision, fallback to branch, fall back to
1183
# None or perhaps NULL_REVISION to mean copy nothing
1185
revision_id = br_from.last_revision()
1186
if to_location is None:
1187
to_location = urlutils.derive_to_location(from_location)
1188
to_transport = transport.get_transport(to_location)
1190
to_transport.mkdir('.')
1191
except errors.FileExists:
1192
if not use_existing_dir:
1193
raise errors.BzrCommandError('Target directory "%s" '
1194
'already exists.' % to_location)
1118
if revision is not None:
1119
revision_id = revision.as_revision_id(br_from)
1197
bzrdir.BzrDir.open_from_transport(to_transport)
1198
except errors.NotBranchError:
1201
raise errors.AlreadyBranchError(to_location)
1202
except errors.NoSuchFile:
1203
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1206
# preserve whatever source format we have.
1207
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1208
possible_transports=[to_transport],
1209
accelerator_tree=accelerator_tree,
1210
hardlink=hardlink, stacked=stacked,
1211
force_new_repo=standalone,
1212
create_tree_if_local=not no_tree,
1213
source_branch=br_from)
1214
branch = dir.open_branch()
1215
except errors.NoSuchRevision:
1216
to_transport.delete_tree('.')
1217
msg = "The branch %s has no revision %s." % (from_location,
1219
raise errors.BzrCommandError(msg)
1220
_merge_tags_if_possible(br_from, branch)
1221
# If the source branch is stacked, the new branch may
1222
# be stacked whether we asked for that explicitly or not.
1223
# We therefore need a try/except here and not just 'if stacked:'
1225
note('Created new stacked branch referring to %s.' %
1226
branch.get_stacked_on_url())
1227
except (errors.NotStacked, errors.UnstackableBranchFormat,
1228
errors.UnstackableRepositoryFormat), e:
1229
note('Branched %d revision(s).' % branch.revno())
1231
# Bind to the parent
1232
parent_branch = Branch.open(from_location)
1233
branch.bind(parent_branch)
1234
note('New branch bound to %s' % from_location)
1236
# Switch to the new branch
1237
wt, _ = WorkingTree.open_containing('.')
1238
_mod_switch.switch(wt.bzrdir, branch)
1239
note('Switched to branch: %s',
1240
urlutils.unescape_for_display(branch.base, 'utf-8'))
1121
# FIXME - wt.last_revision, fallback to branch, fall back to
1122
# None or perhaps NULL_REVISION to mean copy nothing
1124
revision_id = br_from.last_revision()
1125
if to_location is None:
1126
to_location = urlutils.derive_to_location(from_location)
1127
to_transport = transport.get_transport(to_location)
1129
to_transport.mkdir('.')
1130
except errors.FileExists:
1131
raise errors.BzrCommandError('Target directory "%s" already'
1132
' exists.' % to_location)
1133
except errors.NoSuchFile:
1134
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1137
# preserve whatever source format we have.
1138
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1139
possible_transports=[to_transport],
1140
accelerator_tree=accelerator_tree,
1141
hardlink=hardlink, stacked=stacked,
1142
force_new_repo=standalone,
1143
create_tree_if_local=not no_tree,
1144
source_branch=br_from)
1145
branch = dir.open_branch()
1146
except errors.NoSuchRevision:
1147
to_transport.delete_tree('.')
1148
msg = "The branch %s has no revision %s." % (from_location,
1150
raise errors.BzrCommandError(msg)
1151
_merge_tags_if_possible(br_from, branch)
1152
# If the source branch is stacked, the new branch may
1153
# be stacked whether we asked for that explicitly or not.
1154
# We therefore need a try/except here and not just 'if stacked:'
1156
note('Created new stacked branch referring to %s.' %
1157
branch.get_stacked_on_url())
1158
except (errors.NotStacked, errors.UnstackableBranchFormat,
1159
errors.UnstackableRepositoryFormat), e:
1160
note('Branched %d revision(s).' % branch.revno())
1243
1165
class cmd_checkout(Command):
1244
__doc__ = """Create a new checkout of an existing branch.
1166
"""Create a new checkout of an existing branch.
1246
1168
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1247
1169
the branch found in '.'. This is useful if you have removed the working tree
1326
1243
@display_command
1327
1244
def run(self, dir=u'.'):
1328
1245
tree = WorkingTree.open_containing(dir)[0]
1329
self.add_cleanup(tree.lock_read().unlock)
1330
new_inv = tree.inventory
1331
old_tree = tree.basis_tree()
1332
self.add_cleanup(old_tree.lock_read().unlock)
1333
old_inv = old_tree.inventory
1335
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1336
for f, paths, c, v, p, n, k, e in iterator:
1337
if paths[0] == paths[1]:
1341
renames.append(paths)
1343
for old_name, new_name in renames:
1344
self.outf.write("%s => %s\n" % (old_name, new_name))
1248
new_inv = tree.inventory
1249
old_tree = tree.basis_tree()
1250
old_tree.lock_read()
1252
old_inv = old_tree.inventory
1254
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1255
for f, paths, c, v, p, n, k, e in iterator:
1256
if paths[0] == paths[1]:
1260
renames.append(paths)
1262
for old_name, new_name in renames:
1263
self.outf.write("%s => %s\n" % (old_name, new_name))
1347
1270
class cmd_update(Command):
1348
__doc__ = """Update a tree to have the latest code committed to its branch.
1271
"""Update a tree to have the latest code committed to its branch.
1350
1273
This will perform a merge into the working tree, and may generate
1351
1274
conflicts. If you have any local changes, you will still
1354
1277
If you want to discard your local changes, you can just do a
1355
1278
'bzr revert' instead of 'bzr commit' after the update.
1357
If the tree's branch is bound to a master branch, it will also update
1358
the branch from the master.
1361
1281
_see_also = ['pull', 'working-trees', 'status-flags']
1362
1282
takes_args = ['dir?']
1363
takes_options = ['revision']
1364
1283
aliases = ['up']
1366
def run(self, dir='.', revision=None):
1367
if revision is not None and len(revision) != 1:
1368
raise errors.BzrCommandError(
1369
"bzr update --revision takes exactly one revision")
1285
def run(self, dir='.'):
1370
1286
tree = WorkingTree.open_containing(dir)[0]
1371
branch = tree.branch
1372
1287
possible_transports = []
1373
master = branch.get_master_branch(
1288
master = tree.branch.get_master_branch(
1374
1289
possible_transports=possible_transports)
1375
1290
if master is not None:
1376
branch_location = master.base
1377
1291
tree.lock_write()
1379
branch_location = tree.branch.base
1380
1293
tree.lock_tree_write()
1381
self.add_cleanup(tree.unlock)
1382
# get rid of the final '/' and be ready for display
1383
branch_location = urlutils.unescape_for_display(
1384
branch_location.rstrip('/'),
1386
existing_pending_merges = tree.get_parent_ids()[1:]
1390
# may need to fetch data into a heavyweight checkout
1391
# XXX: this may take some time, maybe we should display a
1393
old_tip = branch.update(possible_transports)
1394
if revision is not None:
1395
revision_id = revision[0].as_revision_id(branch)
1397
revision_id = branch.last_revision()
1398
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1399
revno = branch.revision_id_to_dotted_revno(revision_id)
1400
note("Tree is up to date at revision %s of branch %s" %
1401
('.'.join(map(str, revno)), branch_location))
1403
view_info = _get_view_info_for_change_reporter(tree)
1404
change_reporter = delta._ChangeReporter(
1405
unversioned_filter=tree.is_ignored,
1406
view_info=view_info)
1295
existing_pending_merges = tree.get_parent_ids()[1:]
1296
last_rev = _mod_revision.ensure_null(tree.last_revision())
1297
if last_rev == _mod_revision.ensure_null(
1298
tree.branch.last_revision()):
1299
# may be up to date, check master too.
1300
if master is None or last_rev == _mod_revision.ensure_null(
1301
master.last_revision()):
1302
revno = tree.branch.revision_id_to_revno(last_rev)
1303
note("Tree is up to date at revision %d." % (revno,))
1305
view_info = _get_view_info_for_change_reporter(tree)
1408
1306
conflicts = tree.update(
1410
possible_transports=possible_transports,
1411
revision=revision_id,
1413
except errors.NoSuchRevision, e:
1414
raise errors.BzrCommandError(
1415
"branch has no revision %s\n"
1416
"bzr update --revision only works"
1417
" for a revision in the branch history"
1419
revno = tree.branch.revision_id_to_dotted_revno(
1420
_mod_revision.ensure_null(tree.last_revision()))
1421
note('Updated to revision %s of branch %s' %
1422
('.'.join(map(str, revno)), branch_location))
1423
parent_ids = tree.get_parent_ids()
1424
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1425
note('Your local commits will now show as pending merges with '
1426
"'bzr status', and can be committed with 'bzr commit'.")
1307
delta._ChangeReporter(unversioned_filter=tree.is_ignored,
1308
view_info=view_info), possible_transports=possible_transports)
1309
revno = tree.branch.revision_id_to_revno(
1310
_mod_revision.ensure_null(tree.last_revision()))
1311
note('Updated to revision %d.' % (revno,))
1312
if tree.get_parent_ids()[1:] != existing_pending_merges:
1313
note('Your local commits will now show as pending merges with '
1314
"'bzr status', and can be committed with 'bzr commit'.")
1433
1323
class cmd_info(Command):
1434
__doc__ = """Show information about a working tree, branch or repository.
1324
"""Show information about a working tree, branch or repository.
1436
1326
This command will show all known locations and formats associated to the
1437
1327
tree, branch or repository.
1499
1389
def run(self, file_list, verbose=False, new=False,
1500
1390
file_deletion_strategy='safe'):
1501
tree, file_list = WorkingTree.open_containing_paths(file_list)
1391
tree, file_list = tree_files(file_list)
1503
1393
if file_list is not None:
1504
1394
file_list = [f for f in file_list]
1506
self.add_cleanup(tree.lock_write().unlock)
1507
# Heuristics should probably all move into tree.remove_smart or
1510
added = tree.changes_from(tree.basis_tree(),
1511
specific_files=file_list).added
1512
file_list = sorted([f[0] for f in added], reverse=True)
1513
if len(file_list) == 0:
1514
raise errors.BzrCommandError('No matching files.')
1515
elif file_list is None:
1516
# missing files show up in iter_changes(basis) as
1517
# versioned-with-no-kind.
1519
for change in tree.iter_changes(tree.basis_tree()):
1520
# Find paths in the working tree that have no kind:
1521
if change[1][1] is not None and change[6][1] is None:
1522
missing.append(change[1][1])
1523
file_list = sorted(missing, reverse=True)
1524
file_deletion_strategy = 'keep'
1525
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1526
keep_files=file_deletion_strategy=='keep',
1527
force=file_deletion_strategy=='force')
1398
# Heuristics should probably all move into tree.remove_smart or
1401
added = tree.changes_from(tree.basis_tree(),
1402
specific_files=file_list).added
1403
file_list = sorted([f[0] for f in added], reverse=True)
1404
if len(file_list) == 0:
1405
raise errors.BzrCommandError('No matching files.')
1406
elif file_list is None:
1407
# missing files show up in iter_changes(basis) as
1408
# versioned-with-no-kind.
1410
for change in tree.iter_changes(tree.basis_tree()):
1411
# Find paths in the working tree that have no kind:
1412
if change[1][1] is not None and change[6][1] is None:
1413
missing.append(change[1][1])
1414
file_list = sorted(missing, reverse=True)
1415
file_deletion_strategy = 'keep'
1416
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1417
keep_files=file_deletion_strategy=='keep',
1418
force=file_deletion_strategy=='force')
1530
1423
class cmd_file_id(Command):
1531
__doc__ = """Print file_id of a particular file or directory.
1424
"""Print file_id of a particular file or directory.
1533
1426
The file_id is assigned when the file is first added and remains the
1534
1427
same through all revisions where the file exists, even when it is
1944
1802
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1945
1803
' one or two revision specifiers')
1947
if using is not None and format is not None:
1948
raise errors.BzrCommandError('--using and --format are mutually '
1951
(old_tree, new_tree,
1952
old_branch, new_branch,
1953
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1954
file_list, revision, old, new, self.add_cleanup, apply_view=True)
1955
# GNU diff on Windows uses ANSI encoding for filenames
1956
path_encoding = osutils.get_diff_header_encoding()
1805
old_tree, new_tree, specific_files, extra_trees = \
1806
_get_trees_to_diff(file_list, revision, old, new,
1957
1808
return show_diff_trees(old_tree, new_tree, sys.stdout,
1958
1809
specific_files=specific_files,
1959
1810
external_diff_options=diff_options,
1960
1811
old_label=old_label, new_label=new_label,
1961
extra_trees=extra_trees,
1962
path_encoding=path_encoding,
1812
extra_trees=extra_trees, using=using)
1967
1815
class cmd_deleted(Command):
1968
__doc__ = """List files deleted in the working tree.
1816
"""List files deleted in the working tree.
1970
1818
# TODO: Show files deleted since a previous revision, or
1971
1819
# between two revisions.
1974
1822
# level of effort but possibly much less IO. (Or possibly not,
1975
1823
# if the directories are very large...)
1976
1824
_see_also = ['status', 'ls']
1977
takes_options = ['directory', 'show-ids']
1825
takes_options = ['show-ids']
1979
1827
@display_command
1980
def run(self, show_ids=False, directory=u'.'):
1981
tree = WorkingTree.open_containing(directory)[0]
1982
self.add_cleanup(tree.lock_read().unlock)
1983
old = tree.basis_tree()
1984
self.add_cleanup(old.lock_read().unlock)
1985
for path, ie in old.inventory.iter_entries():
1986
if not tree.has_id(ie.file_id):
1987
self.outf.write(path)
1989
self.outf.write(' ')
1990
self.outf.write(ie.file_id)
1991
self.outf.write('\n')
1828
def run(self, show_ids=False):
1829
tree = WorkingTree.open_containing(u'.')[0]
1832
old = tree.basis_tree()
1835
for path, ie in old.inventory.iter_entries():
1836
if not tree.has_id(ie.file_id):
1837
self.outf.write(path)
1839
self.outf.write(' ')
1840
self.outf.write(ie.file_id)
1841
self.outf.write('\n')
1994
1848
class cmd_modified(Command):
1995
__doc__ = """List files modified in working tree.
1849
"""List files modified in working tree.
1999
1853
_see_also = ['status', 'ls']
2000
takes_options = ['directory', 'null']
1856
help='Write an ascii NUL (\\0) separator '
1857
'between files rather than a newline.')
2002
1860
@display_command
2003
def run(self, null=False, directory=u'.'):
2004
tree = WorkingTree.open_containing(directory)[0]
1861
def run(self, null=False):
1862
tree = WorkingTree.open_containing(u'.')[0]
2005
1863
td = tree.changes_from(tree.basis_tree())
2006
1864
for path, id, kind, text_modified, meta_modified in td.modified:
2013
1871
class cmd_added(Command):
2014
__doc__ = """List files added in working tree.
1872
"""List files added in working tree.
2018
1876
_see_also = ['status', 'ls']
2019
takes_options = ['directory', 'null']
1879
help='Write an ascii NUL (\\0) separator '
1880
'between files rather than a newline.')
2021
1883
@display_command
2022
def run(self, null=False, directory=u'.'):
2023
wt = WorkingTree.open_containing(directory)[0]
2024
self.add_cleanup(wt.lock_read().unlock)
2025
basis = wt.basis_tree()
2026
self.add_cleanup(basis.lock_read().unlock)
2027
basis_inv = basis.inventory
2030
if file_id in basis_inv:
2032
if inv.is_root(file_id) and len(basis_inv) == 0:
2034
path = inv.id2path(file_id)
2035
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2038
self.outf.write(path + '\0')
2040
self.outf.write(osutils.quotefn(path) + '\n')
1884
def run(self, null=False):
1885
wt = WorkingTree.open_containing(u'.')[0]
1888
basis = wt.basis_tree()
1891
basis_inv = basis.inventory
1894
if file_id in basis_inv:
1896
if inv.is_root(file_id) and len(basis_inv) == 0:
1898
path = inv.id2path(file_id)
1899
if not os.access(osutils.abspath(path), os.F_OK):
1902
self.outf.write(path + '\0')
1904
self.outf.write(osutils.quotefn(path) + '\n')
2043
1911
class cmd_root(Command):
2044
__doc__ = """Show the tree root directory.
1912
"""Show the tree root directory.
2046
1914
The root is the nearest enclosing directory with a .bzr control
2358
2212
diff_type = 'full'
2360
# Build the log formatter
2361
if log_format is None:
2362
log_format = log.log_formatter_registry.get_default(b)
2363
# Make a non-encoding output to include the diffs - bug 328007
2364
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2365
lf = log_format(show_ids=show_ids, to_file=self.outf,
2366
to_exact_file=unencoded_output,
2367
show_timezone=timezone,
2368
delta_format=get_verbosity_level(),
2370
show_advice=levels is None,
2371
author_list_handler=authors)
2373
# Choose the algorithm for doing the logging. It's annoying
2374
# having multiple code paths like this but necessary until
2375
# the underlying repository format is faster at generating
2376
# deltas or can provide everything we need from the indices.
2377
# The default algorithm - match-using-deltas - works for
2378
# multiple files and directories and is faster for small
2379
# amounts of history (200 revisions say). However, it's too
2380
# slow for logging a single file in a repository with deep
2381
# history, i.e. > 10K revisions. In the spirit of "do no
2382
# evil when adding features", we continue to use the
2383
# original algorithm - per-file-graph - for the "single
2384
# file that isn't a directory without showing a delta" case.
2385
partial_history = revision and b.repository._format.supports_chks
2386
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2387
or delta_type or partial_history)
2389
# Build the LogRequest and execute it
2390
if len(file_ids) == 0:
2392
rqst = make_log_request_dict(
2393
direction=direction, specific_fileids=file_ids,
2394
start_revision=rev1, end_revision=rev2, limit=limit,
2395
message_search=message, delta_type=delta_type,
2396
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2397
exclude_common_ancestry=exclude_common_ancestry,
2399
Logger(b, rqst).show(lf)
2216
# Build the log formatter
2217
if log_format is None:
2218
log_format = log.log_formatter_registry.get_default(b)
2219
lf = log_format(show_ids=show_ids, to_file=self.outf,
2220
show_timezone=timezone,
2221
delta_format=get_verbosity_level(),
2223
show_advice=levels is None)
2225
# Choose the algorithm for doing the logging. It's annoying
2226
# having multiple code paths like this but necessary until
2227
# the underlying repository format is faster at generating
2228
# deltas or can provide everything we need from the indices.
2229
# The default algorithm - match-using-deltas - works for
2230
# multiple files and directories and is faster for small
2231
# amounts of history (200 revisions say). However, it's too
2232
# slow for logging a single file in a repository with deep
2233
# history, i.e. > 10K revisions. In the spirit of "do no
2234
# evil when adding features", we continue to use the
2235
# original algorithm - per-file-graph - for the "single
2236
# file that isn't a directory without showing a delta" case.
2237
partial_history = revision and b.repository._format.supports_chks
2238
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2239
or delta_type or partial_history)
2241
# Build the LogRequest and execute it
2242
if len(file_ids) == 0:
2244
rqst = make_log_request_dict(
2245
direction=direction, specific_fileids=file_ids,
2246
start_revision=rev1, end_revision=rev2, limit=limit,
2247
message_search=message, delta_type=delta_type,
2248
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2249
Logger(b, rqst).show(lf)
2402
2254
def _get_revision_range(revisionspec_list, branch, command_name):
2491
2337
help='Recurse into subdirectories.'),
2492
2338
Option('from-root',
2493
2339
help='Print paths relative to the root of the branch.'),
2494
Option('unknown', short_name='u',
2495
help='Print unknown files.'),
2340
Option('unknown', help='Print unknown files.'),
2496
2341
Option('versioned', help='Print versioned files.',
2497
2342
short_name='V'),
2498
Option('ignored', short_name='i',
2499
help='Print ignored files.'),
2500
Option('kind', short_name='k',
2343
Option('ignored', help='Print ignored files.'),
2345
help='Write an ascii NUL (\\0) separator '
2346
'between files rather than a newline.'),
2501
2348
help='List entries of a particular kind: file, directory, symlink.',
2507
2352
@display_command
2508
2353
def run(self, revision=None, verbose=False,
2509
2354
recursive=False, from_root=False,
2510
2355
unknown=False, versioned=False, ignored=False,
2511
null=False, kind=None, show_ids=False, path=None, directory=None):
2356
null=False, kind=None, show_ids=False, path=None):
2513
2358
if kind and kind not in ('file', 'directory', 'symlink'):
2514
2359
raise errors.BzrCommandError('invalid kind specified')
2548
2390
view_str = views.view_display_str(view_files)
2549
2391
note("Ignoring files outside view. View is %s" % view_str)
2551
self.add_cleanup(tree.lock_read().unlock)
2552
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2553
from_dir=relpath, recursive=recursive):
2554
# Apply additional masking
2555
if not all and not selection[fc]:
2557
if kind is not None and fkind != kind:
2562
fullpath = osutils.pathjoin(relpath, fp)
2565
views.check_path_in_view(tree, fullpath)
2566
except errors.FileOutsideView:
2571
fp = osutils.pathjoin(prefix, fp)
2572
kindch = entry.kind_character()
2573
outstring = fp + kindch
2574
ui.ui_factory.clear_term()
2576
outstring = '%-8s %s' % (fc, outstring)
2577
if show_ids and fid is not None:
2578
outstring = "%-50s %s" % (outstring, fid)
2579
self.outf.write(outstring + '\n')
2581
self.outf.write(fp + '\0')
2584
self.outf.write(fid)
2585
self.outf.write('\0')
2593
self.outf.write('%-50s %s\n' % (outstring, my_id))
2595
self.outf.write(outstring + '\n')
2395
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2396
if fp.startswith(relpath):
2397
rp = fp[len(relpath):]
2398
fp = osutils.pathjoin(prefix, rp)
2399
if not recursive and '/' in rp:
2401
if not all and not selection[fc]:
2403
if kind is not None and fkind != kind:
2407
views.check_path_in_view(tree, fp)
2408
except errors.FileOutsideView:
2410
kindch = entry.kind_character()
2411
outstring = fp + kindch
2413
outstring = '%-8s %s' % (fc, outstring)
2414
if show_ids and fid is not None:
2415
outstring = "%-50s %s" % (outstring, fid)
2416
self.outf.write(outstring + '\n')
2418
self.outf.write(fp + '\0')
2421
self.outf.write(fid)
2422
self.outf.write('\0')
2430
self.outf.write('%-50s %s\n' % (outstring, my_id))
2432
self.outf.write(outstring + '\n')
2598
2437
class cmd_unknowns(Command):
2599
__doc__ = """List unknown files.
2438
"""List unknown files.
2603
2442
_see_also = ['ls']
2604
takes_options = ['directory']
2606
2444
@display_command
2607
def run(self, directory=u'.'):
2608
for f in WorkingTree.open_containing(directory)[0].unknowns():
2446
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2609
2447
self.outf.write(osutils.quotefn(f) + '\n')
2612
2450
class cmd_ignore(Command):
2613
__doc__ = """Ignore specified files or patterns.
2451
"""Ignore specified files or patterns.
2615
2453
See ``bzr help patterns`` for details on the syntax of patterns.
2617
If a .bzrignore file does not exist, the ignore command
2618
will create one and add the specified files or patterns to the newly
2619
created file. The ignore command will also automatically add the
2620
.bzrignore file to be versioned. Creating a .bzrignore file without
2621
the use of the ignore command will require an explicit add command.
2623
2455
To remove patterns from the ignore list, edit the .bzrignore file.
2624
2456
After adding, editing or deleting that file either indirectly by
2625
2457
using this command or directly by using an editor, be sure to commit
2628
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2629
the global ignore file can be found in the application data directory as
2630
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2631
Global ignores are not touched by this command. The global ignore file
2632
can be edited directly using an editor.
2634
Patterns prefixed with '!' are exceptions to ignore patterns and take
2635
precedence over regular ignores. Such exceptions are used to specify
2636
files that should be versioned which would otherwise be ignored.
2638
Patterns prefixed with '!!' act as regular ignore patterns, but have
2639
precedence over the '!' exception patterns.
2641
2460
Note: ignore patterns containing shell wildcards must be quoted from
2642
2461
the shell on Unix.
2665
2480
Ignore everything but the "debian" toplevel directory::
2667
2482
bzr ignore "RE:(?!debian/).*"
2669
Ignore everything except the "local" toplevel directory,
2670
but always ignore "*~" autosave files, even under local/::
2673
bzr ignore "!./local"
2677
2485
_see_also = ['status', 'ignored', 'patterns']
2678
2486
takes_args = ['name_pattern*']
2679
takes_options = ['directory',
2680
Option('default-rules',
2681
help='Display the default ignore rules that bzr uses.')
2488
Option('old-default-rules',
2489
help='Write out the ignore rules bzr < 0.9 always used.')
2684
def run(self, name_pattern_list=None, default_rules=None,
2492
def run(self, name_pattern_list=None, old_default_rules=None):
2686
2493
from bzrlib import ignores
2687
if default_rules is not None:
2688
# dump the default rules and exit
2689
for pattern in ignores.USER_DEFAULTS:
2690
self.outf.write("%s\n" % pattern)
2494
if old_default_rules is not None:
2495
# dump the rules and exit
2496
for pattern in ignores.OLD_DEFAULTS:
2692
2499
if not name_pattern_list:
2693
2500
raise errors.BzrCommandError("ignore requires at least one "
2694
"NAME_PATTERN or --default-rules.")
2501
"NAME_PATTERN or --old-default-rules")
2695
2502
name_pattern_list = [globbing.normalize_pattern(p)
2696
2503
for p in name_pattern_list]
2698
for p in name_pattern_list:
2699
if not globbing.Globster.is_pattern_valid(p):
2700
bad_patterns += ('\n %s' % p)
2702
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2703
ui.ui_factory.show_error(msg)
2704
raise errors.InvalidPattern('')
2705
2504
for name_pattern in name_pattern_list:
2706
2505
if (name_pattern[0] == '/' or
2707
2506
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2708
2507
raise errors.BzrCommandError(
2709
2508
"NAME_PATTERN should not be an absolute path")
2710
tree, relpath = WorkingTree.open_containing(directory)
2509
tree, relpath = WorkingTree.open_containing(u'.')
2711
2510
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2712
2511
ignored = globbing.Globster(name_pattern_list)
2714
self.add_cleanup(tree.lock_read().unlock)
2715
2514
for entry in tree.list_files():
2717
2516
if id is not None:
2718
2517
filename = entry[0]
2719
2518
if ignored.match(filename):
2720
matches.append(filename)
2519
matches.append(filename.encode('utf-8'))
2721
2521
if len(matches) > 0:
2722
self.outf.write("Warning: the following files are version controlled and"
2723
" match your ignore pattern:\n%s"
2724
"\nThese files will continue to be version controlled"
2725
" unless you 'bzr remove' them.\n" % ("\n".join(matches),))
2522
print "Warning: the following files are version controlled and" \
2523
" match your ignore pattern:\n%s" \
2524
"\nThese files will continue to be version controlled" \
2525
" unless you 'bzr remove' them." % ("\n".join(matches),)
2728
2528
class cmd_ignored(Command):
2729
__doc__ = """List ignored files and the patterns that matched them.
2529
"""List ignored files and the patterns that matched them.
2731
2531
List all the ignored files and the ignore pattern that caused the file to
2739
2539
encoding_type = 'replace'
2740
2540
_see_also = ['ignore', 'ls']
2741
takes_options = ['directory']
2743
2542
@display_command
2744
def run(self, directory=u'.'):
2745
tree = WorkingTree.open_containing(directory)[0]
2746
self.add_cleanup(tree.lock_read().unlock)
2747
for path, file_class, kind, file_id, entry in tree.list_files():
2748
if file_class != 'I':
2750
## XXX: Slightly inefficient since this was already calculated
2751
pat = tree.is_ignored(path)
2752
self.outf.write('%-50s %s\n' % (path, pat))
2544
tree = WorkingTree.open_containing(u'.')[0]
2547
for path, file_class, kind, file_id, entry in tree.list_files():
2548
if file_class != 'I':
2550
## XXX: Slightly inefficient since this was already calculated
2551
pat = tree.is_ignored(path)
2552
self.outf.write('%-50s %s\n' % (path, pat))
2755
2557
class cmd_lookup_revision(Command):
2756
__doc__ = """Lookup the revision-id from a revision-number
2558
"""Lookup the revision-id from a revision-number
2759
2561
bzr lookup-revision 33
2762
2564
takes_args = ['revno']
2763
takes_options = ['directory']
2765
2566
@display_command
2766
def run(self, revno, directory=u'.'):
2567
def run(self, revno):
2768
2569
revno = int(revno)
2769
2570
except ValueError:
2770
raise errors.BzrCommandError("not a valid revision-number: %r"
2772
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2773
self.outf.write("%s\n" % revid)
2571
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2573
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2776
2576
class cmd_export(Command):
2777
__doc__ = """Export current or past revision to a destination directory or archive.
2577
"""Export current or past revision to a destination directory or archive.
2779
2579
If no revision is specified this exports the last committed revision.
2858
2654
@display_command
2859
2655
def run(self, filename, revision=None, name_from_revision=False,
2860
filters=False, directory=None):
2861
2657
if revision is not None and len(revision) != 1:
2862
2658
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2863
2659
" one revision specifier")
2864
2660
tree, branch, relpath = \
2865
_open_directory_or_containing_tree_or_branch(filename, directory)
2866
self.add_cleanup(branch.lock_read().unlock)
2867
return self._run(tree, branch, relpath, filename, revision,
2868
name_from_revision, filters)
2661
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2664
return self._run(tree, branch, relpath, filename, revision,
2665
name_from_revision, filters)
2870
2669
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2872
2671
if tree is None:
2873
2672
tree = b.basis_tree()
2874
2673
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2875
self.add_cleanup(rev_tree.lock_read().unlock)
2877
2675
old_file_id = rev_tree.path2id(relpath)
3116
2901
if local and not tree.branch.get_bound_location():
3117
2902
raise errors.LocalRequiresBoundBranch()
3119
if message is not None:
3121
file_exists = osutils.lexists(message)
3122
except UnicodeError:
3123
# The commit message contains unicode characters that can't be
3124
# represented in the filesystem encoding, so that can't be a
3129
'The commit message is a file name: "%(f)s".\n'
3130
'(use --file "%(f)s" to take commit message from that file)'
3132
ui.ui_factory.show_warning(warning_msg)
3134
message = message.replace('\r\n', '\n')
3135
message = message.replace('\r', '\n')
3137
raise errors.BzrCommandError(
3138
"please specify either --message or --file")
3140
2904
def get_message(commit_obj):
3141
2905
"""Callback to get commit message"""
3145
my_message = f.read().decode(osutils.get_user_encoding())
3148
elif message is not None:
3149
my_message = message
3151
# No message supplied: make one up.
3152
# text is the status of the tree
3153
text = make_commit_message_template_encoded(tree,
2906
my_message = message
2907
if my_message is None and not file:
2908
t = make_commit_message_template_encoded(tree,
3154
2909
selected_list, diff=show_diff,
3155
2910
output_encoding=osutils.get_user_encoding())
3156
# start_message is the template generated from hooks
3157
# XXX: Warning - looks like hooks return unicode,
3158
# make_commit_message_template_encoded returns user encoding.
3159
# We probably want to be using edit_commit_message instead to
3161
2911
start_message = generate_commit_message_template(commit_obj)
3162
my_message = edit_commit_message_encoded(text,
2912
my_message = edit_commit_message_encoded(t,
3163
2913
start_message=start_message)
3164
2914
if my_message is None:
3165
2915
raise errors.BzrCommandError("please specify a commit"
3166
2916
" message with either --message or --file")
2917
elif my_message and file:
2918
raise errors.BzrCommandError(
2919
"please specify either --message or --file")
2921
my_message = codecs.open(file, 'rt',
2922
osutils.get_user_encoding()).read()
3167
2923
if my_message == "":
3168
2924
raise errors.BzrCommandError("empty commit message specified")
3169
2925
return my_message
3171
# The API permits a commit with a filter of [] to mean 'select nothing'
3172
# but the command line should not do that.
3173
if not selected_list:
3174
selected_list = None
3176
2928
tree.commit(message_callback=get_message,
3177
2929
specific_files=selected_list,
3178
2930
allow_pointless=unchanged, strict=strict, local=local,
3179
2931
reporter=None, verbose=verbose, revprops=properties,
3180
authors=author, timestamp=commit_stamp,
3182
exclude=tree.safe_relpath_files(exclude))
2933
exclude=safe_relpath_files(tree, exclude))
3183
2934
except PointlessCommit:
2935
# FIXME: This should really happen before the file is read in;
2936
# perhaps prepare the commit; get the message; then actually commit
3184
2937
raise errors.BzrCommandError("No changes to commit."
3185
2938
" Use --unchanged to commit anyhow.")
3186
2939
except ConflictsInTree:
3207
2959
The working tree and branch checks will only give output if a problem is
3208
2960
detected. The output fields of the repository check are:
3211
This is just the number of revisions checked. It doesn't
3215
This is just the number of versionedfiles checked. It
3216
doesn't indicate a problem.
3218
unreferenced ancestors
3219
Texts that are ancestors of other texts, but
3220
are not properly referenced by the revision ancestry. This is a
3221
subtle problem that Bazaar can work around.
3224
This is the total number of unique file contents
3225
seen in the checked revisions. It does not indicate a problem.
3228
This is the total number of repeated texts seen
3229
in the checked revisions. Texts can be repeated when their file
3230
entries are modified, but the file contents are not. It does not
2962
revisions: This is just the number of revisions checked. It doesn't
2964
versionedfiles: This is just the number of versionedfiles checked. It
2965
doesn't indicate a problem.
2966
unreferenced ancestors: Texts that are ancestors of other texts, but
2967
are not properly referenced by the revision ancestry. This is a
2968
subtle problem that Bazaar can work around.
2969
unique file texts: This is the total number of unique file contents
2970
seen in the checked revisions. It does not indicate a problem.
2971
repeated file texts: This is the total number of repeated texts seen
2972
in the checked revisions. Texts can be repeated when their file
2973
entries are modified, but the file contents are not. It does not
3233
2976
If no restrictions are specified, all Bazaar data that is found at the given
3234
2977
location will be checked.
3583
3322
raise errors.BzrCommandError("subunit not available. subunit "
3584
3323
"needs to be installed to use --subunit.")
3585
3324
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3586
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3587
# stdout, which would corrupt the subunit stream.
3588
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3589
# following code can be deleted when it's sufficiently deployed
3590
# -- vila/mgz 20100514
3591
if (sys.platform == "win32"
3592
and getattr(sys.stdout, 'fileno', None) is not None):
3594
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3596
3326
self.additional_selftest_args.setdefault(
3597
3327
'suite_decorators', []).append(parallel)
3599
raise errors.BzrCommandError(
3600
"--benchmark is no longer supported from bzr 2.2; "
3601
"use bzr-usertest instead")
3602
test_suite_factory = None
3603
selftest_kwargs = {"verbose": verbose,
3605
"stop_on_failure": one,
3606
"transport": transport,
3607
"test_suite_factory": test_suite_factory,
3608
"lsprof_timed": lsprof_timed,
3609
"lsprof_tests": lsprof_tests,
3610
"matching_tests_first": first,
3611
"list_only": list_only,
3612
"random_seed": randomize,
3613
"exclude_pattern": exclude,
3615
"load_list": load_list,
3616
"debug_flags": debugflag,
3617
"starting_with": starting_with
3619
selftest_kwargs.update(self.additional_selftest_args)
3621
# Make deprecation warnings visible, unless -Werror is set
3622
cleanup = symbol_versioning.activate_deprecation_warnings(
3329
test_suite_factory = benchmarks.test_suite
3330
# Unless user explicitly asks for quiet, be verbose in benchmarks
3331
verbose = not is_quiet()
3332
# TODO: should possibly lock the history file...
3333
benchfile = open(".perf_history", "at", buffering=1)
3335
test_suite_factory = None
3625
result = tests.selftest(**selftest_kwargs)
3338
selftest_kwargs = {"verbose": verbose,
3340
"stop_on_failure": one,
3341
"transport": transport,
3342
"test_suite_factory": test_suite_factory,
3343
"lsprof_timed": lsprof_timed,
3344
"bench_history": benchfile,
3345
"matching_tests_first": first,
3346
"list_only": list_only,
3347
"random_seed": randomize,
3348
"exclude_pattern": exclude,
3350
"load_list": load_list,
3351
"debug_flags": debugflag,
3352
"starting_with": starting_with
3354
selftest_kwargs.update(self.additional_selftest_args)
3355
result = selftest(**selftest_kwargs)
3357
if benchfile is not None:
3628
3359
return int(not result)
3631
3362
class cmd_version(Command):
3632
__doc__ = """Show version of bzr."""
3363
"""Show version of bzr."""
3634
3365
encoding_type = 'replace'
3635
3366
takes_options = [
3795
3516
verified = 'inapplicable'
3796
3517
tree = WorkingTree.open_containing(directory)[0]
3519
# die as quickly as possible if there are uncommitted changes
3799
3521
basis_tree = tree.revision_tree(tree.last_revision())
3800
3522
except errors.NoSuchRevision:
3801
3523
basis_tree = tree.basis_tree()
3803
# die as quickly as possible if there are uncommitted changes
3805
if tree.has_changes():
3525
changes = tree.changes_from(basis_tree)
3526
if changes.has_changed():
3806
3527
raise errors.UncommittedChanges(tree)
3808
3529
view_info = _get_view_info_for_change_reporter(tree)
3809
3530
change_reporter = delta._ChangeReporter(
3810
3531
unversioned_filter=tree.is_ignored, view_info=view_info)
3811
pb = ui.ui_factory.nested_progress_bar()
3812
self.add_cleanup(pb.finished)
3813
self.add_cleanup(tree.lock_write().unlock)
3814
if location is not None:
3816
mergeable = bundle.read_mergeable_from_url(location,
3817
possible_transports=possible_transports)
3818
except errors.NotABundle:
3534
pb = ui.ui_factory.nested_progress_bar()
3535
cleanups.append(pb.finished)
3537
cleanups.append(tree.unlock)
3538
if location is not None:
3540
mergeable = bundle.read_mergeable_from_url(location,
3541
possible_transports=possible_transports)
3542
except errors.NotABundle:
3546
raise errors.BzrCommandError('Cannot use --uncommitted'
3547
' with bundles or merge directives.')
3549
if revision is not None:
3550
raise errors.BzrCommandError(
3551
'Cannot use -r with merge directives or bundles')
3552
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3555
if merger is None and uncommitted:
3556
if revision is not None and len(revision) > 0:
3557
raise errors.BzrCommandError('Cannot use --uncommitted and'
3558
' --revision at the same time.')
3559
location = self._select_branch_location(tree, location)[0]
3560
other_tree, other_path = WorkingTree.open_containing(location)
3561
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3563
allow_pending = False
3564
if other_path != '':
3565
merger.interesting_files = [other_path]
3568
merger, allow_pending = self._get_merger_from_branch(tree,
3569
location, revision, remember, possible_transports, pb)
3571
merger.merge_type = merge_type
3572
merger.reprocess = reprocess
3573
merger.show_base = show_base
3574
self.sanity_check_merger(merger)
3575
if (merger.base_rev_id == merger.other_rev_id and
3576
merger.other_rev_id is not None):
3577
note('Nothing to do.')
3580
if merger.interesting_files is not None:
3581
raise errors.BzrCommandError('Cannot pull individual files')
3582
if (merger.base_rev_id == tree.last_revision()):
3583
result = tree.pull(merger.other_branch, False,
3584
merger.other_rev_id)
3585
result.report(self.outf)
3587
merger.check_basis(False)
3589
return self._do_preview(merger)
3822
raise errors.BzrCommandError('Cannot use --uncommitted'
3823
' with bundles or merge directives.')
3825
if revision is not None:
3826
raise errors.BzrCommandError(
3827
'Cannot use -r with merge directives or bundles')
3828
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3831
if merger is None and uncommitted:
3832
if revision is not None and len(revision) > 0:
3833
raise errors.BzrCommandError('Cannot use --uncommitted and'
3834
' --revision at the same time.')
3835
merger = self.get_merger_from_uncommitted(tree, location, None)
3836
allow_pending = False
3839
merger, allow_pending = self._get_merger_from_branch(tree,
3840
location, revision, remember, possible_transports, None)
3842
merger.merge_type = merge_type
3843
merger.reprocess = reprocess
3844
merger.show_base = show_base
3845
self.sanity_check_merger(merger)
3846
if (merger.base_rev_id == merger.other_rev_id and
3847
merger.other_rev_id is not None):
3848
note('Nothing to do.')
3851
if merger.interesting_files is not None:
3852
raise errors.BzrCommandError('Cannot pull individual files')
3853
if (merger.base_rev_id == tree.last_revision()):
3854
result = tree.pull(merger.other_branch, False,
3855
merger.other_rev_id)
3856
result.report(self.outf)
3858
if merger.this_basis is None:
3859
raise errors.BzrCommandError(
3860
"This branch has no commits."
3861
" (perhaps you would prefer 'bzr pull')")
3863
return self._do_preview(merger)
3865
return self._do_interactive(merger)
3867
return self._do_merge(merger, change_reporter, allow_pending,
3870
def _get_preview(self, merger):
3591
return self._do_merge(merger, change_reporter, allow_pending,
3594
for cleanup in reversed(cleanups):
3597
def _do_preview(self, merger):
3598
from bzrlib.diff import show_diff_trees
3871
3599
tree_merger = merger.make_merger()
3872
3600
tt = tree_merger.make_preview_transform()
3873
self.add_cleanup(tt.finalize)
3874
result_tree = tt.get_preview_tree()
3877
def _do_preview(self, merger):
3878
from bzrlib.diff import show_diff_trees
3879
result_tree = self._get_preview(merger)
3880
path_encoding = osutils.get_diff_header_encoding()
3881
show_diff_trees(merger.this_tree, result_tree, self.outf,
3882
old_label='', new_label='',
3883
path_encoding=path_encoding)
3602
result_tree = tt.get_preview_tree()
3603
show_diff_trees(merger.this_tree, result_tree, self.outf,
3604
old_label='', new_label='')
3885
3608
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3886
3609
merger.change_reporter = change_reporter
4071
3762
def run(self, file_list=None, merge_type=None, show_base=False,
4072
3763
reprocess=False):
4073
from bzrlib.conflicts import restore
4074
3764
if merge_type is None:
4075
3765
merge_type = _mod_merge.Merge3Merger
4076
tree, file_list = WorkingTree.open_containing_paths(file_list)
4077
self.add_cleanup(tree.lock_write().unlock)
4078
parents = tree.get_parent_ids()
4079
if len(parents) != 2:
4080
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4081
" merges. Not cherrypicking or"
4083
repository = tree.branch.repository
4084
interesting_ids = None
4086
conflicts = tree.conflicts()
4087
if file_list is not None:
4088
interesting_ids = set()
4089
for filename in file_list:
4090
file_id = tree.path2id(filename)
4092
raise errors.NotVersionedError(filename)
4093
interesting_ids.add(file_id)
4094
if tree.kind(file_id) != "directory":
3766
tree, file_list = tree_files(file_list)
3769
parents = tree.get_parent_ids()
3770
if len(parents) != 2:
3771
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3772
" merges. Not cherrypicking or"
3774
repository = tree.branch.repository
3775
interesting_ids = None
3777
conflicts = tree.conflicts()
3778
if file_list is not None:
3779
interesting_ids = set()
3780
for filename in file_list:
3781
file_id = tree.path2id(filename)
3783
raise errors.NotVersionedError(filename)
3784
interesting_ids.add(file_id)
3785
if tree.kind(file_id) != "directory":
4097
for name, ie in tree.inventory.iter_entries(file_id):
4098
interesting_ids.add(ie.file_id)
4099
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4101
# Remerge only supports resolving contents conflicts
4102
allowed_conflicts = ('text conflict', 'contents conflict')
4103
restore_files = [c.path for c in conflicts
4104
if c.typestring in allowed_conflicts]
4105
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4106
tree.set_conflicts(ConflictList(new_conflicts))
4107
if file_list is not None:
4108
restore_files = file_list
4109
for filename in restore_files:
3788
for name, ie in tree.inventory.iter_entries(file_id):
3789
interesting_ids.add(ie.file_id)
3790
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3792
# Remerge only supports resolving contents conflicts
3793
allowed_conflicts = ('text conflict', 'contents conflict')
3794
restore_files = [c.path for c in conflicts
3795
if c.typestring in allowed_conflicts]
3796
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3797
tree.set_conflicts(ConflictList(new_conflicts))
3798
if file_list is not None:
3799
restore_files = file_list
3800
for filename in restore_files:
3802
restore(tree.abspath(filename))
3803
except errors.NotConflicted:
3805
# Disable pending merges, because the file texts we are remerging
3806
# have not had those merges performed. If we use the wrong parents
3807
# list, we imply that the working tree text has seen and rejected
3808
# all the changes from the other tree, when in fact those changes
3809
# have not yet been seen.
3810
pb = ui.ui_factory.nested_progress_bar()
3811
tree.set_parent_ids(parents[:1])
4111
restore(tree.abspath(filename))
4112
except errors.NotConflicted:
4114
# Disable pending merges, because the file texts we are remerging
4115
# have not had those merges performed. If we use the wrong parents
4116
# list, we imply that the working tree text has seen and rejected
4117
# all the changes from the other tree, when in fact those changes
4118
# have not yet been seen.
4119
tree.set_parent_ids(parents[:1])
4121
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4122
merger.interesting_ids = interesting_ids
4123
merger.merge_type = merge_type
4124
merger.show_base = show_base
4125
merger.reprocess = reprocess
4126
conflicts = merger.do_merge()
3813
merger = _mod_merge.Merger.from_revision_ids(pb,
3815
merger.interesting_ids = interesting_ids
3816
merger.merge_type = merge_type
3817
merger.show_base = show_base
3818
merger.reprocess = reprocess
3819
conflicts = merger.do_merge()
3821
tree.set_parent_ids(parents)
4128
tree.set_parent_ids(parents)
4129
3825
if conflicts > 0:
4153
3849
name. If you name a directory, all the contents of that directory will be
4156
If you have newly added files since the target revision, they will be
4157
removed. If the files to be removed have been changed, backups will be
4158
created as above. Directories containing unknown files will not be
3852
Any files that have been newly added since that revision will be deleted,
3853
with a backup kept if appropriate. Directories containing unknown files
3854
will not be deleted.
4161
The working tree contains a list of revisions that have been merged but
4162
not yet committed. These revisions will be included as additional parents
4163
of the next commit. Normally, using revert clears that list as well as
4164
reverting the files. If any files are specified, revert leaves the list
4165
of uncommitted merges alone and reverts only the files. Use ``bzr revert
4166
.`` in the tree root to revert all files but keep the recorded merges,
4167
and ``bzr revert --forget-merges`` to clear the pending merge list without
3856
The working tree contains a list of pending merged revisions, which will
3857
be included as parents in the next commit. Normally, revert clears that
3858
list as well as reverting the files. If any files are specified, revert
3859
leaves the pending merge list alone and reverts only the files. Use "bzr
3860
revert ." in the tree root to revert all files but keep the merge record,
3861
and "bzr revert --forget-merges" to clear the pending merge list without
4168
3862
reverting any files.
4170
Using "bzr revert --forget-merges", it is possible to apply all of the
4171
changes from a branch in a single revision. To do this, perform the merge
4172
as desired. Then doing revert with the "--forget-merges" option will keep
4173
the content of the tree as it was, but it will clear the list of pending
4174
merges. The next commit will then contain all of the changes that are
4175
present in the other branch, but without any other parent revisions.
4176
Because this technique forgets where these changes originated, it may
4177
cause additional conflicts on later merges involving the same source and
4181
3865
_see_also = ['cat', 'export']
4190
3874
def run(self, revision=None, no_backup=False, file_list=None,
4191
3875
forget_merges=None):
4192
tree, file_list = WorkingTree.open_containing_paths(file_list)
4193
self.add_cleanup(tree.lock_tree_write().unlock)
4195
tree.set_parent_ids(tree.get_parent_ids()[:1])
4197
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
3876
tree, file_list = tree_files(file_list)
3880
tree.set_parent_ids(tree.get_parent_ids()[:1])
3882
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4200
3887
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4201
3888
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4202
tree.revert(file_list, rev_tree, not no_backup, None,
4203
report_changes=True)
3889
pb = ui.ui_factory.nested_progress_bar()
3891
tree.revert(file_list, rev_tree, not no_backup, pb,
3892
report_changes=True)
4206
3897
class cmd_assert_fail(Command):
4207
__doc__ = """Test reporting of assertion failures"""
3898
"""Test reporting of assertion failures"""
4208
3899
# intended just for use in testing
4361
4042
_get_revision_range(revision,
4362
4043
remote_branch, self.name()))
4364
local_extra, remote_extra = find_unmerged(
4365
local_branch, remote_branch, restrict,
4366
backward=not reverse,
4367
include_merges=include_merges,
4368
local_revid_range=local_revid_range,
4369
remote_revid_range=remote_revid_range)
4371
if log_format is None:
4372
registry = log.log_formatter_registry
4373
log_format = registry.get_default(local_branch)
4374
lf = log_format(to_file=self.outf,
4376
show_timezone='original')
4379
if local_extra and not theirs_only:
4380
message("You have %d extra revision(s):\n" %
4382
for revision in iter_log_revisions(local_extra,
4383
local_branch.repository,
4385
lf.log_revision(revision)
4386
printed_local = True
4389
printed_local = False
4391
if remote_extra and not mine_only:
4392
if printed_local is True:
4394
message("You are missing %d revision(s):\n" %
4396
for revision in iter_log_revisions(remote_extra,
4397
remote_branch.repository,
4399
lf.log_revision(revision)
4402
if mine_only and not local_extra:
4403
# We checked local, and found nothing extra
4404
message('This branch is up to date.\n')
4405
elif theirs_only and not remote_extra:
4406
# We checked remote, and found nothing extra
4407
message('Other branch is up to date.\n')
4408
elif not (mine_only or theirs_only or local_extra or
4410
# We checked both branches, and neither one had extra
4412
message("Branches are up to date.\n")
4045
local_branch.lock_read()
4047
remote_branch.lock_read()
4049
local_extra, remote_extra = find_unmerged(
4050
local_branch, remote_branch, restrict,
4051
backward=not reverse,
4052
include_merges=include_merges,
4053
local_revid_range=local_revid_range,
4054
remote_revid_range=remote_revid_range)
4056
if log_format is None:
4057
registry = log.log_formatter_registry
4058
log_format = registry.get_default(local_branch)
4059
lf = log_format(to_file=self.outf,
4061
show_timezone='original')
4064
if local_extra and not theirs_only:
4065
message("You have %d extra revision(s):\n" %
4067
for revision in iter_log_revisions(local_extra,
4068
local_branch.repository,
4070
lf.log_revision(revision)
4071
printed_local = True
4074
printed_local = False
4076
if remote_extra and not mine_only:
4077
if printed_local is True:
4079
message("You are missing %d revision(s):\n" %
4081
for revision in iter_log_revisions(remote_extra,
4082
remote_branch.repository,
4084
lf.log_revision(revision)
4087
if mine_only and not local_extra:
4088
# We checked local, and found nothing extra
4089
message('This branch is up to date.\n')
4090
elif theirs_only and not remote_extra:
4091
# We checked remote, and found nothing extra
4092
message('Other branch is up to date.\n')
4093
elif not (mine_only or theirs_only or local_extra or
4095
# We checked both branches, and neither one had extra
4097
message("Branches are up to date.\n")
4099
remote_branch.unlock()
4101
local_branch.unlock()
4414
4102
if not status_code and parent is None and other_branch is not None:
4415
self.add_cleanup(local_branch.lock_write().unlock)
4416
# handle race conditions - a parent might be set while we run.
4417
if local_branch.get_parent() is None:
4418
local_branch.set_parent(remote_branch.base)
4103
local_branch.lock_write()
4105
# handle race conditions - a parent might be set while we run.
4106
if local_branch.get_parent() is None:
4107
local_branch.set_parent(remote_branch.base)
4109
local_branch.unlock()
4419
4110
return status_code
4422
4113
class cmd_pack(Command):
4423
__doc__ = """Compress the data within a repository.
4425
This operation compresses the data within a bazaar repository. As
4426
bazaar supports automatic packing of repository, this operation is
4427
normally not required to be done manually.
4429
During the pack operation, bazaar takes a backup of existing repository
4430
data, i.e. pack files. This backup is eventually removed by bazaar
4431
automatically when it is safe to do so. To save disk space by removing
4432
the backed up pack files, the --clean-obsolete-packs option may be
4435
Warning: If you use --clean-obsolete-packs and your machine crashes
4436
during or immediately after repacking, you may be left with a state
4437
where the deletion has been written to disk but the new packs have not
4438
been. In this case the repository may be unusable.
4114
"""Compress the data within a repository."""
4441
4116
_see_also = ['repositories']
4442
4117
takes_args = ['branch_or_repo?']
4444
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4447
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4119
def run(self, branch_or_repo='.'):
4448
4120
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4450
4122
branch = dir.open_branch()
4451
4123
repository = branch.repository
4452
4124
except errors.NotBranchError:
4453
4125
repository = dir.open_repository()
4454
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4457
4129
class cmd_plugins(Command):
4458
__doc__ = """List the installed plugins.
4130
"""List the installed plugins.
4460
4132
This command displays the list of installed plugins including
4461
4133
version of plugin and a short description of each.
4548
4223
Option('long', help='Show commit date in annotations.'),
4553
4227
encoding_type = 'exact'
4555
4229
@display_command
4556
4230
def run(self, filename, all=False, long=False, revision=None,
4557
show_ids=False, directory=None):
4558
4232
from bzrlib.annotate import annotate_file, annotate_file_tree
4559
4233
wt, branch, relpath = \
4560
_open_directory_or_containing_tree_or_branch(filename, directory)
4562
self.add_cleanup(wt.lock_read().unlock)
4564
self.add_cleanup(branch.lock_read().unlock)
4565
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4566
self.add_cleanup(tree.lock_read().unlock)
4568
file_id = wt.path2id(relpath)
4570
file_id = tree.path2id(relpath)
4572
raise errors.NotVersionedError(filename)
4573
file_version = tree.inventory[file_id].revision
4574
if wt is not None and revision is None:
4575
# If there is a tree and we're not annotating historical
4576
# versions, annotate the working tree's content.
4577
annotate_file_tree(wt, file_id, self.outf, long, all,
4580
annotate_file(branch, file_version, file_id, long, all, self.outf,
4234
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4240
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4242
file_id = wt.path2id(relpath)
4244
file_id = tree.path2id(relpath)
4246
raise errors.NotVersionedError(filename)
4247
file_version = tree.inventory[file_id].revision
4248
if wt is not None and revision is None:
4249
# If there is a tree and we're not annotating historical
4250
# versions, annotate the working tree's content.
4251
annotate_file_tree(wt, file_id, self.outf, long, all,
4254
annotate_file(branch, file_version, file_id, long, all, self.outf,
4584
4263
class cmd_re_sign(Command):
4585
__doc__ = """Create a digital signature for an existing revision."""
4264
"""Create a digital signature for an existing revision."""
4586
4265
# TODO be able to replace existing ones.
4588
4267
hidden = True # is this right ?
4589
4268
takes_args = ['revision_id*']
4590
takes_options = ['directory', 'revision']
4269
takes_options = ['revision']
4592
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4271
def run(self, revision_id_list=None, revision=None):
4593
4272
if revision_id_list is not None and revision is not None:
4594
4273
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4595
4274
if revision_id_list is None and revision is None:
4596
4275
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4597
b = WorkingTree.open_containing(directory)[0].branch
4598
self.add_cleanup(b.lock_write().unlock)
4599
return self._run(b, revision_id_list, revision)
4276
b = WorkingTree.open_containing(u'.')[0].branch
4279
return self._run(b, revision_id_list, revision)
4601
4283
def _run(self, b, revision_id_list, revision):
4602
4284
import bzrlib.gpg as gpg
4792
4477
end_revision=last_revno)
4795
self.outf.write('Dry-run, pretending to remove'
4796
' the above revisions.\n')
4480
print 'Dry-run, pretending to remove the above revisions.'
4482
val = raw_input('Press <enter> to continue')
4798
self.outf.write('The above revision(s) will be removed.\n')
4801
if not ui.ui_factory.get_boolean('Are you sure'):
4802
self.outf.write('Canceled')
4484
print 'The above revision(s) will be removed.'
4486
val = raw_input('Are you sure [y/N]? ')
4487
if val.lower() not in ('y', 'yes'):
4805
4491
mutter('Uncommitting from {%s} to {%s}',
4806
4492
last_rev_id, rev_id)
4807
4493
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4808
4494
revno=revno, local=local)
4809
self.outf.write('You can restore the old tip by running:\n'
4810
' bzr pull . -r revid:%s\n' % last_rev_id)
4495
note('You can restore the old tip by running:\n'
4496
' bzr pull . -r revid:%s', last_rev_id)
4813
4499
class cmd_break_lock(Command):
4814
__doc__ = """Break a dead lock.
4816
This command breaks a lock on a repository, branch, working directory or
4500
"""Break a dead lock on a repository, branch or working directory.
4819
4502
CAUTION: Locks should only be broken when you are sure that the process
4820
4503
holding the lock has been stopped.
4822
You can get information on what locks are open via the 'bzr info
4823
[location]' command.
4505
You can get information on what locks are open via the 'bzr info' command.
4827
bzr break-lock bzr+ssh://example.com/bzr/foo
4828
bzr break-lock --conf ~/.bazaar
4831
4510
takes_args = ['location?']
4834
help='LOCATION is the directory where the config lock is.'),
4837
def run(self, location=None, config=False):
4512
def run(self, location=None, show=False):
4838
4513
if location is None:
4839
4514
location = u'.'
4841
conf = _mod_config.LockableConfig(file_name=location)
4844
control, relpath = bzrdir.BzrDir.open_containing(location)
4846
control.break_lock()
4847
except NotImplementedError:
4515
control, relpath = bzrdir.BzrDir.open_containing(location)
4517
control.break_lock()
4518
except NotImplementedError:
4851
4522
class cmd_wait_until_signalled(Command):
4852
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4523
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4854
4525
This just prints a line to signal when it is ready, then blocks on stdin.
5113
4779
directly from the merge directive, without retrieving data from a
5116
`bzr send` creates a compact data set that, when applied using bzr
5117
merge, has the same effect as merging from the source branch.
5119
By default the merge directive is self-contained and can be applied to any
5120
branch containing submit_branch in its ancestory without needing access to
5123
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5124
revisions, but only a structured request to merge from the
5125
public_location. In that case the public_branch is needed and it must be
5126
up-to-date and accessible to the recipient. The public_branch is always
5127
included if known, so that people can check it later.
5129
The submit branch defaults to the parent of the source branch, but can be
5130
overridden. Both submit branch and public branch will be remembered in
5131
branch.conf the first time they are used for a particular branch. The
5132
source branch defaults to that containing the working directory, but can
5133
be changed using --from.
5135
In order to calculate those changes, bzr must analyse the submit branch.
5136
Therefore it is most efficient for the submit branch to be a local mirror.
5137
If a public location is known for the submit_branch, that location is used
5138
in the merge directive.
5140
The default behaviour is to send the merge directive by mail, unless -o is
5141
given, in which case it is sent to a file.
4782
If --no-bundle is specified, then public_branch is needed (and must be
4783
up-to-date), so that the receiver can perform the merge using the
4784
public_branch. The public_branch is always included if known, so that
4785
people can check it later.
4787
The submit branch defaults to the parent, but can be overridden. Both
4788
submit branch and public branch will be remembered if supplied.
4790
If a public_branch is known for the submit_branch, that public submit
4791
branch is used in the merge instructions. This means that a local mirror
4792
can be used as your actual submit branch, once you have set public_branch
5143
4795
Mail is sent using your preferred mail program. This should be transparent
5144
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
4796
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5145
4797
If the preferred client can't be found (or used), your editor will be used.
5147
4799
To use a specific mail program, set the mail_client configuration option.
5148
4800
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5149
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5150
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5151
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
4801
specific clients are "claws", "evolution", "kmail", "mutt", and
4802
"thunderbird"; generic options are "default", "editor", "emacsclient",
4803
"mapi", and "xdg-email". Plugins may also add supported clients.
5154
4805
If mail is being sent, a to address is required. This can be supplied
5155
4806
either on the commandline, by setting the submit_to configuration
5189
4836
short_name='f',
5191
4838
Option('output', short_name='o',
5192
help='Write merge directive to this file or directory; '
4839
help='Write merge directive to this file; '
5193
4840
'use - for stdout.',
5196
help='Refuse to send if there are uncommitted changes in'
5197
' the working tree, --no-strict disables the check.'),
5198
4842
Option('mail-to', help='Mail the request to this address.',
5202
4846
Option('body', help='Body for the email.', type=unicode),
5203
4847
RegistryOption('format',
5204
help='Use the specified output format.',
5205
lazy_registry=('bzrlib.send', 'format_registry')),
4848
help='Use the specified output format.',
4849
lazy_registry=('bzrlib.send', 'format_registry'))
5208
4852
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5209
4853
no_patch=False, revision=None, remember=False, output=None,
5210
format=None, mail_to=None, message=None, body=None,
5211
strict=None, **kwargs):
4854
format=None, mail_to=None, message=None, body=None, **kwargs):
5212
4855
from bzrlib.send import send
5213
4856
return send(submit_branch, revision, public_branch, remember,
5214
format, no_bundle, no_patch, output,
5215
kwargs.get('from', '.'), mail_to, message, body,
4857
format, no_bundle, no_patch, output,
4858
kwargs.get('from', '.'), mail_to, message, body,
5220
4862
class cmd_bundle_revisions(cmd_send):
5221
__doc__ = """Create a merge-directive for submitting changes.
4863
"""Create a merge-directive for submitting changes.
5223
4865
A merge directive provides many things needed for requesting merges:
5306
4945
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5307
4946
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5309
If no tag name is specified it will be determined through the
5310
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5311
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5315
4949
_see_also = ['commit', 'tags']
5316
takes_args = ['tag_name?']
4950
takes_args = ['tag_name']
5317
4951
takes_options = [
5318
4952
Option('delete',
5319
4953
help='Delete this tag rather than placing it.',
5321
custom_help('directory',
5322
help='Branch in which to place the tag.'),
4956
help='Branch in which to place the tag.',
5323
4960
Option('force',
5324
4961
help='Replace existing tags.',
5329
def run(self, tag_name=None,
4966
def run(self, tag_name,
5335
4972
branch, relpath = Branch.open_containing(directory)
5336
self.add_cleanup(branch.lock_write().unlock)
5338
if tag_name is None:
5339
raise errors.BzrCommandError("No tag specified to delete.")
5340
branch.tags.delete_tag(tag_name)
5341
self.outf.write('Deleted tag %s.\n' % tag_name)
5344
if len(revision) != 1:
5345
raise errors.BzrCommandError(
5346
"Tags can only be placed on a single revision, "
5348
revision_id = revision[0].as_revision_id(branch)
4976
branch.tags.delete_tag(tag_name)
4977
self.outf.write('Deleted tag %s.\n' % tag_name)
5350
revision_id = branch.last_revision()
5351
if tag_name is None:
5352
tag_name = branch.automatic_tag_name(revision_id)
5353
if tag_name is None:
5354
raise errors.BzrCommandError(
5355
"Please specify a tag name.")
5356
if (not force) and branch.tags.has_tag(tag_name):
5357
raise errors.TagAlreadyExists(tag_name)
5358
branch.tags.set_tag(tag_name, revision_id)
5359
self.outf.write('Created tag %s.\n' % tag_name)
4980
if len(revision) != 1:
4981
raise errors.BzrCommandError(
4982
"Tags can only be placed on a single revision, "
4984
revision_id = revision[0].as_revision_id(branch)
4986
revision_id = branch.last_revision()
4987
if (not force) and branch.tags.has_tag(tag_name):
4988
raise errors.TagAlreadyExists(tag_name)
4989
branch.tags.set_tag(tag_name, revision_id)
4990
self.outf.write('Created tag %s.\n' % tag_name)
5362
4995
class cmd_tags(Command):
5363
__doc__ = """List tags.
5365
4998
This command shows a table of tag names and the revisions they reference.
5368
5001
_see_also = ['tag']
5369
5002
takes_options = [
5370
custom_help('directory',
5371
help='Branch whose tags should be displayed.'),
5004
help='Branch whose tags should be displayed.',
5372
5008
RegistryOption.from_kwargs('sort',
5373
5009
'Sort tags by different criteria.', title='Sorting',
5374
5010
alpha='Sort tags lexicographically (default).',
5467
5105
Option('bind-to', help='Branch to bind checkout to.', type=str),
5468
5106
Option('force',
5469
help='Perform reconfiguration even if local changes'
5471
Option('stacked-on',
5472
help='Reconfigure a branch to be stacked on another branch.',
5476
help='Reconfigure a branch to be unstacked. This '
5477
'may require copying substantial data into it.',
5107
help='Perform reconfiguration even if local changes'
5481
def run(self, location=None, target_type=None, bind_to=None, force=False,
5111
def run(self, location=None, target_type=None, bind_to=None, force=False):
5484
5112
directory = bzrdir.BzrDir.open(location)
5485
if stacked_on and unstacked:
5486
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5487
elif stacked_on is not None:
5488
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5490
reconfigure.ReconfigureUnstacked().apply(directory)
5491
# At the moment you can use --stacked-on and a different
5492
# reconfiguration shape at the same time; there seems no good reason
5494
5113
if target_type is None:
5495
if stacked_on or unstacked:
5498
raise errors.BzrCommandError('No target configuration '
5114
raise errors.BzrCommandError('No target configuration specified')
5500
5115
elif target_type == 'branch':
5501
5116
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5502
5117
elif target_type == 'tree':
5539
5154
/path/to/newbranch.
5541
5156
Bound branches use the nickname of its master branch unless it is set
5542
locally, in which case switching will update the local nickname to be
5157
locally, in which case switching will update the the local nickname to be
5543
5158
that of the master.
5546
takes_args = ['to_location?']
5547
takes_options = ['directory',
5549
help='Switch even if local commits will be lost.'),
5551
Option('create-branch', short_name='b',
5552
help='Create the target branch from this one before'
5553
' switching to it.'),
5161
takes_args = ['to_location']
5162
takes_options = [Option('force',
5163
help='Switch even if local commits will be lost.')
5556
def run(self, to_location=None, force=False, create_branch=False,
5557
revision=None, directory=u'.'):
5166
def run(self, to_location, force=False):
5558
5167
from bzrlib import switch
5559
tree_location = directory
5560
revision = _get_one_revision('switch', revision)
5561
5169
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5562
if to_location is None:
5563
if revision is None:
5564
raise errors.BzrCommandError('You must supply either a'
5565
' revision or a location')
5566
to_location = tree_location
5568
5171
branch = control_dir.open_branch()
5569
5172
had_explicit_nick = branch.get_config().has_explicit_nickname()
5570
5173
except errors.NotBranchError:
5572
5174
had_explicit_nick = False
5575
raise errors.BzrCommandError('cannot create branch without'
5577
to_location = directory_service.directories.dereference(
5579
if '/' not in to_location and '\\' not in to_location:
5580
# This path is meant to be relative to the existing branch
5581
this_url = self._get_branch_location(control_dir)
5582
to_location = urlutils.join(this_url, '..', to_location)
5583
to_branch = branch.bzrdir.sprout(to_location,
5584
possible_transports=[branch.bzrdir.root_transport],
5585
source_branch=branch).open_branch()
5588
to_branch = Branch.open(to_location)
5589
except errors.NotBranchError:
5590
this_url = self._get_branch_location(control_dir)
5591
to_branch = Branch.open(
5592
urlutils.join(this_url, '..', to_location))
5593
if revision is not None:
5594
revision = revision.as_revision_id(to_branch)
5595
switch.switch(control_dir, to_branch, force, revision_id=revision)
5176
to_branch = Branch.open(to_location)
5177
except errors.NotBranchError:
5178
this_url = self._get_branch_location(control_dir)
5179
to_branch = Branch.open(
5180
urlutils.join(this_url, '..', to_location))
5181
switch.switch(control_dir, to_branch, force)
5596
5182
if had_explicit_nick:
5597
5183
branch = control_dir.open_branch() #get the new branch!
5598
5184
branch.nick = to_branch.nick
5860
5419
_see_also = ['unshelve']
5862
5421
def run(self, revision=None, all=False, file_list=None, message=None,
5863
writer=None, list=False, destroy=False, directory=u'.'):
5422
writer=None, list=False, destroy=False):
5865
5424
return self.run_for_list()
5866
5425
from bzrlib.shelf_ui import Shelver
5867
5426
if writer is None:
5868
5427
writer = bzrlib.option.diff_writer_registry.get()
5870
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5871
file_list, message, destroy=destroy, directory=directory)
5429
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5430
message, destroy=destroy).run()
5876
5431
except errors.UserAbort:
5879
5434
def run_for_list(self):
5880
5435
tree = WorkingTree.open_containing('.')[0]
5881
self.add_cleanup(tree.lock_read().unlock)
5882
manager = tree.get_shelf_manager()
5883
shelves = manager.active_shelves()
5884
if len(shelves) == 0:
5885
note('No shelved changes.')
5887
for shelf_id in reversed(shelves):
5888
message = manager.get_metadata(shelf_id).get('message')
5890
message = '<no message>'
5891
self.outf.write('%3d: %s\n' % (shelf_id, message))
5438
manager = tree.get_shelf_manager()
5439
shelves = manager.active_shelves()
5440
if len(shelves) == 0:
5441
note('No shelved changes.')
5443
for shelf_id in reversed(shelves):
5444
message = manager.get_metadata(shelf_id).get('message')
5446
message = '<no message>'
5447
self.outf.write('%3d: %s\n' % (shelf_id, message))
5895
5453
class cmd_unshelve(Command):
5896
__doc__ = """Restore shelved changes.
5454
"""Restore shelved changes.
5898
5456
By default, the most recently shelved changes are restored. However if you
5899
5457
specify a shelf by id those changes will be restored instead. This works
5903
5461
takes_args = ['shelf_id?']
5904
5462
takes_options = [
5906
5463
RegistryOption.from_kwargs(
5907
5464
'action', help="The action to perform.",
5908
5465
enum_switch=False, value_switches=True,
5909
5466
apply="Apply changes and remove from the shelf.",
5910
5467
dry_run="Show changes, but do not apply or remove them.",
5911
preview="Instead of unshelving the changes, show the diff that "
5912
"would result from unshelving.",
5913
delete_only="Delete changes without applying them.",
5914
keep="Apply changes but don't delete them.",
5468
delete_only="Delete changes without applying them."
5917
5471
_see_also = ['shelve']
5919
def run(self, shelf_id=None, action='apply', directory=u'.'):
5473
def run(self, shelf_id=None, action='apply'):
5920
5474
from bzrlib.shelf_ui import Unshelver
5921
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5925
unshelver.tree.unlock()
5475
Unshelver.from_args(shelf_id, action).run()
5928
5478
class cmd_clean_tree(Command):
5929
__doc__ = """Remove unwanted files from working tree.
5479
"""Remove unwanted files from working tree.
5931
5481
By default, only unknown files, not ignored files, are deleted. Versioned
5932
5482
files are never deleted.
6007
5556
self.outf.write('%s %s\n' % (path, location))
6010
def _register_lazy_builtins():
6011
# register lazy builtins from other modules; called at startup and should
6012
# be only called once.
6013
for (name, aliases, module_name) in [
6014
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6015
('cmd_dpush', [], 'bzrlib.foreign'),
6016
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6017
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6018
('cmd_conflicts', [], 'bzrlib.conflicts'),
6019
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6021
builtin_command_registry.register_lazy(name, aliases, module_name)
5559
# these get imported and then picked up by the scan for cmd_*
5560
# TODO: Some more consistent way to split command definitions across files;
5561
# we do need to load at least some information about them to know of
5562
# aliases. ideally we would avoid loading the implementation until the
5563
# details were needed.
5564
from bzrlib.cmd_version_info import cmd_version_info
5565
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5566
from bzrlib.bundle.commands import (
5569
from bzrlib.foreign import cmd_dpush
5570
from bzrlib.sign_my_commits import cmd_sign_my_commits
5571
from bzrlib.weave_commands import cmd_versionedfile_list, \
5572
cmd_weave_plan_merge, cmd_weave_merge_text