534
534
if len(names_list) < 2:
535
535
raise errors.BzrCommandError("missing file argument")
536
536
tree, rel_names = tree_files(names_list)
538
if os.path.isdir(names_list[-1]):
539
self._run(tree, names_list, rel_names, after)
543
def _run(self, tree, names_list, rel_names, after):
544
into_existing = osutils.isdir(names_list[-1])
545
if into_existing and len(names_list) == 2:
547
# a. case-insensitive filesystem and change case of dir
548
# b. move directory after the fact (if the source used to be
549
# a directory, but now doesn't exist in the working tree
550
# and the target is an existing directory, just rename it)
551
if (not tree.case_sensitive
552
and rel_names[0].lower() == rel_names[1].lower()):
553
into_existing = False
556
from_id = tree.path2id(rel_names[0])
557
if (not osutils.lexists(names_list[0]) and
558
from_id and inv.get_file_kind(from_id) == "directory"):
559
into_existing = False
539
562
# move into existing directory
540
563
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
541
564
self.outf.write("%s => %s\n" % pair)
600
623
possible_transports = []
601
624
if location is not None:
602
mergeable, location_transport = _get_mergeable_helper(location)
603
possible_transports.append(location_transport)
626
mergeable = bundle.read_mergeable_from_url(location,
627
possible_transports=possible_transports)
628
except errors.NotABundle:
605
631
stored_loc = branch_to.get_parent()
606
632
if location is None:
611
637
display_url = urlutils.unescape_for_display(stored_loc,
612
638
self.outf.encoding)
613
self.outf.write("Using saved location: %s\n" % display_url)
640
self.outf.write("Using saved location: %s\n" % display_url)
614
641
location = stored_loc
615
location_transport = transport.get_transport(
616
location, possible_transports=possible_transports)
618
643
if mergeable is not None:
619
644
if revision is not None:
624
649
mergeable.get_merge_request(branch_to.repository)
625
650
branch_from = branch_to
627
branch_from = Branch.open_from_transport(location_transport)
652
branch_from = Branch.open(location,
653
possible_transports=possible_transports)
629
655
if branch_to.get_parent() is None or remember:
630
656
branch_to.set_parent(branch_from.base)
683
709
_see_also = ['pull', 'update', 'working-trees']
684
takes_options = ['remember', 'overwrite', 'verbose',
710
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
685
711
Option('create-prefix',
686
712
help='Create the path leading up to the branch '
687
713
'if it does not already exist.'),
701
727
encoding_type = 'replace'
703
729
def run(self, location=None, remember=False, overwrite=False,
704
create_prefix=False, verbose=False,
730
create_prefix=False, verbose=False, revision=None,
705
731
use_existing_dir=False,
707
733
# FIXME: Way too big! Put this into a function called from the
741
767
# Found a branch, so we must have found a repository
742
768
repository_to = br_to.repository
770
if revision is not None:
771
if len(revision) == 1:
772
revision_id = revision[0].in_history(br_from).rev_id
774
raise errors.BzrCommandError(
775
'bzr push --revision takes one value.')
777
revision_id = br_from.last_revision()
743
779
push_result = None
780
816
# directory. So we need to create it, along with any work to create
781
817
# all of the dependent branches, etc.
782
818
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
783
revision_id=br_from.last_revision())
819
revision_id=revision_id)
784
820
br_to = dir_to.open_branch()
785
821
# TODO: Some more useful message about what was copied
786
822
note('Created new branch.')
798
834
elif br_to is None:
799
835
# We have a repository but no branch, copy the revisions, and then
800
836
# create a branch.
801
last_revision_id = br_from.last_revision()
802
repository_to.fetch(br_from.repository,
803
revision_id=last_revision_id)
804
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
837
repository_to.fetch(br_from.repository, revision_id=revision_id)
838
br_to = br_from.clone(dir_to, revision_id=revision_id)
805
839
note('Created new branch.')
806
840
if br_from.get_push_location() is None or remember:
807
841
br_from.set_push_location(br_to.base)
819
853
warning("This transport does not update the working "
820
854
"tree of: %s. See 'bzr help working-trees' for "
821
855
"more information." % br_to.base)
822
push_result = br_from.push(br_to, overwrite)
856
push_result = br_from.push(br_to, overwrite,
857
stop_revision=revision_id)
823
858
except errors.NoWorkingTree:
824
push_result = br_from.push(br_to, overwrite)
859
push_result = br_from.push(br_to, overwrite,
860
stop_revision=revision_id)
826
862
tree_to.lock_write()
828
push_result = br_from.push(tree_to.branch, overwrite)
864
push_result = br_from.push(tree_to.branch, overwrite,
865
stop_revision=revision_id)
864
901
_see_also = ['checkout']
865
902
takes_args = ['from_location', 'to_location?']
866
takes_options = ['revision']
903
takes_options = ['revision', Option('hardlink',
904
help='Hard-link working tree files where possible.')]
867
905
aliases = ['get', 'clone']
869
def run(self, from_location, to_location=None, revision=None):
907
def run(self, from_location, to_location=None, revision=None,
870
909
from bzrlib.tag import _merge_tags_if_possible
871
910
if revision is None:
872
911
revision = [None]
904
943
# preserve whatever source format we have.
905
944
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
906
945
possible_transports=[to_transport],
907
accelerator_tree=accelerator_tree)
946
accelerator_tree=accelerator_tree,
908
948
branch = dir.open_branch()
909
949
except errors.NoSuchRevision:
910
950
to_transport.delete_tree('.')
949
989
"common operations like diff and status without "
950
990
"such access, and also support local commits."
953
help="Get file contents from this tree.", type=str)
992
Option('files-from', type=str,
993
help="Get file contents from this tree."),
995
help='Hard-link working tree files where possible.'
957
1000
def run(self, branch_location=None, to_location=None, revision=None,
958
lightweight=False, files_from=None):
1001
lightweight=False, files_from=None, hardlink=False):
959
1002
if revision is None:
960
1003
revision = [None]
961
1004
elif len(revision) > 1:
2598
2645
' expression.'),
2599
2646
Option('strict', help='Fail on missing dependencies or '
2600
2647
'known failures.'),
2601
Option('coverage', type=str, argname="DIRECTORY",
2602
help='Generate line coverage report in this '
2648
Option('load-list', type=str, argname='TESTLISTFILE',
2649
help='Load a test id list from a text file.'),
2605
2651
encoding_type = 'replace'
2608
2654
transport=None, benchmark=None,
2609
2655
lsprof_timed=None, cache_dir=None,
2610
2656
first=False, list_only=False,
2611
randomize=None, exclude=None, strict=False, coverage=None):
2657
randomize=None, exclude=None, strict=False,
2612
2659
import bzrlib.ui
2613
2660
from bzrlib.tests import selftest
2614
2661
import bzrlib.benchmarks as benchmarks
2783
2831
short_name='d',
2834
Option('preview', help='Instead of merging, show a diff of the merge.')
2788
2837
def run(self, branch=None, revision=None, force=False, merge_type=None,
2789
2838
show_base=False, reprocess=False, remember=False,
2790
2839
uncommitted=False, pull=False,
2791
2840
directory=None,
2793
2843
# This is actually a branch (or merge-directive) *location*.
2794
2844
location = branch
2812
2862
tree.lock_write()
2813
2863
cleanups.append(tree.unlock)
2814
2864
if location is not None:
2815
mergeable, other_transport = _get_mergeable_helper(location)
2866
mergeable = bundle.read_mergeable_from_url(location,
2867
possible_transports=possible_transports)
2868
except errors.NotABundle:
2817
2871
if uncommitted:
2818
2872
raise errors.BzrCommandError('Cannot use --uncommitted'
2819
2873
' with bundles or merge directives.')
2844
2897
merger.merge_type = merge_type
2845
2898
merger.reprocess = reprocess
2846
2899
merger.show_base = show_base
2847
merger.change_reporter = change_reporter
2848
2900
self.sanity_check_merger(merger)
2849
2901
if (merger.base_rev_id == merger.other_rev_id and
2850
2902
merger.other_rev_id != None):
2859
2911
result.report(self.outf)
2861
2913
merger.check_basis(not force)
2862
conflict_count = merger.do_merge()
2864
merger.set_pending()
2865
if verified == 'failed':
2866
warning('Preview patch does not match changes')
2867
if conflict_count != 0:
2915
return self._do_preview(merger)
2917
return self._do_merge(merger, change_reporter, allow_pending,
2872
2920
for cleanup in reversed(cleanups):
2923
def _do_preview(self, merger):
2924
from bzrlib.diff import show_diff_trees
2925
tree_merger = merger.make_merger()
2926
tt = tree_merger.make_preview_transform()
2928
result_tree = tt.get_preview_tree()
2929
show_diff_trees(merger.this_tree, result_tree, self.outf,
2930
old_label='', new_label='')
2934
def _do_merge(self, merger, change_reporter, allow_pending, verified):
2935
merger.change_reporter = change_reporter
2936
conflict_count = merger.do_merge()
2938
merger.set_pending()
2939
if verified == 'failed':
2940
warning('Preview patch does not match changes')
2941
if conflict_count != 0:
2875
2946
def sanity_check_merger(self, merger):
2876
2947
if (merger.show_base and
2877
2948
not merger.merge_type is _mod_merge.Merge3Merger):
2891
2962
from bzrlib.tag import _merge_tags_if_possible
2892
2963
assert revision is None or len(revision) < 3
2893
2964
# find the branch locations
2894
other_loc, location = self._select_branch_location(tree, location,
2965
other_loc, user_location = self._select_branch_location(tree, location,
2896
2967
if revision is not None and len(revision) == 2:
2897
base_loc, location = self._select_branch_location(tree, location,
2968
base_loc, _unused = self._select_branch_location(tree,
2969
location, revision, 0)
2900
2971
base_loc = other_loc
2901
2972
# Open the branches
2923
2994
base_revision_id = None
2924
2995
# Remember where we merge from
2925
if ((tree.branch.get_parent() is None or remember) and
2926
other_branch is not None):
2927
tree.branch.set_parent(other_branch.base)
2996
if ((remember or tree.branch.get_submit_branch() is None) and
2997
user_location is not None):
2998
tree.branch.set_submit_branch(other_branch.base)
2928
2999
_merge_tags_if_possible(other_branch, tree.branch)
2929
3000
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
2930
3001
other_revision_id, base_revision_id, other_branch, base_branch)
2935
3006
allow_pending = True
2936
3007
return merger, allow_pending
2938
def _select_branch_location(self, tree, location, revision=None,
3009
def _select_branch_location(self, tree, user_location, revision=None,
2940
3011
"""Select a branch location, according to possible inputs.
2943
3014
``revision`` and ``index`` must be supplied.)
2945
3016
Otherwise, the ``location`` parameter is used. If it is None, then the
2946
``parent`` location is used, and a note is printed.
3017
``submit`` or ``parent`` location is used, and a note is printed.
2948
3019
:param tree: The working tree to select a branch for merging into
2949
3020
:param location: The location entered by the user
2950
3021
:param revision: The revision parameter to the command
2951
3022
:param index: The index to use for the revision parameter. Negative
2952
3023
indices are permitted.
2953
:return: (selected_location, default_location). The default location
2954
will be the user-entered location, if any, or else the remembered
3024
:return: (selected_location, user_location). The default location
3025
will be the user-entered location.
2957
3027
if (revision is not None and index is not None
2958
3028
and revision[index] is not None):
2959
3029
branch = revision[index].get_branch()
2960
3030
if branch is not None:
2961
return branch, location
2962
location = self._get_remembered_parent(tree, location, 'Merging from')
2963
return location, location
3031
return branch, branch
3032
if user_location is None:
3033
location = self._get_remembered(tree, 'Merging from')
3035
location = user_location
3036
return location, user_location
2965
# TODO: move up to common parent; this isn't merge-specific anymore.
2966
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3038
def _get_remembered(self, tree, verb_string):
2967
3039
"""Use tree.branch's parent if none was supplied.
2969
3041
Report if the remembered location was used.
2971
if supplied_location is not None:
2972
return supplied_location
2973
stored_location = tree.branch.get_parent()
3043
stored_location = tree.branch.get_submit_branch()
3044
if stored_location is None:
3045
stored_location = tree.branch.get_parent()
2974
3046
mutter("%s", stored_location)
2975
3047
if stored_location is None:
2976
3048
raise errors.BzrCommandError("No location specified or remembered")
2977
display_url = urlutils.unescape_for_display(stored_location,
2979
self.outf.write("%s remembered location %s\n" % (verb_string,
3049
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3050
note(u"%s remembered location %s", verb_string, display_url)
2981
3051
return stored_location
3326
3396
class cmd_plugins(Command):
3327
3397
"""List the installed plugins.
3329
This command displays the list of installed plugins including the
3330
path where each one is located and a short description of each.
3399
This command displays the list of installed plugins including
3400
version of plugin and a short description of each.
3402
--verbose shows the path where each plugin is located.
3332
3404
A plugin is an external component for Bazaar that extends the
3333
3405
revision control system, by adding or replacing code in Bazaar.
3340
3412
install them. Instructions are also provided there on how to
3341
3413
write new plugins using the Python programming language.
3415
takes_options = ['verbose']
3344
3417
@display_command
3418
def run(self, verbose=False):
3346
3419
import bzrlib.plugin
3347
3420
from inspect import getdoc
3348
3422
for name, plugin in bzrlib.plugin.plugins().items():
3349
print plugin.path(), "[%s]" % plugin.__version__
3423
version = plugin.__version__
3424
if version == 'unknown':
3426
name_ver = '%s %s' % (name, version)
3350
3427
d = getdoc(plugin.module)
3352
print '\t', d.split('\n')[0]
3429
doc = d.split('\n')[0]
3431
doc = '(no description)'
3432
result.append((name_ver, doc, plugin.path()))
3433
for name_ver, doc, path in sorted(result):
3355
3441
class cmd_testament(Command):
3576
3662
_see_also = ['commit']
3577
3663
takes_options = ['verbose', 'revision',
3578
3664
Option('dry-run', help='Don\'t actually make changes.'),
3579
Option('force', help='Say yes to all questions.')]
3665
Option('force', help='Say yes to all questions.'),
3667
help="Only remove the commits from the local branch"
3668
" when in a checkout."
3580
3671
takes_args = ['location?']
3582
3673
encoding_type = 'replace'
3584
3675
def run(self, location=None,
3585
3676
dry_run=False, verbose=False,
3586
revision=None, force=False):
3677
revision=None, force=False, local=False):
3587
3678
if location is None:
3588
3679
location = u'.'
3589
3680
control, relpath = bzrdir.BzrDir.open_containing(location)
3602
return self._run(b, tree, dry_run, verbose, revision, force)
3693
return self._run(b, tree, dry_run, verbose, revision, force,
3604
3696
if tree is not None:
3609
def _run(self, b, tree, dry_run, verbose, revision, force):
3701
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
3610
3702
from bzrlib.log import log_formatter, show_log
3611
3703
from bzrlib.uncommit import uncommit
3977
4069
generic options are "default", "editor", "mapi", and "xdg-email".
3979
4071
If mail is being sent, a to address is required. This can be supplied
3980
either on the commandline, or by setting the submit_to configuration
4072
either on the commandline, by setting the submit_to configuration
4073
option in the branch itself or the child_submit_to configuration option
4074
in the submit branch.
3983
4076
Two formats are currently supported: "4" uses revision bundle format 4 and
3984
4077
merge directive format 2. It is significantly faster and smaller than
4063
4156
if remembered_submit_branch:
4064
4157
note('Using saved location: %s', submit_branch)
4160
submit_config = Branch.open(submit_branch).get_config()
4161
mail_to = submit_config.get_user_option("child_submit_to")
4066
4163
stored_public_branch = branch.get_public_branch()
4067
4164
if public_branch is None:
4068
4165
public_branch = stored_public_branch
4383
4481
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4484
class cmd_hooks(Command):
4485
"""Show a branch's currently registered hooks.
4489
takes_args = ['path?']
4491
def run(self, path=None):
4494
branch_hooks = Branch.open(path).hooks
4495
for hook_type in branch_hooks:
4496
hooks = branch_hooks[hook_type]
4497
self.outf.write("%s:\n" % (hook_type,))
4500
self.outf.write(" %s\n" %
4501
(branch_hooks.get_hook_name(hook),))
4503
self.outf.write(" <no hooks installed>\n")
4386
4506
def _create_prefix(cur_transport):
4387
4507
needed = [cur_transport]
4388
4508
# Recurse upwards until we can create a directory successfully
4405
4525
cur_transport.ensure_base()
4408
def _get_mergeable_helper(location):
4409
"""Get a merge directive or bundle if 'location' points to one.
4411
Try try to identify a bundle and returns its mergeable form. If it's not,
4412
we return the tried transport anyway so that it can reused to access the
4415
:param location: can point to a bundle or a branch.
4417
:return: mergeable, transport
4420
url = urlutils.normalize_url(location)
4421
url, filename = urlutils.split(url, exclude_trailing_slash=False)
4422
location_transport = transport.get_transport(url)
4425
# There may be redirections but we ignore the intermediate
4426
# and final transports used
4427
read = bundle.read_mergeable_from_transport
4428
mergeable, t = read(location_transport, filename)
4429
except errors.NotABundle:
4430
# Continue on considering this url a Branch but adjust the
4431
# location_transport
4432
location_transport = location_transport.clone(filename)
4433
return mergeable, location_transport
4436
4528
# these get imported and then picked up by the scan for cmd_*
4437
4529
# TODO: Some more consistent way to split command definitions across files;
4438
4530
# we do need to load at least some information about them to know of