481
475
self.print_revision(revisions, rev_id)
484
class cmd_dump_btree(Command):
485
__doc__ = """Dump the contents of a btree index file to stdout.
487
PATH is a btree index file, it can be any URL. This includes things like
488
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
490
By default, the tuples stored in the index file will be displayed. With
491
--raw, we will uncompress the pages, but otherwise display the raw bytes
495
# TODO: Do we want to dump the internal nodes as well?
496
# TODO: It would be nice to be able to dump the un-parsed information,
497
# rather than only going through iter_all_entries. However, this is
498
# good enough for a start
500
encoding_type = 'exact'
501
takes_args = ['path']
502
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
503
' rather than the parsed tuples.'),
506
def run(self, path, raw=False):
507
dirname, basename = osutils.split(path)
508
t = transport.get_transport(dirname)
510
self._dump_raw_bytes(t, basename)
512
self._dump_entries(t, basename)
514
def _get_index_and_bytes(self, trans, basename):
515
"""Create a BTreeGraphIndex and raw bytes."""
516
bt = btree_index.BTreeGraphIndex(trans, basename, None)
517
bytes = trans.get_bytes(basename)
518
bt._file = BytesIO(bytes)
519
bt._size = len(bytes)
522
def _dump_raw_bytes(self, trans, basename):
525
# We need to parse at least the root node.
526
# This is because the first page of every row starts with an
527
# uncompressed header.
528
bt, bytes = self._get_index_and_bytes(trans, basename)
529
for page_idx, page_start in enumerate(range(0, len(bytes),
530
btree_index._PAGE_SIZE)):
531
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
532
page_bytes = bytes[page_start:page_end]
534
self.outf.write('Root node:\n')
535
header_end, data = bt._parse_header_from_bytes(page_bytes)
536
self.outf.write(page_bytes[:header_end])
538
self.outf.write('\nPage %d\n' % (page_idx,))
539
if len(page_bytes) == 0:
540
self.outf.write('(empty)\n');
542
decomp_bytes = zlib.decompress(page_bytes)
543
self.outf.write(decomp_bytes)
544
self.outf.write('\n')
546
def _dump_entries(self, trans, basename):
548
st = trans.stat(basename)
549
except errors.TransportNotPossible:
550
# We can't stat, so we'll fake it because we have to do the 'get()'
552
bt, _ = self._get_index_and_bytes(trans, basename)
554
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
555
for node in bt.iter_all_entries():
556
# Node is made up of:
557
# (index, key, value, [references])
561
refs_as_tuples = None
563
refs_as_tuples = static_tuple.as_tuples(refs)
564
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
565
self.outf.write('%s\n' % (as_tuple,))
568
478
class cmd_remove_tree(Command):
569
479
__doc__ = """Remove the working tree from a given branch/checkout.
935
858
takes_options = [
861
Option('include-root',
862
help='Include the entry for the root of the tree, if any.'),
939
help='List entries of a particular kind: file, directory, symlink.',
864
help='List entries of a particular kind: file, directory, '
942
868
takes_args = ['file*']
945
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
871
def run(self, revision=None, show_ids=False, kind=None, include_root=False,
946
873
if kind and kind not in ['file', 'directory', 'symlink']:
947
raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
874
raise errors.BzrCommandError(
875
gettext('invalid kind %r specified') % (kind,))
949
877
revision = _get_one_revision('inventory', revision)
950
878
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
951
self.add_cleanup(work_tree.lock_read().unlock)
879
self.enter_context(work_tree.lock_read())
952
880
if revision is not None:
953
881
tree = revision.as_tree(work_tree.branch)
955
883
extra_trees = [work_tree]
956
self.add_cleanup(tree.lock_read().unlock)
884
self.enter_context(tree.lock_read())
961
self.add_cleanup(tree.lock_read().unlock)
889
self.enter_context(tree.lock_read())
962
890
if file_list is not None:
963
file_ids = tree.paths2ids(file_list, trees=extra_trees,
964
require_versioned=True)
891
paths = tree.find_related_paths_across_trees(
892
file_list, extra_trees, require_versioned=True)
965
893
# find_ids_across_trees may include some paths that don't
966
894
# exist in 'tree'.
967
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
895
entries = tree.iter_entries_by_dir(specific_files=paths)
969
897
entries = tree.iter_entries_by_dir()
971
899
for path, entry in sorted(entries):
972
900
if kind and kind != entry.kind:
902
if path == "" and not include_root:
977
self.outf.write('%-50s %s\n' % (path, entry.file_id))
905
self.outf.write('%-50s %s\n' % (
906
path, entry.file_id.decode('utf-8')))
979
908
self.outf.write(path)
980
909
self.outf.write('\n')
1002
931
encoding_type = 'replace'
1004
933
def run(self, names_list):
1006
934
if names_list is None:
1008
936
if len(names_list) < 2:
1009
937
raise errors.BzrCommandError(gettext("missing file argument"))
1010
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
938
tree, rel_names = WorkingTree.open_containing_paths(
939
names_list, canonicalize=False)
1011
940
for file_name in rel_names[0:-1]:
1012
941
if file_name == '':
1013
raise errors.BzrCommandError(gettext("can not copy root of branch"))
1014
self.add_cleanup(tree.lock_tree_write().unlock)
942
raise errors.BzrCommandError(
943
gettext("can not copy root of branch"))
944
self.enter_context(tree.lock_tree_write())
1015
945
into_existing = osutils.isdir(names_list[-1])
1016
946
if not into_existing:
1018
948
(src, dst) = rel_names
1019
949
except IndexError:
1020
raise errors.BzrCommandError(gettext('to copy multiple files the'
1021
' destination must be a versioned'
950
raise errors.BzrCommandError(
951
gettext('to copy multiple files the'
952
' destination must be a versioned'
1023
954
pairs = [(src, dst)]
1025
pairs = [(n, osutils.joinpath([rel_names[-1], osutils.basename(n)]))
1026
for n in rel_names[:-1]]
957
(n, osutils.joinpath([rel_names[-1], osutils.basename(n)]))
958
for n in rel_names[:-1]]
1028
960
for src, dst in pairs:
1030
962
src_kind = tree.stored_kind(src)
1031
963
except errors.NoSuchFile:
1032
964
raise errors.BzrCommandError(
1033
gettext('Could not copy %s => %s: %s is not versioned.')
965
gettext('Could not copy %s => %s: %s is not versioned.')
1035
967
if src_kind is None:
1036
968
raise errors.BzrCommandError(
1037
gettext('Could not copy %s => %s . %s is not versioned\.'
969
gettext('Could not copy %s => %s . %s is not versioned\\.'
1039
971
if src_kind == 'directory':
1040
972
raise errors.BzrCommandError(
1041
973
gettext('Could not copy %s => %s . %s is a directory.'
1043
975
dst_parent = osutils.split(dst)[0]
1044
976
if dst_parent != '':
1046
978
dst_parent_kind = tree.stored_kind(dst_parent)
1047
979
except errors.NoSuchFile:
1048
980
raise errors.BzrCommandError(
1049
gettext('Could not copy %s => %s: %s is not versioned.')
1050
% (src, dst, dst_parent))
981
gettext('Could not copy %s => %s: %s is not versioned.')
982
% (src, dst, dst_parent))
1051
983
if dst_parent_kind != 'directory':
1052
984
raise errors.BzrCommandError(
1053
gettext('Could not copy to %s: %s is not a directory.')
1054
% (dst_parent, dst_parent))
985
gettext('Could not copy to %s: %s is not a directory.')
986
% (dst_parent, dst_parent))
1056
988
tree.copy_one(src, dst)
1374
1311
_see_also = ['pull', 'update', 'working-trees']
1375
1312
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1376
Option('create-prefix',
1377
help='Create the path leading up to the branch '
1378
'if it does not already exist.'),
1379
custom_help('directory',
1380
help='Branch to push from, '
1381
'rather than the one containing the working directory.'),
1382
Option('use-existing-dir',
1383
help='By default push will fail if the target'
1384
' directory exists, but does not already'
1385
' have a control directory. This flag will'
1386
' allow push to proceed.'),
1388
help='Create a stacked branch that references the public location '
1389
'of the parent branch.'),
1390
Option('stacked-on',
1391
help='Create a stacked branch that refers to another branch '
1392
'for the commit history. Only the work not present in the '
1393
'referenced branch is included in the branch created.',
1396
help='Refuse to push if there are uncommitted changes in'
1397
' the working tree, --no-strict disables the check.'),
1399
help="Don't populate the working tree, even for protocols"
1400
" that support it."),
1401
Option('overwrite-tags',
1402
help="Overwrite tags only."),
1313
Option('create-prefix',
1314
help='Create the path leading up to the branch '
1315
'if it does not already exist.'),
1316
custom_help('directory',
1317
help='Branch to push from, '
1318
'rather than the one containing the working directory.'),
1319
Option('use-existing-dir',
1320
help='By default push will fail if the target'
1321
' directory exists, but does not already'
1322
' have a control directory. This flag will'
1323
' allow push to proceed.'),
1325
help='Create a stacked branch that references the public location '
1326
'of the parent branch.'),
1327
Option('stacked-on',
1328
help='Create a stacked branch that refers to another branch '
1329
'for the commit history. Only the work not present in the '
1330
'referenced branch is included in the branch created.',
1333
help='Refuse to push if there are uncommitted changes in'
1334
' the working tree, --no-strict disables the check.'),
1336
help="Don't populate the working tree, even for protocols"
1337
" that support it."),
1338
Option('overwrite-tags',
1339
help="Overwrite tags only."),
1340
Option('lossy', help="Allow lossy push, i.e. dropping metadata "
1341
"that can't be represented in the target.")
1404
1343
takes_args = ['location?']
1405
1344
encoding_type = 'replace'
1407
1346
def run(self, location=None, remember=None, overwrite=False,
1408
create_prefix=False, verbose=False, revision=None,
1409
use_existing_dir=False, directory=None, stacked_on=None,
1410
stacked=False, strict=None, no_tree=False,
1411
overwrite_tags=False):
1347
create_prefix=False, verbose=False, revision=None,
1348
use_existing_dir=False, directory=None, stacked_on=None,
1349
stacked=False, strict=None, no_tree=False,
1350
overwrite_tags=False, lossy=False):
1351
from .location import location_to_url
1412
1352
from .push import _show_push_branch
1492
1434
parameter, as in "branch foo/bar -r 5".
1495
1438
_see_also = ['checkout']
1496
1439
takes_args = ['from_location', 'to_location?']
1497
1440
takes_options = ['revision',
1498
Option('hardlink', help='Hard-link working tree files where possible.'),
1499
Option('files-from', type=text_type,
1500
help="Get file contents from this tree."),
1502
help="Create a branch without a working-tree."),
1504
help="Switch the checkout in the current directory "
1505
"to the new branch."),
1507
help='Create a stacked branch referring to the source branch. '
1508
'The new branch will depend on the availability of the source '
1509
'branch for all operations.'),
1510
Option('standalone',
1511
help='Do not use a shared repository, even if available.'),
1512
Option('use-existing-dir',
1513
help='By default branch will fail if the target'
1514
' directory exists, but does not already'
1515
' have a control directory. This flag will'
1516
' allow branch to proceed.'),
1518
help="Bind new branch to from location."),
1442
'hardlink', help='Hard-link working tree files where possible.'),
1443
Option('files-from', type=str,
1444
help="Get file contents from this tree."),
1446
help="Create a branch without a working-tree."),
1448
help="Switch the checkout in the current directory "
1449
"to the new branch."),
1451
help='Create a stacked branch referring to the source branch. '
1452
'The new branch will depend on the availability of the source '
1453
'branch for all operations.'),
1454
Option('standalone',
1455
help='Do not use a shared repository, even if available.'),
1456
Option('use-existing-dir',
1457
help='By default branch will fail if the target'
1458
' directory exists, but does not already'
1459
' have a control directory. This flag will'
1460
' allow branch to proceed.'),
1462
help="Bind new branch to from location."),
1463
Option('no-recurse-nested',
1464
help='Do not recursively check out nested trees.'),
1465
Option('colocated-branch', short_name='b',
1466
type=str, help='Name of colocated branch to sprout.'),
1521
1469
def run(self, from_location, to_location=None, revision=None,
1522
1470
hardlink=False, stacked=False, standalone=False, no_tree=False,
1523
1471
use_existing_dir=False, switch=False, bind=False,
1472
files_from=None, no_recurse_nested=False, colocated_branch=None):
1525
1473
from breezy import switch as _mod_switch
1526
1474
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1475
from_location, name=colocated_branch)
1476
if no_recurse_nested:
1528
1480
if not (hardlink or files_from):
1529
1481
# accelerator_tree is usually slower because you have to read N
1530
1482
# files (no readahead, lots of seeks, etc), but allow the user to
1931
1918
class cmd_remove(Command):
1932
1919
__doc__ = """Remove files or directories.
1934
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1921
This makes Breezy stop tracking changes to the specified files. Breezy will
1935
1922
delete them if they can easily be recovered using revert otherwise they
1936
1923
will be backed up (adding an extension of the form .~#~). If no options or
1937
parameters are given Bazaar will scan for files that are being tracked by
1938
Bazaar but missing in your tree and stop tracking them for you.
1924
parameters are given Breezy will scan for files that are being tracked by
1925
Breezy but missing in your tree and stop tracking them for you.
1940
1927
takes_args = ['file*']
1941
1928
takes_options = ['verbose',
1942
Option('new', help='Only remove files that have never been committed.'),
1943
RegistryOption.from_kwargs('file-deletion-strategy',
1944
'The file deletion mode to be used.',
1945
title='Deletion Strategy', value_switches=True, enum_switch=False,
1946
safe='Backup changed files (default).',
1947
keep='Delete from brz but leave the working copy.',
1948
no_backup='Don\'t backup changed files.'),
1930
'new', help='Only remove files that have never been committed.'),
1931
RegistryOption.from_kwargs('file-deletion-strategy',
1932
'The file deletion mode to be used.',
1933
title='Deletion Strategy', value_switches=True, enum_switch=False,
1934
safe='Backup changed files (default).',
1935
keep='Delete from brz but leave the working copy.',
1936
no_backup='Don\'t backup changed files.'),
1950
1938
aliases = ['rm', 'del']
1951
1939
encoding_type = 'replace'
1953
1941
def run(self, file_list, verbose=False, new=False,
1954
file_deletion_strategy='safe'):
1942
file_deletion_strategy='safe'):
1956
1944
tree, file_list = WorkingTree.open_containing_paths(file_list)
1958
1946
if file_list is not None:
1959
1947
file_list = [f for f in file_list]
1961
self.add_cleanup(tree.lock_write().unlock)
1949
self.enter_context(tree.lock_write())
1962
1950
# Heuristics should probably all move into tree.remove_smart or
1965
1953
added = tree.changes_from(tree.basis_tree(),
1966
specific_files=file_list).added
1967
file_list = sorted([f[0] for f in added], reverse=True)
1954
specific_files=file_list).added
1955
file_list = sorted([f.path[1] for f in added], reverse=True)
1968
1956
if len(file_list) == 0:
1969
1957
raise errors.BzrCommandError(gettext('No matching files.'))
1970
1958
elif file_list is None:
2378
2332
_see_also = ['status']
2379
2333
takes_args = ['file*']
2380
2334
takes_options = [
2381
Option('diff-options', type=text_type,
2335
Option('diff-options', type=str,
2382
2336
help='Pass these options to the external diff program.'),
2383
Option('prefix', type=text_type,
2337
Option('prefix', type=str,
2384
2338
short_name='p',
2385
2339
help='Set prefixes added to old and new filenames, as '
2386
2340
'two values separated by a colon. (eg "old/:new/").'),
2388
help='Branch/tree to compare from.',
2342
help='Branch/tree to compare from.',
2392
help='Branch/tree to compare to.',
2346
help='Branch/tree to compare to.',
2397
2351
Option('using',
2398
help='Use this command to compare files.',
2352
help='Use this command to compare files.',
2401
2355
RegistryOption('format',
2403
help='Diff format to use.',
2404
lazy_registry=('breezy.diff', 'format_registry'),
2405
title='Diff format'),
2357
help='Diff format to use.',
2358
lazy_registry=('breezy.diff', 'format_registry'),
2359
title='Diff format'),
2406
2360
Option('context',
2407
help='How many lines of context to show.',
2361
help='How many lines of context to show.',
2364
RegistryOption.from_kwargs(
2366
help='Color mode to use.',
2367
title='Color Mode', value_switches=False, enum_switch=True,
2368
never='Never colorize output.',
2369
auto='Only colorize output if terminal supports it and STDOUT is a'
2371
always='Always colorize output (default).'),
2374
help=('Warn if trailing whitespace or spurious changes have been'
2411
2378
aliases = ['di', 'dif']
2412
2379
encoding_type = 'exact'
2414
2381
@display_command
2415
2382
def run(self, revision=None, file_list=None, diff_options=None,
2416
2383
prefix=None, old=None, new=None, using=None, format=None,
2384
context=None, color='never'):
2418
2385
from .diff import (get_trees_and_branches_to_diff_locked,
2421
2388
if prefix == u'0':
2422
2389
# diff -p0 format
2721
2698
takes_args = ['file*']
2722
2699
_see_also = ['log-formats', 'revisionspec']
2723
2700
takes_options = [
2725
help='Show from oldest to newest.'),
2727
custom_help('verbose',
2728
help='Show files changed in each revision.'),
2732
type=breezy.option._parse_revision_str,
2734
help='Show just the specified revision.'
2735
' See also "help revisionspec".'),
2737
RegistryOption('authors',
2738
'What names to list as authors - first, all or committer.',
2740
lazy_registry=('breezy.log', 'author_list_registry'),
2744
help='Number of levels to display - 0 for all, 1 for flat.',
2746
type=_parse_levels),
2748
help='Show revisions whose message matches this '
2749
'regular expression.',
2754
help='Limit the output to the first N revisions.',
2759
help='Show changes made in each revision as a patch.'),
2760
Option('include-merged',
2761
help='Show merged revisions like --levels 0 does.'),
2762
Option('include-merges', hidden=True,
2763
help='Historical alias for --include-merged.'),
2764
Option('omit-merges',
2765
help='Do not report commits with more than one parent.'),
2766
Option('exclude-common-ancestry',
2767
help='Display only the revisions that are not part'
2768
' of both ancestries (require -rX..Y).'
2770
Option('signatures',
2771
help='Show digital signature validity.'),
2774
help='Show revisions whose properties match this '
2777
ListOption('match-message',
2778
help='Show revisions whose message matches this '
2781
ListOption('match-committer',
2702
help='Show from oldest to newest.'),
2704
custom_help('verbose',
2705
help='Show files changed in each revision.'),
2709
type=breezy.option._parse_revision_str,
2711
help='Show just the specified revision.'
2712
' See also "help revisionspec".'),
2714
RegistryOption('authors',
2715
'What names to list as authors - first, all or committer.',
2718
'breezy.log', 'author_list_registry'),
2722
help='Number of levels to display - 0 for all, 1 for flat.',
2724
type=_parse_levels),
2726
help='Show revisions whose message matches this '
2727
'regular expression.',
2732
help='Limit the output to the first N revisions.',
2737
help='Show changes made in each revision as a patch.'),
2738
Option('include-merged',
2739
help='Show merged revisions like --levels 0 does.'),
2740
Option('include-merges', hidden=True,
2741
help='Historical alias for --include-merged.'),
2742
Option('omit-merges',
2743
help='Do not report commits with more than one parent.'),
2744
Option('exclude-common-ancestry',
2745
help='Display only the revisions that are not part'
2746
' of both ancestries (require -rX..Y).'
2748
Option('signatures',
2749
help='Show digital signature validity.'),
2752
help='Show revisions whose properties match this '
2755
ListOption('match-message',
2756
help='Show revisions whose message matches this '
2759
ListOption('match-committer',
2782
2760
help='Show revisions whose committer matches this '
2785
ListOption('match-author',
2763
ListOption('match-author',
2786
2764
help='Show revisions whose authors match this '
2789
ListOption('match-bugs',
2767
ListOption('match-bugs',
2790
2768
help='Show revisions whose bugs match this '
2794
2772
encoding_type = 'replace'
2796
2774
@display_command
3039
3018
_see_also = ['status', 'cat']
3040
3019
takes_args = ['path?']
3041
3020
takes_options = [
3044
Option('recursive', short_name='R',
3045
help='Recurse into subdirectories.'),
3047
help='Print paths relative to the root of the branch.'),
3048
Option('unknown', short_name='u',
3049
help='Print unknown files.'),
3050
Option('versioned', help='Print versioned files.',
3052
Option('ignored', short_name='i',
3053
help='Print ignored files.'),
3054
Option('kind', short_name='k',
3055
help='List entries of a particular kind: file, directory, symlink.',
3023
Option('recursive', short_name='R',
3024
help='Recurse into subdirectories.'),
3026
help='Print paths relative to the root of the branch.'),
3027
Option('unknown', short_name='u',
3028
help='Print unknown files.'),
3029
Option('versioned', help='Print versioned files.',
3031
Option('ignored', short_name='i',
3032
help='Print ignored files.'),
3033
Option('kind', short_name='k',
3034
help=('List entries of a particular kind: file, '
3035
'directory, symlink, tree-reference.'),
3061
3042
@display_command
3062
3043
def run(self, revision=None, verbose=False,
3063
3044
recursive=False, from_root=False,
3064
3045
unknown=False, versioned=False, ignored=False,
3065
3046
null=False, kind=None, show_ids=False, path=None, directory=None):
3067
if kind and kind not in ('file', 'directory', 'symlink'):
3048
if kind and kind not in ('file', 'directory', 'symlink', 'tree-reference'):
3068
3049
raise errors.BzrCommandError(gettext('invalid kind specified'))
3070
3051
if verbose and null:
3071
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
3052
raise errors.BzrCommandError(
3053
gettext('Cannot set both --verbose and --null'))
3072
3054
all = not (unknown or versioned or ignored)
3074
selection = {'I':ignored, '?':unknown, 'V':versioned}
3056
selection = {'I': ignored, '?': unknown, 'V': versioned}
3076
3058
if path is None:
3080
3062
raise errors.BzrCommandError(gettext('cannot specify both --from-root'
3083
3065
tree, branch, relpath = \
3084
3066
_open_directory_or_containing_tree_or_branch(fs_path, directory)
3439
3444
filters=False, directory=None):
3440
3445
if revision is not None and len(revision) != 1:
3441
3446
raise errors.BzrCommandError(gettext("brz cat --revision takes exactly"
3442
" one revision specifier"))
3447
" one revision specifier"))
3443
3448
tree, branch, relpath = \
3444
3449
_open_directory_or_containing_tree_or_branch(filename, directory)
3445
self.add_cleanup(branch.lock_read().unlock)
3450
self.enter_context(branch.lock_read())
3446
3451
return self._run(tree, branch, relpath, filename, revision,
3447
3452
name_from_revision, filters)
3449
3454
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
3451
3457
if tree is None:
3452
3458
tree = b.basis_tree()
3453
3459
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3454
self.add_cleanup(rev_tree.lock_read().unlock)
3456
old_file_id = rev_tree.path2id(relpath)
3458
# TODO: Split out this code to something that generically finds the
3459
# best id for a path across one or more trees; it's like
3460
# find_ids_across_trees but restricted to find just one. -- mbp
3460
self.enter_context(rev_tree.lock_read())
3462
3462
if name_from_revision:
3463
3463
# Try in revision if requested
3464
if old_file_id is None:
3464
if not rev_tree.is_versioned(relpath):
3465
3465
raise errors.BzrCommandError(gettext(
3466
3466
"{0!r} is not present in revision {1}").format(
3467
3467
filename, rev_tree.get_revision_id()))
3469
actual_file_id = old_file_id
3468
rev_tree_path = relpath
3471
cur_file_id = tree.path2id(relpath)
3472
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3473
actual_file_id = cur_file_id
3474
elif old_file_id is not None:
3475
actual_file_id = old_file_id
3477
raise errors.BzrCommandError(gettext(
3478
"{0!r} is not present in revision {1}").format(
3479
filename, rev_tree.get_revision_id()))
3471
rev_tree_path = _mod_tree.find_previous_path(
3472
tree, rev_tree, relpath)
3473
except errors.NoSuchFile:
3474
rev_tree_path = None
3476
if rev_tree_path is None:
3477
# Path didn't exist in working tree
3478
if not rev_tree.is_versioned(relpath):
3479
raise errors.BzrCommandError(gettext(
3480
"{0!r} is not present in revision {1}").format(
3481
filename, rev_tree.get_revision_id()))
3483
# Fall back to the same path in the basis tree, if present.
3484
rev_tree_path = relpath
3481
3487
from .filter_tree import ContentFilterTree
3482
filter_tree = ContentFilterTree(rev_tree,
3483
rev_tree._content_filter_stack)
3484
content = filter_tree.get_file_text(relpath, actual_file_id)
3488
filter_tree = ContentFilterTree(
3489
rev_tree, rev_tree._content_filter_stack)
3490
fileobj = filter_tree.get_file(rev_tree_path)
3486
content = rev_tree.get_file_text(relpath, actual_file_id)
3492
fileobj = rev_tree.get_file(rev_tree_path)
3493
shutil.copyfileobj(fileobj, self.outf)
3487
3494
self.cleanup_now()
3488
self.outf.write(content)
3491
3497
class cmd_local_time_offset(Command):
3492
3498
__doc__ = """Show the offset in seconds from GMT to local time."""
3494
3501
@display_command
3496
3503
self.outf.write("%s\n" % osutils.local_time_offset())
3500
3506
class cmd_commit(Command):
3501
3507
__doc__ = """Commit changes into a new revision.
3557
3563
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
3558
3564
takes_args = ['selected*']
3559
3565
takes_options = [
3560
ListOption('exclude', type=text_type, short_name='x',
3561
help="Do not consider changes made to a given path."),
3562
Option('message', type=text_type,
3564
help="Description of the new revision."),
3567
help='Commit even if nothing has changed.'),
3568
Option('file', type=text_type,
3571
help='Take commit message from this file.'),
3573
help="Refuse to commit if there are unknown "
3574
"files in the working tree."),
3575
Option('commit-time', type=text_type,
3576
help="Manually set a commit time using commit date "
3577
"format, e.g. '2009-10-10 08:00:00 +0100'."),
3578
ListOption('fixes', type=text_type,
3579
help="Mark a bug as being fixed by this revision "
3580
"(see \"brz help bugs\")."),
3581
ListOption('author', type=text_type,
3582
help="Set the author's name, if it's different "
3583
"from the committer."),
3585
help="Perform a local commit in a bound "
3586
"branch. Local commits are not pushed to "
3587
"the master branch until a normal commit "
3590
Option('show-diff', short_name='p',
3591
help='When no message is supplied, show the diff along'
3592
' with the status summary in the message editor.'),
3594
help='When committing to a foreign version control '
3595
'system do not push data that can not be natively '
3567
'exclude', type=str, short_name='x',
3568
help="Do not consider changes made to a given path."),
3569
Option('message', type=str,
3571
help="Description of the new revision."),
3574
help='Commit even if nothing has changed.'),
3575
Option('file', type=str,
3578
help='Take commit message from this file.'),
3580
help="Refuse to commit if there are unknown "
3581
"files in the working tree."),
3582
Option('commit-time', type=str,
3583
help="Manually set a commit time using commit date "
3584
"format, e.g. '2009-10-10 08:00:00 +0100'."),
3587
help="Link to a related bug. (see \"brz help bugs\")."),
3590
help="Mark a bug as being fixed by this revision "
3591
"(see \"brz help bugs\")."),
3594
help="Set the author's name, if it's different "
3595
"from the committer."),
3597
help="Perform a local commit in a bound "
3598
"branch. Local commits are not pushed to "
3599
"the master branch until a normal commit "
3602
Option('show-diff', short_name='p',
3603
help='When no message is supplied, show the diff along'
3604
' with the status summary in the message editor.'),
3606
help='When committing to a foreign version control '
3607
'system do not push data that can not be natively '
3598
3609
aliases = ['ci', 'checkin']
3600
def _iter_bug_fix_urls(self, fixes, branch):
3601
default_bugtracker = None
3611
def _iter_bug_urls(self, bugs, branch, status):
3612
default_bugtracker = None
3602
3613
# Configure the properties for bug fixing attributes.
3603
for fixed_bug in fixes:
3604
tokens = fixed_bug.split(':')
3615
tokens = bug.split(':')
3605
3616
if len(tokens) == 1:
3606
3617
if default_bugtracker is None:
3607
3618
branch_config = branch.get_config_stack()
4478
4502
change_reporter = delta._ChangeReporter(
4479
4503
unversioned_filter=tree.is_ignored, view_info=view_info)
4480
4504
pb = ui.ui_factory.nested_progress_bar()
4481
self.add_cleanup(pb.finished)
4482
self.add_cleanup(tree.lock_write().unlock)
4505
self.enter_context(pb)
4506
self.enter_context(tree.lock_write())
4483
4507
if location is not None:
4485
mergeable = bundle.read_mergeable_from_url(location,
4486
possible_transports=possible_transports)
4509
mergeable = _mod_mergeable.read_mergeable_from_url(
4510
location, possible_transports=possible_transports)
4487
4511
except errors.NotABundle:
4488
4512
mergeable = None
4490
4514
if uncommitted:
4491
4515
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4492
' with bundles or merge directives.'))
4516
' with bundles or merge directives.'))
4494
4518
if revision is not None:
4495
4519
raise errors.BzrCommandError(gettext(
4496
4520
'Cannot use -r with merge directives or bundles'))
4497
4521
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4500
4524
if merger is None and uncommitted:
4501
4525
if revision is not None and len(revision) > 0:
4502
4526
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4503
' --revision at the same time.'))
4527
' --revision at the same time.'))
4504
4528
merger = self.get_merger_from_uncommitted(tree, location, None)
4505
4529
allow_pending = False
4507
4531
if merger is None:
4508
4532
merger, allow_pending = self._get_merger_from_branch(tree,
4509
location, revision, remember, possible_transports, None)
4533
location, revision, remember, possible_transports, None)
4511
4535
merger.merge_type = merge_type
4512
4536
merger.reprocess = reprocess
4513
4537
merger.show_base = show_base
4514
4538
self.sanity_check_merger(merger)
4515
4539
if (merger.base_rev_id == merger.other_rev_id and
4516
merger.other_rev_id is not None):
4540
merger.other_rev_id is not None):
4517
4541
# check if location is a nonexistent file (and not a branch) to
4518
4542
# disambiguate the 'Nothing to do'
4519
4543
if merger.interesting_files:
4520
4544
if not merger.other_tree.has_filename(
4521
merger.interesting_files[0]):
4545
merger.interesting_files[0]):
4522
4546
note(gettext("merger: ") + str(merger))
4523
4547
raise errors.PathsDoNotExist([location])
4524
4548
note(gettext('Nothing to do.'))
4526
4550
if pull and not preview:
4527
4551
if merger.interesting_files is not None:
4528
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4552
raise errors.BzrCommandError(
4553
gettext('Cannot pull individual files'))
4529
4554
if (merger.base_rev_id == tree.last_revision()):
4530
4555
result = tree.pull(merger.other_branch, False,
4531
4556
merger.other_rev_id)
4757
4792
if merge_type is None:
4758
4793
merge_type = _mod_merge.Merge3Merger
4759
4794
tree, file_list = WorkingTree.open_containing_paths(file_list)
4760
self.add_cleanup(tree.lock_write().unlock)
4795
self.enter_context(tree.lock_write())
4761
4796
parents = tree.get_parent_ids()
4762
4797
if len(parents) != 2:
4763
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4764
" merges. Not cherrypicking or"
4766
repository = tree.branch.repository
4767
interesting_ids = None
4798
raise errors.BzrCommandError(
4799
gettext("Sorry, remerge only works after normal"
4800
" merges. Not cherrypicking or multi-merges."))
4801
interesting_files = None
4768
4802
new_conflicts = []
4769
4803
conflicts = tree.conflicts()
4770
4804
if file_list is not None:
4771
interesting_ids = set()
4805
interesting_files = set()
4772
4806
for filename in file_list:
4773
file_id = tree.path2id(filename)
4807
if not tree.is_versioned(filename):
4775
4808
raise errors.NotVersionedError(filename)
4776
interesting_ids.add(file_id)
4777
if tree.kind(filename, file_id) != "directory":
4809
interesting_files.add(filename)
4810
if tree.kind(filename) != "directory":
4780
# FIXME: Support nested trees
4781
for name, ie in tree.root_inventory.iter_entries(file_id):
4782
interesting_ids.add(ie.file_id)
4813
for path, ie in tree.iter_entries_by_dir(
4814
specific_files=[filename]):
4815
interesting_files.add(path)
4783
4816
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4785
4818
# Remerge only supports resolving contents conflicts
4786
4819
allowed_conflicts = ('text conflict', 'contents conflict')
4787
4820
restore_files = [c.path for c in conflicts
4788
4821
if c.typestring in allowed_conflicts]
4789
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4822
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_files)
4790
4823
tree.set_conflicts(ConflictList(new_conflicts))
4791
4824
if file_list is not None:
4792
4825
restore_files = file_list
5253
5289
wt, branch, relpath = \
5254
5290
_open_directory_or_containing_tree_or_branch(filename, directory)
5255
5291
if wt is not None:
5256
self.add_cleanup(wt.lock_read().unlock)
5292
self.enter_context(wt.lock_read())
5258
self.add_cleanup(branch.lock_read().unlock)
5294
self.enter_context(branch.lock_read())
5259
5295
tree = _get_one_revision_tree('annotate', revision, branch=branch)
5260
self.add_cleanup(tree.lock_read().unlock)
5261
if wt is not None and revision is None:
5262
file_id = wt.path2id(relpath)
5264
file_id = tree.path2id(relpath)
5266
raise errors.NotVersionedError(filename)
5267
if wt is not None and revision is None:
5296
self.enter_context(tree.lock_read())
5297
if wt is not None and revision is None:
5298
if not wt.is_versioned(relpath):
5299
raise errors.NotVersionedError(relpath)
5268
5300
# If there is a tree and we're not annotating historical
5269
5301
# versions, annotate the working tree's content.
5270
5302
annotate_file_tree(wt, relpath, self.outf, long, all,
5271
show_ids=show_ids, file_id=file_id)
5305
if not tree.is_versioned(relpath):
5306
raise errors.NotVersionedError(relpath)
5273
5307
annotate_file_tree(tree, relpath, self.outf, long, all,
5274
show_ids=show_ids, branch=branch, file_id=file_id)
5308
show_ids=show_ids, branch=branch)
5277
5311
class cmd_re_sign(Command):
5278
5312
__doc__ = """Create a digital signature for an existing revision."""
5279
5313
# TODO be able to replace existing ones.
5281
hidden = True # is this right ?
5315
hidden = True # is this right ?
5282
5316
takes_args = ['revision_id*']
5283
5317
takes_options = ['directory', 'revision']
5285
5319
def run(self, revision_id_list=None, revision=None, directory=u'.'):
5286
5320
if revision_id_list is not None and revision is not None:
5287
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
5321
raise errors.BzrCommandError(
5322
gettext('You can only supply one of revision_id or --revision'))
5288
5323
if revision_id_list is None and revision is None:
5289
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
5324
raise errors.BzrCommandError(
5325
gettext('You must supply either --revision or a revision_id'))
5290
5326
b = WorkingTree.open_containing(directory)[0].branch
5291
self.add_cleanup(b.lock_write().unlock)
5327
self.enter_context(b.lock_write())
5292
5328
return self._run(b, revision_id_list, revision)
5294
5330
def _run(self, b, revision_id_list, revision):
5331
from .repository import WriteGroup
5296
5332
gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
5297
5333
if revision_id_list is not None:
5298
b.repository.start_write_group()
5334
with WriteGroup(b.repository):
5300
5335
for revision_id in revision_id_list:
5301
5336
revision_id = cache_utf8.encode(revision_id)
5302
5337
b.repository.sign_revision(revision_id, gpg_strategy)
5304
b.repository.abort_write_group()
5307
b.repository.commit_write_group()
5308
5338
elif revision is not None:
5309
5339
if len(revision) == 1:
5310
5340
revno, rev_id = revision[0].in_history(b)
5311
b.repository.start_write_group()
5341
with WriteGroup(b.repository):
5313
5342
b.repository.sign_revision(rev_id, gpg_strategy)
5315
b.repository.abort_write_group()
5318
b.repository.commit_write_group()
5319
5343
elif len(revision) == 2:
5320
5344
# are they both on rh- if so we can walk between them
5321
5345
# might be nice to have a range helper for arbitrary
6317
6342
except errors.NotBranchError:
6319
6344
had_explicit_nick = False
6346
possible_transports.append(branch.user_transport)
6320
6347
if create_branch:
6321
6348
if branch is None:
6322
6349
raise errors.BzrCommandError(
6323
6350
gettext('cannot create branch without source branch'))
6324
to_location = lookup_new_sibling_branch(control_dir, to_location,
6325
possible_transports=possible_transports)
6326
to_branch = branch.controldir.sprout(to_location,
6327
possible_transports=possible_transports,
6328
source_branch=branch).open_branch()
6351
to_location = lookup_new_sibling_branch(
6352
control_dir, to_location,
6353
possible_transports=possible_transports)
6354
if revision is not None:
6355
revision = revision.as_revision_id(branch)
6356
to_branch = branch.controldir.sprout(
6358
possible_transports=possible_transports,
6359
revision_id=revision,
6360
source_branch=branch).open_branch()
6331
to_branch = Branch.open(to_location,
6332
possible_transports=possible_transports)
6363
to_branch = Branch.open(
6364
to_location, possible_transports=possible_transports)
6333
6365
except errors.NotBranchError:
6334
to_branch = open_sibling_branch(control_dir, to_location,
6366
to_branch = open_sibling_branch(
6367
control_dir, to_location,
6335
6368
possible_transports=possible_transports)
6336
if revision is not None:
6337
revision = revision.as_revision_id(to_branch)
6338
switch.switch(control_dir, to_branch, force, revision_id=revision,
6339
store_uncommitted=store)
6369
if revision is not None:
6370
revision = revision.as_revision_id(to_branch)
6371
possible_transports.append(to_branch.user_transport)
6373
switch.switch(control_dir, to_branch, force, revision_id=revision,
6374
store_uncommitted=store,
6375
possible_transports=possible_transports)
6376
except controldir.BranchReferenceLoop:
6377
raise errors.BzrCommandError(
6378
gettext('switching would create a branch reference loop. '
6379
'Use the "bzr up" command to switch to a '
6380
'different revision.'))
6340
6381
if had_explicit_nick:
6341
branch = control_dir.open_branch() #get the new branch!
6382
branch = control_dir.open_branch() # get the new branch!
6342
6383
branch.nick = to_branch.nick
6343
note(gettext('Switched to branch: %s'),
6344
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6385
if to_branch.controldir.control_url != control_dir.control_url:
6386
note(gettext('Switched to branch %s at %s'),
6387
to_branch.name, urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6389
note(gettext('Switched to branch %s'), to_branch.name)
6391
note(gettext('Switched to branch at %s'),
6392
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6348
6395
class cmd_view(Command):
6725
6779
takes_args = ['path?', 'location?']
6782
Option('force-unversioned',
6783
help='Set reference even if path is not versioned.'),
6727
def run(self, path=None, location=None):
6729
if path is not None:
6731
tree, branch, relpath =(
6732
controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6733
if path is not None:
6786
def run(self, path=None, directory='.', location=None, force_unversioned=False):
6787
tree, branch, relpath = (
6788
controldir.ControlDir.open_containing_tree_or_branch(directory))
6735
6789
if tree is None:
6736
6790
tree = branch.basis_tree()
6737
6791
if path is None:
6738
info = viewitems(branch._get_all_reference_info())
6739
self._display_reference_info(tree, branch, info)
6792
with tree.lock_read():
6794
(path, tree.get_reference_info(path, branch))
6795
for path in tree.iter_references()]
6796
self._display_reference_info(tree, branch, info)
6741
file_id = tree.path2id(path)
6798
if not tree.is_versioned(path) and not force_unversioned:
6743
6799
raise errors.NotVersionedError(path)
6744
6800
if location is None:
6745
info = [(file_id, branch.get_reference_info(file_id))]
6801
info = [(path, tree.get_reference_info(path, branch))]
6746
6802
self._display_reference_info(tree, branch, info)
6748
branch.set_reference_info(file_id, path, location)
6804
tree.set_reference_info(path, location)
6750
6806
def _display_reference_info(self, tree, branch, info):
6752
for file_id, (path, location) in info:
6754
path = tree.id2path(file_id)
6755
except errors.NoSuchId:
6808
for path, location in info:
6757
6809
ref_list.append((path, location))
6758
6810
for path, location in sorted(ref_list):
6759
6811
self.outf.write('%s %s\n' % (path, location))
6838
6883
if len(installed) > 0:
6839
6884
self.outf.write("Installed:\n")
6840
6885
for rev in installed:
6841
self.outf.write(rev + "\n")
6886
self.outf.write(rev.decode('utf-8') + "\n")
6842
6887
if len(failed) > 0:
6843
6888
self.outf.write("Still missing:\n")
6844
6889
for rev in failed:
6845
self.outf.write(rev + "\n")
6890
self.outf.write(rev.decode('utf-8') + "\n")
6846
6891
if not no_fix and len(installed) > 0:
6847
6892
cmd_reconcile().run(".")
6895
class cmd_grep(Command):
6896
"""Print lines matching PATTERN for specified files and revisions.
6898
This command searches the specified files and revisions for a given
6899
pattern. The pattern is specified as a Python regular expressions[1].
6901
If the file name is not specified, the revisions starting with the
6902
current directory are searched recursively. If the revision number is
6903
not specified, the working copy is searched. To search the last committed
6904
revision, use the '-r -1' or '-r last:1' option.
6906
Unversioned files are not searched unless explicitly specified on the
6907
command line. Unversioned directores are not searched.
6909
When searching a pattern, the output is shown in the 'filepath:string'
6910
format. If a revision is explicitly searched, the output is shown as
6911
'filepath~N:string', where N is the revision number.
6913
--include and --exclude options can be used to search only (or exclude
6914
from search) files with base name matches the specified Unix style GLOB
6915
pattern. The GLOB pattern an use *, ?, and [...] as wildcards, and \\
6916
to quote wildcard or backslash character literally. Note that the glob
6917
pattern is not a regular expression.
6919
[1] http://docs.python.org/library/re.html#regular-expression-syntax
6922
encoding_type = 'replace'
6923
takes_args = ['pattern', 'path*']
6927
Option('color', type=str, argname='when',
6928
help='Show match in color. WHEN is never, always or auto.'),
6929
Option('diff', short_name='p',
6930
help='Grep for pattern in changeset for each revision.'),
6931
ListOption('exclude', type=str, argname='glob', short_name='X',
6932
help="Skip files whose base name matches GLOB."),
6933
ListOption('include', type=str, argname='glob', short_name='I',
6934
help="Search only files whose base name matches GLOB."),
6935
Option('files-with-matches', short_name='l',
6936
help='Print only the name of each input file in '
6937
'which PATTERN is found.'),
6938
Option('files-without-match', short_name='L',
6939
help='Print only the name of each input file in '
6940
'which PATTERN is not found.'),
6941
Option('fixed-string', short_name='F',
6942
help='Interpret PATTERN is a single fixed string (not regex).'),
6944
help='Search for pattern starting from the root of the branch. '
6945
'(implies --recursive)'),
6946
Option('ignore-case', short_name='i',
6947
help='Ignore case distinctions while matching.'),
6949
help='Number of levels to display - 0 for all, 1 for collapsed '
6952
type=_parse_levels),
6953
Option('line-number', short_name='n',
6954
help='Show 1-based line number.'),
6955
Option('no-recursive',
6956
help="Don't recurse into subdirectories. (default is --recursive)"),
6957
Option('null', short_name='Z',
6958
help='Write an ASCII NUL (\\0) separator '
6959
'between output lines rather than a newline.'),
6963
def run(self, verbose=False, ignore_case=False, no_recursive=False,
6964
from_root=False, null=False, levels=None, line_number=False,
6965
path_list=None, revision=None, pattern=None, include=None,
6966
exclude=None, fixed_string=False, files_with_matches=False,
6967
files_without_match=False, color=None, diff=False):
6968
from breezy import _termcolor
6971
if path_list is None:
6975
raise errors.BzrCommandError(
6976
'cannot specify both --from-root and PATH.')
6978
if files_with_matches and files_without_match:
6979
raise errors.BzrCommandError(
6980
'cannot specify both '
6981
'-l/--files-with-matches and -L/--files-without-matches.')
6983
global_config = _mod_config.GlobalConfig()
6986
color = global_config.get_user_option('grep_color')
6991
if color not in ['always', 'never', 'auto']:
6992
raise errors.BzrCommandError('Valid values for --color are '
6993
'"always", "never" or "auto".')
6999
if revision is not None or levels == 0:
7000
# print revision numbers as we may be showing multiple revisions
7007
if not ignore_case and grep.is_fixed_string(pattern):
7008
# if the pattern isalnum, implicitly use to -F for faster grep
7010
elif ignore_case and fixed_string:
7011
# GZ 2010-06-02: Fall back to regexp rather than lowercasing
7012
# pattern and text which will cause pain later
7013
fixed_string = False
7014
pattern = re.escape(pattern)
7017
re_flags = re.MULTILINE
7019
re_flags |= re.IGNORECASE
7021
if not fixed_string:
7022
patternc = grep.compile_pattern(
7023
pattern.encode(grep._user_encoding), re_flags)
7025
if color == 'always':
7027
elif color == 'never':
7029
elif color == 'auto':
7030
show_color = _termcolor.allow_color()
7032
opts = grep.GrepOptions()
7034
opts.verbose = verbose
7035
opts.ignore_case = ignore_case
7036
opts.no_recursive = no_recursive
7037
opts.from_root = from_root
7039
opts.levels = levels
7040
opts.line_number = line_number
7041
opts.path_list = path_list
7042
opts.revision = revision
7043
opts.pattern = pattern
7044
opts.include = include
7045
opts.exclude = exclude
7046
opts.fixed_string = fixed_string
7047
opts.files_with_matches = files_with_matches
7048
opts.files_without_match = files_without_match
7052
opts.eol_marker = eol_marker
7053
opts.print_revno = print_revno
7054
opts.patternc = patternc
7055
opts.recursive = not no_recursive
7056
opts.fixed_string = fixed_string
7057
opts.outf = self.outf
7058
opts.show_color = show_color
7062
# files_with_matches, files_without_match
7063
# levels(?), line_number, from_root
7065
# These are silently ignored.
7066
grep.grep_diff(opts)
7067
elif revision is None:
7068
grep.workingtree_grep(opts)
7070
grep.versioned_grep(opts)
7073
class cmd_patch(Command):
7074
"""Apply a named patch to the current tree.
7078
takes_args = ['filename?']
7079
takes_options = [Option('strip', type=int, short_name='p',
7080
help=("Strip the smallest prefix containing num "
7081
"leading slashes from filenames.")),
7082
Option('silent', help='Suppress chatter.')]
7084
def run(self, filename=None, strip=None, silent=False):
7085
from .patch import patch_tree
7086
wt = WorkingTree.open_containing('.')[0]
7090
if filename is None:
7091
my_file = getattr(sys.stdin, 'buffer', sys.stdin)
7093
my_file = open(filename, 'rb')
7094
patches = [my_file.read()]
7095
return patch_tree(wt, patches, strip, quiet=is_quiet(), out=self.outf)
7098
class cmd_resolve_location(Command):
7099
__doc__ = """Expand a location to a full URL.
7102
Look up a Launchpad URL.
7104
brz resolve-location lp:brz
7106
takes_args = ['location']
7109
def run(self, location):
7110
from .location import location_to_url
7111
url = location_to_url(location)
7112
display_url = urlutils.unescape_for_display(url, self.outf.encoding)
7113
self.outf.write('%s\n' % display_url)
6850
7116
def _register_lazy_builtins():
6851
7117
# register lazy builtins from other modules; called at startup and should
6852
7118
# be only called once.
6853
7119
for (name, aliases, module_name) in [
6854
('cmd_bisect', [], 'breezy.bisect'),
6855
('cmd_bundle_info', [], 'breezy.bundle.commands'),
6856
('cmd_config', [], 'breezy.config'),
6857
('cmd_dpush', [], 'breezy.foreign'),
6858
('cmd_version_info', [], 'breezy.cmd_version_info'),
6859
('cmd_resolve', ['resolved'], 'breezy.conflicts'),
6860
('cmd_conflicts', [], 'breezy.conflicts'),
6861
('cmd_ping', [], 'breezy.bzr.smart.ping'),
6862
('cmd_sign_my_commits', [], 'breezy.commit_signature_commands'),
6863
('cmd_verify_signatures', [], 'breezy.commit_signature_commands'),
6864
('cmd_test_script', [], 'breezy.cmd_test_script'),
7120
('cmd_bisect', [], 'breezy.bisect'),
7121
('cmd_bundle_info', [], 'breezy.bzr.bundle.commands'),
7122
('cmd_config', [], 'breezy.config'),
7123
('cmd_dump_btree', [], 'breezy.bzr.debug_commands'),
7124
('cmd_file_id', [], 'breezy.bzr.debug_commands'),
7125
('cmd_file_path', [], 'breezy.bzr.debug_commands'),
7126
('cmd_version_info', [], 'breezy.cmd_version_info'),
7127
('cmd_resolve', ['resolved'], 'breezy.conflicts'),
7128
('cmd_conflicts', [], 'breezy.conflicts'),
7129
('cmd_ping', [], 'breezy.bzr.smart.ping'),
7130
('cmd_sign_my_commits', [], 'breezy.commit_signature_commands'),
7131
('cmd_verify_signatures', [], 'breezy.commit_signature_commands'),
7132
('cmd_test_script', [], 'breezy.cmd_test_script'),
6866
7134
builtin_command_registry.register_lazy(name, aliases, module_name)