235
def _open_directory_or_containing_tree_or_branch(filename, directory):
236
"""Open the tree or branch containing the specified file, unless
237
the --directory option is used to specify a different branch."""
238
if directory is not None:
239
return (None, Branch.open(directory), filename)
240
return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
235
243
# TODO: Make sure no commands unconditionally use the working directory as a
236
244
# branch. If a filename argument is used, the first of them should be used to
237
245
# specify the branch. (Perhaps this can be factored out into some kind of
342
350
takes_args = ['revision_id?']
343
takes_options = ['revision']
351
takes_options = ['directory', 'revision']
344
352
# cat-revision is more for frontends so should be exact
345
353
encoding = 'strict'
353
361
self.outf.write(revtext.decode('utf-8'))
356
def run(self, revision_id=None, revision=None):
364
def run(self, revision_id=None, revision=None, directory=u'.'):
357
365
if revision_id is not None and revision is not None:
358
366
raise errors.BzrCommandError('You can only supply one of'
359
367
' revision_id or --revision')
360
368
if revision_id is None and revision is None:
361
369
raise errors.BzrCommandError('You must supply either'
362
370
' --revision or a revision_id')
363
b = WorkingTree.open_containing(u'.')[0].branch
371
b = WorkingTree.open_containing(directory)[0].branch
365
373
revisions = b.repository.revisions
366
374
if revisions is None:
483
491
takes_options = [
485
493
help='Remove the working tree even if it has '
486
'uncommitted changes.'),
494
'uncommitted or shelved changes.'),
489
497
def run(self, location_list, force=False):
504
512
if (working.has_changes()):
505
513
raise errors.UncommittedChanges(working)
514
if working.get_shelf_manager().last_shelf() is not None:
515
raise errors.ShelvedChanges(working)
507
517
if working.user_url != working.branch.user_url:
508
518
raise errors.BzrCommandError("You cannot remove the working tree"
530
540
wt = WorkingTree.open_containing(location)[0]
541
self.add_cleanup(wt.lock_read().unlock)
532
542
except (errors.NoWorkingTree, errors.NotLocalUrl):
533
543
raise errors.NoWorkingTree(location)
534
self.add_cleanup(wt.unlock)
535
544
revid = wt.last_revision()
537
546
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
540
549
revno = ".".join(str(n) for n in revno_t)
542
551
b = Branch.open_containing(location)[0]
544
self.add_cleanup(b.unlock)
552
self.add_cleanup(b.lock_read().unlock)
545
553
revno = b.revno()
546
554
self.cleanup_now()
547
555
self.outf.write(str(revno) + '\n')
554
562
takes_args = ['revision_info*']
555
563
takes_options = [
565
custom_help('directory',
558
566
help='Branch to examine, '
559
'rather than the one containing the working directory.',
567
'rather than the one containing the working directory.'),
563
568
Option('tree', help='Show revno of working tree'),
571
576
wt = WorkingTree.open_containing(directory)[0]
574
self.add_cleanup(wt.unlock)
578
self.add_cleanup(wt.lock_read().unlock)
575
579
except (errors.NoWorkingTree, errors.NotLocalUrl):
577
581
b = Branch.open_containing(directory)[0]
579
self.add_cleanup(b.unlock)
582
self.add_cleanup(b.lock_read().unlock)
580
583
revision_ids = []
581
584
if revision is not None:
582
585
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
681
684
should_print=(not is_quiet()))
684
base_tree.lock_read()
685
self.add_cleanup(base_tree.unlock)
687
self.add_cleanup(base_tree.lock_read().unlock)
686
688
tree, file_list = tree_files_for_add(file_list)
687
689
added, ignored = tree.smart_add(file_list, not
688
690
no_recurse, action=action, save=not dry_run)
761
763
revision = _get_one_revision('inventory', revision)
762
764
work_tree, file_list = tree_files(file_list)
763
work_tree.lock_read()
764
self.add_cleanup(work_tree.unlock)
765
self.add_cleanup(work_tree.lock_read().unlock)
765
766
if revision is not None:
766
767
tree = revision.as_tree(work_tree.branch)
768
769
extra_trees = [work_tree]
770
self.add_cleanup(tree.unlock)
770
self.add_cleanup(tree.lock_read().unlock)
833
833
if len(names_list) < 2:
834
834
raise errors.BzrCommandError("missing file argument")
835
835
tree, rel_names = tree_files(names_list, canonicalize=False)
836
tree.lock_tree_write()
837
self.add_cleanup(tree.unlock)
836
self.add_cleanup(tree.lock_tree_write().unlock)
838
837
self._run(tree, names_list, rel_names, after)
840
839
def run_auto(self, names_list, after, dry_run):
845
844
raise errors.BzrCommandError('--after cannot be specified with'
847
846
work_tree, file_list = tree_files(names_list, default_branch='.')
848
work_tree.lock_tree_write()
849
self.add_cleanup(work_tree.unlock)
847
self.add_cleanup(work_tree.lock_tree_write().unlock)
850
848
rename_map.RenameMap.guess_renames(work_tree, dry_run)
852
850
def _run(self, tree, names_list, rel_names, after):
960
958
takes_options = ['remember', 'overwrite', 'revision',
961
959
custom_help('verbose',
962
960
help='Show logs of pulled revisions.'),
961
custom_help('directory',
964
962
help='Branch to pull into, '
965
'rather than the one containing the working directory.',
963
'rather than the one containing the working directory.'),
970
965
help="Perform a local pull in a bound "
971
966
"branch. Local pulls are not applied to "
987
982
tree_to = WorkingTree.open_containing(directory)[0]
988
983
branch_to = tree_to.branch
990
self.add_cleanup(tree_to.unlock)
984
self.add_cleanup(tree_to.lock_write().unlock)
991
985
except errors.NoWorkingTree:
993
987
branch_to = Branch.open_containing(directory)[0]
994
branch_to.lock_write()
995
self.add_cleanup(branch_to.unlock)
988
self.add_cleanup(branch_to.lock_write().unlock)
997
990
if local and not branch_to.get_bound_location():
998
991
raise errors.LocalRequiresBoundBranch()
1030
1023
branch_from = Branch.open(location,
1031
1024
possible_transports=possible_transports)
1032
branch_from.lock_read()
1033
self.add_cleanup(branch_from.unlock)
1025
self.add_cleanup(branch_from.lock_read().unlock)
1035
1027
if branch_to.get_parent() is None or remember:
1036
1028
branch_to.set_parent(branch_from.base)
1088
1080
Option('create-prefix',
1089
1081
help='Create the path leading up to the branch '
1090
1082
'if it does not already exist.'),
1083
custom_help('directory',
1092
1084
help='Branch to push from, '
1093
'rather than the one containing the working directory.',
1085
'rather than the one containing the working directory.'),
1097
1086
Option('use-existing-dir',
1098
1087
help='By default push will fail if the target'
1099
1088
' directory exists, but does not already'
1219
1208
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1221
1210
revision = _get_one_revision('branch', revision)
1223
self.add_cleanup(br_from.unlock)
1211
self.add_cleanup(br_from.lock_read().unlock)
1224
1212
if revision is not None:
1225
1213
revision_id = revision.as_revision_id(br_from)
1366
1354
@display_command
1367
1355
def run(self, dir=u'.'):
1368
1356
tree = WorkingTree.open_containing(dir)[0]
1370
self.add_cleanup(tree.unlock)
1357
self.add_cleanup(tree.lock_read().unlock)
1371
1358
new_inv = tree.inventory
1372
1359
old_tree = tree.basis_tree()
1373
old_tree.lock_read()
1374
self.add_cleanup(old_tree.unlock)
1360
self.add_cleanup(old_tree.lock_read().unlock)
1375
1361
old_inv = old_tree.inventory
1377
1363
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1415
1401
master = branch.get_master_branch(
1416
1402
possible_transports=possible_transports)
1417
1403
if master is not None:
1419
1404
branch_location = master.base
1407
branch_location = tree.branch.base
1421
1408
tree.lock_tree_write()
1422
branch_location = tree.branch.base
1423
1409
self.add_cleanup(tree.unlock)
1424
1410
# get rid of the final '/' and be ready for display
1425
1411
branch_location = urlutils.unescape_for_display(
1519
1505
class cmd_remove(Command):
1520
1506
__doc__ = """Remove files or directories.
1522
This makes bzr stop tracking changes to the specified files. bzr will delete
1523
them if they can easily be recovered using revert. If no options or
1524
parameters are given bzr will scan for files that are being tracked by bzr
1525
but missing in your tree and stop tracking them for you.
1508
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1509
delete them if they can easily be recovered using revert otherwise they
1510
will be backed up (adding an extention of the form .~#~). If no options or
1511
parameters are given Bazaar will scan for files that are being tracked by
1512
Bazaar but missing in your tree and stop tracking them for you.
1527
1514
takes_args = ['file*']
1528
1515
takes_options = ['verbose',
1530
1517
RegistryOption.from_kwargs('file-deletion-strategy',
1531
1518
'The file deletion mode to be used.',
1532
1519
title='Deletion Strategy', value_switches=True, enum_switch=False,
1533
safe='Only delete files if they can be'
1534
' safely recovered (default).',
1520
safe='Backup changed files (default).',
1535
1521
keep='Delete from bzr but leave the working copy.',
1536
1522
force='Delete all the specified files, even if they can not be '
1537
1523
'recovered and even if they are non-empty directories.')]
1545
1531
if file_list is not None:
1546
1532
file_list = [f for f in file_list]
1549
self.add_cleanup(tree.unlock)
1534
self.add_cleanup(tree.lock_write().unlock)
1550
1535
# Heuristics should probably all move into tree.remove_smart or
1985
1970
old_branch, new_branch,
1986
1971
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1987
1972
file_list, revision, old, new, self.add_cleanup, apply_view=True)
1973
# GNU diff on Windows uses ANSI encoding for filenames
1974
path_encoding = osutils.get_diff_header_encoding()
1988
1975
return show_diff_trees(old_tree, new_tree, sys.stdout,
1989
1976
specific_files=specific_files,
1990
1977
external_diff_options=diff_options,
1991
1978
old_label=old_label, new_label=new_label,
1992
extra_trees=extra_trees, using=using,
1979
extra_trees=extra_trees,
1980
path_encoding=path_encoding,
1993
1982
format_cls=format)
2003
1992
# level of effort but possibly much less IO. (Or possibly not,
2004
1993
# if the directories are very large...)
2005
1994
_see_also = ['status', 'ls']
2006
takes_options = ['show-ids']
1995
takes_options = ['directory', 'show-ids']
2008
1997
@display_command
2009
def run(self, show_ids=False):
2010
tree = WorkingTree.open_containing(u'.')[0]
2012
self.add_cleanup(tree.unlock)
1998
def run(self, show_ids=False, directory=u'.'):
1999
tree = WorkingTree.open_containing(directory)[0]
2000
self.add_cleanup(tree.lock_read().unlock)
2013
2001
old = tree.basis_tree()
2015
self.add_cleanup(old.unlock)
2002
self.add_cleanup(old.lock_read().unlock)
2016
2003
for path, ie in old.inventory.iter_entries():
2017
2004
if not tree.has_id(ie.file_id):
2018
2005
self.outf.write(path)
2030
2017
_see_also = ['status', 'ls']
2033
help='Write an ascii NUL (\\0) separator '
2034
'between files rather than a newline.')
2018
takes_options = ['directory', 'null']
2037
2020
@display_command
2038
def run(self, null=False):
2039
tree = WorkingTree.open_containing(u'.')[0]
2021
def run(self, null=False, directory=u'.'):
2022
tree = WorkingTree.open_containing(directory)[0]
2040
2023
td = tree.changes_from(tree.basis_tree())
2041
2024
for path, id, kind, text_modified, meta_modified in td.modified:
2053
2036
_see_also = ['status', 'ls']
2056
help='Write an ascii NUL (\\0) separator '
2057
'between files rather than a newline.')
2037
takes_options = ['directory', 'null']
2060
2039
@display_command
2061
def run(self, null=False):
2062
wt = WorkingTree.open_containing(u'.')[0]
2064
self.add_cleanup(wt.unlock)
2040
def run(self, null=False, directory=u'.'):
2041
wt = WorkingTree.open_containing(directory)[0]
2042
self.add_cleanup(wt.lock_read().unlock)
2065
2043
basis = wt.basis_tree()
2067
self.add_cleanup(basis.unlock)
2044
self.add_cleanup(basis.lock_read().unlock)
2068
2045
basis_inv = basis.inventory
2069
2046
inv = wt.inventory
2070
2047
for file_id in inv:
2073
2050
if inv.is_root(file_id) and len(basis_inv) == 0:
2075
2052
path = inv.id2path(file_id)
2076
if not os.access(osutils.abspath(path), os.F_OK):
2053
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2079
2056
self.outf.write(path + '\0')
2279
2256
help='Show just the specified revision.'
2280
2257
' See also "help revisionspec".'),
2259
RegistryOption('authors',
2260
'What names to list as authors - first, all or committer.',
2262
lazy_registry=('bzrlib.log', 'author_list_registry'),
2282
2264
Option('levels',
2283
2265
short_name='n',
2284
2266
help='Number of levels to display - 0 for all, 1 for flat.',
2353
2336
# find the file ids to log and check for directory filtering
2354
2337
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2355
revision, file_list)
2356
self.add_cleanup(b.unlock)
2338
revision, file_list, self.add_cleanup)
2357
2339
for relpath, file_id, kind in file_info_list:
2358
2340
if file_id is None:
2359
2341
raise errors.BzrCommandError(
2378
2360
dir, relpath = bzrdir.BzrDir.open_containing(location)
2379
2361
b = dir.open_branch()
2381
self.add_cleanup(b.unlock)
2362
self.add_cleanup(b.lock_read().unlock)
2382
2363
rev1, rev2 = _get_revision_range(revision, b, self.name())
2384
2365
# Decide on the type of delta & diff filtering to use
2404
2385
show_timezone=timezone,
2405
2386
delta_format=get_verbosity_level(),
2407
show_advice=levels is None)
2388
show_advice=levels is None,
2389
author_list_handler=authors)
2409
2391
# Choose the algorithm for doing the logging. It's annoying
2410
2392
# having multiple code paths like this but necessary until
2508
2490
tree, relpath = WorkingTree.open_containing(filename)
2509
2491
file_id = tree.path2id(relpath)
2510
2492
b = tree.branch
2512
self.add_cleanup(b.unlock)
2493
self.add_cleanup(b.lock_read().unlock)
2513
2494
touching_revs = log.find_touching_revisions(b, file_id)
2514
2495
for revno, revision_id, what in touching_revs:
2515
2496
self.outf.write("%6d %s\n" % (revno, what))
2528
2509
help='Recurse into subdirectories.'),
2529
2510
Option('from-root',
2530
2511
help='Print paths relative to the root of the branch.'),
2531
Option('unknown', help='Print unknown files.'),
2512
Option('unknown', short_name='u',
2513
help='Print unknown files.'),
2532
2514
Option('versioned', help='Print versioned files.',
2533
2515
short_name='V'),
2534
Option('ignored', help='Print ignored files.'),
2536
help='Write an ascii NUL (\\0) separator '
2537
'between files rather than a newline.'),
2516
Option('ignored', short_name='i',
2517
help='Print ignored files.'),
2518
Option('kind', short_name='k',
2539
2519
help='List entries of a particular kind: file, directory, symlink.',
2543
2525
@display_command
2544
2526
def run(self, revision=None, verbose=False,
2545
2527
recursive=False, from_root=False,
2546
2528
unknown=False, versioned=False, ignored=False,
2547
null=False, kind=None, show_ids=False, path=None):
2529
null=False, kind=None, show_ids=False, path=None, directory=None):
2549
2531
if kind and kind not in ('file', 'directory', 'symlink'):
2550
2532
raise errors.BzrCommandError('invalid kind specified')
2562
2544
raise errors.BzrCommandError('cannot specify both --from-root'
2565
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2547
tree, branch, relpath = \
2548
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2568
2550
# Calculate the prefix to use
2584
2566
view_str = views.view_display_str(view_files)
2585
2567
note("Ignoring files outside view. View is %s" % view_str)
2588
self.add_cleanup(tree.unlock)
2569
self.add_cleanup(tree.lock_read().unlock)
2589
2570
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2590
2571
from_dir=relpath, recursive=recursive):
2591
2572
# Apply additional masking
2640
2621
_see_also = ['ls']
2622
takes_options = ['directory']
2642
2624
@display_command
2644
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2625
def run(self, directory=u'.'):
2626
for f in WorkingTree.open_containing(directory)[0].unknowns():
2645
2627
self.outf.write(osutils.quotefn(f) + '\n')
2713
2695
_see_also = ['status', 'ignored', 'patterns']
2714
2696
takes_args = ['name_pattern*']
2697
takes_options = ['directory',
2716
2698
Option('default-rules',
2717
2699
help='Display the default ignore rules that bzr uses.')
2720
def run(self, name_pattern_list=None, default_rules=None):
2702
def run(self, name_pattern_list=None, default_rules=None,
2721
2704
from bzrlib import ignores
2722
2705
if default_rules is not None:
2723
2706
# dump the default rules and exit
2734
2717
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2735
2718
raise errors.BzrCommandError(
2736
2719
"NAME_PATTERN should not be an absolute path")
2737
tree, relpath = WorkingTree.open_containing(u'.')
2720
tree, relpath = WorkingTree.open_containing(directory)
2738
2721
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2739
2722
ignored = globbing.Globster(name_pattern_list)
2724
self.add_cleanup(tree.lock_read().unlock)
2742
2725
for entry in tree.list_files():
2744
2727
if id is not None:
2745
2728
filename = entry[0]
2746
2729
if ignored.match(filename):
2747
2730
matches.append(filename)
2749
2731
if len(matches) > 0:
2750
2732
self.outf.write("Warning: the following files are version controlled and"
2751
2733
" match your ignore pattern:\n%s"
2767
2749
encoding_type = 'replace'
2768
2750
_see_also = ['ignore', 'ls']
2751
takes_options = ['directory']
2770
2753
@display_command
2772
tree = WorkingTree.open_containing(u'.')[0]
2774
self.add_cleanup(tree.unlock)
2754
def run(self, directory=u'.'):
2755
tree = WorkingTree.open_containing(directory)[0]
2756
self.add_cleanup(tree.lock_read().unlock)
2775
2757
for path, file_class, kind, file_id, entry in tree.list_files():
2776
2758
if file_class != 'I':
2790
2772
takes_args = ['revno']
2773
takes_options = ['directory']
2792
2775
@display_command
2793
def run(self, revno):
2776
def run(self, revno, directory=u'.'):
2795
2778
revno = int(revno)
2796
2779
except ValueError:
2797
2780
raise errors.BzrCommandError("not a valid revision-number: %r"
2799
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2782
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2800
2783
self.outf.write("%s\n" % revid)
2829
2812
================= =========================
2831
2814
takes_args = ['dest', 'branch_or_subdir?']
2815
takes_options = ['directory',
2833
2816
Option('format',
2834
2817
help="Type of file to export to.",
2844
2827
'revision in which it was changed.'),
2846
2829
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2847
root=None, filters=False, per_file_timestamps=False):
2830
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2848
2831
from bzrlib.export import export
2850
2833
if branch_or_subdir is None:
2851
tree = WorkingTree.open_containing(u'.')[0]
2834
tree = WorkingTree.open_containing(directory)[0]
2852
2835
b = tree.branch
2875
2858
_see_also = ['ls']
2859
takes_options = ['directory',
2877
2860
Option('name-from-revision', help='The path name in the old tree.'),
2878
2861
Option('filters', help='Apply content filters to display the '
2879
2862
'convenience form.'),
2885
2868
@display_command
2886
2869
def run(self, filename, revision=None, name_from_revision=False,
2870
filters=False, directory=None):
2888
2871
if revision is not None and len(revision) != 1:
2889
2872
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2890
2873
" one revision specifier")
2891
2874
tree, branch, relpath = \
2892
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2894
self.add_cleanup(branch.unlock)
2875
_open_directory_or_containing_tree_or_branch(filename, directory)
2876
self.add_cleanup(branch.lock_read().unlock)
2895
2877
return self._run(tree, branch, relpath, filename, revision,
2896
2878
name_from_revision, filters)
2900
2882
if tree is None:
2901
2883
tree = b.basis_tree()
2902
2884
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2903
rev_tree.lock_read()
2904
self.add_cleanup(rev_tree.unlock)
2885
self.add_cleanup(rev_tree.lock_read().unlock)
2906
2887
old_file_id = rev_tree.path2id(relpath)
3169
3150
def get_message(commit_obj):
3170
3151
"""Callback to get commit message"""
3172
my_message = codecs.open(
3173
file, 'rt', osutils.get_user_encoding()).read()
3153
f = codecs.open(file, 'rt', osutils.get_user_encoding())
3155
my_message = f.read()
3174
3158
elif message is not None:
3175
3159
my_message = message
3331
3315
bzr whoami "Frank Chu <fchu@example.com>"
3333
takes_options = [ Option('email',
3317
takes_options = [ 'directory',
3334
3319
help='Display email address only.'),
3335
3320
Option('branch',
3336
3321
help='Set identity for the current branch instead of '
3340
3325
encoding_type = 'replace'
3342
3327
@display_command
3343
def run(self, email=False, branch=False, name=None):
3328
def run(self, email=False, branch=False, name=None, directory=None):
3344
3329
if name is None:
3345
# use branch if we're inside one; otherwise global config
3347
c = Branch.open_containing('.')[0].get_config()
3348
except errors.NotBranchError:
3349
c = config.GlobalConfig()
3330
if directory is None:
3331
# use branch if we're inside one; otherwise global config
3333
c = Branch.open_containing(u'.')[0].get_config()
3334
except errors.NotBranchError:
3335
c = config.GlobalConfig()
3337
c = Branch.open(directory).get_config()
3351
3339
self.outf.write(c.user_email() + '\n')
3363
3351
# use global config unless --branch given
3365
c = Branch.open_containing('.')[0].get_config()
3353
if directory is None:
3354
c = Branch.open_containing(u'.')[0].get_config()
3356
c = Branch.open(directory).get_config()
3367
3358
c = config.GlobalConfig()
3368
3359
c.set_user_option('email', name)
3381
3372
_see_also = ['info']
3382
3373
takes_args = ['nickname?']
3383
def run(self, nickname=None):
3384
branch = Branch.open_containing(u'.')[0]
3374
takes_options = ['directory']
3375
def run(self, nickname=None, directory=u'.'):
3376
branch = Branch.open_containing(directory)[0]
3385
3377
if nickname is None:
3386
3378
self.printme(branch)
3612
3604
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3613
3605
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3614
3606
# stdout, which would corrupt the subunit stream.
3615
if sys.platform == "win32" and sys.stdout.fileno() >= 0:
3607
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3608
# following code can be deleted when it's sufficiently deployed
3609
# -- vila/mgz 20100514
3610
if (sys.platform == "win32"
3611
and getattr(sys.stdout, 'fileno', None) is not None):
3617
3613
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3691
3687
branch1 = Branch.open_containing(branch)[0]
3692
3688
branch2 = Branch.open_containing(other)[0]
3694
self.add_cleanup(branch1.unlock)
3696
self.add_cleanup(branch2.unlock)
3689
self.add_cleanup(branch1.lock_read().unlock)
3690
self.add_cleanup(branch2.lock_read().unlock)
3697
3691
last1 = ensure_null(branch1.last_revision())
3698
3692
last2 = ensure_null(branch2.last_revision())
3793
3787
' completely merged into the source, pull from the'
3794
3788
' source rather than merging. When this happens,'
3795
3789
' you do not need to commit the result.'),
3790
custom_help('directory',
3797
3791
help='Branch to merge into, '
3798
'rather than the one containing the working directory.',
3792
'rather than the one containing the working directory.'),
3802
3793
Option('preview', help='Instead of merging, show a diff of the'
3804
3795
Option('interactive', help='Select changes interactively.',
3837
3828
unversioned_filter=tree.is_ignored, view_info=view_info)
3838
3829
pb = ui.ui_factory.nested_progress_bar()
3839
3830
self.add_cleanup(pb.finished)
3841
self.add_cleanup(tree.unlock)
3831
self.add_cleanup(tree.lock_write().unlock)
3842
3832
if location is not None:
3844
3834
mergeable = bundle.read_mergeable_from_url(location,
3905
3895
def _do_preview(self, merger):
3906
3896
from bzrlib.diff import show_diff_trees
3907
3897
result_tree = self._get_preview(merger)
3898
path_encoding = osutils.get_diff_header_encoding()
3908
3899
show_diff_trees(merger.this_tree, result_tree, self.outf,
3909
old_label='', new_label='')
3900
old_label='', new_label='',
3901
path_encoding=path_encoding)
3911
3903
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3912
3904
merger.change_reporter = change_reporter
4100
4092
if merge_type is None:
4101
4093
merge_type = _mod_merge.Merge3Merger
4102
4094
tree, file_list = tree_files(file_list)
4104
self.add_cleanup(tree.unlock)
4095
self.add_cleanup(tree.lock_write().unlock)
4105
4096
parents = tree.get_parent_ids()
4106
4097
if len(parents) != 2:
4107
4098
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4217
4208
def run(self, revision=None, no_backup=False, file_list=None,
4218
4209
forget_merges=None):
4219
4210
tree, file_list = tree_files(file_list)
4220
tree.lock_tree_write()
4221
self.add_cleanup(tree.unlock)
4211
self.add_cleanup(tree.lock_tree_write().unlock)
4222
4212
if forget_merges:
4223
4213
tree.set_parent_ids(tree.get_parent_ids()[:1])
4313
4303
_see_also = ['merge', 'pull']
4314
4304
takes_args = ['other_branch?']
4315
4305
takes_options = [
4316
4307
Option('reverse', 'Reverse the order of revisions.'),
4317
4308
Option('mine-only',
4318
4309
'Display changes in the local branch only.'),
4340
4331
theirs_only=False,
4341
4332
log_format=None, long=False, short=False, line=False,
4342
4333
show_ids=False, verbose=False, this=False, other=False,
4343
include_merges=False, revision=None, my_revision=None):
4334
include_merges=False, revision=None, my_revision=None,
4344
4336
from bzrlib.missing import find_unmerged, iter_log_revisions
4345
4337
def message(s):
4346
4338
if not is_quiet():
4359
4351
elif theirs_only:
4360
4352
restrict = 'remote'
4362
local_branch = Branch.open_containing(u".")[0]
4363
local_branch.lock_read()
4364
self.add_cleanup(local_branch.unlock)
4354
local_branch = Branch.open_containing(directory)[0]
4355
self.add_cleanup(local_branch.lock_read().unlock)
4366
4357
parent = local_branch.get_parent()
4367
4358
if other_branch is None:
4378
4369
if remote_branch.base == local_branch.base:
4379
4370
remote_branch = local_branch
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4372
self.add_cleanup(remote_branch.lock_read().unlock)
4384
4374
local_revid_range = _revision_range_to_revid_range(
4385
4375
_get_revision_range(my_revision, local_branch,
4440
4430
message("Branches are up to date.\n")
4441
4431
self.cleanup_now()
4442
4432
if not status_code and parent is None and other_branch is not None:
4443
local_branch.lock_write()
4444
self.add_cleanup(local_branch.unlock)
4433
self.add_cleanup(local_branch.lock_write().unlock)
4445
4434
# handle race conditions - a parent might be set while we run.
4446
4435
if local_branch.get_parent() is None:
4447
4436
local_branch.set_parent(remote_branch.base)
4578
4566
Option('long', help='Show commit date in annotations.'),
4582
4571
encoding_type = 'exact'
4584
4573
@display_command
4585
4574
def run(self, filename, all=False, long=False, revision=None,
4575
show_ids=False, directory=None):
4587
4576
from bzrlib.annotate import annotate_file, annotate_file_tree
4588
4577
wt, branch, relpath = \
4589
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4578
_open_directory_or_containing_tree_or_branch(filename, directory)
4590
4579
if wt is not None:
4592
self.add_cleanup(wt.unlock)
4580
self.add_cleanup(wt.lock_read().unlock)
4595
self.add_cleanup(branch.unlock)
4582
self.add_cleanup(branch.lock_read().unlock)
4596
4583
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4598
self.add_cleanup(tree.unlock)
4584
self.add_cleanup(tree.lock_read().unlock)
4599
4585
if wt is not None:
4600
4586
file_id = wt.path2id(relpath)
4620
4606
hidden = True # is this right ?
4621
4607
takes_args = ['revision_id*']
4622
takes_options = ['revision']
4608
takes_options = ['directory', 'revision']
4624
def run(self, revision_id_list=None, revision=None):
4610
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4625
4611
if revision_id_list is not None and revision is not None:
4626
4612
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4627
4613
if revision_id_list is None and revision is None:
4628
4614
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4629
b = WorkingTree.open_containing(u'.')[0].branch
4631
self.add_cleanup(b.unlock)
4615
b = WorkingTree.open_containing(directory)[0].branch
4616
self.add_cleanup(b.lock_write().unlock)
4632
4617
return self._run(b, revision_id_list, revision)
4634
4619
def _run(self, b, revision_id_list, revision):
4694
4679
_see_also = ['checkouts', 'unbind']
4695
4680
takes_args = ['location?']
4681
takes_options = ['directory']
4698
def run(self, location=None):
4699
b, relpath = Branch.open_containing(u'.')
4683
def run(self, location=None, directory=u'.'):
4684
b, relpath = Branch.open_containing(directory)
4700
4685
if location is None:
4702
4687
location = b.get_old_bound_location()
4730
4715
_see_also = ['checkouts', 'bind']
4731
4716
takes_args = []
4717
takes_options = ['directory']
4735
b, relpath = Branch.open_containing(u'.')
4719
def run(self, directory=u'.'):
4720
b, relpath = Branch.open_containing(directory)
4736
4721
if not b.unbind():
4737
4722
raise errors.BzrCommandError('Local branch is not bound')
4784
4769
b = control.open_branch()
4786
4771
if tree is not None:
4788
self.add_cleanup(tree.unlock)
4772
self.add_cleanup(tree.lock_write().unlock)
4791
self.add_cleanup(b.unlock)
4774
self.add_cleanup(b.lock_write().unlock)
4792
4775
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4794
4777
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4902
4885
'result in a dynamically allocated port. The default port '
4903
4886
'depends on the protocol.',
4906
help='Serve contents of this directory.',
4888
custom_help('directory',
4889
help='Serve contents of this directory.'),
4908
4890
Option('allow-writes',
4909
4891
help='By default the server is a readonly server. Supplying '
4910
4892
'--allow-writes enables write access to the contents of '
4938
4920
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4939
4921
protocol=None):
4940
from bzrlib.transport import get_transport, transport_server_registry
4922
from bzrlib import transport
4941
4923
if directory is None:
4942
4924
directory = os.getcwd()
4943
4925
if protocol is None:
4944
protocol = transport_server_registry.get()
4926
protocol = transport.transport_server_registry.get()
4945
4927
host, port = self.get_host_and_port(port)
4946
4928
url = urlutils.local_path_to_url(directory)
4947
4929
if not allow_writes:
4948
4930
url = 'readonly+' + url
4949
transport = get_transport(url)
4950
protocol(transport, host, port, inet)
4931
t = transport.get_transport(url)
4932
protocol(t, host, port, inet)
4953
4935
class cmd_join(Command):
5064
5047
encoding_type = 'exact'
5066
5049
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5067
sign=False, revision=None, mail_to=None, message=None):
5050
sign=False, revision=None, mail_to=None, message=None,
5068
5052
from bzrlib.revision import ensure_null, NULL_REVISION
5069
5053
include_patch, include_bundle = {
5070
5054
'plain': (False, False),
5071
5055
'diff': (True, False),
5072
5056
'bundle': (True, True),
5074
branch = Branch.open('.')
5058
branch = Branch.open(directory)
5075
5059
stored_submit_branch = branch.get_submit_branch()
5076
5060
if submit_branch is None:
5077
5061
submit_branch = stored_submit_branch
5162
5146
given, in which case it is sent to a file.
5164
5148
Mail is sent using your preferred mail program. This should be transparent
5165
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5149
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5166
5150
If the preferred client can't be found (or used), your editor will be used.
5168
5152
To use a specific mail program, set the mail_client configuration option.
5339
5323
Option('delete',
5340
5324
help='Delete this tag rather than placing it.',
5343
help='Branch in which to place the tag.',
5326
custom_help('directory',
5327
help='Branch in which to place the tag.'),
5347
5328
Option('force',
5348
5329
help='Replace existing tags.',
5359
5340
branch, relpath = Branch.open_containing(directory)
5361
self.add_cleanup(branch.unlock)
5341
self.add_cleanup(branch.lock_write().unlock)
5363
5343
if tag_name is None:
5364
5344
raise errors.BzrCommandError("No tag specified to delete.")
5393
5373
_see_also = ['tag']
5394
5374
takes_options = [
5396
help='Branch whose tags should be displayed.',
5375
custom_help('directory',
5376
help='Branch whose tags should be displayed.'),
5400
5377
RegistryOption.from_kwargs('sort',
5401
5378
'Sort tags by different criteria.', title='Sorting',
5402
5379
alpha='Sort tags lexicographically (default).',
5423
self.add_cleanup(branch.unlock)
5399
self.add_cleanup(branch.lock_read().unlock)
5425
5401
graph = branch.repository.get_graph()
5426
5402
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5575
5551
takes_args = ['to_location?']
5576
takes_options = [Option('force',
5552
takes_options = ['directory',
5577
5554
help='Switch even if local commits will be lost.'),
5579
5556
Option('create-branch', short_name='b',
5584
5561
def run(self, to_location=None, force=False, create_branch=False,
5562
revision=None, directory=u'.'):
5586
5563
from bzrlib import switch
5564
tree_location = directory
5588
5565
revision = _get_one_revision('switch', revision)
5589
5566
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5590
5567
if to_location is None:
5591
5568
if revision is None:
5592
5569
raise errors.BzrCommandError('You must supply either a'
5593
5570
' revision or a location')
5571
to_location = tree_location
5596
5573
branch = control_dir.open_branch()
5597
5574
had_explicit_nick = branch.get_config().has_explicit_nickname()
5886
5864
_see_also = ['unshelve']
5888
5866
def run(self, revision=None, all=False, file_list=None, message=None,
5889
writer=None, list=False, destroy=False):
5867
writer=None, list=False, destroy=False, directory=u'.'):
5891
5869
return self.run_for_list()
5892
5870
from bzrlib.shelf_ui import Shelver
5894
5872
writer = bzrlib.option.diff_writer_registry.get()
5896
5874
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5897
file_list, message, destroy=destroy)
5875
file_list, message, destroy=destroy, directory=directory)
5905
5883
def run_for_list(self):
5906
5884
tree = WorkingTree.open_containing('.')[0]
5908
self.add_cleanup(tree.unlock)
5885
self.add_cleanup(tree.lock_read().unlock)
5909
5886
manager = tree.get_shelf_manager()
5910
5887
shelves = manager.active_shelves()
5911
5888
if len(shelves) == 0:
5930
5907
takes_args = ['shelf_id?']
5931
5908
takes_options = [
5932
5910
RegistryOption.from_kwargs(
5933
5911
'action', help="The action to perform.",
5934
5912
enum_switch=False, value_switches=True,
5943
5921
_see_also = ['shelve']
5945
def run(self, shelf_id=None, action='apply'):
5923
def run(self, shelf_id=None, action='apply', directory=u'.'):
5946
5924
from bzrlib.shelf_ui import Unshelver
5947
unshelver = Unshelver.from_args(shelf_id, action)
5925
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5949
5927
unshelver.run()
5967
5945
To check what clean-tree will do, use --dry-run.
5969
takes_options = [Option('ignored', help='Delete all ignored files.'),
5947
takes_options = ['directory',
5948
Option('ignored', help='Delete all ignored files.'),
5970
5949
Option('detritus', help='Delete conflict files, merge'
5971
5950
' backups, and failed selftest dirs.'),
5972
5951
Option('unknown',
5975
5954
' deleting them.'),
5976
5955
Option('force', help='Do not prompt before deleting.')]
5977
5956
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5957
force=False, directory=u'.'):
5979
5958
from bzrlib.clean_tree import clean_tree
5980
5959
if not (unknown or ignored or detritus):
5984
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5985
dry_run=dry_run, no_prompt=force)
5963
clean_tree(directory, unknown=unknown, ignored=ignored,
5964
detritus=detritus, dry_run=dry_run, no_prompt=force)
5988
5967
class cmd_reference(Command):