732
669
location can be accessed.
735
_see_also = ['pull', 'update', 'working-trees']
736
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
672
_see_also = ['pull', 'update']
673
takes_options = ['remember', 'overwrite', 'verbose',
737
674
Option('create-prefix',
738
675
help='Create the path leading up to the branch '
739
'if it does not already exist.'),
676
'if it does not already exist'),
740
677
Option('directory',
741
help='Branch to push from, '
742
'rather than the one containing the working directory.',
678
help='branch to push from, '
679
'rather than the one containing the working directory',
746
683
Option('use-existing-dir',
747
684
help='By default push will fail if the target'
748
685
' directory exists, but does not already'
749
' have a control directory. This flag will'
686
' have a control directory. This flag will'
750
687
' allow push to proceed.'),
752
help='Create a stacked branch that references the public location '
753
'of the parent branch.'),
755
help='Create a stacked branch that refers to another branch '
756
'for the commit history. Only the work not present in the '
757
'referenced branch is included in the branch created.',
760
689
takes_args = ['location?']
761
690
encoding_type = 'replace'
763
692
def run(self, location=None, remember=False, overwrite=False,
764
create_prefix=False, verbose=False, revision=None,
765
use_existing_dir=False, directory=None, stacked_on=None,
767
from bzrlib.push import _show_push_branch
769
# Get the source branch and revision_id
693
create_prefix=False, verbose=False,
694
use_existing_dir=False,
696
# FIXME: Way too big! Put this into a function called from the
770
698
if directory is None:
772
700
br_from = Branch.open_containing(directory)[0]
773
if revision is not None:
774
if len(revision) == 1:
775
revision_id = revision[0].in_history(br_from).rev_id
777
raise errors.BzrCommandError(
778
'bzr push --revision takes one value.')
780
revision_id = br_from.last_revision()
782
# Get the stacked_on branch, if any
783
if stacked_on is not None:
784
stacked_on = urlutils.normalize_url(stacked_on)
786
parent_url = br_from.get_parent()
788
parent = Branch.open(parent_url)
789
stacked_on = parent.get_public_branch()
791
# I considered excluding non-http url's here, thus forcing
792
# 'public' branches only, but that only works for some
793
# users, so it's best to just depend on the user spotting an
794
# error by the feedback given to them. RBC 20080227.
795
stacked_on = parent_url
797
raise errors.BzrCommandError(
798
"Could not determine branch to refer to.")
800
# Get the destination location
701
stored_loc = br_from.get_push_location()
801
702
if location is None:
802
stored_loc = br_from.get_push_location()
803
703
if stored_loc is None:
804
raise errors.BzrCommandError(
805
"No push location known or specified.")
704
raise errors.BzrCommandError("No push location known or specified.")
807
706
display_url = urlutils.unescape_for_display(stored_loc,
808
707
self.outf.encoding)
809
self.outf.write("Using saved push location: %s\n" % display_url)
708
self.outf.write("Using saved location: %s\n" % display_url)
810
709
location = stored_loc
812
_show_push_branch(br_from, revision_id, location, self.outf,
813
verbose=verbose, overwrite=overwrite, remember=remember,
814
stacked_on=stacked_on, create_prefix=create_prefix,
815
use_existing_dir=use_existing_dir)
711
to_transport = transport.get_transport(location)
712
location_url = to_transport.base
714
br_to = repository_to = dir_to = None
716
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
717
except errors.NotBranchError:
718
pass # Didn't find anything
720
# If we can open a branch, use its direct repository, otherwise see
721
# if there is a repository without a branch.
723
br_to = dir_to.open_branch()
724
except errors.NotBranchError:
725
# Didn't find a branch, can we find a repository?
727
repository_to = dir_to.find_repository()
728
except errors.NoRepositoryPresent:
731
# Found a branch, so we must have found a repository
732
repository_to = br_to.repository
736
# The destination doesn't exist; create it.
737
# XXX: Refactor the create_prefix/no_create_prefix code into a
738
# common helper function
740
to_transport.mkdir('.')
741
except errors.FileExists:
742
if not use_existing_dir:
743
raise errors.BzrCommandError("Target directory %s"
744
" already exists, but does not have a valid .bzr"
745
" directory. Supply --use-existing-dir to push"
746
" there anyway." % location)
747
except errors.NoSuchFile:
748
if not create_prefix:
749
raise errors.BzrCommandError("Parent directory of %s"
751
"\nYou may supply --create-prefix to create all"
752
" leading parent directories."
755
cur_transport = to_transport
756
needed = [cur_transport]
757
# Recurse upwards until we can create a directory successfully
759
new_transport = cur_transport.clone('..')
760
if new_transport.base == cur_transport.base:
761
raise errors.BzrCommandError("Failed to create path"
765
new_transport.mkdir('.')
766
except errors.NoSuchFile:
767
needed.append(new_transport)
768
cur_transport = new_transport
772
# Now we only need to create child directories
774
cur_transport = needed.pop()
775
cur_transport.mkdir('.')
777
# Now the target directory exists, but doesn't have a .bzr
778
# directory. So we need to create it, along with any work to create
779
# all of the dependent branches, etc.
780
dir_to = br_from.bzrdir.clone(location_url,
781
revision_id=br_from.last_revision())
782
br_to = dir_to.open_branch()
783
# TODO: Some more useful message about what was copied
784
note('Created new branch.')
785
# We successfully created the target, remember it
786
if br_from.get_push_location() is None or remember:
787
br_from.set_push_location(br_to.base)
788
elif repository_to is None:
789
# we have a bzrdir but no branch or repository
790
# XXX: Figure out what to do other than complain.
791
raise errors.BzrCommandError("At %s you have a valid .bzr control"
792
" directory, but not a branch or repository. This is an"
793
" unsupported configuration. Please move the target directory"
794
" out of the way and try again."
797
# We have a repository but no branch, copy the revisions, and then
799
last_revision_id = br_from.last_revision()
800
repository_to.fetch(br_from.repository,
801
revision_id=last_revision_id)
802
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
803
note('Created new branch.')
804
if br_from.get_push_location() is None or remember:
805
br_from.set_push_location(br_to.base)
806
else: # We have a valid to branch
807
# We were able to connect to the remote location, so remember it
808
# we don't need to successfully push because of possible divergence.
809
if br_from.get_push_location() is None or remember:
810
br_from.set_push_location(br_to.base)
811
old_rh = br_to.revision_history()
814
tree_to = dir_to.open_workingtree()
815
except errors.NotLocalUrl:
816
warning('This transport does not update the working '
817
'tree of: %s' % (br_to.base,))
818
push_result = br_from.push(br_to, overwrite)
819
except errors.NoWorkingTree:
820
push_result = br_from.push(br_to, overwrite)
824
push_result = br_from.push(tree_to.branch, overwrite)
828
except errors.DivergedBranches:
829
raise errors.BzrCommandError('These branches have diverged.'
830
' Try using "merge" and then "push".')
831
if push_result is not None:
832
push_result.report(self.outf)
834
new_rh = br_to.revision_history()
837
from bzrlib.log import show_changed_revisions
838
show_changed_revisions(br_to, old_rh, new_rh,
841
# we probably did a clone rather than a push, so a message was
818
846
class cmd_branch(Command):
1386
1351
to_transport = transport.get_transport(location)
1387
to_transport.ensure_base()
1353
to_transport.mkdir('.')
1354
except errors.FileExists:
1389
1357
newdir = format.initialize_on_transport(to_transport)
1390
1358
repo = newdir.create_repository(shared=True)
1391
1359
repo.set_make_working_trees(not no_trees)
1393
from bzrlib.info import show_bzrdir_info
1394
show_bzrdir_info(bzrdir.BzrDir.open_containing_from_transport(
1395
to_transport)[0], verbose=0, outfile=self.outf)
1398
1362
class cmd_diff(Command):
1399
"""Show differences in the working tree, between revisions or branches.
1363
"""Show differences in the working tree or between revisions.
1401
If no arguments are given, all changes for the current tree are listed.
1402
If files are given, only the changes in those files are listed.
1403
Remote and multiple branches can be compared by using the --old and
1404
--new options. If not provided, the default for both is derived from
1405
the first argument, if any, or the current tree if no arguments are
1365
If files are listed, only the changes in those files are listed.
1366
Otherwise, all changes for the tree are listed.
1408
1368
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1409
1369
produces patches suitable for "patch -p1".
1413
2 - unrepresentable changes
1418
Shows the difference in the working tree versus the last commit::
1422
Difference between the working tree and revision 1::
1426
Difference between revision 2 and revision 1::
1430
Difference between revision 2 and revision 1 for branch xxx::
1434
Show just the differences for file NEWS::
1438
Show the differences in working tree xxx for file NEWS::
1442
Show the differences from branch xxx to this working tree:
1446
Show the differences between two branches for file NEWS::
1448
bzr diff --old xxx --new yyy NEWS
1450
Same as 'bzr diff' but prefix paths with old/ and new/::
1452
bzr diff --prefix old/:new/
1373
Shows the difference in the working tree versus the last commit
1375
Difference between the working tree and revision 1
1377
Difference between revision 2 and revision 1
1378
bzr diff --prefix old/:new/
1379
Same as 'bzr diff' but prefix paths with old/ and new/
1380
bzr diff bzr.mine bzr.dev
1381
Show the differences between the two working trees
1383
Show just the differences for 'foo.c'
1385
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1386
# or a graphical diff.
1388
# TODO: Python difflib is not exactly the same as unidiff; should
1389
# either fix it up or prefer to use an external diff.
1391
# TODO: Selected-file diff is inefficient and doesn't show you
1394
# TODO: This probably handles non-Unix newlines poorly.
1454
1396
_see_also = ['status']
1455
1397
takes_args = ['file*']
1457
Option('diff-options', type=str,
1458
help='Pass these options to the external diff program.'),
1398
takes_options = ['revision', 'diff-options',
1459
1399
Option('prefix', type=str,
1460
1400
short_name='p',
1461
help='Set prefixes added to old and new filenames, as '
1462
'two values separated by a colon. (eg "old/:new/").'),
1464
help='Branch/tree to compare from.',
1468
help='Branch/tree to compare to.',
1474
help='Use this command to compare files.',
1401
help='Set prefixes to added to old and new filenames, as '
1402
'two values separated by a colon. (eg "old/:new/")'),
1478
1404
aliases = ['di', 'dif']
1479
1405
encoding_type = 'exact'
1481
1407
@display_command
1482
1408
def run(self, revision=None, file_list=None, diff_options=None,
1483
prefix=None, old=None, new=None, using=None):
1484
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1410
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1486
1412
if (prefix is None) or (prefix == '0'):
1487
1413
# diff -p0 format
2632
2410
takes_args = ['testspecs*']
2633
2411
takes_options = ['verbose',
2635
help='Stop when one test fails.',
2413
help='stop when one test fails',
2636
2414
short_name='1',
2416
Option('keep-output',
2417
help='keep output directories when tests fail'),
2638
2418
Option('transport',
2639
2419
help='Use a different transport by default '
2640
2420
'throughout the test suite.',
2641
2421
type=get_transport_type),
2643
help='Run the benchmarks rather than selftests.'),
2422
Option('benchmark', help='run the bzr benchmarks.'),
2644
2423
Option('lsprof-timed',
2645
help='Generate lsprof output for benchmarked'
2424
help='generate lsprof output for benchmarked'
2646
2425
' sections of code.'),
2647
2426
Option('cache-dir', type=str,
2648
help='Cache intermediate benchmark output in this '
2427
help='a directory to cache intermediate'
2428
' benchmark steps'),
2429
Option('clean-output',
2430
help='clean temporary tests directories'
2431
' without running tests'),
2650
2432
Option('first',
2651
help='Run all tests, but run specified tests first.',
2433
help='run all tests, but run specified tests first',
2652
2434
short_name='f',
2436
Option('numbered-dirs',
2437
help='use numbered dirs for TestCaseInTempDir'),
2654
2438
Option('list-only',
2655
help='List the tests instead of running them.'),
2439
help='list the tests instead of running them'),
2656
2440
Option('randomize', type=str, argname="SEED",
2657
help='Randomize the order of tests using the given'
2658
' seed or "now" for the current time.'),
2441
help='randomize the order of tests using the given'
2442
' seed or "now" for the current time'),
2659
2443
Option('exclude', type=str, argname="PATTERN",
2660
2444
short_name='x',
2661
help='Exclude tests that match this regular'
2663
Option('strict', help='Fail on missing dependencies or '
2665
Option('load-list', type=str, argname='TESTLISTFILE',
2666
help='Load a test id list from a text file.'),
2667
ListOption('debugflag', type=str, short_name='E',
2668
help='Turn on a selftest debug flag.'),
2669
ListOption('starting-with', type=str, argname='TESTID',
2670
param_name='starting_with', short_name='s',
2672
'Load only the tests starting with TESTID.'),
2445
help='exclude tests that match this regular'
2674
2448
encoding_type = 'replace'
2676
def run(self, testspecs_list=None, verbose=False, one=False,
2677
transport=None, benchmark=None,
2678
lsprof_timed=None, cache_dir=None,
2679
first=False, list_only=False,
2680
randomize=None, exclude=None, strict=False,
2681
load_list=None, debugflag=None, starting_with=None):
2450
def run(self, testspecs_list=None, verbose=None, one=False,
2451
keep_output=False, transport=None, benchmark=None,
2452
lsprof_timed=None, cache_dir=None, clean_output=False,
2453
first=False, numbered_dirs=None, list_only=False,
2454
randomize=None, exclude=None):
2682
2455
import bzrlib.ui
2683
2456
from bzrlib.tests import selftest
2684
2457
import bzrlib.benchmarks as benchmarks
2685
2458
from bzrlib.benchmarks import tree_creator
2687
# Make deprecation warnings visible, unless -Werror is set
2688
symbol_versioning.activate_deprecation_warnings(override=False)
2461
from bzrlib.tests import clean_selftest_output
2462
clean_selftest_output()
2465
if numbered_dirs is None and sys.platform == 'win32':
2466
numbered_dirs = True
2690
2468
if cache_dir is not None:
2691
2469
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2693
print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
2694
print ' %s (%s python%s)' % (
2696
bzrlib.version_string,
2697
bzrlib._format_version_tuple(sys.version_info),
2470
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2471
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2700
2473
if testspecs_list is not None:
2701
2474
pattern = '|'.join(testspecs_list)
2828
2582
The results of the merge are placed into the destination working
2829
2583
directory, where they can be reviewed (with bzr diff), tested, and then
2830
2584
committed to record the result of the merge.
2588
To merge the latest revision from bzr.dev:
2589
bzr merge ../bzr.dev
2591
To merge changes up to and including revision 82 from bzr.dev:
2592
bzr merge -r 82 ../bzr.dev
2594
To merge the changes introduced by 82, without previous changes:
2595
bzr merge -r 81..82 ../bzr.dev
2832
2597
merge refuses to run if there are any uncommitted changes, unless
2833
2598
--force is given.
2836
To merge the latest revision from bzr.dev::
2838
bzr merge ../bzr.dev
2840
To merge changes up to and including revision 82 from bzr.dev::
2842
bzr merge -r 82 ../bzr.dev
2844
To merge the changes introduced by 82, without previous changes::
2846
bzr merge -r 81..82 ../bzr.dev
2848
To apply a merge directive contained in in /tmp/merge:
2850
bzr merge /tmp/merge
2853
encoding_type = 'exact'
2854
_see_also = ['update', 'remerge', 'status-flags']
2855
takes_args = ['location?']
2860
help='Merge even if the destination tree has uncommitted changes.'),
2601
_see_also = ['update', 'remerge']
2602
takes_args = ['branch?']
2603
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2864
2604
Option('show-base', help="Show base revision text in "
2866
2606
Option('uncommitted', help='Apply uncommitted changes'
2867
' from a working copy, instead of branch changes.'),
2607
' from a working copy, instead of branch changes'),
2868
2608
Option('pull', help='If the destination is already'
2869
2609
' completely merged into the source, pull from the'
2870
' source rather than merging. When this happens,'
2610
' source rather than merging. When this happens,'
2871
2611
' you do not need to commit the result.'),
2872
2612
Option('directory',
2873
help='Branch to merge into, '
2874
'rather than the one containing the working directory.',
2878
Option('preview', help='Instead of merging, show a diff of the merge.')
2613
help='Branch to merge into, '
2614
'rather than the one containing the working directory',
2881
def run(self, location=None, revision=None, force=False,
2882
merge_type=None, show_base=False, reprocess=False, remember=False,
2620
def run(self, branch=None, revision=None, force=False, merge_type=None,
2621
show_base=False, reprocess=False, remember=False,
2883
2622
uncommitted=False, pull=False,
2884
2623
directory=None,
2625
from bzrlib.tag import _merge_tags_if_possible
2626
other_revision_id = None
2887
2627
if merge_type is None:
2888
2628
merge_type = _mod_merge.Merge3Merger
2890
2630
if directory is None: directory = u'.'
2891
possible_transports = []
2893
allow_pending = True
2894
verified = 'inapplicable'
2631
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2632
# inventory. Because merge is a mutating operation, it really
2633
# should be a lock_write() for the whole cmd_merge operation.
2634
# However, cmd_merge open's its own tree in _merge_helper, which
2635
# means if we lock here, the later lock_write() will always block.
2636
# Either the merge helper code should be updated to take a tree,
2637
# (What about tree.merge_from_branch?)
2895
2638
tree = WorkingTree.open_containing(directory)[0]
2896
2639
change_reporter = delta._ChangeReporter(
2897
2640
unversioned_filter=tree.is_ignored)
2900
pb = ui.ui_factory.nested_progress_bar()
2901
cleanups.append(pb.finished)
2903
cleanups.append(tree.unlock)
2904
if location is not None:
2906
mergeable = bundle.read_mergeable_from_url(location,
2907
possible_transports=possible_transports)
2908
except errors.NotABundle:
2642
if branch is not None:
2644
mergeable = bundle.read_mergeable_from_url(
2646
except errors.NotABundle:
2647
pass # Continue on considering this url a Branch
2649
if revision is not None:
2650
raise errors.BzrCommandError(
2651
'Cannot use -r with merge directives or bundles')
2652
other_revision_id = mergeable.install_revisions(
2653
tree.branch.repository)
2654
revision = [RevisionSpec.from_string(
2655
'revid:' + other_revision_id)]
2657
if revision is None \
2658
or len(revision) < 1 or revision[0].needs_branch():
2659
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2661
if revision is None or len(revision) < 1:
2664
other = [branch, None]
2667
other = [branch, -1]
2668
other_branch, path = Branch.open_containing(branch)
2671
raise errors.BzrCommandError('Cannot use --uncommitted and'
2672
' --revision at the same time.')
2673
branch = revision[0].get_branch() or branch
2674
if len(revision) == 1:
2676
if other_revision_id is not None:
2912
raise errors.BzrCommandError('Cannot use --uncommitted'
2913
' with bundles or merge directives.')
2915
if revision is not None:
2916
raise errors.BzrCommandError(
2917
'Cannot use -r with merge directives or bundles')
2918
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2921
if merger is None and uncommitted:
2922
if revision is not None and len(revision) > 0:
2923
raise errors.BzrCommandError('Cannot use --uncommitted and'
2924
' --revision at the same time.')
2925
location = self._select_branch_location(tree, location)[0]
2926
other_tree, other_path = WorkingTree.open_containing(location)
2927
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2929
allow_pending = False
2930
if other_path != '':
2931
merger.interesting_files = [other_path]
2934
merger, allow_pending = self._get_merger_from_branch(tree,
2935
location, revision, remember, possible_transports, pb)
2937
merger.merge_type = merge_type
2938
merger.reprocess = reprocess
2939
merger.show_base = show_base
2940
self.sanity_check_merger(merger)
2941
if (merger.base_rev_id == merger.other_rev_id and
2942
merger.other_rev_id is not None):
2943
note('Nothing to do.')
2681
other_branch, path = Branch.open_containing(branch)
2682
revno = revision[0].in_history(other_branch).revno
2683
other = [branch, revno]
2685
assert len(revision) == 2
2686
if None in revision:
2687
raise errors.BzrCommandError(
2688
"Merge doesn't permit empty revision specifier.")
2689
base_branch, path = Branch.open_containing(branch)
2690
branch1 = revision[1].get_branch() or branch
2691
other_branch, path1 = Branch.open_containing(branch1)
2692
if revision[0].get_branch() is not None:
2693
# then path was obtained from it, and is None.
2696
base = [branch, revision[0].in_history(base_branch).revno]
2697
other = [branch1, revision[1].in_history(other_branch).revno]
2699
if ((tree.branch.get_parent() is None or remember) and
2700
other_branch is not None):
2701
tree.branch.set_parent(other_branch.base)
2703
# pull tags now... it's a bit inconsistent to do it ahead of copying
2704
# the history but that's done inside the merge code
2705
if other_branch is not None:
2706
_merge_tags_if_possible(other_branch, tree.branch)
2709
interesting_files = [path]
2711
interesting_files = None
2712
pb = ui.ui_factory.nested_progress_bar()
2715
conflict_count = _merge_helper(
2716
other, base, other_rev_id=other_revision_id,
2717
check_clean=(not force),
2718
merge_type=merge_type,
2719
reprocess=reprocess,
2720
show_base=show_base,
2723
pb=pb, file_list=interesting_files,
2724
change_reporter=change_reporter)
2727
if conflict_count != 0:
2946
if merger.interesting_files is not None:
2947
raise errors.BzrCommandError('Cannot pull individual files')
2948
if (merger.base_rev_id == tree.last_revision()):
2949
result = tree.pull(merger.other_branch, False,
2950
merger.other_rev_id)
2951
result.report(self.outf)
2953
merger.check_basis(not force)
2955
return self._do_preview(merger)
2957
return self._do_merge(merger, change_reporter, allow_pending,
2960
for cleanup in reversed(cleanups):
2963
def _do_preview(self, merger):
2964
from bzrlib.diff import show_diff_trees
2965
tree_merger = merger.make_merger()
2966
tt = tree_merger.make_preview_transform()
2968
result_tree = tt.get_preview_tree()
2969
show_diff_trees(merger.this_tree, result_tree, self.outf,
2970
old_label='', new_label='')
2974
def _do_merge(self, merger, change_reporter, allow_pending, verified):
2975
merger.change_reporter = change_reporter
2976
conflict_count = merger.do_merge()
2978
merger.set_pending()
2979
if verified == 'failed':
2980
warning('Preview patch does not match changes')
2981
if conflict_count != 0:
2986
def sanity_check_merger(self, merger):
2987
if (merger.show_base and
2988
not merger.merge_type is _mod_merge.Merge3Merger):
2989
raise errors.BzrCommandError("Show-base is not supported for this"
2990
" merge type. %s" % merger.merge_type)
2991
if merger.reprocess and not merger.merge_type.supports_reprocess:
2992
raise errors.BzrCommandError("Conflict reduction is not supported"
2993
" for merge type %s." %
2995
if merger.reprocess and merger.show_base:
2996
raise errors.BzrCommandError("Cannot do conflict reduction and"
2999
def _get_merger_from_branch(self, tree, location, revision, remember,
3000
possible_transports, pb):
3001
"""Produce a merger from a location, assuming it refers to a branch."""
3002
from bzrlib.tag import _merge_tags_if_possible
3003
# find the branch locations
3004
other_loc, user_location = self._select_branch_location(tree, location,
3006
if revision is not None and len(revision) == 2:
3007
base_loc, _unused = self._select_branch_location(tree,
3008
location, revision, 0)
3010
base_loc = other_loc
3012
other_branch, other_path = Branch.open_containing(other_loc,
3013
possible_transports)
3014
if base_loc == other_loc:
3015
base_branch = other_branch
3017
base_branch, base_path = Branch.open_containing(base_loc,
3018
possible_transports)
3019
# Find the revision ids
3020
if revision is None or len(revision) < 1 or revision[-1] is None:
3021
other_revision_id = _mod_revision.ensure_null(
3022
other_branch.last_revision())
3024
other_revision_id = revision[-1].as_revision_id(other_branch)
3025
if (revision is not None and len(revision) == 2
3026
and revision[0] is not None):
3027
base_revision_id = revision[0].as_revision_id(base_branch)
3029
base_revision_id = None
3030
# Remember where we merge from
3031
if ((remember or tree.branch.get_submit_branch() is None) and
3032
user_location is not None):
3033
tree.branch.set_submit_branch(other_branch.base)
3034
_merge_tags_if_possible(other_branch, tree.branch)
3035
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3036
other_revision_id, base_revision_id, other_branch, base_branch)
3037
if other_path != '':
3038
allow_pending = False
3039
merger.interesting_files = [other_path]
3041
allow_pending = True
3042
return merger, allow_pending
3044
def _select_branch_location(self, tree, user_location, revision=None,
3046
"""Select a branch location, according to possible inputs.
3048
If provided, branches from ``revision`` are preferred. (Both
3049
``revision`` and ``index`` must be supplied.)
3051
Otherwise, the ``location`` parameter is used. If it is None, then the
3052
``submit`` or ``parent`` location is used, and a note is printed.
3054
:param tree: The working tree to select a branch for merging into
3055
:param location: The location entered by the user
3056
:param revision: The revision parameter to the command
3057
:param index: The index to use for the revision parameter. Negative
3058
indices are permitted.
3059
:return: (selected_location, user_location). The default location
3060
will be the user-entered location.
3062
if (revision is not None and index is not None
3063
and revision[index] is not None):
3064
branch = revision[index].get_branch()
3065
if branch is not None:
3066
return branch, branch
3067
if user_location is None:
3068
location = self._get_remembered(tree, 'Merging from')
3070
location = user_location
3071
return location, user_location
3073
def _get_remembered(self, tree, verb_string):
2731
except errors.AmbiguousBase, e:
2732
m = ("sorry, bzr can't determine the right merge base yet\n"
2733
"candidates are:\n "
2734
+ "\n ".join(e.bases)
2736
"please specify an explicit base with -r,\n"
2737
"and (if you want) report this to the bzr developers\n")
2740
# TODO: move up to common parent; this isn't merge-specific anymore.
2741
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3074
2742
"""Use tree.branch's parent if none was supplied.
3076
2744
Report if the remembered location was used.
3078
stored_location = tree.branch.get_submit_branch()
3079
stored_location_type = "submit"
3080
if stored_location is None:
3081
stored_location = tree.branch.get_parent()
3082
stored_location_type = "parent"
2746
if supplied_location is not None:
2747
return supplied_location
2748
stored_location = tree.branch.get_parent()
3083
2749
mutter("%s", stored_location)
3084
2750
if stored_location is None:
3085
2751
raise errors.BzrCommandError("No location specified or remembered")
3086
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3087
note(u"%s remembered %s location %s", verb_string,
3088
stored_location_type, display_url)
2752
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2753
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3089
2754
return stored_location
3300
2935
shellcomplete.shellcomplete(context)
2938
class cmd_fetch(Command):
2939
"""Copy in history from another branch but don't merge it.
2941
This is an internal method used for pull and merge.
2944
takes_args = ['from_branch', 'to_branch']
2945
def run(self, from_branch, to_branch):
2946
from bzrlib.fetch import Fetcher
2947
from_b = Branch.open(from_branch)
2948
to_b = Branch.open(to_branch)
2949
Fetcher(to_b, from_b)
3303
2952
class cmd_missing(Command):
3304
2953
"""Show unmerged/unpulled revisions between two branches.
3306
2955
OTHER_BRANCH may be local or remote.
3309
2958
_see_also = ['merge', 'pull']
3310
2959
takes_args = ['other_branch?']
3312
Option('reverse', 'Reverse the order of revisions.'),
3314
'Display changes in the local branch only.'),
3315
Option('this' , 'Same as --mine-only.'),
3316
Option('theirs-only',
3317
'Display changes in the remote branch only.'),
3318
Option('other', 'Same as --theirs-only.'),
2960
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2962
'Display changes in the local branch only'),
2963
Option('theirs-only',
2964
'Display changes in the remote branch only'),
3323
2969
encoding_type = 'replace'
3325
2971
@display_command
3326
2972
def run(self, other_branch=None, reverse=False, mine_only=False,
3327
2973
theirs_only=False, log_format=None, long=False, short=False, line=False,
3328
show_ids=False, verbose=False, this=False, other=False):
3329
from bzrlib.missing import find_unmerged, iter_log_revisions
3335
# TODO: We should probably check that we don't have mine-only and
3336
# theirs-only set, but it gets complicated because we also have
3337
# this and other which could be used.
2974
show_ids=False, verbose=False):
2975
from bzrlib.missing import find_unmerged, iter_log_data
2976
from bzrlib.log import log_formatter
3344
2977
local_branch = Branch.open_containing(u".")[0]
3345
2978
parent = local_branch.get_parent()
3346
2979
if other_branch is None:
3347
2980
other_branch = parent
3348
2981
if other_branch is None:
3349
raise errors.BzrCommandError("No peer location known"
2982
raise errors.BzrCommandError("No peer location known or specified.")
3351
2983
display_url = urlutils.unescape_for_display(parent,
3352
2984
self.outf.encoding)
3353
self.outf.write("Using saved parent location: "
3354
+ display_url + "\n")
2985
print "Using last location: " + display_url
3356
2987
remote_branch = Branch.open(other_branch)
3357
2988
if remote_branch.base == local_branch.base:
3425
3036
return status_code
3428
class cmd_pack(Command):
3429
"""Compress the data within a repository."""
3431
_see_also = ['repositories']
3432
takes_args = ['branch_or_repo?']
3434
def run(self, branch_or_repo='.'):
3435
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3437
branch = dir.open_branch()
3438
repository = branch.repository
3439
except errors.NotBranchError:
3440
repository = dir.open_repository()
3444
3039
class cmd_plugins(Command):
3445
"""List the installed plugins.
3447
This command displays the list of installed plugins including
3448
version of plugin and a short description of each.
3450
--verbose shows the path where each plugin is located.
3452
A plugin is an external component for Bazaar that extends the
3453
revision control system, by adding or replacing code in Bazaar.
3454
Plugins can do a variety of things, including overriding commands,
3455
adding new commands, providing additional network transports and
3456
customizing log output.
3458
See the Bazaar web site, http://bazaar-vcs.org, for further
3459
information on plugins including where to find them and how to
3460
install them. Instructions are also provided there on how to
3461
write new plugins using the Python programming language.
3463
takes_options = ['verbose']
3465
3042
@display_command
3466
def run(self, verbose=False):
3467
3044
import bzrlib.plugin
3468
3045
from inspect import getdoc
3470
for name, plugin in bzrlib.plugin.plugins().items():
3471
version = plugin.__version__
3472
if version == 'unknown':
3474
name_ver = '%s %s' % (name, version)
3475
d = getdoc(plugin.module)
3046
for name, plugin in bzrlib.plugin.all_plugins().items():
3047
if getattr(plugin, '__path__', None) is not None:
3048
print plugin.__path__[0]
3049
elif getattr(plugin, '__file__', None) is not None:
3050
print plugin.__file__
3477
doc = d.split('\n')[0]
3479
doc = '(no description)'
3480
result.append((name_ver, doc, plugin.path()))
3481
for name_ver, doc, path in sorted(result):
3056
print '\t', d.split('\n')[0]
3489
3059
class cmd_testament(Command):
3490
3060
"""Show testament (signing-form) of a revision."""
3493
Option('long', help='Produce long-format testament.'),
3495
help='Produce a strict-format testament.')]
3061
takes_options = ['revision',
3062
Option('long', help='Produce long-format testament'),
3063
Option('strict', help='Produce a strict-format'
3496
3065
takes_args = ['branch?']
3497
3066
@display_command
3498
3067
def run(self, branch=u'.', revision=None, long=False, strict=False):
4084
3559
self.outf.writelines(directive.to_lines())
4086
3561
message = directive.to_email(mail_to, branch, sign)
4087
s = SMTPConnection(branch.get_config())
4088
s.send_email(message)
4091
class cmd_send(Command):
4092
"""Mail or create a merge-directive for submiting changes.
4094
A merge directive provides many things needed for requesting merges:
4096
* A machine-readable description of the merge to perform
4098
* An optional patch that is a preview of the changes requested
4100
* An optional bundle of revision data, so that the changes can be applied
4101
directly from the merge directive, without retrieving data from a
4104
If --no-bundle is specified, then public_branch is needed (and must be
4105
up-to-date), so that the receiver can perform the merge using the
4106
public_branch. The public_branch is always included if known, so that
4107
people can check it later.
4109
The submit branch defaults to the parent, but can be overridden. Both
4110
submit branch and public branch will be remembered if supplied.
4112
If a public_branch is known for the submit_branch, that public submit
4113
branch is used in the merge instructions. This means that a local mirror
4114
can be used as your actual submit branch, once you have set public_branch
4117
Mail is sent using your preferred mail program. This should be transparent
4118
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4119
If the preferred client can't be found (or used), your editor will be used.
4121
To use a specific mail program, set the mail_client configuration option.
4122
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4123
specific clients are "evolution", "kmail", "mutt", and "thunderbird";
4124
generic options are "default", "editor", "emacsclient", "mapi", and
4125
"xdg-email". Plugins may also add supported clients.
4127
If mail is being sent, a to address is required. This can be supplied
4128
either on the commandline, by setting the submit_to configuration
4129
option in the branch itself or the child_submit_to configuration option
4130
in the submit branch.
4132
Two formats are currently supported: "4" uses revision bundle format 4 and
4133
merge directive format 2. It is significantly faster and smaller than
4134
older formats. It is compatible with Bazaar 0.19 and later. It is the
4135
default. "0.9" uses revision bundle format 0.9 and merge directive
4136
format 1. It is compatible with Bazaar 0.12 - 0.18.
4138
Merge directives are applied using the merge command or the pull command.
4141
encoding_type = 'exact'
4143
_see_also = ['merge', 'pull']
4145
takes_args = ['submit_branch?', 'public_branch?']
4149
help='Do not include a bundle in the merge directive.'),
4150
Option('no-patch', help='Do not include a preview patch in the merge'
4153
help='Remember submit and public branch.'),
4155
help='Branch to generate the submission from, '
4156
'rather than the one containing the working directory.',
4159
Option('output', short_name='o',
4160
help='Write merge directive to this file; '
4161
'use - for stdout.',
4163
Option('mail-to', help='Mail the request to this address.',
4167
RegistryOption.from_kwargs('format',
4168
'Use the specified output format.',
4169
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4170
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4173
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4174
no_patch=False, revision=None, remember=False, output=None,
4175
format='4', mail_to=None, message=None, **kwargs):
4176
return self._run(submit_branch, revision, public_branch, remember,
4177
format, no_bundle, no_patch, output,
4178
kwargs.get('from', '.'), mail_to, message)
4180
def _run(self, submit_branch, revision, public_branch, remember, format,
4181
no_bundle, no_patch, output, from_, mail_to, message):
4182
from bzrlib.revision import NULL_REVISION
4183
branch = Branch.open_containing(from_)[0]
4185
outfile = StringIO()
4189
outfile = open(output, 'wb')
4190
# we may need to write data into branch's repository to calculate
4195
config = branch.get_config()
4197
mail_to = config.get_user_option('submit_to')
4198
mail_client = config.get_mail_client()
4199
if remember and submit_branch is None:
4200
raise errors.BzrCommandError(
4201
'--remember requires a branch to be specified.')
4202
stored_submit_branch = branch.get_submit_branch()
4203
remembered_submit_branch = None
4204
if submit_branch is None:
4205
submit_branch = stored_submit_branch
4206
remembered_submit_branch = "submit"
4208
if stored_submit_branch is None or remember:
4209
branch.set_submit_branch(submit_branch)
4210
if submit_branch is None:
4211
submit_branch = branch.get_parent()
4212
remembered_submit_branch = "parent"
4213
if submit_branch is None:
4214
raise errors.BzrCommandError('No submit branch known or'
4216
if remembered_submit_branch is not None:
4217
note('Using saved %s location "%s" to determine what '
4218
'changes to submit.', remembered_submit_branch,
4222
submit_config = Branch.open(submit_branch).get_config()
4223
mail_to = submit_config.get_user_option("child_submit_to")
4225
stored_public_branch = branch.get_public_branch()
4226
if public_branch is None:
4227
public_branch = stored_public_branch
4228
elif stored_public_branch is None or remember:
4229
branch.set_public_branch(public_branch)
4230
if no_bundle and public_branch is None:
4231
raise errors.BzrCommandError('No public branch specified or'
4233
base_revision_id = None
4235
if revision is not None:
4236
if len(revision) > 2:
4237
raise errors.BzrCommandError('bzr send takes '
4238
'at most two one revision identifiers')
4239
revision_id = revision[-1].as_revision_id(branch)
4240
if len(revision) == 2:
4241
base_revision_id = revision[0].as_revision_id(branch)
4242
if revision_id is None:
4243
revision_id = branch.last_revision()
4244
if revision_id == NULL_REVISION:
4245
raise errors.BzrCommandError('No revisions to submit.')
4247
directive = merge_directive.MergeDirective2.from_objects(
4248
branch.repository, revision_id, time.time(),
4249
osutils.local_time_offset(), submit_branch,
4250
public_branch=public_branch, include_patch=not no_patch,
4251
include_bundle=not no_bundle, message=message,
4252
base_revision_id=base_revision_id)
4253
elif format == '0.9':
4256
patch_type = 'bundle'
4258
raise errors.BzrCommandError('Format 0.9 does not'
4259
' permit bundle with no patch')
4265
directive = merge_directive.MergeDirective.from_objects(
4266
branch.repository, revision_id, time.time(),
4267
osutils.local_time_offset(), submit_branch,
4268
public_branch=public_branch, patch_type=patch_type,
4271
outfile.writelines(directive.to_lines())
4273
subject = '[MERGE] '
4274
if message is not None:
4277
revision = branch.repository.get_revision(revision_id)
4278
subject += revision.get_summary()
4279
basename = directive.get_disk_name(branch)
4280
mail_client.compose_merge_request(mail_to, subject,
4281
outfile.getvalue(), basename)
4288
class cmd_bundle_revisions(cmd_send):
4290
"""Create a merge-directive for submiting changes.
4292
A merge directive provides many things needed for requesting merges:
4294
* A machine-readable description of the merge to perform
4296
* An optional patch that is a preview of the changes requested
4298
* An optional bundle of revision data, so that the changes can be applied
4299
directly from the merge directive, without retrieving data from a
4302
If --no-bundle is specified, then public_branch is needed (and must be
4303
up-to-date), so that the receiver can perform the merge using the
4304
public_branch. The public_branch is always included if known, so that
4305
people can check it later.
4307
The submit branch defaults to the parent, but can be overridden. Both
4308
submit branch and public branch will be remembered if supplied.
4310
If a public_branch is known for the submit_branch, that public submit
4311
branch is used in the merge instructions. This means that a local mirror
4312
can be used as your actual submit branch, once you have set public_branch
4315
Two formats are currently supported: "4" uses revision bundle format 4 and
4316
merge directive format 2. It is significantly faster and smaller than
4317
older formats. It is compatible with Bazaar 0.19 and later. It is the
4318
default. "0.9" uses revision bundle format 0.9 and merge directive
4319
format 1. It is compatible with Bazaar 0.12 - 0.18.
4324
help='Do not include a bundle in the merge directive.'),
4325
Option('no-patch', help='Do not include a preview patch in the merge'
4328
help='Remember submit and public branch.'),
4330
help='Branch to generate the submission from, '
4331
'rather than the one containing the working directory.',
4334
Option('output', short_name='o', help='Write directive to this file.',
4337
RegistryOption.from_kwargs('format',
4338
'Use the specified output format.',
4339
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4340
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4342
aliases = ['bundle']
4344
_see_also = ['send', 'merge']
4348
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4349
no_patch=False, revision=None, remember=False, output=None,
4350
format='4', **kwargs):
4353
return self._run(submit_branch, revision, public_branch, remember,
4354
format, no_bundle, no_patch, output,
4355
kwargs.get('from', '.'), None, None)
3563
server = branch.get_config().get_user_option('smtp_server')
3565
server = 'localhost'
3567
s.sendmail(message['From'], message['To'], message.as_string())
4358
3570
class cmd_tag(Command):
4359
"""Create, remove or modify a tag naming a revision.
3571
"""Create a tag naming a revision.
4361
3573
Tags give human-meaningful names to revisions. Commands that take a -r
4362
3574
(--revision) option can be given -rtag:X, where X is any previously
4421
3630
class cmd_tags(Command):
4424
This command shows a table of tag names and the revisions they reference.
3633
This tag shows a table of tag names and the revisions they reference.
4427
3636
_see_also = ['tag']
4428
3637
takes_options = [
4429
3638
Option('directory',
4430
help='Branch whose tags should be displayed.',
3639
help='Branch whose tags should be displayed',
4431
3640
short_name='d',
4434
RegistryOption.from_kwargs('sort',
4435
'Sort tags by different criteria.', title='Sorting',
4436
alpha='Sort tags lexicographically (default).',
4437
time='Sort tags chronologically.',
4442
3645
@display_command
4448
3649
branch, relpath = Branch.open_containing(directory)
4449
tags = branch.tags.get_tag_dict().items()
4454
elif sort == 'time':
4456
for tag, revid in tags:
4458
revobj = branch.repository.get_revision(revid)
4459
except errors.NoSuchRevision:
4460
timestamp = sys.maxint # place them at the end
3650
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3651
self.outf.write('%-20s %s\n' % (tag_name, target))
3654
# command-line interpretation helper for merge-related commands
3655
def _merge_helper(other_revision, base_revision,
3656
check_clean=True, ignore_zero=False,
3657
this_dir=None, backup_files=False,
3659
file_list=None, show_base=False, reprocess=False,
3662
change_reporter=None,
3664
"""Merge changes into a tree.
3667
list(path, revno) Base for three-way merge.
3668
If [None, None] then a base will be automatically determined.
3670
list(path, revno) Other revision for three-way merge.
3672
Directory to merge changes into; '.' by default.
3674
If true, this_dir must have no uncommitted changes before the
3676
ignore_zero - If true, suppress the "zero conflicts" message when
3677
there are no conflicts; should be set when doing something we expect
3678
to complete perfectly.
3679
file_list - If supplied, merge only changes to selected files.
3681
All available ancestors of other_revision and base_revision are
3682
automatically pulled into the branch.
3684
The revno may be -1 to indicate the last revision on the branch, which is
3687
This function is intended for use from the command line; programmatic
3688
clients might prefer to call merge.merge_inner(), which has less magic
3691
# Loading it late, so that we don't always have to import bzrlib.merge
3692
if merge_type is None:
3693
merge_type = _mod_merge.Merge3Merger
3694
if this_dir is None:
3696
this_tree = WorkingTree.open_containing(this_dir)[0]
3697
if show_base and not merge_type is _mod_merge.Merge3Merger:
3698
raise errors.BzrCommandError("Show-base is not supported for this merge"
3699
" type. %s" % merge_type)
3700
if reprocess and not merge_type.supports_reprocess:
3701
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3702
" type %s." % merge_type)
3703
if reprocess and show_base:
3704
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3705
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3706
# only want to take out a lock_tree_write() if we don't have to pull
3707
# any ancestry. But merge might fetch ancestry in the middle, in
3708
# which case we would need a lock_write().
3709
# Because we cannot upgrade locks, for now we live with the fact that
3710
# the tree will be locked multiple times during a merge. (Maybe
3711
# read-only some of the time, but it means things will get read
3714
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3715
pb=pb, change_reporter=change_reporter)
3716
merger.pp = ProgressPhase("Merge phase", 5, pb)
3717
merger.pp.next_phase()
3718
merger.check_basis(check_clean)
3719
if other_rev_id is not None:
3720
merger.set_other_revision(other_rev_id, this_tree.branch)
3722
merger.set_other(other_revision)
3723
merger.pp.next_phase()
3724
merger.set_base(base_revision)
3725
if merger.base_rev_id == merger.other_rev_id:
3726
note('Nothing to do.')
3728
if file_list is None:
3729
if pull and merger.base_rev_id == merger.this_rev_id:
3730
# FIXME: deduplicate with pull
3731
result = merger.this_tree.pull(merger.this_branch,
3732
False, merger.other_rev_id)
3733
if result.old_revid == result.new_revid:
3734
note('No revisions to pull.')
4462
timestamp = revobj.timestamp
4463
timestamps[revid] = timestamp
4464
tags.sort(key=lambda x: timestamps[x[1]])
4466
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
4467
revno_map = branch.get_revision_id_to_revno_map()
4468
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
4469
for tag, revid in tags ]
4470
for tag, revspec in tags:
4471
self.outf.write('%-20s %s\n' % (tag, revspec))
4474
class cmd_reconfigure(Command):
4475
"""Reconfigure the type of a bzr directory.
4477
A target configuration must be specified.
4479
For checkouts, the bind-to location will be auto-detected if not specified.
4480
The order of preference is
4481
1. For a lightweight checkout, the current bound location.
4482
2. For branches that used to be checkouts, the previously-bound location.
4483
3. The push location.
4484
4. The parent location.
4485
If none of these is available, --bind-to must be specified.
4488
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
4489
takes_args = ['location?']
4490
takes_options = [RegistryOption.from_kwargs('target_type',
4491
title='Target type',
4492
help='The type to reconfigure the directory to.',
4493
value_switches=True, enum_switch=False,
4494
branch='Reconfigure to be an unbound branch '
4495
'with no working tree.',
4496
tree='Reconfigure to be an unbound branch '
4497
'with a working tree.',
4498
checkout='Reconfigure to be a bound branch '
4499
'with a working tree.',
4500
lightweight_checkout='Reconfigure to be a lightweight'
4501
' checkout (with no local history).',
4502
standalone='Reconfigure to be a standalone branch '
4503
'(i.e. stop using shared repository).',
4504
use_shared='Reconfigure to use a shared repository.'),
4505
Option('bind-to', help='Branch to bind checkout to.',
4508
help='Perform reconfiguration even if local changes'
4512
def run(self, location=None, target_type=None, bind_to=None, force=False):
4513
directory = bzrdir.BzrDir.open(location)
4514
if target_type is None:
4515
raise errors.BzrCommandError('No target configuration specified')
4516
elif target_type == 'branch':
4517
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4518
elif target_type == 'tree':
4519
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4520
elif target_type == 'checkout':
4521
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4523
elif target_type == 'lightweight-checkout':
4524
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4526
elif target_type == 'use-shared':
4527
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
4528
elif target_type == 'standalone':
4529
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
4530
reconfiguration.apply(force)
4533
class cmd_switch(Command):
4534
"""Set the branch of a checkout and update.
4536
For lightweight checkouts, this changes the branch being referenced.
4537
For heavyweight checkouts, this checks that there are no local commits
4538
versus the current bound branch, then it makes the local branch a mirror
4539
of the new location and binds to it.
4541
In both cases, the working tree is updated and uncommitted changes
4542
are merged. The user can commit or revert these as they desire.
4544
Pending merges need to be committed or reverted before using switch.
4546
The path to the branch to switch to can be specified relative to the parent
4547
directory of the current branch. For example, if you are currently in a
4548
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4552
takes_args = ['to_location']
4553
takes_options = [Option('force',
4554
help='Switch even if local commits will be lost.')
4557
def run(self, to_location, force=False):
4558
from bzrlib import switch
4560
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4562
to_branch = Branch.open(to_location)
4563
except errors.NotBranchError:
4564
to_branch = Branch.open(
4565
control_dir.open_branch().base + '../' + to_location)
4566
switch.switch(control_dir, to_branch, force)
4567
note('Switched to branch: %s',
4568
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4571
class cmd_hooks(Command):
4572
"""Show a branch's currently registered hooks.
4576
takes_args = ['path?']
4578
def run(self, path=None):
4581
branch_hooks = Branch.open(path).hooks
4582
for hook_type in branch_hooks:
4583
hooks = branch_hooks[hook_type]
4584
self.outf.write("%s:\n" % (hook_type,))
4587
self.outf.write(" %s\n" %
4588
(branch_hooks.get_hook_name(hook),))
4590
self.outf.write(" <no hooks installed>\n")
4593
def _create_prefix(cur_transport):
4594
needed = [cur_transport]
4595
# Recurse upwards until we can create a directory successfully
4597
new_transport = cur_transport.clone('..')
4598
if new_transport.base == cur_transport.base:
4599
raise errors.BzrCommandError(
4600
"Failed to create path prefix for %s."
4601
% cur_transport.base)
4603
new_transport.mkdir('.')
4604
except errors.NoSuchFile:
4605
needed.append(new_transport)
4606
cur_transport = new_transport
4609
# Now we only need to create child directories
4611
cur_transport = needed.pop()
4612
cur_transport.ensure_base()
3736
note('Now on revision %d.' % result.new_revno)
3738
merger.backup_files = backup_files
3739
merger.merge_type = merge_type
3740
merger.set_interesting_files(file_list)
3741
merger.show_base = show_base
3742
merger.reprocess = reprocess
3743
conflicts = merger.do_merge()
3744
if file_list is None:
3745
merger.set_pending()
3752
merge = _merge_helper
4615
3755
# these get imported and then picked up by the scan for cmd_*