74
75
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
77
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
78
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
80
return internal_tree_files(file_list, default_branch, canonicalize,
81
return internal_tree_files(file_list, default_branch, canonicalize,
83
except errors.FileInWrongBranch, e:
84
raise errors.BzrCommandError("%s is not in the same branch as %s" %
85
(e.path, file_list[0]))
84
88
def tree_files_for_add(file_list):
149
153
# XXX: Bad function name; should possibly also be a class method of
150
154
# WorkingTree rather than a function.
151
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
152
155
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
153
156
apply_view=True):
154
157
"""Convert command-line paths to a WorkingTree and relative paths.
156
Deprecated: use WorkingTree.open_containing_paths instead.
158
159
This is typically used for command-line processors that take one or
159
160
more filenames, and infer the workingtree that contains them.
171
172
:return: workingtree, [relative_paths]
173
return WorkingTree.open_containing_paths(
174
file_list, default_directory='.',
174
if file_list is None or len(file_list) == 0:
175
tree = WorkingTree.open_containing(default_branch)[0]
176
if tree.supports_views() and apply_view:
177
view_files = tree.views.lookup_view()
179
file_list = view_files
180
view_str = views.view_display_str(view_files)
181
note("Ignoring files outside view. View is %s" % view_str)
182
return tree, file_list
183
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
184
return tree, safe_relpath_files(tree, file_list, canonicalize,
185
apply_view=apply_view)
188
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
189
"""Convert file_list into a list of relpaths in tree.
191
:param tree: A tree to operate on.
192
:param file_list: A list of user provided paths or None.
193
:param apply_view: if True and a view is set, apply it or check that
194
specified files are within it
195
:return: A list of relative paths.
196
:raises errors.PathNotChild: When a provided path is in a different tree
199
if file_list is None:
201
if tree.supports_views() and apply_view:
202
view_files = tree.views.lookup_view()
206
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
207
# doesn't - fix that up here before we enter the loop.
209
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
212
for filename in file_list:
214
relpath = fixer(osutils.dereference_path(filename))
215
if view_files and not osutils.is_inside_any(view_files, relpath):
216
raise errors.FileOutsideView(filename, view_files)
217
new_list.append(relpath)
218
except errors.PathNotChild:
219
raise errors.FileInWrongBranch(tree.branch, filename)
179
223
def _get_view_info_for_change_reporter(tree):
191
def _open_directory_or_containing_tree_or_branch(filename, directory):
192
"""Open the tree or branch containing the specified file, unless
193
the --directory option is used to specify a different branch."""
194
if directory is not None:
195
return (None, Branch.open(directory), filename)
196
return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
199
235
# TODO: Make sure no commands unconditionally use the working directory as a
200
236
# branch. If a filename argument is used, the first of them should be used to
201
237
# specify the branch. (Perhaps this can be factored out into some kind of
279
315
raise errors.BzrCommandError('bzr status --revision takes exactly'
280
316
' one or two revision specifiers')
282
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
318
tree, relfile_list = tree_files(file_list)
283
319
# Avoid asking for specific files when that is not needed.
284
320
if relfile_list == ['']:
285
321
relfile_list = None
317
353
self.outf.write(revtext.decode('utf-8'))
320
def run(self, revision_id=None, revision=None, directory=u'.'):
356
def run(self, revision_id=None, revision=None):
321
357
if revision_id is not None and revision is not None:
322
358
raise errors.BzrCommandError('You can only supply one of'
323
359
' revision_id or --revision')
324
360
if revision_id is None and revision is None:
325
361
raise errors.BzrCommandError('You must supply either'
326
362
' --revision or a revision_id')
327
b = WorkingTree.open_containing(directory)[0].branch
363
b = WorkingTree.open_containing(u'.')[0].branch
329
365
revisions = b.repository.revisions
330
366
if revisions is None:
356
392
class cmd_dump_btree(Command):
357
__doc__ = """Dump the contents of a btree index file to stdout.
393
"""Dump the contents of a btree index file to stdout.
359
395
PATH is a btree index file, it can be any URL. This includes things like
360
396
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
468
504
if (working.has_changes()):
469
505
raise errors.UncommittedChanges(working)
470
if working.get_shelf_manager().last_shelf() is not None:
471
raise errors.ShelvedChanges(working)
473
507
if working.user_url != working.branch.user_url:
474
508
raise errors.BzrCommandError("You cannot remove the working tree"
496
530
wt = WorkingTree.open_containing(location)[0]
497
self.add_cleanup(wt.lock_read().unlock)
498
532
except (errors.NoWorkingTree, errors.NotLocalUrl):
499
533
raise errors.NoWorkingTree(location)
534
self.add_cleanup(wt.unlock)
500
535
revid = wt.last_revision()
502
537
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
505
540
revno = ".".join(str(n) for n in revno_t)
507
542
b = Branch.open_containing(location)[0]
508
self.add_cleanup(b.lock_read().unlock)
544
self.add_cleanup(b.unlock)
509
545
revno = b.revno()
510
546
self.cleanup_now()
511
547
self.outf.write(str(revno) + '\n')
514
550
class cmd_revision_info(Command):
515
__doc__ = """Show revision number and revision id for a given revision identifier.
551
"""Show revision number and revision id for a given revision identifier.
518
554
takes_args = ['revision_info*']
519
555
takes_options = [
521
custom_help('directory',
522
558
help='Branch to examine, '
523
'rather than the one containing the working directory.'),
559
'rather than the one containing the working directory.',
524
563
Option('tree', help='Show revno of working tree'),
532
571
wt = WorkingTree.open_containing(directory)[0]
534
self.add_cleanup(wt.lock_read().unlock)
574
self.add_cleanup(wt.unlock)
535
575
except (errors.NoWorkingTree, errors.NotLocalUrl):
537
577
b = Branch.open_containing(directory)[0]
538
self.add_cleanup(b.lock_read().unlock)
579
self.add_cleanup(b.unlock)
539
580
revision_ids = []
540
581
if revision is not None:
541
582
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
640
681
should_print=(not is_quiet()))
643
self.add_cleanup(base_tree.lock_read().unlock)
684
base_tree.lock_read()
685
self.add_cleanup(base_tree.unlock)
644
686
tree, file_list = tree_files_for_add(file_list)
645
687
added, ignored = tree.smart_add(file_list, not
646
688
no_recurse, action=action, save=not dry_run)
717
759
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
719
761
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)
762
work_tree, file_list = tree_files(file_list)
763
work_tree.lock_read()
764
self.add_cleanup(work_tree.unlock)
722
765
if revision is not None:
723
766
tree = revision.as_tree(work_tree.branch)
725
768
extra_trees = [work_tree]
726
self.add_cleanup(tree.lock_read().unlock)
770
self.add_cleanup(tree.unlock)
789
833
if len(names_list) < 2:
790
834
raise errors.BzrCommandError("missing file argument")
791
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
792
self.add_cleanup(tree.lock_tree_write().unlock)
835
tree, rel_names = tree_files(names_list, canonicalize=False)
836
tree.lock_tree_write()
837
self.add_cleanup(tree.unlock)
793
838
self._run(tree, names_list, rel_names, after)
795
840
def run_auto(self, names_list, after, dry_run):
800
845
raise errors.BzrCommandError('--after cannot be specified with'
802
work_tree, file_list = WorkingTree.open_containing_paths(
803
names_list, default_directory='.')
804
self.add_cleanup(work_tree.lock_tree_write().unlock)
847
work_tree, file_list = tree_files(names_list, default_branch='.')
848
work_tree.lock_tree_write()
849
self.add_cleanup(work_tree.unlock)
805
850
rename_map.RenameMap.guess_renames(work_tree, dry_run)
807
852
def _run(self, tree, names_list, rel_names, after):
915
960
takes_options = ['remember', 'overwrite', 'revision',
916
961
custom_help('verbose',
917
962
help='Show logs of pulled revisions.'),
918
custom_help('directory',
919
964
help='Branch to pull into, '
920
'rather than the one containing the working directory.'),
965
'rather than the one containing the working directory.',
922
970
help="Perform a local pull in a bound "
923
971
"branch. Local pulls are not applied to "
939
987
tree_to = WorkingTree.open_containing(directory)[0]
940
988
branch_to = tree_to.branch
941
self.add_cleanup(tree_to.lock_write().unlock)
990
self.add_cleanup(tree_to.unlock)
942
991
except errors.NoWorkingTree:
944
993
branch_to = Branch.open_containing(directory)[0]
945
self.add_cleanup(branch_to.lock_write().unlock)
994
branch_to.lock_write()
995
self.add_cleanup(branch_to.unlock)
947
997
if local and not branch_to.get_bound_location():
948
998
raise errors.LocalRequiresBoundBranch()
980
1030
branch_from = Branch.open(location,
981
1031
possible_transports=possible_transports)
982
self.add_cleanup(branch_from.lock_read().unlock)
1032
branch_from.lock_read()
1033
self.add_cleanup(branch_from.unlock)
984
1035
if branch_to.get_parent() is None or remember:
985
1036
branch_to.set_parent(branch_from.base)
1037
1088
Option('create-prefix',
1038
1089
help='Create the path leading up to the branch '
1039
1090
'if it does not already exist.'),
1040
custom_help('directory',
1041
1092
help='Branch to push from, '
1042
'rather than the one containing the working directory.'),
1093
'rather than the one containing the working directory.',
1043
1097
Option('use-existing-dir',
1044
1098
help='By default push will fail if the target'
1045
1099
' directory exists, but does not already'
1079
1133
revision_id = None
1080
1134
if tree is not None and revision_id is None:
1081
tree.check_changed_or_out_of_date(
1082
strict, 'push_strict',
1083
more_error='Use --no-strict to force the push.',
1084
more_warning='Uncommitted changes will not be pushed.')
1135
tree.warn_if_changed_or_out_of_date(
1136
strict, 'push_strict', 'Use --no-strict to force the push.')
1085
1137
# Get the stacked_on branch, if any
1086
1138
if stacked_on is not None:
1087
1139
stacked_on = urlutils.normalize_url(stacked_on)
1121
1173
class cmd_branch(Command):
1122
__doc__ = """Create a new branch that is a copy of an existing branch.
1174
"""Create a new branch that is a copy of an existing branch.
1124
1176
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1125
1177
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1135
1187
_see_also = ['checkout']
1136
1188
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."),
1189
takes_options = ['revision', Option('hardlink',
1190
help='Hard-link working tree files where possible.'),
1141
1191
Option('no-tree',
1142
1192
help="Create a branch without a working-tree."),
1143
1193
Option('switch',
1162
1212
def run(self, from_location, to_location=None, revision=None,
1163
1213
hardlink=False, stacked=False, standalone=False, no_tree=False,
1164
use_existing_dir=False, switch=False, bind=False,
1214
use_existing_dir=False, switch=False, bind=False):
1166
1215
from bzrlib import switch as _mod_switch
1167
1216
from bzrlib.tag import _merge_tags_if_possible
1168
1217
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
1219
revision = _get_one_revision('branch', revision)
1178
self.add_cleanup(br_from.lock_read().unlock)
1221
self.add_cleanup(br_from.unlock)
1179
1222
if revision is not None:
1180
1223
revision_id = revision.as_revision_id(br_from)
1286
1329
to_location = branch_location
1287
1330
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1288
1331
branch_location)
1289
if not (hardlink or files_from):
1290
# accelerator_tree is usually slower because you have to read N
1291
# files (no readahead, lots of seeks, etc), but allow the user to
1292
# explicitly request it
1293
accelerator_tree = None
1294
1332
revision = _get_one_revision('checkout', revision)
1295
if files_from is not None and files_from != branch_location:
1333
if files_from is not None:
1296
1334
accelerator_tree = WorkingTree.open(files_from)
1297
1335
if revision is not None:
1298
1336
revision_id = revision.as_revision_id(source)
1326
1364
@display_command
1327
1365
def run(self, dir=u'.'):
1328
1366
tree = WorkingTree.open_containing(dir)[0]
1329
self.add_cleanup(tree.lock_read().unlock)
1368
self.add_cleanup(tree.unlock)
1330
1369
new_inv = tree.inventory
1331
1370
old_tree = tree.basis_tree()
1332
self.add_cleanup(old_tree.lock_read().unlock)
1371
old_tree.lock_read()
1372
self.add_cleanup(old_tree.unlock)
1333
1373
old_inv = old_tree.inventory
1335
1375
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1347
1387
class cmd_update(Command):
1348
__doc__ = """Update a tree to have the latest code committed to its branch.
1388
"""Update a tree to have the latest code committed to its branch.
1350
1390
This will perform a merge into the working tree, and may generate
1351
1391
conflicts. If you have any local changes, you will still
1373
1413
master = branch.get_master_branch(
1374
1414
possible_transports=possible_transports)
1375
1415
if master is not None:
1376
1417
branch_location = master.base
1419
tree.lock_tree_write()
1379
1420
branch_location = tree.branch.base
1380
tree.lock_tree_write()
1381
1421
self.add_cleanup(tree.unlock)
1382
1422
# get rid of the final '/' and be ready for display
1383
1423
branch_location = urlutils.unescape_for_display(
1477
1517
class cmd_remove(Command):
1478
__doc__ = """Remove files or directories.
1518
"""Remove files or directories.
1480
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1481
delete them if they can easily be recovered using revert otherwise they
1482
will be backed up (adding an extention of the form .~#~). If no options or
1483
parameters are given Bazaar will scan for files that are being tracked by
1484
Bazaar but missing in your tree and stop tracking them for you.
1520
This makes bzr stop tracking changes to the specified files. bzr will delete
1521
them if they can easily be recovered using revert. If no options or
1522
parameters are given bzr will scan for files that are being tracked by bzr
1523
but missing in your tree and stop tracking them for you.
1486
1525
takes_args = ['file*']
1487
1526
takes_options = ['verbose',
1489
1528
RegistryOption.from_kwargs('file-deletion-strategy',
1490
1529
'The file deletion mode to be used.',
1491
1530
title='Deletion Strategy', value_switches=True, enum_switch=False,
1492
safe='Backup changed files (default).',
1531
safe='Only delete files if they can be'
1532
' safely recovered (default).',
1493
1533
keep='Delete from bzr but leave the working copy.',
1494
1534
force='Delete all the specified files, even if they can not be '
1495
1535
'recovered and even if they are non-empty directories.')]
1499
1539
def run(self, file_list, verbose=False, new=False,
1500
1540
file_deletion_strategy='safe'):
1501
tree, file_list = WorkingTree.open_containing_paths(file_list)
1541
tree, file_list = tree_files(file_list)
1503
1543
if file_list is not None:
1504
1544
file_list = [f for f in file_list]
1506
self.add_cleanup(tree.lock_write().unlock)
1547
self.add_cleanup(tree.unlock)
1507
1548
# Heuristics should probably all move into tree.remove_smart or
1593
1634
_see_also = ['check']
1594
1635
takes_args = ['branch?']
1596
Option('canonicalize-chks',
1597
help='Make sure CHKs are in canonical form (repairs '
1602
def run(self, branch=".", canonicalize_chks=False):
1637
def run(self, branch="."):
1603
1638
from bzrlib.reconcile import reconcile
1604
1639
dir = bzrdir.BzrDir.open(branch)
1605
reconcile(dir, canonicalize_chks=canonicalize_chks)
1608
1643
class cmd_revision_history(Command):
1609
__doc__ = """Display the list of revision ids on a branch."""
1644
"""Display the list of revision ids on a branch."""
1611
1646
_see_also = ['log']
1612
1647
takes_args = ['location?']
1818
1853
class cmd_diff(Command):
1819
__doc__ = """Show differences in the working tree, between revisions or branches.
1854
"""Show differences in the working tree, between revisions or branches.
1821
1856
If no arguments are given, all changes for the current tree are listed.
1822
1857
If files are given, only the changes in those files are listed.
1952
1983
old_branch, new_branch,
1953
1984
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1954
1985
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()
1957
1986
return show_diff_trees(old_tree, new_tree, sys.stdout,
1958
1987
specific_files=specific_files,
1959
1988
external_diff_options=diff_options,
1960
1989
old_label=old_label, new_label=new_label,
1961
extra_trees=extra_trees,
1962
path_encoding=path_encoding,
1990
extra_trees=extra_trees, using=using,
1964
1991
format_cls=format)
1967
1994
class cmd_deleted(Command):
1968
__doc__ = """List files deleted in the working tree.
1995
"""List files deleted in the working tree.
1970
1997
# TODO: Show files deleted since a previous revision, or
1971
1998
# between two revisions.
1974
2001
# level of effort but possibly much less IO. (Or possibly not,
1975
2002
# if the directories are very large...)
1976
2003
_see_also = ['status', 'ls']
1977
takes_options = ['directory', 'show-ids']
2004
takes_options = ['show-ids']
1979
2006
@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)
2007
def run(self, show_ids=False):
2008
tree = WorkingTree.open_containing(u'.')[0]
2010
self.add_cleanup(tree.unlock)
1983
2011
old = tree.basis_tree()
1984
self.add_cleanup(old.lock_read().unlock)
2013
self.add_cleanup(old.unlock)
1985
2014
for path, ie in old.inventory.iter_entries():
1986
2015
if not tree.has_id(ie.file_id):
1987
2016
self.outf.write(path)
1994
2023
class cmd_modified(Command):
1995
__doc__ = """List files modified in working tree.
2024
"""List files modified in working tree.
1999
2028
_see_also = ['status', 'ls']
2000
takes_options = ['directory', 'null']
2031
help='Write an ascii NUL (\\0) separator '
2032
'between files rather than a newline.')
2002
2035
@display_command
2003
def run(self, null=False, directory=u'.'):
2004
tree = WorkingTree.open_containing(directory)[0]
2036
def run(self, null=False):
2037
tree = WorkingTree.open_containing(u'.')[0]
2005
2038
td = tree.changes_from(tree.basis_tree())
2006
2039
for path, id, kind, text_modified, meta_modified in td.modified:
2013
2046
class cmd_added(Command):
2014
__doc__ = """List files added in working tree.
2047
"""List files added in working tree.
2018
2051
_see_also = ['status', 'ls']
2019
takes_options = ['directory', 'null']
2054
help='Write an ascii NUL (\\0) separator '
2055
'between files rather than a newline.')
2021
2058
@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)
2059
def run(self, null=False):
2060
wt = WorkingTree.open_containing(u'.')[0]
2062
self.add_cleanup(wt.unlock)
2025
2063
basis = wt.basis_tree()
2026
self.add_cleanup(basis.lock_read().unlock)
2065
self.add_cleanup(basis.unlock)
2027
2066
basis_inv = basis.inventory
2028
2067
inv = wt.inventory
2029
2068
for file_id in inv:
2032
2071
if inv.is_root(file_id) and len(basis_inv) == 0:
2034
2073
path = inv.id2path(file_id)
2035
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2074
if not os.access(osutils.abspath(path), os.F_OK):
2038
2077
self.outf.write(path + '\0')
2238
2277
help='Show just the specified revision.'
2239
2278
' See also "help revisionspec".'),
2241
RegistryOption('authors',
2242
'What names to list as authors - first, all or committer.',
2244
lazy_registry=('bzrlib.log', 'author_list_registry'),
2246
2280
Option('levels',
2247
2281
short_name='n',
2248
2282
help='Number of levels to display - 0 for all, 1 for flat.',
2263
2297
help='Show changes made in each revision as a patch.'),
2264
2298
Option('include-merges',
2265
2299
help='Show merged revisions like --levels 0 does.'),
2266
Option('exclude-common-ancestry',
2267
help='Display only the revisions that are not part'
2268
' of both ancestries (require -rX..Y)'
2271
2301
encoding_type = 'replace'
2284
2314
show_diff=False,
2285
include_merges=False,
2287
exclude_common_ancestry=False,
2315
include_merges=False):
2289
2316
from bzrlib.log import (
2291
2318
make_log_request_dict,
2292
2319
_get_info_for_log_files,
2294
2321
direction = (forward and 'forward') or 'reverse'
2295
if (exclude_common_ancestry
2296
and (revision is None or len(revision) != 2)):
2297
raise errors.BzrCommandError(
2298
'--exclude-common-ancestry requires -r with two revisions')
2299
2322
if include_merges:
2300
2323
if levels is None:
2318
2341
# find the file ids to log and check for directory filtering
2319
2342
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2320
revision, file_list, self.add_cleanup)
2343
revision, file_list)
2344
self.add_cleanup(b.unlock)
2321
2345
for relpath, file_id, kind in file_info_list:
2322
2346
if file_id is None:
2323
2347
raise errors.BzrCommandError(
2342
2366
dir, relpath = bzrdir.BzrDir.open_containing(location)
2343
2367
b = dir.open_branch()
2344
self.add_cleanup(b.lock_read().unlock)
2369
self.add_cleanup(b.unlock)
2345
2370
rev1, rev2 = _get_revision_range(revision, b, self.name())
2347
2372
# Decide on the type of delta & diff filtering to use
2367
2392
show_timezone=timezone,
2368
2393
delta_format=get_verbosity_level(),
2370
show_advice=levels is None,
2371
author_list_handler=authors)
2395
show_advice=levels is None)
2373
2397
# Choose the algorithm for doing the logging. It's annoying
2374
2398
# having multiple code paths like this but necessary until
2393
2417
direction=direction, specific_fileids=file_ids,
2394
2418
start_revision=rev1, end_revision=rev2, limit=limit,
2395
2419
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,
2420
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2399
2421
Logger(b, rqst).show(lf)
2472
2494
tree, relpath = WorkingTree.open_containing(filename)
2473
2495
file_id = tree.path2id(relpath)
2474
2496
b = tree.branch
2475
self.add_cleanup(b.lock_read().unlock)
2498
self.add_cleanup(b.unlock)
2476
2499
touching_revs = log.find_touching_revisions(b, file_id)
2477
2500
for revno, revision_id, what in touching_revs:
2478
2501
self.outf.write("%6d %s\n" % (revno, what))
2481
2504
class cmd_ls(Command):
2482
__doc__ = """List files in a tree.
2505
"""List files in a tree.
2485
2508
_see_also = ['status', 'cat']
2491
2514
help='Recurse into subdirectories.'),
2492
2515
Option('from-root',
2493
2516
help='Print paths relative to the root of the branch.'),
2494
Option('unknown', short_name='u',
2495
help='Print unknown files.'),
2517
Option('unknown', help='Print unknown files.'),
2496
2518
Option('versioned', help='Print versioned files.',
2497
2519
short_name='V'),
2498
Option('ignored', short_name='i',
2499
help='Print ignored files.'),
2500
Option('kind', short_name='k',
2520
Option('ignored', help='Print ignored files.'),
2522
help='Write an ascii NUL (\\0) separator '
2523
'between files rather than a newline.'),
2501
2525
help='List entries of a particular kind: file, directory, symlink.',
2507
2529
@display_command
2508
2530
def run(self, revision=None, verbose=False,
2509
2531
recursive=False, from_root=False,
2510
2532
unknown=False, versioned=False, ignored=False,
2511
null=False, kind=None, show_ids=False, path=None, directory=None):
2533
null=False, kind=None, show_ids=False, path=None):
2513
2535
if kind and kind not in ('file', 'directory', 'symlink'):
2514
2536
raise errors.BzrCommandError('invalid kind specified')
2526
2548
raise errors.BzrCommandError('cannot specify both --from-root'
2529
tree, branch, relpath = \
2530
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2551
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2532
2554
# Calculate the prefix to use
2548
2570
view_str = views.view_display_str(view_files)
2549
2571
note("Ignoring files outside view. View is %s" % view_str)
2551
self.add_cleanup(tree.lock_read().unlock)
2574
self.add_cleanup(tree.unlock)
2552
2575
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2553
2576
from_dir=relpath, recursive=recursive):
2554
2577
# Apply additional masking
2598
2621
class cmd_unknowns(Command):
2599
__doc__ = """List unknown files.
2622
"""List unknown files.
2603
2626
_see_also = ['ls']
2604
takes_options = ['directory']
2606
2628
@display_command
2607
def run(self, directory=u'.'):
2608
for f in WorkingTree.open_containing(directory)[0].unknowns():
2630
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2609
2631
self.outf.write(osutils.quotefn(f) + '\n')
2612
2634
class cmd_ignore(Command):
2613
__doc__ = """Ignore specified files or patterns.
2635
"""Ignore specified files or patterns.
2615
2637
See ``bzr help patterns`` for details on the syntax of patterns.
2625
2647
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
2650
Patterns prefixed with '!' are exceptions to ignore patterns and take
2635
2651
precedence over regular ignores. Such exceptions are used to specify
2636
2652
files that should be versioned which would otherwise be ignored.
2677
2693
_see_also = ['status', 'ignored', 'patterns']
2678
2694
takes_args = ['name_pattern*']
2679
takes_options = ['directory',
2680
Option('default-rules',
2681
help='Display the default ignore rules that bzr uses.')
2696
Option('old-default-rules',
2697
help='Write out the ignore rules bzr < 0.9 always used.')
2684
def run(self, name_pattern_list=None, default_rules=None,
2700
def run(self, name_pattern_list=None, old_default_rules=None):
2686
2701
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:
2702
if old_default_rules is not None:
2703
# dump the rules and exit
2704
for pattern in ignores.OLD_DEFAULTS:
2690
2705
self.outf.write("%s\n" % pattern)
2692
2707
if not name_pattern_list:
2693
2708
raise errors.BzrCommandError("ignore requires at least one "
2694
"NAME_PATTERN or --default-rules.")
2709
"NAME_PATTERN or --old-default-rules")
2695
2710
name_pattern_list = [globbing.normalize_pattern(p)
2696
2711
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
2712
for name_pattern in name_pattern_list:
2706
2713
if (name_pattern[0] == '/' or
2707
2714
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2708
2715
raise errors.BzrCommandError(
2709
2716
"NAME_PATTERN should not be an absolute path")
2710
tree, relpath = WorkingTree.open_containing(directory)
2717
tree, relpath = WorkingTree.open_containing(u'.')
2711
2718
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2712
2719
ignored = globbing.Globster(name_pattern_list)
2714
self.add_cleanup(tree.lock_read().unlock)
2715
2722
for entry in tree.list_files():
2717
2724
if id is not None:
2718
2725
filename = entry[0]
2719
2726
if ignored.match(filename):
2720
2727
matches.append(filename)
2721
2729
if len(matches) > 0:
2722
2730
self.outf.write("Warning: the following files are version controlled and"
2723
2731
" match your ignore pattern:\n%s"
2739
2747
encoding_type = 'replace'
2740
2748
_see_also = ['ignore', 'ls']
2741
takes_options = ['directory']
2743
2750
@display_command
2744
def run(self, directory=u'.'):
2745
tree = WorkingTree.open_containing(directory)[0]
2746
self.add_cleanup(tree.lock_read().unlock)
2752
tree = WorkingTree.open_containing(u'.')[0]
2754
self.add_cleanup(tree.unlock)
2747
2755
for path, file_class, kind, file_id, entry in tree.list_files():
2748
2756
if file_class != 'I':
2755
2763
class cmd_lookup_revision(Command):
2756
__doc__ = """Lookup the revision-id from a revision-number
2764
"""Lookup the revision-id from a revision-number
2759
2767
bzr lookup-revision 33
2762
2770
takes_args = ['revno']
2763
takes_options = ['directory']
2765
2772
@display_command
2766
def run(self, revno, directory=u'.'):
2773
def run(self, revno):
2768
2775
revno = int(revno)
2769
2776
except ValueError:
2770
2777
raise errors.BzrCommandError("not a valid revision-number: %r"
2772
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2779
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2773
2780
self.outf.write("%s\n" % revid)
2776
2783
class cmd_export(Command):
2777
__doc__ = """Export current or past revision to a destination directory or archive.
2784
"""Export current or past revision to a destination directory or archive.
2779
2786
If no revision is specified this exports the last committed revision.
2817
2824
'revision in which it was changed.'),
2819
2826
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2820
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2827
root=None, filters=False, per_file_timestamps=False):
2821
2828
from bzrlib.export import export
2823
2830
if branch_or_subdir is None:
2824
tree = WorkingTree.open_containing(directory)[0]
2831
tree = WorkingTree.open_containing(u'.')[0]
2825
2832
b = tree.branch
2858
2865
@display_command
2859
2866
def run(self, filename, revision=None, name_from_revision=False,
2860
filters=False, directory=None):
2861
2868
if revision is not None and len(revision) != 1:
2862
2869
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2863
2870
" one revision specifier")
2864
2871
tree, branch, relpath = \
2865
_open_directory_or_containing_tree_or_branch(filename, directory)
2866
self.add_cleanup(branch.lock_read().unlock)
2872
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2874
self.add_cleanup(branch.unlock)
2867
2875
return self._run(tree, branch, relpath, filename, revision,
2868
2876
name_from_revision, filters)
3100
3109
properties = {}
3102
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3111
tree, selected_list = tree_files(selected_list)
3103
3112
if selected_list == ['']:
3104
3113
# workaround - commit of root of tree should be exactly the same
3105
3114
# as just default commit in that tree, and succeed even though
3140
3149
def get_message(commit_obj):
3141
3150
"""Callback to get commit message"""
3145
my_message = f.read().decode(osutils.get_user_encoding())
3152
my_message = codecs.open(
3153
file, 'rt', osutils.get_user_encoding()).read()
3148
3154
elif message is not None:
3149
3155
my_message = message
3179
3185
reporter=None, verbose=verbose, revprops=properties,
3180
3186
authors=author, timestamp=commit_stamp,
3181
3187
timezone=offset,
3182
exclude=tree.safe_relpath_files(exclude))
3188
exclude=safe_relpath_files(tree, exclude))
3183
3189
except PointlessCommit:
3184
3190
raise errors.BzrCommandError("No changes to commit."
3185
3191
" Use --unchanged to commit anyhow.")
3201
3207
class cmd_check(Command):
3202
__doc__ = """Validate working tree structure, branch consistency and repository history.
3208
"""Validate working tree structure, branch consistency and repository history.
3204
3210
This command checks various invariants about branch and repository storage
3205
3211
to detect data corruption or bzr bugs.
3305
3311
bzr whoami "Frank Chu <fchu@example.com>"
3307
takes_options = [ 'directory',
3313
takes_options = [ Option('email',
3309
3314
help='Display email address only.'),
3310
3315
Option('branch',
3311
3316
help='Set identity for the current branch instead of '
3315
3320
encoding_type = 'replace'
3317
3322
@display_command
3318
def run(self, email=False, branch=False, name=None, directory=None):
3323
def run(self, email=False, branch=False, name=None):
3319
3324
if name is None:
3320
if directory is None:
3321
# use branch if we're inside one; otherwise global config
3323
c = Branch.open_containing(u'.')[0].get_config()
3324
except errors.NotBranchError:
3325
c = _mod_config.GlobalConfig()
3327
c = Branch.open(directory).get_config()
3325
# use branch if we're inside one; otherwise global config
3327
c = Branch.open_containing('.')[0].get_config()
3328
except errors.NotBranchError:
3329
c = config.GlobalConfig()
3329
3331
self.outf.write(c.user_email() + '\n')
3334
3336
# display a warning if an email address isn't included in the given name.
3336
_mod_config.extract_email_address(name)
3338
config.extract_email_address(name)
3337
3339
except errors.NoEmailInUsername, e:
3338
3340
warning('"%s" does not seem to contain an email address. '
3339
3341
'This is allowed, but not recommended.', name)
3341
3343
# use global config unless --branch given
3343
if directory is None:
3344
c = Branch.open_containing(u'.')[0].get_config()
3346
c = Branch.open(directory).get_config()
3345
c = Branch.open_containing('.')[0].get_config()
3348
c = _mod_config.GlobalConfig()
3347
c = config.GlobalConfig()
3349
3348
c.set_user_option('email', name)
3352
3351
class cmd_nick(Command):
3353
__doc__ = """Print or set the branch nickname.
3352
"""Print or set the branch nickname.
3355
3354
If unset, the tree root directory name is used as the nickname.
3356
3355
To print the current nickname, execute with no argument.
3362
3361
_see_also = ['info']
3363
3362
takes_args = ['nickname?']
3364
takes_options = ['directory']
3365
def run(self, nickname=None, directory=u'.'):
3366
branch = Branch.open_containing(directory)[0]
3363
def run(self, nickname=None):
3364
branch = Branch.open_containing(u'.')[0]
3367
3365
if nickname is None:
3368
3366
self.printme(branch)
3418
3416
'bzr alias --remove expects an alias to remove.')
3419
3417
# If alias is not found, print something like:
3420
3418
# unalias: foo: not found
3421
c = _mod_config.GlobalConfig()
3419
c = config.GlobalConfig()
3422
3420
c.unset_alias(alias_name)
3424
3422
@display_command
3425
3423
def print_aliases(self):
3426
3424
"""Print out the defined aliases in a similar format to bash."""
3427
aliases = _mod_config.GlobalConfig().get_aliases()
3425
aliases = config.GlobalConfig().get_aliases()
3428
3426
for key, value in sorted(aliases.iteritems()):
3429
3427
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3441
3439
def set_alias(self, alias_name, alias_command):
3442
3440
"""Save the alias in the global config."""
3443
c = _mod_config.GlobalConfig()
3441
c = config.GlobalConfig()
3444
3442
c.set_alias(alias_name, alias_command)
3447
3445
class cmd_selftest(Command):
3448
__doc__ = """Run internal test suite.
3446
"""Run internal test suite.
3450
3448
If arguments are given, they are regular expressions that say which tests
3451
3449
should run. Tests matching any expression are run, and other tests are
3519
3517
'throughout the test suite.',
3520
3518
type=get_transport_type),
3521
3519
Option('benchmark',
3522
help='Run the benchmarks rather than selftests.',
3520
help='Run the benchmarks rather than selftests.'),
3524
3521
Option('lsprof-timed',
3525
3522
help='Generate lsprof output for benchmarked'
3526
3523
' sections of code.'),
3527
3524
Option('lsprof-tests',
3528
3525
help='Generate lsprof output for each test.'),
3526
Option('cache-dir', type=str,
3527
help='Cache intermediate benchmark output in this '
3529
3529
Option('first',
3530
3530
help='Run all tests, but run specified tests first.',
3531
3531
short_name='f',
3566
3566
def run(self, testspecs_list=None, verbose=False, one=False,
3567
3567
transport=None, benchmark=None,
3568
lsprof_timed=None, cache_dir=None,
3569
3569
first=False, list_only=False,
3570
3570
randomize=None, exclude=None, strict=False,
3571
3571
load_list=None, debugflag=None, starting_with=None, subunit=False,
3572
3572
parallel=None, lsprof_tests=False):
3573
from bzrlib import tests
3573
from bzrlib.tests import selftest
3574
import bzrlib.benchmarks as benchmarks
3575
from bzrlib.benchmarks import tree_creator
3577
# Make deprecation warnings visible, unless -Werror is set
3578
symbol_versioning.activate_deprecation_warnings(override=False)
3580
if cache_dir is not None:
3581
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3575
3582
if testspecs_list is not None:
3576
3583
pattern = '|'.join(testspecs_list)
3583
3590
raise errors.BzrCommandError("subunit not available. subunit "
3584
3591
"needs to be installed to use --subunit.")
3585
3592
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
3594
self.additional_selftest_args.setdefault(
3597
3595
'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
3597
test_suite_factory = benchmarks.test_suite
3598
# Unless user explicitly asks for quiet, be verbose in benchmarks
3599
verbose = not is_quiet()
3600
# TODO: should possibly lock the history file...
3601
benchfile = open(".perf_history", "at", buffering=1)
3602
self.add_cleanup(benchfile.close)
3604
test_suite_factory = None
3603
3606
selftest_kwargs = {"verbose": verbose,
3604
3607
"pattern": pattern,
3605
3608
"stop_on_failure": one,
3607
3610
"test_suite_factory": test_suite_factory,
3608
3611
"lsprof_timed": lsprof_timed,
3609
3612
"lsprof_tests": lsprof_tests,
3613
"bench_history": benchfile,
3610
3614
"matching_tests_first": first,
3611
3615
"list_only": list_only,
3612
3616
"random_seed": randomize,
3617
3621
"starting_with": starting_with
3619
3623
selftest_kwargs.update(self.additional_selftest_args)
3621
# Make deprecation warnings visible, unless -Werror is set
3622
cleanup = symbol_versioning.activate_deprecation_warnings(
3625
result = tests.selftest(**selftest_kwargs)
3624
result = selftest(**selftest_kwargs)
3628
3625
return int(not result)
3631
3628
class cmd_version(Command):
3632
__doc__ = """Show version of bzr."""
3629
"""Show version of bzr."""
3634
3631
encoding_type = 'replace'
3635
3632
takes_options = [
3658
3655
class cmd_find_merge_base(Command):
3659
__doc__ = """Find and print a base revision for merging two branches."""
3656
"""Find and print a base revision for merging two branches."""
3660
3657
# TODO: Options to specify revisions on either side, as if
3661
3658
# merging only part of the history.
3662
3659
takes_args = ['branch', 'other']
3669
3666
branch1 = Branch.open_containing(branch)[0]
3670
3667
branch2 = Branch.open_containing(other)[0]
3671
self.add_cleanup(branch1.lock_read().unlock)
3672
self.add_cleanup(branch2.lock_read().unlock)
3669
self.add_cleanup(branch1.unlock)
3671
self.add_cleanup(branch2.unlock)
3673
3672
last1 = ensure_null(branch1.last_revision())
3674
3673
last2 = ensure_null(branch2.last_revision())
3769
3768
' completely merged into the source, pull from the'
3770
3769
' source rather than merging. When this happens,'
3771
3770
' you do not need to commit the result.'),
3772
custom_help('directory',
3773
3772
help='Branch to merge into, '
3774
'rather than the one containing the working directory.'),
3773
'rather than the one containing the working directory.',
3775
3777
Option('preview', help='Instead of merging, show a diff of the'
3777
3779
Option('interactive', help='Select changes interactively.',
3810
3812
unversioned_filter=tree.is_ignored, view_info=view_info)
3811
3813
pb = ui.ui_factory.nested_progress_bar()
3812
3814
self.add_cleanup(pb.finished)
3813
self.add_cleanup(tree.lock_write().unlock)
3816
self.add_cleanup(tree.unlock)
3814
3817
if location is not None:
3816
3819
mergeable = bundle.read_mergeable_from_url(location,
3877
3880
def _do_preview(self, merger):
3878
3881
from bzrlib.diff import show_diff_trees
3879
3882
result_tree = self._get_preview(merger)
3880
path_encoding = osutils.get_diff_header_encoding()
3881
3883
show_diff_trees(merger.this_tree, result_tree, self.outf,
3882
old_label='', new_label='',
3883
path_encoding=path_encoding)
3884
old_label='', new_label='')
3885
3886
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3886
3887
merger.change_reporter = change_reporter
4073
4074
from bzrlib.conflicts import restore
4074
4075
if merge_type is None:
4075
4076
merge_type = _mod_merge.Merge3Merger
4076
tree, file_list = WorkingTree.open_containing_paths(file_list)
4077
self.add_cleanup(tree.lock_write().unlock)
4077
tree, file_list = tree_files(file_list)
4079
self.add_cleanup(tree.unlock)
4078
4080
parents = tree.get_parent_ids()
4079
4081
if len(parents) != 2:
4080
4082
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4135
4137
class cmd_revert(Command):
4136
__doc__ = """Revert files to a previous revision.
4138
"""Revert files to a previous revision.
4138
4140
Giving a list of files will revert only those files. Otherwise, all files
4139
4141
will be reverted. If the revision is not specified with '--revision', the
4190
4192
def run(self, revision=None, no_backup=False, file_list=None,
4191
4193
forget_merges=None):
4192
tree, file_list = WorkingTree.open_containing_paths(file_list)
4193
self.add_cleanup(tree.lock_tree_write().unlock)
4194
tree, file_list = tree_files(file_list)
4196
self.add_cleanup(tree.unlock)
4194
4197
if forget_merges:
4195
4198
tree.set_parent_ids(tree.get_parent_ids()[:1])
4313
4315
theirs_only=False,
4314
4316
log_format=None, long=False, short=False, line=False,
4315
4317
show_ids=False, verbose=False, this=False, other=False,
4316
include_merges=False, revision=None, my_revision=None,
4318
include_merges=False, revision=None, my_revision=None):
4318
4319
from bzrlib.missing import find_unmerged, iter_log_revisions
4319
4320
def message(s):
4320
4321
if not is_quiet():
4351
4353
if remote_branch.base == local_branch.base:
4352
4354
remote_branch = local_branch
4354
self.add_cleanup(remote_branch.lock_read().unlock)
4356
remote_branch.lock_read()
4357
self.add_cleanup(remote_branch.unlock)
4356
4359
local_revid_range = _revision_range_to_revid_range(
4357
4360
_get_revision_range(my_revision, local_branch,
4412
4415
message("Branches are up to date.\n")
4413
4416
self.cleanup_now()
4414
4417
if not status_code and parent is None and other_branch is not None:
4415
self.add_cleanup(local_branch.lock_write().unlock)
4418
local_branch.lock_write()
4419
self.add_cleanup(local_branch.unlock)
4416
4420
# handle race conditions - a parent might be set while we run.
4417
4421
if local_branch.get_parent() is None:
4418
4422
local_branch.set_parent(remote_branch.base)
4422
4426
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.
4427
"""Compress the data within a repository."""
4441
4429
_see_also = ['repositories']
4442
4430
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):
4432
def run(self, branch_or_repo='.'):
4448
4433
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4450
4435
branch = dir.open_branch()
4451
4436
repository = branch.repository
4452
4437
except errors.NotBranchError:
4453
4438
repository = dir.open_repository()
4454
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4457
4442
class cmd_plugins(Command):
4458
__doc__ = """List the installed plugins.
4443
"""List the installed plugins.
4460
4445
This command displays the list of installed plugins including
4461
4446
version of plugin and a short description of each.
4548
4534
Option('long', help='Show commit date in annotations.'),
4553
4538
encoding_type = 'exact'
4555
4540
@display_command
4556
4541
def run(self, filename, all=False, long=False, revision=None,
4557
show_ids=False, directory=None):
4558
4543
from bzrlib.annotate import annotate_file, annotate_file_tree
4559
4544
wt, branch, relpath = \
4560
_open_directory_or_containing_tree_or_branch(filename, directory)
4545
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4561
4546
if wt is not None:
4562
self.add_cleanup(wt.lock_read().unlock)
4548
self.add_cleanup(wt.unlock)
4564
self.add_cleanup(branch.lock_read().unlock)
4551
self.add_cleanup(branch.unlock)
4565
4552
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4566
self.add_cleanup(tree.lock_read().unlock)
4554
self.add_cleanup(tree.unlock)
4567
4555
if wt is not None:
4568
4556
file_id = wt.path2id(relpath)
4584
4572
class cmd_re_sign(Command):
4585
__doc__ = """Create a digital signature for an existing revision."""
4573
"""Create a digital signature for an existing revision."""
4586
4574
# TODO be able to replace existing ones.
4588
4576
hidden = True # is this right ?
4589
4577
takes_args = ['revision_id*']
4590
takes_options = ['directory', 'revision']
4578
takes_options = ['revision']
4592
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4580
def run(self, revision_id_list=None, revision=None):
4593
4581
if revision_id_list is not None and revision is not None:
4594
4582
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4595
4583
if revision_id_list is None and revision is None:
4596
4584
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)
4585
b = WorkingTree.open_containing(u'.')[0].branch
4587
self.add_cleanup(b.unlock)
4599
4588
return self._run(b, revision_id_list, revision)
4601
4590
def _run(self, b, revision_id_list, revision):
4649
4638
class cmd_bind(Command):
4650
__doc__ = """Convert the current branch into a checkout of the supplied branch.
4651
If no branch is supplied, rebind to the last bound location.
4639
"""Convert the current branch into a checkout of the supplied branch.
4653
4641
Once converted into a checkout, commits must succeed on the master branch
4654
4642
before they will be applied to the local branch.
4661
4649
_see_also = ['checkouts', 'unbind']
4662
4650
takes_args = ['location?']
4663
takes_options = ['directory']
4665
def run(self, location=None, directory=u'.'):
4666
b, relpath = Branch.open_containing(directory)
4653
def run(self, location=None):
4654
b, relpath = Branch.open_containing(u'.')
4667
4655
if location is None:
4669
4657
location = b.get_old_bound_location()
4697
4685
_see_also = ['checkouts', 'bind']
4698
4686
takes_args = []
4699
takes_options = ['directory']
4701
def run(self, directory=u'.'):
4702
b, relpath = Branch.open_containing(directory)
4690
b, relpath = Branch.open_containing(u'.')
4703
4691
if not b.unbind():
4704
4692
raise errors.BzrCommandError('Local branch is not bound')
4707
4695
class cmd_uncommit(Command):
4708
__doc__ = """Remove the last committed revision.
4696
"""Remove the last committed revision.
4710
4698
--verbose will print out what is being removed.
4711
4699
--dry-run will go through all the motions, but not actually
4751
4739
b = control.open_branch()
4753
4741
if tree is not None:
4754
self.add_cleanup(tree.lock_write().unlock)
4743
self.add_cleanup(tree.unlock)
4756
self.add_cleanup(b.lock_write().unlock)
4746
self.add_cleanup(b.unlock)
4757
4747
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4759
4749
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4813
4803
class cmd_break_lock(Command):
4814
__doc__ = """Break a dead lock.
4816
This command breaks a lock on a repository, branch, working directory or
4804
"""Break a dead lock on a repository, branch or working directory.
4819
4806
CAUTION: Locks should only be broken when you are sure that the process
4820
4807
holding the lock has been stopped.
4827
4814
bzr break-lock bzr+ssh://example.com/bzr/foo
4828
bzr break-lock --conf ~/.bazaar
4831
4816
takes_args = ['location?']
4834
help='LOCATION is the directory where the config lock is.'),
4837
def run(self, location=None, config=False):
4818
def run(self, location=None, show=False):
4838
4819
if location is None:
4839
4820
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:
4821
control, relpath = bzrdir.BzrDir.open_containing(location)
4823
control.break_lock()
4824
except NotImplementedError:
4851
4828
class cmd_wait_until_signalled(Command):
4852
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4829
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4854
4831
This just prints a line to signal when it is ready, then blocks on stdin.
4880
4857
'result in a dynamically allocated port. The default port '
4881
4858
'depends on the protocol.',
4883
custom_help('directory',
4884
help='Serve contents of this directory.'),
4861
help='Serve contents of this directory.',
4885
4863
Option('allow-writes',
4886
4864
help='By default the server is a readonly server. Supplying '
4887
4865
'--allow-writes enables write access to the contents of '
4915
4893
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4916
4894
protocol=None):
4917
from bzrlib import transport
4895
from bzrlib.transport import get_transport, transport_server_registry
4918
4896
if directory is None:
4919
4897
directory = os.getcwd()
4920
4898
if protocol is None:
4921
protocol = transport.transport_server_registry.get()
4899
protocol = transport_server_registry.get()
4922
4900
host, port = self.get_host_and_port(port)
4923
4901
url = urlutils.local_path_to_url(directory)
4924
4902
if not allow_writes:
4925
4903
url = 'readonly+' + url
4926
t = transport.get_transport(url)
4927
protocol(t, host, port, inet)
4904
transport = get_transport(url)
4905
protocol(transport, host, port, inet)
4930
4908
class cmd_join(Command):
4931
__doc__ = """Combine a tree into its containing tree.
4909
"""Combine a tree into its containing tree.
4933
4911
This command requires the target tree to be in a rich-root format.
5042
5019
encoding_type = 'exact'
5044
5021
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5045
sign=False, revision=None, mail_to=None, message=None,
5022
sign=False, revision=None, mail_to=None, message=None):
5047
5023
from bzrlib.revision import ensure_null, NULL_REVISION
5048
5024
include_patch, include_bundle = {
5049
5025
'plain': (False, False),
5050
5026
'diff': (True, False),
5051
5027
'bundle': (True, True),
5053
branch = Branch.open(directory)
5029
branch = Branch.open('.')
5054
5030
stored_submit_branch = branch.get_submit_branch()
5055
5031
if submit_branch is None:
5056
5032
submit_branch = stored_submit_branch
5141
5117
given, in which case it is sent to a file.
5143
5119
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.
5120
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5145
5121
If the preferred client can't be found (or used), your editor will be used.
5147
5123
To use a specific mail program, set the mail_client configuration option.
5362
5342
class cmd_tags(Command):
5363
__doc__ = """List tags.
5365
5345
This command shows a table of tag names and the revisions they reference.
5368
5348
_see_also = ['tag']
5369
5349
takes_options = [
5370
custom_help('directory',
5371
help='Branch whose tags should be displayed.'),
5351
help='Branch whose tags should be displayed.',
5372
5355
RegistryOption.from_kwargs('sort',
5373
5356
'Sort tags by different criteria.', title='Sorting',
5374
5357
alpha='Sort tags lexicographically (default).',
5523
5507
class cmd_switch(Command):
5524
__doc__ = """Set the branch of a checkout and update.
5508
"""Set the branch of a checkout and update.
5526
5510
For lightweight checkouts, this changes the branch being referenced.
5527
5511
For heavyweight checkouts, this checks that there are no local commits
5546
5530
takes_args = ['to_location?']
5547
takes_options = ['directory',
5531
takes_options = [Option('force',
5549
5532
help='Switch even if local commits will be lost.'),
5551
5534
Option('create-branch', short_name='b',
5556
5539
def run(self, to_location=None, force=False, create_branch=False,
5557
revision=None, directory=u'.'):
5558
5541
from bzrlib import switch
5559
tree_location = directory
5560
5543
revision = _get_one_revision('switch', revision)
5561
5544
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5562
5545
if to_location is None:
5563
5546
if revision is None:
5564
5547
raise errors.BzrCommandError('You must supply either a'
5565
5548
' revision or a location')
5566
to_location = tree_location
5568
5551
branch = control_dir.open_branch()
5569
5552
had_explicit_nick = branch.get_config().has_explicit_nickname()
5820
5802
class cmd_shelve(Command):
5821
__doc__ = """Temporarily set aside some changes from the current tree.
5803
"""Temporarily set aside some changes from the current tree.
5823
5805
Shelve allows you to temporarily put changes you've made "on the shelf",
5824
5806
ie. out of the way, until a later time when you can bring them back from
5860
5841
_see_also = ['unshelve']
5862
5843
def run(self, revision=None, all=False, file_list=None, message=None,
5863
writer=None, list=False, destroy=False, directory=u'.'):
5844
writer=None, list=False, destroy=False):
5865
5846
return self.run_for_list()
5866
5847
from bzrlib.shelf_ui import Shelver
5868
5849
writer = bzrlib.option.diff_writer_registry.get()
5870
5851
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5871
file_list, message, destroy=destroy, directory=directory)
5852
file_list, message, destroy=destroy)
5917
5898
_see_also = ['shelve']
5919
def run(self, shelf_id=None, action='apply', directory=u'.'):
5900
def run(self, shelf_id=None, action='apply'):
5920
5901
from bzrlib.shelf_ui import Unshelver
5921
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5902
unshelver = Unshelver.from_args(shelf_id, action)
5923
5904
unshelver.run()
5941
5922
To check what clean-tree will do, use --dry-run.
5943
takes_options = ['directory',
5944
Option('ignored', help='Delete all ignored files.'),
5924
takes_options = [Option('ignored', help='Delete all ignored files.'),
5945
5925
Option('detritus', help='Delete conflict files, merge'
5946
5926
' backups, and failed selftest dirs.'),
5947
5927
Option('unknown',
5950
5930
' deleting them.'),
5951
5931
Option('force', help='Do not prompt before deleting.')]
5952
5932
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5953
force=False, directory=u'.'):
5954
5934
from bzrlib.clean_tree import clean_tree
5955
5935
if not (unknown or ignored or detritus):
5959
clean_tree(directory, unknown=unknown, ignored=ignored,
5960
detritus=detritus, dry_run=dry_run, no_prompt=force)
5939
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5940
dry_run=dry_run, no_prompt=force)
5963
5943
class cmd_reference(Command):
5964
__doc__ = """list, view and set branch locations for nested trees.
5944
"""list, view and set branch locations for nested trees.
5966
5946
If no arguments are provided, lists the branch locations for nested trees.
5967
5947
If one argument is provided, display the branch location for that tree.