783
515
takes_args = ['names*']
784
takes_options = [Option("after", help="Move only the bzr identifier"
785
" of the file, because the file has already been moved."),
786
Option('auto', help='Automatically guess renames.'),
787
Option('dry-run', help='Avoid making changes when guessing renames.'),
516
takes_options = [Option("after", help="move only the bzr identifier"
517
" of the file (file has already been moved). Use this flag if"
518
" bzr is not able to detect this itself.")]
789
519
aliases = ['move', 'rename']
790
520
encoding_type = 'replace'
792
def run(self, names_list, after=False, auto=False, dry_run=False):
794
return self.run_auto(names_list, after, dry_run)
796
raise errors.BzrCommandError('--dry-run requires --auto.')
522
def run(self, names_list, after=False):
797
523
if names_list is None:
799
526
if len(names_list) < 2:
800
527
raise errors.BzrCommandError("missing file argument")
801
tree, rel_names = tree_files(names_list, canonicalize=False)
802
tree.lock_tree_write()
803
self.add_cleanup(tree.unlock)
804
self._run(tree, names_list, rel_names, after)
806
def run_auto(self, names_list, after, dry_run):
807
if names_list is not None and len(names_list) > 1:
808
raise errors.BzrCommandError('Only one path may be specified to'
811
raise errors.BzrCommandError('--after cannot be specified with'
813
work_tree, file_list = tree_files(names_list, default_branch='.')
814
work_tree.lock_tree_write()
815
self.add_cleanup(work_tree.unlock)
816
rename_map.RenameMap.guess_renames(work_tree, dry_run)
818
def _run(self, tree, names_list, rel_names, after):
819
into_existing = osutils.isdir(names_list[-1])
820
if into_existing and len(names_list) == 2:
822
# a. case-insensitive filesystem and change case of dir
823
# b. move directory after the fact (if the source used to be
824
# a directory, but now doesn't exist in the working tree
825
# and the target is an existing directory, just rename it)
826
if (not tree.case_sensitive
827
and rel_names[0].lower() == rel_names[1].lower()):
828
into_existing = False
831
# 'fix' the case of a potential 'from'
832
from_id = tree.path2id(
833
tree.get_canonical_inventory_path(rel_names[0]))
834
if (not osutils.lexists(names_list[0]) and
835
from_id and inv.get_file_kind(from_id) == "directory"):
836
into_existing = False
528
tree, rel_names = tree_files(names_list)
530
if os.path.isdir(names_list[-1]):
839
531
# move into existing directory
840
# All entries reference existing inventory items, so fix them up
841
# for cicp file-systems.
842
rel_names = tree.get_canonical_inventory_paths(rel_names)
843
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
845
self.outf.write("%s => %s\n" % (src, dest))
532
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
533
self.outf.write("%s => %s\n" % pair)
847
535
if len(names_list) != 2:
848
536
raise errors.BzrCommandError('to mv multiple files the'
849
537
' destination must be a versioned'
852
# for cicp file-systems: the src references an existing inventory
854
src = tree.get_canonical_inventory_path(rel_names[0])
855
# Find the canonical version of the destination: In all cases, the
856
# parent of the target must be in the inventory, so we fetch the
857
# canonical version from there (we do not always *use* the
858
# canonicalized tail portion - we may be attempting to rename the
860
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
861
dest_parent = osutils.dirname(canon_dest)
862
spec_tail = osutils.basename(rel_names[1])
863
# For a CICP file-system, we need to avoid creating 2 inventory
864
# entries that differ only by case. So regardless of the case
865
# we *want* to use (ie, specified by the user or the file-system),
866
# we must always choose to use the case of any existing inventory
867
# items. The only exception to this is when we are attempting a
868
# case-only rename (ie, canonical versions of src and dest are
870
dest_id = tree.path2id(canon_dest)
871
if dest_id is None or tree.path2id(src) == dest_id:
872
# No existing item we care about, so work out what case we
873
# are actually going to use.
875
# If 'after' is specified, the tail must refer to a file on disk.
877
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
879
# pathjoin with an empty tail adds a slash, which breaks
881
dest_parent_fq = tree.basedir
883
dest_tail = osutils.canonical_relpath(
885
osutils.pathjoin(dest_parent_fq, spec_tail))
887
# not 'after', so case as specified is used
888
dest_tail = spec_tail
890
# Use the existing item so 'mv' fails with AlreadyVersioned.
891
dest_tail = os.path.basename(canon_dest)
892
dest = osutils.pathjoin(dest_parent, dest_tail)
893
mutter("attempting to move %s => %s", src, dest)
894
tree.rename_one(src, dest, after=after)
896
self.outf.write("%s => %s\n" % (src, dest))
539
tree.rename_one(rel_names[0], rel_names[1], after=after)
540
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
899
543
class cmd_pull(Command):
900
544
"""Turn this branch into a mirror of another branch.
902
By default, this command only works on branches that have not diverged.
903
Branches are considered diverged if the destination branch's most recent
904
commit is one that has not been merged (directly or indirectly) into the
546
This command only works on branches that have not diverged. Branches are
547
considered diverged if the destination branch's most recent commit is one
548
that has not been merged (directly or indirectly) into the parent.
907
550
If branches have diverged, you can use 'bzr merge' to integrate the changes
908
551
from one into the other. Once one branch has merged, the other should
909
552
be able to pull it again.
911
If you want to replace your local changes and just want your branch to
912
match the remote one, use pull --overwrite. This will work even if the two
913
branches have diverged.
554
If you want to forget your local changes and just update your branch to
555
match the remote one, use pull --overwrite.
915
557
If there is no default location set, the first pull will set it. After
916
558
that, you can omit the location to use the default. To change the
917
559
default, use --remember. The value will only be saved if the remote
918
560
location can be accessed.
920
Note: The location can be specified either in the form of a branch,
921
or in the form of a path to a file containing a merge directive generated
925
_see_also = ['push', 'update', 'status-flags', 'send']
926
takes_options = ['remember', 'overwrite', 'revision',
927
custom_help('verbose',
928
help='Show logs of pulled revisions.'),
563
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
929
564
Option('directory',
930
help='Branch to pull into, '
931
'rather than the one containing the working directory.',
565
help='branch to pull into, '
566
'rather than the one containing the working directory',
936
help="Perform a local pull in a bound "
937
"branch. Local pulls are not applied to "
941
571
takes_args = ['location?']
942
572
encoding_type = 'replace'
944
574
def run(self, location=None, remember=False, overwrite=False,
945
575
revision=None, verbose=False,
946
directory=None, local=False):
577
from bzrlib.tag import _merge_tags_if_possible
947
578
# FIXME: too much stuff is in the command class
948
579
revision_id = None
1048
666
location can be accessed.
1051
_see_also = ['pull', 'update', 'working-trees']
1052
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
669
takes_options = ['remember', 'overwrite', 'verbose',
1053
670
Option('create-prefix',
1054
671
help='Create the path leading up to the branch '
1055
'if it does not already exist.'),
672
'if it does not already exist'),
1056
673
Option('directory',
1057
help='Branch to push from, '
1058
'rather than the one containing the working directory.',
674
help='branch to push from, '
675
'rather than the one containing the working directory',
1062
679
Option('use-existing-dir',
1063
680
help='By default push will fail if the target'
1064
681
' directory exists, but does not already'
1065
' have a control directory. This flag will'
682
' have a control directory. This flag will'
1066
683
' allow push to proceed.'),
1068
help='Create a stacked branch that references the public location '
1069
'of the parent branch.'),
1070
Option('stacked-on',
1071
help='Create a stacked branch that refers to another branch '
1072
'for the commit history. Only the work not present in the '
1073
'referenced branch is included in the branch created.',
1076
help='Refuse to push if there are uncommitted changes in'
1077
' the working tree, --no-strict disables the check.'),
1079
685
takes_args = ['location?']
1080
686
encoding_type = 'replace'
1082
688
def run(self, location=None, remember=False, overwrite=False,
1083
create_prefix=False, verbose=False, revision=None,
1084
use_existing_dir=False, directory=None, stacked_on=None,
1085
stacked=False, strict=None):
1086
from bzrlib.push import _show_push_branch
689
create_prefix=False, verbose=False,
690
use_existing_dir=False,
692
# FIXME: Way too big! Put this into a function called from the
1088
694
if directory is None:
1090
# Get the source branch
1092
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1096
# Get the tip's revision_id
1097
revision = _get_one_revision('push', revision)
1098
if revision is not None:
1099
revision_id = revision.in_history(br_from).rev_id
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
tree, more='Use --no-strict to force the push.')
1113
# Get the stacked_on branch, if any
1114
if stacked_on is not None:
1115
stacked_on = urlutils.normalize_url(stacked_on)
1117
parent_url = br_from.get_parent()
1119
parent = Branch.open(parent_url)
1120
stacked_on = parent.get_public_branch()
1122
# I considered excluding non-http url's here, thus forcing
1123
# 'public' branches only, but that only works for some
1124
# users, so it's best to just depend on the user spotting an
1125
# error by the feedback given to them. RBC 20080227.
1126
stacked_on = parent_url
1128
raise errors.BzrCommandError(
1129
"Could not determine branch to refer to.")
1131
# Get the destination location
696
br_from = Branch.open_containing(directory)[0]
697
stored_loc = br_from.get_push_location()
1132
698
if location is None:
1133
stored_loc = br_from.get_push_location()
1134
699
if stored_loc is None:
1135
raise errors.BzrCommandError(
1136
"No push location known or specified.")
700
raise errors.BzrCommandError("No push location known or specified.")
1138
702
display_url = urlutils.unescape_for_display(stored_loc,
1139
703
self.outf.encoding)
1140
self.outf.write("Using saved push location: %s\n" % display_url)
704
self.outf.write("Using saved location: %s\n" % display_url)
1141
705
location = stored_loc
1143
_show_push_branch(br_from, revision_id, location, self.outf,
1144
verbose=verbose, overwrite=overwrite, remember=remember,
1145
stacked_on=stacked_on, create_prefix=create_prefix,
1146
use_existing_dir=use_existing_dir)
707
to_transport = transport.get_transport(location)
708
location_url = to_transport.base
710
br_to = repository_to = dir_to = None
712
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
713
except errors.NotBranchError:
714
pass # Didn't find anything
716
# If we can open a branch, use its direct repository, otherwise see
717
# if there is a repository without a branch.
719
br_to = dir_to.open_branch()
720
except errors.NotBranchError:
721
# Didn't find a branch, can we find a repository?
723
repository_to = dir_to.find_repository()
724
except errors.NoRepositoryPresent:
727
# Found a branch, so we must have found a repository
728
repository_to = br_to.repository
732
# The destination doesn't exist; create it.
733
# XXX: Refactor the create_prefix/no_create_prefix code into a
734
# common helper function
736
to_transport.mkdir('.')
737
except errors.FileExists:
738
if not use_existing_dir:
739
raise errors.BzrCommandError("Target directory %s"
740
" already exists, but does not have a valid .bzr"
741
" directory. Supply --use-existing-dir to push"
742
" there anyway." % location)
743
except errors.NoSuchFile:
744
if not create_prefix:
745
raise errors.BzrCommandError("Parent directory of %s"
747
"\nYou may supply --create-prefix to create all"
748
" leading parent directories."
751
cur_transport = to_transport
752
needed = [cur_transport]
753
# Recurse upwards until we can create a directory successfully
755
new_transport = cur_transport.clone('..')
756
if new_transport.base == cur_transport.base:
757
raise errors.BzrCommandError("Failed to create path"
761
new_transport.mkdir('.')
762
except errors.NoSuchFile:
763
needed.append(new_transport)
764
cur_transport = new_transport
768
# Now we only need to create child directories
770
cur_transport = needed.pop()
771
cur_transport.mkdir('.')
773
# Now the target directory exists, but doesn't have a .bzr
774
# directory. So we need to create it, along with any work to create
775
# all of the dependent branches, etc.
776
dir_to = br_from.bzrdir.clone(location_url,
777
revision_id=br_from.last_revision())
778
br_to = dir_to.open_branch()
779
# TODO: Some more useful message about what was copied
780
note('Created new branch.')
781
# We successfully created the target, remember it
782
if br_from.get_push_location() is None or remember:
783
br_from.set_push_location(br_to.base)
784
elif repository_to is None:
785
# we have a bzrdir but no branch or repository
786
# XXX: Figure out what to do other than complain.
787
raise errors.BzrCommandError("At %s you have a valid .bzr control"
788
" directory, but not a branch or repository. This is an"
789
" unsupported configuration. Please move the target directory"
790
" out of the way and try again."
793
# We have a repository but no branch, copy the revisions, and then
795
last_revision_id = br_from.last_revision()
796
repository_to.fetch(br_from.repository,
797
revision_id=last_revision_id)
798
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
799
note('Created new branch.')
800
if br_from.get_push_location() is None or remember:
801
br_from.set_push_location(br_to.base)
802
else: # We have a valid to branch
803
# We were able to connect to the remote location, so remember it
804
# we don't need to successfully push because of possible divergence.
805
if br_from.get_push_location() is None or remember:
806
br_from.set_push_location(br_to.base)
807
old_rh = br_to.revision_history()
810
tree_to = dir_to.open_workingtree()
811
except errors.NotLocalUrl:
812
warning('This transport does not update the working '
813
'tree of: %s' % (br_to.base,))
814
push_result = br_from.push(br_to, overwrite)
815
except errors.NoWorkingTree:
816
push_result = br_from.push(br_to, overwrite)
820
push_result = br_from.push(tree_to.branch, overwrite)
824
except errors.DivergedBranches:
825
raise errors.BzrCommandError('These branches have diverged.'
826
' Try using "merge" and then "push".')
827
if push_result is not None:
828
push_result.report(self.outf)
830
new_rh = br_to.revision_history()
833
from bzrlib.log import show_changed_revisions
834
show_changed_revisions(br_to, old_rh, new_rh,
837
# we probably did a clone rather than a push, so a message was
1149
842
class cmd_branch(Command):
1150
"""Create a new branch that is a copy of an existing branch.
843
"""Create a new copy of a branch.
1152
845
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1153
846
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1154
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
1155
is derived from the FROM_LOCATION by stripping a leading scheme or drive
1156
identifier, if any. For example, "branch lp:foo-bar" will attempt to
1159
848
To retrieve the branch as of a particular revision, supply the --revision
1160
849
parameter, as in "branch foo/bar -r 5".
1163
_see_also = ['checkout']
1164
851
takes_args = ['from_location', 'to_location?']
1165
takes_options = ['revision', Option('hardlink',
1166
help='Hard-link working tree files where possible.'),
1168
help="Create a branch without a working-tree."),
1170
help="Switch the checkout in the current directory "
1171
"to the new branch."),
1173
help='Create a stacked branch referring to the source branch. '
1174
'The new branch will depend on the availability of the source '
1175
'branch for all operations.'),
1176
Option('standalone',
1177
help='Do not use a shared repository, even if available.'),
1178
Option('use-existing-dir',
1179
help='By default branch will fail if the target'
1180
' directory exists, but does not already'
1181
' have a control directory. This flag will'
1182
' allow branch to proceed.'),
1184
help="Bind new branch to from location."),
852
takes_options = ['revision']
1186
853
aliases = ['get', 'clone']
1188
def run(self, from_location, to_location=None, revision=None,
1189
hardlink=False, stacked=False, standalone=False, no_tree=False,
1190
use_existing_dir=False, switch=False, bind=False):
1191
from bzrlib import switch as _mod_switch
855
def run(self, from_location, to_location=None, revision=None):
1192
856
from bzrlib.tag import _merge_tags_if_possible
1193
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1195
revision = _get_one_revision('branch', revision)
859
elif len(revision) > 1:
860
raise errors.BzrCommandError(
861
'bzr branch --revision takes exactly 1 revision value')
863
br_from = Branch.open(from_location)
1196
864
br_from.lock_read()
1197
self.add_cleanup(br_from.unlock)
1198
if revision is not None:
1199
revision_id = revision.as_revision_id(br_from)
1201
# FIXME - wt.last_revision, fallback to branch, fall back to
1202
# None or perhaps NULL_REVISION to mean copy nothing
1204
revision_id = br_from.last_revision()
1205
if to_location is None:
1206
to_location = urlutils.derive_to_location(from_location)
1207
to_transport = transport.get_transport(to_location)
1209
to_transport.mkdir('.')
1210
except errors.FileExists:
1211
if not use_existing_dir:
1212
raise errors.BzrCommandError('Target directory "%s" '
1213
'already exists.' % to_location)
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1217
except errors.NotBranchError:
1220
raise errors.AlreadyBranchError(to_location)
1221
except errors.NoSuchFile:
1222
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1225
# preserve whatever source format we have.
1226
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1227
possible_transports=[to_transport],
1228
accelerator_tree=accelerator_tree,
1229
hardlink=hardlink, stacked=stacked,
1230
force_new_repo=standalone,
1231
create_tree_if_local=not no_tree,
1232
source_branch=br_from)
1233
branch = dir.open_branch()
1234
except errors.NoSuchRevision:
1235
to_transport.delete_tree('.')
1236
msg = "The branch %s has no revision %s." % (from_location,
1238
raise errors.BzrCommandError(msg)
1239
_merge_tags_if_possible(br_from, branch)
1240
# If the source branch is stacked, the new branch may
1241
# be stacked whether we asked for that explicitly or not.
1242
# We therefore need a try/except here and not just 'if stacked:'
1244
note('Created new stacked branch referring to %s.' %
1245
branch.get_stacked_on_url())
1246
except (errors.NotStacked, errors.UnstackableBranchFormat,
1247
errors.UnstackableRepositoryFormat), e:
866
if len(revision) == 1 and revision[0] is not None:
867
revision_id = revision[0].in_history(br_from)[1]
869
# FIXME - wt.last_revision, fallback to branch, fall back to
870
# None or perhaps NULL_REVISION to mean copy nothing
872
revision_id = br_from.last_revision()
873
if to_location is None:
874
to_location = os.path.basename(from_location.rstrip("/\\"))
877
name = os.path.basename(to_location) + '\n'
879
to_transport = transport.get_transport(to_location)
881
to_transport.mkdir('.')
882
except errors.FileExists:
883
raise errors.BzrCommandError('Target directory "%s" already'
884
' exists.' % to_location)
885
except errors.NoSuchFile:
886
raise errors.BzrCommandError('Parent of "%s" does not exist.'
889
# preserve whatever source format we have.
890
dir = br_from.bzrdir.sprout(to_transport.base, revision_id)
891
branch = dir.open_branch()
892
except errors.NoSuchRevision:
893
to_transport.delete_tree('.')
894
msg = "The branch %s has no revision %s." % (from_location, revision[0])
895
raise errors.BzrCommandError(msg)
897
branch.control_files.put_utf8('branch-name', name)
898
_merge_tags_if_possible(br_from, branch)
1248
899
note('Branched %d revision(s).' % branch.revno())
1250
# Bind to the parent
1251
parent_branch = Branch.open(from_location)
1252
branch.bind(parent_branch)
1253
note('New branch bound to %s' % from_location)
1255
# Switch to the new branch
1256
wt, _ = WorkingTree.open_containing('.')
1257
_mod_switch.switch(wt.bzrdir, branch)
1258
note('Switched to branch: %s',
1259
urlutils.unescape_for_display(branch.base, 'utf-8'))
1262
904
class cmd_checkout(Command):
1334
978
# TODO: Option to show renames between two historical versions.
1336
980
# TODO: Only show renames under dir, rather than in the whole branch.
1337
_see_also = ['status']
1338
981
takes_args = ['dir?']
1340
983
@display_command
1341
984
def run(self, dir=u'.'):
1342
985
tree = WorkingTree.open_containing(dir)[0]
1343
986
tree.lock_read()
1344
self.add_cleanup(tree.unlock)
1345
new_inv = tree.inventory
1346
old_tree = tree.basis_tree()
1347
old_tree.lock_read()
1348
self.add_cleanup(old_tree.unlock)
1349
old_inv = old_tree.inventory
1351
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1352
for f, paths, c, v, p, n, k, e in iterator:
1353
if paths[0] == paths[1]:
1357
renames.append(paths)
1359
for old_name, new_name in renames:
1360
self.outf.write("%s => %s\n" % (old_name, new_name))
988
new_inv = tree.inventory
989
old_tree = tree.basis_tree()
992
old_inv = old_tree.inventory
993
renames = list(_mod_tree.find_renames(old_inv, new_inv))
995
for old_name, new_name in renames:
996
self.outf.write("%s => %s\n" % (old_name, new_name))
1363
1003
class cmd_update(Command):
1364
1004
"""Update a tree to have the latest code committed to its branch.
1366
1006
This will perform a merge into the working tree, and may generate
1367
conflicts. If you have any local changes, you will still
1007
conflicts. If you have any local changes, you will still
1368
1008
need to commit them after the update for the update to be complete.
1370
If you want to discard your local changes, you can just do a
1010
If you want to discard your local changes, you can just do a
1371
1011
'bzr revert' instead of 'bzr commit' after the update.
1373
If the tree's branch is bound to a master branch, it will also update
1374
the branch from the master.
1377
_see_also = ['pull', 'working-trees', 'status-flags']
1378
1013
takes_args = ['dir?']
1379
takes_options = ['revision']
1380
1014
aliases = ['up']
1382
def run(self, dir='.', revision=None):
1383
if revision is not None and len(revision) != 1:
1384
raise errors.BzrCommandError(
1385
"bzr update --revision takes exactly one revision")
1016
def run(self, dir='.'):
1386
1017
tree = WorkingTree.open_containing(dir)[0]
1387
branch = tree.branch
1388
possible_transports = []
1389
master = branch.get_master_branch(
1390
possible_transports=possible_transports)
1018
master = tree.branch.get_master_branch()
1391
1019
if master is not None:
1392
1020
tree.lock_write()
1393
branch_location = master.base
1395
1022
tree.lock_tree_write()
1396
branch_location = tree.branch.base
1397
self.add_cleanup(tree.unlock)
1398
# get rid of the final '/' and be ready for display
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1401
existing_pending_merges = tree.get_parent_ids()[1:]
1405
# may need to fetch data into a heavyweight checkout
1406
# XXX: this may take some time, maybe we should display a
1408
old_tip = branch.update(possible_transports)
1409
if revision is not None:
1410
revision_id = revision[0].as_revision_id(branch)
1412
revision_id = branch.last_revision()
1413
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1414
revno = branch.revision_id_to_revno(revision_id)
1415
note("Tree is up to date at revision %d of branch %s" %
1416
(revno, branch_location))
1418
view_info = _get_view_info_for_change_reporter(tree)
1419
change_reporter = delta._ChangeReporter(
1420
unversioned_filter=tree.is_ignored,
1421
view_info=view_info)
1423
conflicts = tree.update(
1425
possible_transports=possible_transports,
1426
revision=revision_id,
1428
except errors.NoSuchRevision, e:
1429
raise errors.BzrCommandError(
1430
"branch has no revision %s\n"
1431
"bzr update --revision only works"
1432
" for a revision in the branch history"
1434
revno = tree.branch.revision_id_to_revno(
1435
_mod_revision.ensure_null(tree.last_revision()))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
if tree.get_parent_ids()[1:] != existing_pending_merges:
1439
note('Your local commits will now show as pending merges with '
1440
"'bzr status', and can be committed with 'bzr commit'.")
1024
existing_pending_merges = tree.get_parent_ids()[1:]
1025
last_rev = tree.last_revision()
1026
if last_rev == tree.branch.last_revision():
1027
# may be up to date, check master too.
1028
master = tree.branch.get_master_branch()
1029
if master is None or last_rev == master.last_revision():
1030
revno = tree.branch.revision_id_to_revno(last_rev)
1031
note("Tree is up to date at revision %d." % (revno,))
1033
conflicts = tree.update()
1034
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1035
note('Updated to revision %d.' % (revno,))
1036
if tree.get_parent_ids()[1:] != existing_pending_merges:
1037
note('Your local commits will now show as pending merges with '
1038
"'bzr status', and can be committed with 'bzr commit'.")
1447
1047
class cmd_info(Command):
1448
1048
"""Show information about a working tree, branch or repository.
1450
1050
This command will show all known locations and formats associated to the
1451
tree, branch or repository.
1453
In verbose mode, statistical information is included with each report.
1454
To see extended statistic information, use a verbosity level of 2 or
1455
higher by specifying the verbose option multiple times, e.g. -vv.
1051
tree, branch or repository. Statistical information is included with
1457
1054
Branches and working trees will also report any missing revisions.
1461
Display information on the format and related locations:
1465
Display the above together with extended format information and
1466
basic statistics (like the number of files in the working tree and
1467
number of revisions in the branch and repository):
1471
Display the above together with number of committers to the branch:
1475
_see_also = ['revno', 'working-trees', 'repositories']
1476
1056
takes_args = ['location?']
1477
1057
takes_options = ['verbose']
1478
encoding_type = 'replace'
1480
1059
@display_command
1481
1060
def run(self, location=None, verbose=False):
1483
noise_level = get_verbosity_level()
1486
1061
from bzrlib.info import show_bzrdir_info
1487
1062
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1488
verbose=noise_level, outfile=self.outf)
1491
1066
class cmd_remove(Command):
1492
"""Remove files or directories.
1494
This makes bzr stop tracking changes to the specified files. bzr will delete
1495
them if they can easily be recovered using revert. If no options or
1496
parameters are given bzr will scan for files that are being tracked by bzr
1497
but missing in your tree and stop tracking them for you.
1067
"""Make a file unversioned.
1069
This makes bzr stop tracking changes to a versioned file. It does
1070
not delete the working copy.
1072
You can specify one or more files, and/or --new. If you specify --new,
1073
only 'added' files will be removed. If you specify both, then new files
1074
in the specified directories will be removed. If the directories are
1075
also new, they will also be removed.
1499
1077
takes_args = ['file*']
1500
takes_options = ['verbose',
1501
Option('new', help='Only remove files that have never been committed.'),
1502
RegistryOption.from_kwargs('file-deletion-strategy',
1503
'The file deletion mode to be used.',
1504
title='Deletion Strategy', value_switches=True, enum_switch=False,
1505
safe='Only delete files if they can be'
1506
' safely recovered (default).',
1507
keep='Delete from bzr but leave the working copy.',
1508
force='Delete all the specified files, even if they can not be '
1509
'recovered and even if they are non-empty directories.')]
1510
aliases = ['rm', 'del']
1078
takes_options = ['verbose', Option('new', help='remove newly-added files')]
1511
1080
encoding_type = 'replace'
1513
def run(self, file_list, verbose=False, new=False,
1514
file_deletion_strategy='safe'):
1082
def run(self, file_list, verbose=False, new=False):
1515
1083
tree, file_list = tree_files(file_list)
1517
if file_list is not None:
1518
file_list = [f for f in file_list]
1521
self.add_cleanup(tree.unlock)
1522
# Heuristics should probably all move into tree.remove_smart or
1085
if file_list is None:
1086
raise errors.BzrCommandError('Specify one or more files to'
1087
' remove, or use --new.')
1525
1089
added = tree.changes_from(tree.basis_tree(),
1526
1090
specific_files=file_list).added
1527
1091
file_list = sorted([f[0] for f in added], reverse=True)
1528
1092
if len(file_list) == 0:
1529
1093
raise errors.BzrCommandError('No matching files.')
1530
elif file_list is None:
1531
# missing files show up in iter_changes(basis) as
1532
# versioned-with-no-kind.
1534
for change in tree.iter_changes(tree.basis_tree()):
1535
# Find paths in the working tree that have no kind:
1536
if change[1][1] is not None and change[6][1] is None:
1537
missing.append(change[1][1])
1538
file_list = sorted(missing, reverse=True)
1539
file_deletion_strategy = 'keep'
1540
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1541
keep_files=file_deletion_strategy=='keep',
1542
force=file_deletion_strategy=='force')
1094
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1545
1097
class cmd_file_id(Command):
2057
1528
self.outf.write(tree.basedir + '\n')
2060
def _parse_limit(limitstring):
2062
return int(limitstring)
2064
msg = "The limit argument must be an integer."
2065
raise errors.BzrCommandError(msg)
2068
def _parse_levels(s):
2072
msg = "The levels argument must be an integer."
2073
raise errors.BzrCommandError(msg)
2076
1531
class cmd_log(Command):
2077
"""Show historical log for a branch or subset of a branch.
2079
log is bzr's default tool for exploring the history of a branch.
2080
The branch to use is taken from the first parameter. If no parameters
2081
are given, the branch containing the working directory is logged.
2082
Here are some simple examples::
2084
bzr log log the current branch
2085
bzr log foo.py log a file in its branch
2086
bzr log http://server/branch log a branch on a server
2088
The filtering, ordering and information shown for each revision can
2089
be controlled as explained below. By default, all revisions are
2090
shown sorted (topologically) so that newer revisions appear before
2091
older ones and descendants always appear before ancestors. If displayed,
2092
merged revisions are shown indented under the revision in which they
2097
The log format controls how information about each revision is
2098
displayed. The standard log formats are called ``long``, ``short``
2099
and ``line``. The default is long. See ``bzr help log-formats``
2100
for more details on log formats.
2102
The following options can be used to control what information is
2105
-l N display a maximum of N revisions
2106
-n N display N levels of revisions (0 for all, 1 for collapsed)
2107
-v display a status summary (delta) for each revision
2108
-p display a diff (patch) for each revision
2109
--show-ids display revision-ids (and file-ids), not just revnos
2111
Note that the default number of levels to display is a function of the
2112
log format. If the -n option is not used, the standard log formats show
2113
just the top level (mainline).
2115
Status summaries are shown using status flags like A, M, etc. To see
2116
the changes explained using words like ``added`` and ``modified``
2117
instead, use the -vv option.
2121
To display revisions from oldest to newest, use the --forward option.
2122
In most cases, using this option will have little impact on the total
2123
time taken to produce a log, though --forward does not incrementally
2124
display revisions like --reverse does when it can.
2126
:Revision filtering:
2128
The -r option can be used to specify what revision or range of revisions
2129
to filter against. The various forms are shown below::
2131
-rX display revision X
2132
-rX.. display revision X and later
2133
-r..Y display up to and including revision Y
2134
-rX..Y display from X to Y inclusive
2136
See ``bzr help revisionspec`` for details on how to specify X and Y.
2137
Some common examples are given below::
2139
-r-1 show just the tip
2140
-r-10.. show the last 10 mainline revisions
2141
-rsubmit:.. show what's new on this branch
2142
-rancestor:path.. show changes since the common ancestor of this
2143
branch and the one at location path
2144
-rdate:yesterday.. show changes since yesterday
2146
When logging a range of revisions using -rX..Y, log starts at
2147
revision Y and searches back in history through the primary
2148
("left-hand") parents until it finds X. When logging just the
2149
top level (using -n1), an error is reported if X is not found
2150
along the way. If multi-level logging is used (-n0), X may be
2151
a nested merge revision and the log will be truncated accordingly.
2155
If parameters are given and the first one is not a branch, the log
2156
will be filtered to show only those revisions that changed the
2157
nominated files or directories.
2159
Filenames are interpreted within their historical context. To log a
2160
deleted file, specify a revision range so that the file existed at
2161
the end or start of the range.
2163
Historical context is also important when interpreting pathnames of
2164
renamed files/directories. Consider the following example:
2166
* revision 1: add tutorial.txt
2167
* revision 2: modify tutorial.txt
2168
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2172
* ``bzr log guide.txt`` will log the file added in revision 1
2174
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2176
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2177
the original file in revision 2.
2179
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2180
was no file called guide.txt in revision 2.
2182
Renames are always followed by log. By design, there is no need to
2183
explicitly ask for this (and no way to stop logging a file back
2184
until it was last renamed).
2188
The --message option can be used for finding revisions that match a
2189
regular expression in a commit message.
2193
GUI tools and IDEs are often better at exploring history than command
2194
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2195
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2196
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2197
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2199
You may find it useful to add the aliases below to ``bazaar.conf``::
2203
top = log -l10 --line
2206
``bzr tip`` will then show the latest revision while ``bzr top``
2207
will show the last 10 mainline revisions. To see the details of a
2208
particular revision X, ``bzr show -rX``.
2210
If you are interested in looking deeper into a particular merge X,
2211
use ``bzr log -n0 -rX``.
2213
``bzr log -v`` on a branch with lots of history is currently
2214
very slow. A fix for this issue is currently under development.
2215
With or without that fix, it is recommended that a revision range
2216
be given when using the -v option.
2218
bzr has a generic full-text matching plugin, bzr-search, that can be
2219
used to find revisions matching user names, commit messages, etc.
2220
Among other features, this plugin can find all revisions containing
2221
a list of words but not others.
2223
When exploring non-mainline history on large projects with deep
2224
history, the performance of log can be greatly improved by installing
2225
the historycache plugin. This plugin buffers historical information
2226
trading disk space for faster speed.
1532
"""Show log of a branch, file, or directory.
1534
By default show the log of the branch containing the working directory.
1536
To request a range of logs, you can use the command -r begin..end
1537
-r revision requests a specific revision, -r ..end or -r begin.. are
1543
bzr log -r -10.. http://server/branch
2228
takes_args = ['file*']
2229
_see_also = ['log-formats', 'revisionspec']
2232
help='Show from oldest to newest.'),
2234
custom_help('verbose',
2235
help='Show files changed in each revision.'),
2239
type=bzrlib.option._parse_revision_str,
2241
help='Show just the specified revision.'
2242
' See also "help revisionspec".'),
2246
help='Number of levels to display - 0 for all, 1 for flat.',
2248
type=_parse_levels),
2251
help='Show revisions whose message matches this '
2252
'regular expression.',
2256
help='Limit the output to the first N revisions.',
2261
help='Show changes made in each revision as a patch.'),
2262
Option('include-merges',
2263
help='Show merged revisions like --levels 0 does.'),
1546
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1548
takes_args = ['location?']
1549
takes_options = [Option('forward',
1550
help='show from oldest to newest'),
1554
help='show files changed in each revision'),
1555
'show-ids', 'revision',
1559
help='show revisions whose message matches this regexp',
2265
1562
encoding_type = 'replace'
2267
1564
@display_command
2268
def run(self, file_list=None, timezone='original',
1565
def run(self, location=None, timezone='original',
2270
1567
show_ids=False,
2274
1570
log_format=None,
2279
include_merges=False):
2280
from bzrlib.log import (
2282
make_log_request_dict,
2283
_get_info_for_log_files,
1572
from bzrlib.log import show_log
1573
assert message is None or isinstance(message, basestring), \
1574
"invalid message argument %r" % message
2285
1575
direction = (forward and 'forward') or 'reverse'
2290
raise errors.BzrCommandError(
2291
'--levels and --include-merges are mutually exclusive')
2293
if change is not None:
2295
raise errors.RangeInChangeOption()
2296
if revision is not None:
2297
raise errors.BzrCommandError(
2298
'--revision and --change are mutually exclusive')
2303
filter_by_dir = False
2305
# find the file ids to log and check for directory filtering
2306
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2307
revision, file_list)
2308
self.add_cleanup(b.unlock)
2309
for relpath, file_id, kind in file_info_list:
1580
# find the file id to log:
1582
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1586
tree = b.basis_tree()
1587
file_id = tree.path2id(fp)
2310
1588
if file_id is None:
2311
1589
raise errors.BzrCommandError(
2312
"Path unknown at end or start of revision range: %s" %
2314
# If the relpath is the top of the tree, we log everything
2319
file_ids.append(file_id)
2320
filter_by_dir = filter_by_dir or (
2321
kind in ['directory', 'tree-reference'])
1590
"Path does not have any revision history: %s" %
2324
# FIXME ? log the current subdir only RBC 20060203
1594
# FIXME ? log the current subdir only RBC 20060203
2325
1595
if revision is not None \
2326
1596
and len(revision) > 0 and revision[0].get_branch():
2327
1597
location = revision[0].get_branch()
3457
2318
takes_args = ['testspecs*']
3458
2319
takes_options = ['verbose',
3460
help='Stop when one test fails.',
2321
help='stop when one test fails',
3461
2322
short_name='1',
2324
Option('keep-output',
2325
help='keep output directories when tests fail'),
3463
2326
Option('transport',
3464
2327
help='Use a different transport by default '
3465
2328
'throughout the test suite.',
3466
2329
type=get_transport_type),
3468
help='Run the benchmarks rather than selftests.'),
2330
Option('benchmark', help='run the bzr benchmarks.'),
3469
2331
Option('lsprof-timed',
3470
help='Generate lsprof output for benchmarked'
2332
help='generate lsprof output for benchmarked'
3471
2333
' sections of code.'),
3472
Option('lsprof-tests',
3473
help='Generate lsprof output for each test.'),
3474
2334
Option('cache-dir', type=str,
3475
help='Cache intermediate benchmark output in this '
2335
help='a directory to cache intermediate'
2336
' benchmark steps'),
2337
Option('clean-output',
2338
help='clean temporary tests directories'
2339
' without running tests'),
3477
2340
Option('first',
3478
help='Run all tests, but run specified tests first.',
2341
help='run all tests, but run specified tests first',
3479
2342
short_name='f',
3482
help='List the tests instead of running them.'),
3483
RegistryOption('parallel',
3484
help="Run the test suite in parallel.",
3485
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3486
value_switches=False,
3488
Option('randomize', type=str, argname="SEED",
3489
help='Randomize the order of tests using the given'
3490
' seed or "now" for the current time.'),
3491
Option('exclude', type=str, argname="PATTERN",
3493
help='Exclude tests that match this regular'
3496
help='Output test progress via subunit.'),
3497
Option('strict', help='Fail on missing dependencies or '
3499
Option('load-list', type=str, argname='TESTLISTFILE',
3500
help='Load a test id list from a text file.'),
3501
ListOption('debugflag', type=str, short_name='E',
3502
help='Turn on a selftest debug flag.'),
3503
ListOption('starting-with', type=str, argname='TESTID',
3504
param_name='starting_with', short_name='s',
3506
'Load only the tests starting with TESTID.'),
2344
Option('numbered-dirs',
2345
help='use numbered dirs for TestCaseInTempDir'),
3508
2347
encoding_type = 'replace'
3511
Command.__init__(self)
3512
self.additional_selftest_args = {}
3514
def run(self, testspecs_list=None, verbose=False, one=False,
3515
transport=None, benchmark=None,
3516
lsprof_timed=None, cache_dir=None,
3517
first=False, list_only=False,
3518
randomize=None, exclude=None, strict=False,
3519
load_list=None, debugflag=None, starting_with=None, subunit=False,
3520
parallel=None, lsprof_tests=False):
2349
def run(self, testspecs_list=None, verbose=None, one=False,
2350
keep_output=False, transport=None, benchmark=None,
2351
lsprof_timed=None, cache_dir=None, clean_output=False,
2352
first=False, numbered_dirs=None):
3521
2354
from bzrlib.tests import selftest
3522
2355
import bzrlib.benchmarks as benchmarks
3523
2356
from bzrlib.benchmarks import tree_creator
3525
# Make deprecation warnings visible, unless -Werror is set
3526
symbol_versioning.activate_deprecation_warnings(override=False)
2359
from bzrlib.tests import clean_selftest_output
2360
clean_selftest_output()
2363
if numbered_dirs is None and sys.platform == 'win32':
2364
numbered_dirs = True
3528
2366
if cache_dir is not None:
3529
2367
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2368
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2369
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
3530
2371
if testspecs_list is not None:
3531
2372
pattern = '|'.join(testspecs_list)
3536
from bzrlib.tests import SubUnitBzrRunner
3538
raise errors.BzrCommandError("subunit not available. subunit "
3539
"needs to be installed to use --subunit.")
3540
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3542
self.additional_selftest_args.setdefault(
3543
'suite_decorators', []).append(parallel)
3545
2376
test_suite_factory = benchmarks.test_suite
3546
# Unless user explicitly asks for quiet, be verbose in benchmarks
3547
verbose = not is_quiet()
3548
2379
# TODO: should possibly lock the history file...
3549
2380
benchfile = open(".perf_history", "at", buffering=1)
3550
self.add_cleanup(benchfile.close)
3552
2382
test_suite_factory = None
3553
2385
benchfile = None
3554
selftest_kwargs = {"verbose": verbose,
3556
"stop_on_failure": one,
3557
"transport": transport,
3558
"test_suite_factory": test_suite_factory,
3559
"lsprof_timed": lsprof_timed,
3560
"lsprof_tests": lsprof_tests,
3561
"bench_history": benchfile,
3562
"matching_tests_first": first,
3563
"list_only": list_only,
3564
"random_seed": randomize,
3565
"exclude_pattern": exclude,
3567
"load_list": load_list,
3568
"debug_flags": debugflag,
3569
"starting_with": starting_with
3571
selftest_kwargs.update(self.additional_selftest_args)
3572
result = selftest(**selftest_kwargs)
2387
result = selftest(verbose=verbose,
2389
stop_on_failure=one,
2390
keep_output=keep_output,
2391
transport=transport,
2392
test_suite_factory=test_suite_factory,
2393
lsprof_timed=lsprof_timed,
2394
bench_history=benchfile,
2395
matching_tests_first=first,
2396
numbered_dirs=numbered_dirs,
2399
if benchfile is not None:
2402
info('tests passed')
2404
info('tests failed')
3573
2405
return int(not result)
3576
2408
class cmd_version(Command):
3577
2409
"""Show version of bzr."""
3579
encoding_type = 'replace'
3581
Option("short", help="Print just the version number."),
3584
2411
@display_command
3585
def run(self, short=False):
3586
2413
from bzrlib.version import show_version
3588
self.outf.write(bzrlib.version_string + '\n')
3590
show_version(to_file=self.outf)
3593
2417
class cmd_rocks(Command):
3661
2478
directory, where they can be reviewed (with bzr diff), tested, and then
3662
2479
committed to record the result of the merge.
2483
To merge the latest revision from bzr.dev:
2484
bzr merge ../bzr.dev
2486
To merge changes up to and including revision 82 from bzr.dev:
2487
bzr merge -r 82 ../bzr.dev
2489
To merge the changes introduced by 82, without previous changes:
2490
bzr merge -r 81..82 ../bzr.dev
3664
2492
merge refuses to run if there are any uncommitted changes, unless
3665
--force is given. The --force option can also be used to create a
3666
merge revision which has more than two parents.
3668
If one would like to merge changes from the working tree of the other
3669
branch without merging any committed revisions, the --uncommitted option
3672
To select only some changes to merge, use "merge -i", which will prompt
3673
you to apply each diff hunk and file change, similar to "shelve".
3676
To merge the latest revision from bzr.dev::
3678
bzr merge ../bzr.dev
3680
To merge changes up to and including revision 82 from bzr.dev::
3682
bzr merge -r 82 ../bzr.dev
3684
To merge the changes introduced by 82, without previous changes::
3686
bzr merge -r 81..82 ../bzr.dev
3688
To apply a merge directive contained in /tmp/merge::
3690
bzr merge /tmp/merge
3692
To create a merge revision with three parents from two branches
3693
feature1a and feature1b:
3695
bzr merge ../feature1a
3696
bzr merge ../feature1b --force
3697
bzr commit -m 'revision with three parents'
3700
encoding_type = 'exact'
3701
_see_also = ['update', 'remerge', 'status-flags', 'send']
3702
takes_args = ['location?']
3707
help='Merge even if the destination tree has uncommitted changes.'),
2495
takes_args = ['branch?']
2496
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
3711
2497
Option('show-base', help="Show base revision text in "
3713
2499
Option('uncommitted', help='Apply uncommitted changes'
3714
' from a working copy, instead of branch changes.'),
2500
' from a working copy, instead of branch changes'),
3715
2501
Option('pull', help='If the destination is already'
3716
2502
' completely merged into the source, pull from the'
3717
' source rather than merging. When this happens,'
2503
' source rather than merging. When this happens,'
3718
2504
' you do not need to commit the result.'),
3719
2505
Option('directory',
3720
help='Branch to merge into, '
3721
'rather than the one containing the working directory.',
3725
Option('preview', help='Instead of merging, show a diff of the'
3727
Option('interactive', help='Select changes interactively.',
2506
help='Branch to merge into, '
2507
'rather than the one containing the working directory',
3731
def run(self, location=None, revision=None, force=False,
3732
merge_type=None, show_base=False, reprocess=None, remember=False,
2513
def run(self, branch=None, revision=None, force=False, merge_type=None,
2514
show_base=False, reprocess=False, remember=False,
3733
2515
uncommitted=False, pull=False,
3734
2516
directory=None,
2518
from bzrlib.tag import _merge_tags_if_possible
2519
other_revision_id = None
3738
2520
if merge_type is None:
3739
2521
merge_type = _mod_merge.Merge3Merger
3741
2523
if directory is None: directory = u'.'
3742
possible_transports = []
3744
allow_pending = True
3745
verified = 'inapplicable'
2524
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2525
# inventory. Because merge is a mutating operation, it really
2526
# should be a lock_write() for the whole cmd_merge operation.
2527
# However, cmd_merge open's its own tree in _merge_helper, which
2528
# means if we lock here, the later lock_write() will always block.
2529
# Either the merge helper code should be updated to take a tree,
2530
# (What about tree.merge_from_branch?)
3746
2531
tree = WorkingTree.open_containing(directory)[0]
3749
basis_tree = tree.revision_tree(tree.last_revision())
3750
except errors.NoSuchRevision:
3751
basis_tree = tree.basis_tree()
3753
# die as quickly as possible if there are uncommitted changes
3755
if tree.has_changes():
3756
raise errors.UncommittedChanges(tree)
3758
view_info = _get_view_info_for_change_reporter(tree)
3759
2532
change_reporter = delta._ChangeReporter(
3760
unversioned_filter=tree.is_ignored, view_info=view_info)
3761
pb = ui.ui_factory.nested_progress_bar()
3762
self.add_cleanup(pb.finished)
3764
self.add_cleanup(tree.unlock)
3765
if location is not None:
2533
unversioned_filter=tree.is_ignored)
2535
if branch is not None:
3767
mergeable = bundle.read_mergeable_from_url(location,
3768
possible_transports=possible_transports)
2537
mergeable = bundle.read_mergeable_from_url(
3769
2539
except errors.NotABundle:
2540
pass # Continue on considering this url a Branch
3773
raise errors.BzrCommandError('Cannot use --uncommitted'
3774
' with bundles or merge directives.')
3776
2542
if revision is not None:
3777
2543
raise errors.BzrCommandError(
3778
2544
'Cannot use -r with merge directives or bundles')
3779
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3782
if merger is None and uncommitted:
3783
if revision is not None and len(revision) > 0:
2545
other_revision_id = mergeable.install_revisions(
2546
tree.branch.repository)
2547
revision = [RevisionSpec.from_string(
2548
'revid:' + other_revision_id)]
2550
if revision is None \
2551
or len(revision) < 1 or revision[0].needs_branch():
2552
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2554
if revision is None or len(revision) < 1:
2557
other = [branch, None]
2560
other = [branch, -1]
2561
other_branch, path = Branch.open_containing(branch)
3784
2564
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
3787
allow_pending = False
3790
merger, allow_pending = self._get_merger_from_branch(tree,
3791
location, revision, remember, possible_transports, pb)
3793
merger.merge_type = merge_type
3794
merger.reprocess = reprocess
3795
merger.show_base = show_base
3796
self.sanity_check_merger(merger)
3797
if (merger.base_rev_id == merger.other_rev_id and
3798
merger.other_rev_id is not None):
3799
note('Nothing to do.')
3802
if merger.interesting_files is not None:
3803
raise errors.BzrCommandError('Cannot pull individual files')
3804
if (merger.base_rev_id == tree.last_revision()):
3805
result = tree.pull(merger.other_branch, False,
3806
merger.other_rev_id)
3807
result.report(self.outf)
2565
' --revision at the same time.')
2566
branch = revision[0].get_branch() or branch
2567
if len(revision) == 1:
2569
if other_revision_id is not None:
2574
other_branch, path = Branch.open_containing(branch)
2575
revno = revision[0].in_history(other_branch).revno
2576
other = [branch, revno]
2578
assert len(revision) == 2
2579
if None in revision:
2580
raise errors.BzrCommandError(
2581
"Merge doesn't permit empty revision specifier.")
2582
base_branch, path = Branch.open_containing(branch)
2583
branch1 = revision[1].get_branch() or branch
2584
other_branch, path1 = Branch.open_containing(branch1)
2585
if revision[0].get_branch() is not None:
2586
# then path was obtained from it, and is None.
2589
base = [branch, revision[0].in_history(base_branch).revno]
2590
other = [branch1, revision[1].in_history(other_branch).revno]
2592
if ((tree.branch.get_parent() is None or remember) and
2593
other_branch is not None):
2594
tree.branch.set_parent(other_branch.base)
2596
# pull tags now... it's a bit inconsistent to do it ahead of copying
2597
# the history but that's done inside the merge code
2598
if other_branch is not None:
2599
_merge_tags_if_possible(other_branch, tree.branch)
2602
interesting_files = [path]
2604
interesting_files = None
2605
pb = ui.ui_factory.nested_progress_bar()
2608
conflict_count = _merge_helper(
2609
other, base, other_rev_id=other_revision_id,
2610
check_clean=(not force),
2611
merge_type=merge_type,
2612
reprocess=reprocess,
2613
show_base=show_base,
2616
pb=pb, file_list=interesting_files,
2617
change_reporter=change_reporter)
2620
if conflict_count != 0:
3809
if merger.this_basis is None:
3810
raise errors.BzrCommandError(
3811
"This branch has no commits."
3812
" (perhaps you would prefer 'bzr pull')")
3814
return self._do_preview(merger)
3816
return self._do_interactive(merger)
3818
return self._do_merge(merger, change_reporter, allow_pending,
3821
def _get_preview(self, merger):
3822
tree_merger = merger.make_merger()
3823
tt = tree_merger.make_preview_transform()
3824
self.add_cleanup(tt.finalize)
3825
result_tree = tt.get_preview_tree()
3828
def _do_preview(self, merger):
3829
from bzrlib.diff import show_diff_trees
3830
result_tree = self._get_preview(merger)
3831
show_diff_trees(merger.this_tree, result_tree, self.outf,
3832
old_label='', new_label='')
3834
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3835
merger.change_reporter = change_reporter
3836
conflict_count = merger.do_merge()
3838
merger.set_pending()
3839
if verified == 'failed':
3840
warning('Preview patch does not match changes')
3841
if conflict_count != 0:
3846
def _do_interactive(self, merger):
3847
"""Perform an interactive merge.
3849
This works by generating a preview tree of the merge, then using
3850
Shelver to selectively remove the differences between the working tree
3851
and the preview tree.
3853
from bzrlib import shelf_ui
3854
result_tree = self._get_preview(merger)
3855
writer = bzrlib.option.diff_writer_registry.get()
3856
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3857
reporter=shelf_ui.ApplyReporter(),
3858
diff_writer=writer(sys.stdout))
3864
def sanity_check_merger(self, merger):
3865
if (merger.show_base and
3866
not merger.merge_type is _mod_merge.Merge3Merger):
3867
raise errors.BzrCommandError("Show-base is not supported for this"
3868
" merge type. %s" % merger.merge_type)
3869
if merger.reprocess is None:
3870
if merger.show_base:
3871
merger.reprocess = False
3873
# Use reprocess if the merger supports it
3874
merger.reprocess = merger.merge_type.supports_reprocess
3875
if merger.reprocess and not merger.merge_type.supports_reprocess:
3876
raise errors.BzrCommandError("Conflict reduction is not supported"
3877
" for merge type %s." %
3879
if merger.reprocess and merger.show_base:
3880
raise errors.BzrCommandError("Cannot do conflict reduction and"
3883
def _get_merger_from_branch(self, tree, location, revision, remember,
3884
possible_transports, pb):
3885
"""Produce a merger from a location, assuming it refers to a branch."""
3886
from bzrlib.tag import _merge_tags_if_possible
3887
# find the branch locations
3888
other_loc, user_location = self._select_branch_location(tree, location,
3890
if revision is not None and len(revision) == 2:
3891
base_loc, _unused = self._select_branch_location(tree,
3892
location, revision, 0)
3894
base_loc = other_loc
3896
other_branch, other_path = Branch.open_containing(other_loc,
3897
possible_transports)
3898
if base_loc == other_loc:
3899
base_branch = other_branch
3901
base_branch, base_path = Branch.open_containing(base_loc,
3902
possible_transports)
3903
# Find the revision ids
3904
other_revision_id = None
3905
base_revision_id = None
3906
if revision is not None:
3907
if len(revision) >= 1:
3908
other_revision_id = revision[-1].as_revision_id(other_branch)
3909
if len(revision) == 2:
3910
base_revision_id = revision[0].as_revision_id(base_branch)
3911
if other_revision_id is None:
3912
other_revision_id = _mod_revision.ensure_null(
3913
other_branch.last_revision())
3914
# Remember where we merge from
3915
if ((remember or tree.branch.get_submit_branch() is None) and
3916
user_location is not None):
3917
tree.branch.set_submit_branch(other_branch.base)
3918
_merge_tags_if_possible(other_branch, tree.branch)
3919
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3920
other_revision_id, base_revision_id, other_branch, base_branch)
3921
if other_path != '':
3922
allow_pending = False
3923
merger.interesting_files = [other_path]
3925
allow_pending = True
3926
return merger, allow_pending
3928
def get_merger_from_uncommitted(self, tree, location, pb):
3929
"""Get a merger for uncommitted changes.
3931
:param tree: The tree the merger should apply to.
3932
:param location: The location containing uncommitted changes.
3933
:param pb: The progress bar to use for showing progress.
3935
location = self._select_branch_location(tree, location)[0]
3936
other_tree, other_path = WorkingTree.open_containing(location)
3937
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
3938
if other_path != '':
3939
merger.interesting_files = [other_path]
3942
def _select_branch_location(self, tree, user_location, revision=None,
3944
"""Select a branch location, according to possible inputs.
3946
If provided, branches from ``revision`` are preferred. (Both
3947
``revision`` and ``index`` must be supplied.)
3949
Otherwise, the ``location`` parameter is used. If it is None, then the
3950
``submit`` or ``parent`` location is used, and a note is printed.
3952
:param tree: The working tree to select a branch for merging into
3953
:param location: The location entered by the user
3954
:param revision: The revision parameter to the command
3955
:param index: The index to use for the revision parameter. Negative
3956
indices are permitted.
3957
:return: (selected_location, user_location). The default location
3958
will be the user-entered location.
3960
if (revision is not None and index is not None
3961
and revision[index] is not None):
3962
branch = revision[index].get_branch()
3963
if branch is not None:
3964
return branch, branch
3965
if user_location is None:
3966
location = self._get_remembered(tree, 'Merging from')
3968
location = user_location
3969
return location, user_location
3971
def _get_remembered(self, tree, verb_string):
2624
except errors.AmbiguousBase, e:
2625
m = ("sorry, bzr can't determine the right merge base yet\n"
2626
"candidates are:\n "
2627
+ "\n ".join(e.bases)
2629
"please specify an explicit base with -r,\n"
2630
"and (if you want) report this to the bzr developers\n")
2633
# TODO: move up to common parent; this isn't merge-specific anymore.
2634
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3972
2635
"""Use tree.branch's parent if none was supplied.
3974
2637
Report if the remembered location was used.
3976
stored_location = tree.branch.get_submit_branch()
3977
stored_location_type = "submit"
3978
if stored_location is None:
3979
stored_location = tree.branch.get_parent()
3980
stored_location_type = "parent"
2639
if supplied_location is not None:
2640
return supplied_location
2641
stored_location = tree.branch.get_parent()
3981
2642
mutter("%s", stored_location)
3982
2643
if stored_location is None:
3983
2644
raise errors.BzrCommandError("No location specified or remembered")
3984
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3985
note(u"%s remembered %s location %s", verb_string,
3986
stored_location_type, display_url)
2645
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2646
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3987
2647
return stored_location
4197
2819
takes_args = ['context?']
4198
2820
aliases = ['s-c']
4201
2823
@display_command
4202
2824
def run(self, context=None):
4203
2825
import shellcomplete
4204
2826
shellcomplete.shellcomplete(context)
2829
class cmd_fetch(Command):
2830
"""Copy in history from another branch but don't merge it.
2832
This is an internal method used for pull and merge.
2835
takes_args = ['from_branch', 'to_branch']
2836
def run(self, from_branch, to_branch):
2837
from bzrlib.fetch import Fetcher
2838
from_b = Branch.open(from_branch)
2839
to_b = Branch.open(to_branch)
2840
Fetcher(to_b, from_b)
4207
2843
class cmd_missing(Command):
4208
2844
"""Show unmerged/unpulled revisions between two branches.
4210
2846
OTHER_BRANCH may be local or remote.
4212
To filter on a range of revisions, you can use the command -r begin..end
4213
-r revision requests a specific revision, -r ..end or -r begin.. are
4217
1 - some missing revisions
4218
0 - no missing revisions
4222
Determine the missing revisions between this and the branch at the
4223
remembered pull location::
4227
Determine the missing revisions between this and another branch::
4229
bzr missing http://server/branch
4231
Determine the missing revisions up to a specific revision on the other
4234
bzr missing -r ..-10
4236
Determine the missing revisions up to a specific revision on this
4239
bzr missing --my-revision ..-10
4242
_see_also = ['merge', 'pull']
4243
2848
takes_args = ['other_branch?']
4245
Option('reverse', 'Reverse the order of revisions.'),
4247
'Display changes in the local branch only.'),
4248
Option('this' , 'Same as --mine-only.'),
4249
Option('theirs-only',
4250
'Display changes in the remote branch only.'),
4251
Option('other', 'Same as --theirs-only.'),
4255
custom_help('revision',
4256
help='Filter on other branch revisions (inclusive). '
4257
'See "help revisionspec" for details.'),
4258
Option('my-revision',
4259
type=_parse_revision_str,
4260
help='Filter on local branch revisions (inclusive). '
4261
'See "help revisionspec" for details.'),
4262
Option('include-merges',
4263
'Show all revisions in addition to the mainline ones.'),
2849
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2851
'Display changes in the local branch only'),
2852
Option('theirs-only',
2853
'Display changes in the remote branch only'),
4265
2858
encoding_type = 'replace'
4267
2860
@display_command
4268
2861
def run(self, other_branch=None, reverse=False, mine_only=False,
4270
log_format=None, long=False, short=False, line=False,
4271
show_ids=False, verbose=False, this=False, other=False,
4272
include_merges=False, revision=None, my_revision=None):
4273
from bzrlib.missing import find_unmerged, iter_log_revisions
4282
# TODO: We should probably check that we don't have mine-only and
4283
# theirs-only set, but it gets complicated because we also have
4284
# this and other which could be used.
2862
theirs_only=False, log_format=None, long=False, short=False, line=False,
2863
show_ids=False, verbose=False):
2864
from bzrlib.missing import find_unmerged, iter_log_data
2865
from bzrlib.log import log_formatter
4291
2866
local_branch = Branch.open_containing(u".")[0]
4292
2867
parent = local_branch.get_parent()
4293
2868
if other_branch is None:
4294
2869
other_branch = parent
4295
2870
if other_branch is None:
4296
raise errors.BzrCommandError("No peer location known"
2871
raise errors.BzrCommandError("No peer location known or specified.")
4298
2872
display_url = urlutils.unescape_for_display(parent,
4299
2873
self.outf.encoding)
4300
message("Using saved parent location: "
4301
+ display_url + "\n")
2874
print "Using last location: " + display_url
4303
2876
remote_branch = Branch.open(other_branch)
4304
2877
if remote_branch.base == local_branch.base:
4305
2878
remote_branch = local_branch
4307
2879
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4309
local_revid_range = _revision_range_to_revid_range(
4310
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4315
remote_revid_range = _revision_range_to_revid_range(
4316
_get_revision_range(revision,
4317
remote_branch, self.name()))
4319
local_extra, remote_extra = find_unmerged(
4320
local_branch, remote_branch, restrict,
4321
backward=not reverse,
4322
include_merges=include_merges,
4323
local_revid_range=local_revid_range,
4324
remote_revid_range=remote_revid_range)
4326
if log_format is None:
4327
registry = log.log_formatter_registry
4328
log_format = registry.get_default(local_branch)
4329
lf = log_format(to_file=self.outf,
4331
show_timezone='original')
4334
if local_extra and not theirs_only:
4335
message("You have %d extra revision(s):\n" %
4337
for revision in iter_log_revisions(local_extra,
4338
local_branch.repository,
4340
lf.log_revision(revision)
4341
printed_local = True
4344
printed_local = False
4346
if remote_extra and not mine_only:
4347
if printed_local is True:
4349
message("You are missing %d revision(s):\n" %
4351
for revision in iter_log_revisions(remote_extra,
4352
remote_branch.repository,
4354
lf.log_revision(revision)
4357
if mine_only and not local_extra:
4358
# We checked local, and found nothing extra
4359
message('This branch is up to date.\n')
4360
elif theirs_only and not remote_extra:
4361
# We checked remote, and found nothing extra
4362
message('Other branch is up to date.\n')
4363
elif not (mine_only or theirs_only or local_extra or
4365
# We checked both branches, and neither one had extra
4367
message("Branches are up to date.\n")
2881
remote_branch.lock_read()
2883
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2884
if (log_format is None):
2885
log_format = log.log_formatter_registry.get_default(
2887
lf = log_format(to_file=self.outf,
2889
show_timezone='original')
2890
if reverse is False:
2891
local_extra.reverse()
2892
remote_extra.reverse()
2893
if local_extra and not theirs_only:
2894
print "You have %d extra revision(s):" % len(local_extra)
2895
for data in iter_log_data(local_extra, local_branch.repository,
2898
printed_local = True
2900
printed_local = False
2901
if remote_extra and not mine_only:
2902
if printed_local is True:
2904
print "You are missing %d revision(s):" % len(remote_extra)
2905
for data in iter_log_data(remote_extra, remote_branch.repository,
2908
if not remote_extra and not local_extra:
2910
print "Branches are up to date."
2914
remote_branch.unlock()
2916
local_branch.unlock()
4369
2917
if not status_code and parent is None and other_branch is not None:
4370
2918
local_branch.lock_write()
4371
self.add_cleanup(local_branch.unlock)
4372
# handle race conditions - a parent might be set while we run.
4373
if local_branch.get_parent() is None:
4374
local_branch.set_parent(remote_branch.base)
2920
# handle race conditions - a parent might be set while we run.
2921
if local_branch.get_parent() is None:
2922
local_branch.set_parent(remote_branch.base)
2924
local_branch.unlock()
4375
2925
return status_code
4378
class cmd_pack(Command):
4379
"""Compress the data within a repository."""
4381
_see_also = ['repositories']
4382
takes_args = ['branch_or_repo?']
4384
def run(self, branch_or_repo='.'):
4385
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4387
branch = dir.open_branch()
4388
repository = branch.repository
4389
except errors.NotBranchError:
4390
repository = dir.open_repository()
4394
2928
class cmd_plugins(Command):
4395
"""List the installed plugins.
4397
This command displays the list of installed plugins including
4398
version of plugin and a short description of each.
4400
--verbose shows the path where each plugin is located.
4402
A plugin is an external component for Bazaar that extends the
4403
revision control system, by adding or replacing code in Bazaar.
4404
Plugins can do a variety of things, including overriding commands,
4405
adding new commands, providing additional network transports and
4406
customizing log output.
4408
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4409
for further information on plugins including where to find them and how to
4410
install them. Instructions are also provided there on how to write new
4411
plugins using the Python programming language.
4413
takes_options = ['verbose']
4415
2931
@display_command
4416
def run(self, verbose=False):
4417
2933
import bzrlib.plugin
4418
2934
from inspect import getdoc
4420
for name, plugin in bzrlib.plugin.plugins().items():
4421
version = plugin.__version__
4422
if version == 'unknown':
4424
name_ver = '%s %s' % (name, version)
4425
d = getdoc(plugin.module)
2935
for name, plugin in bzrlib.plugin.all_plugins().items():
2936
if getattr(plugin, '__path__', None) is not None:
2937
print plugin.__path__[0]
2938
elif getattr(plugin, '__file__', None) is not None:
2939
print plugin.__file__
4427
doc = d.split('\n')[0]
4429
doc = '(no description)'
4430
result.append((name_ver, doc, plugin.path()))
4431
for name_ver, doc, path in sorted(result):
2945
print '\t', d.split('\n')[0]
4439
2948
class cmd_testament(Command):
4440
2949
"""Show testament (signing-form) of a revision."""
4443
Option('long', help='Produce long-format testament.'),
4445
help='Produce a strict-format testament.')]
2950
takes_options = ['revision',
2951
Option('long', help='Produce long-format testament'),
2952
Option('strict', help='Produce a strict-format'
4446
2954
takes_args = ['branch?']
4447
2955
@display_command
4448
2956
def run(self, branch=u'.', revision=None, long=False, strict=False):
5022
3438
self.outf.writelines(directive.to_lines())
5024
3440
message = directive.to_email(mail_to, branch, sign)
5025
s = SMTPConnection(branch.get_config())
5026
s.send_email(message)
5029
class cmd_send(Command):
5030
"""Mail or create a merge-directive for submitting changes.
5032
A merge directive provides many things needed for requesting merges:
5034
* A machine-readable description of the merge to perform
5036
* An optional patch that is a preview of the changes requested
5038
* An optional bundle of revision data, so that the changes can be applied
5039
directly from the merge directive, without retrieving data from a
5042
`bzr send` creates a compact data set that, when applied using bzr
5043
merge, has the same effect as merging from the source branch.
5045
By default the merge directive is self-contained and can be applied to any
5046
branch containing submit_branch in its ancestory without needing access to
5049
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5050
revisions, but only a structured request to merge from the
5051
public_location. In that case the public_branch is needed and it must be
5052
up-to-date and accessible to the recipient. The public_branch is always
5053
included if known, so that people can check it later.
5055
The submit branch defaults to the parent of the source branch, but can be
5056
overridden. Both submit branch and public branch will be remembered in
5057
branch.conf the first time they are used for a particular branch. The
5058
source branch defaults to that containing the working directory, but can
5059
be changed using --from.
5061
In order to calculate those changes, bzr must analyse the submit branch.
5062
Therefore it is most efficient for the submit branch to be a local mirror.
5063
If a public location is known for the submit_branch, that location is used
5064
in the merge directive.
5066
The default behaviour is to send the merge directive by mail, unless -o is
5067
given, in which case it is sent to a file.
5069
Mail is sent using your preferred mail program. This should be transparent
5070
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5071
If the preferred client can't be found (or used), your editor will be used.
5073
To use a specific mail program, set the mail_client configuration option.
5074
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5075
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5076
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5077
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5080
If mail is being sent, a to address is required. This can be supplied
5081
either on the commandline, by setting the submit_to configuration
5082
option in the branch itself or the child_submit_to configuration option
5083
in the submit branch.
5085
Two formats are currently supported: "4" uses revision bundle format 4 and
5086
merge directive format 2. It is significantly faster and smaller than
5087
older formats. It is compatible with Bazaar 0.19 and later. It is the
5088
default. "0.9" uses revision bundle format 0.9 and merge directive
5089
format 1. It is compatible with Bazaar 0.12 - 0.18.
5091
The merge directives created by bzr send may be applied using bzr merge or
5092
bzr pull by specifying a file containing a merge directive as the location.
5094
bzr send makes extensive use of public locations to map local locations into
5095
URLs that can be used by other people. See `bzr help configuration` to
5096
set them, and use `bzr info` to display them.
5099
encoding_type = 'exact'
5101
_see_also = ['merge', 'pull']
5103
takes_args = ['submit_branch?', 'public_branch?']
5107
help='Do not include a bundle in the merge directive.'),
5108
Option('no-patch', help='Do not include a preview patch in the merge'
5111
help='Remember submit and public branch.'),
5113
help='Branch to generate the submission from, '
5114
'rather than the one containing the working directory.',
5117
Option('output', short_name='o',
5118
help='Write merge directive to this file; '
5119
'use - for stdout.',
5122
help='Refuse to send if there are uncommitted changes in'
5123
' the working tree, --no-strict disables the check.'),
5124
Option('mail-to', help='Mail the request to this address.',
5128
Option('body', help='Body for the email.', type=unicode),
5129
RegistryOption('format',
5130
help='Use the specified output format.',
5131
lazy_registry=('bzrlib.send', 'format_registry')),
5134
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5135
no_patch=False, revision=None, remember=False, output=None,
5136
format=None, mail_to=None, message=None, body=None,
5137
strict=None, **kwargs):
5138
from bzrlib.send import send
5139
return send(submit_branch, revision, public_branch, remember,
5140
format, no_bundle, no_patch, output,
5141
kwargs.get('from', '.'), mail_to, message, body,
5146
class cmd_bundle_revisions(cmd_send):
5147
"""Create a merge-directive for submitting changes.
5149
A merge directive provides many things needed for requesting merges:
5151
* A machine-readable description of the merge to perform
5153
* An optional patch that is a preview of the changes requested
5155
* An optional bundle of revision data, so that the changes can be applied
5156
directly from the merge directive, without retrieving data from a
5159
If --no-bundle is specified, then public_branch is needed (and must be
5160
up-to-date), so that the receiver can perform the merge using the
5161
public_branch. The public_branch is always included if known, so that
5162
people can check it later.
5164
The submit branch defaults to the parent, but can be overridden. Both
5165
submit branch and public branch will be remembered if supplied.
5167
If a public_branch is known for the submit_branch, that public submit
5168
branch is used in the merge instructions. This means that a local mirror
5169
can be used as your actual submit branch, once you have set public_branch
5172
Two formats are currently supported: "4" uses revision bundle format 4 and
5173
merge directive format 2. It is significantly faster and smaller than
5174
older formats. It is compatible with Bazaar 0.19 and later. It is the
5175
default. "0.9" uses revision bundle format 0.9 and merge directive
5176
format 1. It is compatible with Bazaar 0.12 - 0.18.
5181
help='Do not include a bundle in the merge directive.'),
5182
Option('no-patch', help='Do not include a preview patch in the merge'
5185
help='Remember submit and public branch.'),
5187
help='Branch to generate the submission from, '
5188
'rather than the one containing the working directory.',
5191
Option('output', short_name='o', help='Write directive to this file.',
5194
help='Refuse to bundle revisions if there are uncommitted'
5195
' changes in the working tree, --no-strict disables the check.'),
5197
RegistryOption('format',
5198
help='Use the specified output format.',
5199
lazy_registry=('bzrlib.send', 'format_registry')),
5201
aliases = ['bundle']
5203
_see_also = ['send', 'merge']
5207
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5208
no_patch=False, revision=None, remember=False, output=None,
5209
format=None, strict=None, **kwargs):
5212
from bzrlib.send import send
5213
return send(submit_branch, revision, public_branch, remember,
5214
format, no_bundle, no_patch, output,
5215
kwargs.get('from', '.'), None, None, None,
5216
self.outf, strict=strict)
3442
server = branch.get_config().get_user_option('smtp_server')
3444
server = 'localhost'
3446
s.sendmail(message['From'], message['To'], message.as_string())
5219
3449
class cmd_tag(Command):
5220
"""Create, remove or modify a tag naming a revision.
3450
"""Create a tag naming a revision.
5222
3452
Tags give human-meaningful names to revisions. Commands that take a -r
5223
3453
(--revision) option can be given -rtag:X, where X is any previously
5259
3485
branch, relpath = Branch.open_containing(directory)
5260
3486
branch.lock_write()
5261
self.add_cleanup(branch.unlock)
5263
branch.tags.delete_tag(tag_name)
5264
self.outf.write('Deleted tag %s.\n' % tag_name)
5267
if len(revision) != 1:
5268
raise errors.BzrCommandError(
5269
"Tags can only be placed on a single revision, "
5271
revision_id = revision[0].as_revision_id(branch)
3489
branch.tags.delete_tag(tag_name)
3490
self.outf.write('Deleted tag %s.\n' % tag_name)
5273
revision_id = branch.last_revision()
5274
if (not force) and branch.tags.has_tag(tag_name):
5275
raise errors.TagAlreadyExists(tag_name)
5276
branch.tags.set_tag(tag_name, revision_id)
5277
self.outf.write('Created tag %s.\n' % tag_name)
3493
if len(revision) != 1:
3494
raise errors.BzrCommandError(
3495
"Tags can only be placed on a single revision, "
3497
revision_id = revision[0].in_history(branch).rev_id
3499
revision_id = branch.last_revision()
3500
if (not force) and branch.tags.has_tag(tag_name):
3501
raise errors.TagAlreadyExists(tag_name)
3502
branch.tags.set_tag(tag_name, revision_id)
3503
self.outf.write('Created tag %s.\n' % tag_name)
5280
3508
class cmd_tags(Command):
5283
This command shows a table of tag names and the revisions they reference.
3511
This tag shows a table of tag names and the revisions they reference.
5287
3514
takes_options = [
5288
3515
Option('directory',
5289
help='Branch whose tags should be displayed.',
3516
help='Branch whose tags should be displayed',
5290
3517
short_name='d',
5293
RegistryOption.from_kwargs('sort',
5294
'Sort tags by different criteria.', title='Sorting',
5295
alpha='Sort tags lexicographically (default).',
5296
time='Sort tags chronologically.',
5302
3522
@display_command
5309
3526
branch, relpath = Branch.open_containing(directory)
5311
tags = branch.tags.get_tag_dict().items()
5316
self.add_cleanup(branch.unlock)
5318
graph = branch.repository.get_graph()
5319
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5320
revid1, revid2 = rev1.rev_id, rev2.rev_id
5321
# only show revisions between revid1 and revid2 (inclusive)
5322
tags = [(tag, revid) for tag, revid in tags if
5323
graph.is_between(revid, revid1, revid2)]
5326
elif sort == 'time':
5328
for tag, revid in tags:
5330
revobj = branch.repository.get_revision(revid)
5331
except errors.NoSuchRevision:
5332
timestamp = sys.maxint # place them at the end
5334
timestamp = revobj.timestamp
5335
timestamps[revid] = timestamp
5336
tags.sort(key=lambda x: timestamps[x[1]])
5338
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5339
for index, (tag, revid) in enumerate(tags):
5341
revno = branch.revision_id_to_dotted_revno(revid)
5342
if isinstance(revno, tuple):
5343
revno = '.'.join(map(str, revno))
5344
except errors.NoSuchRevision:
5345
# Bad tag data/merges can lead to tagged revisions
5346
# which are not in this branch. Fail gracefully ...
5348
tags[index] = (tag, revno)
5350
for tag, revspec in tags:
5351
self.outf.write('%-20s %s\n' % (tag, revspec))
5354
class cmd_reconfigure(Command):
5355
"""Reconfigure the type of a bzr directory.
5357
A target configuration must be specified.
5359
For checkouts, the bind-to location will be auto-detected if not specified.
5360
The order of preference is
5361
1. For a lightweight checkout, the current bound location.
5362
2. For branches that used to be checkouts, the previously-bound location.
5363
3. The push location.
5364
4. The parent location.
5365
If none of these is available, --bind-to must be specified.
5368
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5369
takes_args = ['location?']
5371
RegistryOption.from_kwargs(
5373
title='Target type',
5374
help='The type to reconfigure the directory to.',
5375
value_switches=True, enum_switch=False,
5376
branch='Reconfigure to be an unbound branch with no working tree.',
5377
tree='Reconfigure to be an unbound branch with a working tree.',
5378
checkout='Reconfigure to be a bound branch with a working tree.',
5379
lightweight_checkout='Reconfigure to be a lightweight'
5380
' checkout (with no local history).',
5381
standalone='Reconfigure to be a standalone branch '
5382
'(i.e. stop using shared repository).',
5383
use_shared='Reconfigure to use a shared repository.',
5384
with_trees='Reconfigure repository to create '
5385
'working trees on branches by default.',
5386
with_no_trees='Reconfigure repository to not create '
5387
'working trees on branches by default.'
5389
Option('bind-to', help='Branch to bind checkout to.', type=str),
5391
help='Perform reconfiguration even if local changes'
5393
Option('stacked-on',
5394
help='Reconfigure a branch to be stacked on another branch.',
5398
help='Reconfigure a branch to be unstacked. This '
5399
'may require copying substantial data into it.',
5403
def run(self, location=None, target_type=None, bind_to=None, force=False,
5406
directory = bzrdir.BzrDir.open(location)
5407
if stacked_on and unstacked:
5408
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5409
elif stacked_on is not None:
5410
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5412
reconfigure.ReconfigureUnstacked().apply(directory)
5413
# At the moment you can use --stacked-on and a different
5414
# reconfiguration shape at the same time; there seems no good reason
5416
if target_type is None:
5417
if stacked_on or unstacked:
5420
raise errors.BzrCommandError('No target configuration '
5422
elif target_type == 'branch':
5423
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5424
elif target_type == 'tree':
5425
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5426
elif target_type == 'checkout':
5427
reconfiguration = reconfigure.Reconfigure.to_checkout(
5429
elif target_type == 'lightweight-checkout':
5430
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5432
elif target_type == 'use-shared':
5433
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5434
elif target_type == 'standalone':
5435
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5436
elif target_type == 'with-trees':
5437
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5439
elif target_type == 'with-no-trees':
5440
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5442
reconfiguration.apply(force)
5445
class cmd_switch(Command):
5446
"""Set the branch of a checkout and update.
5448
For lightweight checkouts, this changes the branch being referenced.
5449
For heavyweight checkouts, this checks that there are no local commits
5450
versus the current bound branch, then it makes the local branch a mirror
5451
of the new location and binds to it.
5453
In both cases, the working tree is updated and uncommitted changes
5454
are merged. The user can commit or revert these as they desire.
5456
Pending merges need to be committed or reverted before using switch.
5458
The path to the branch to switch to can be specified relative to the parent
5459
directory of the current branch. For example, if you are currently in a
5460
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5463
Bound branches use the nickname of its master branch unless it is set
5464
locally, in which case switching will update the local nickname to be
5468
takes_args = ['to_location?']
5469
takes_options = [Option('force',
5470
help='Switch even if local commits will be lost.'),
5472
Option('create-branch', short_name='b',
5473
help='Create the target branch from this one before'
5474
' switching to it.'),
5477
def run(self, to_location=None, force=False, create_branch=False,
5479
from bzrlib import switch
5481
revision = _get_one_revision('switch', revision)
5482
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5483
if to_location is None:
5484
if revision is None:
5485
raise errors.BzrCommandError('You must supply either a'
5486
' revision or a location')
5489
branch = control_dir.open_branch()
5490
had_explicit_nick = branch.get_config().has_explicit_nickname()
5491
except errors.NotBranchError:
5493
had_explicit_nick = False
5496
raise errors.BzrCommandError('cannot create branch without'
5498
to_location = directory_service.directories.dereference(
5500
if '/' not in to_location and '\\' not in to_location:
5501
# This path is meant to be relative to the existing branch
5502
this_url = self._get_branch_location(control_dir)
5503
to_location = urlutils.join(this_url, '..', to_location)
5504
to_branch = branch.bzrdir.sprout(to_location,
5505
possible_transports=[branch.bzrdir.root_transport],
5506
source_branch=branch).open_branch()
5509
to_branch = Branch.open(to_location)
5510
except errors.NotBranchError:
5511
this_url = self._get_branch_location(control_dir)
5512
to_branch = Branch.open(
5513
urlutils.join(this_url, '..', to_location))
5514
if revision is not None:
5515
revision = revision.as_revision_id(to_branch)
5516
switch.switch(control_dir, to_branch, force, revision_id=revision)
5517
if had_explicit_nick:
5518
branch = control_dir.open_branch() #get the new branch!
5519
branch.nick = to_branch.nick
5520
note('Switched to branch: %s',
5521
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5523
def _get_branch_location(self, control_dir):
5524
"""Return location of branch for this control dir."""
5526
this_branch = control_dir.open_branch()
5527
# This may be a heavy checkout, where we want the master branch
5528
master_location = this_branch.get_bound_location()
5529
if master_location is not None:
5530
return master_location
5531
# If not, use a local sibling
5532
return this_branch.base
5533
except errors.NotBranchError:
5534
format = control_dir.find_branch_format()
5535
if getattr(format, 'get_reference', None) is not None:
5536
return format.get_reference(control_dir)
5538
return control_dir.root_transport.base
5541
class cmd_view(Command):
5542
"""Manage filtered views.
5544
Views provide a mask over the tree so that users can focus on
5545
a subset of a tree when doing their work. After creating a view,
5546
commands that support a list of files - status, diff, commit, etc -
5547
effectively have that list of files implicitly given each time.
5548
An explicit list of files can still be given but those files
5549
must be within the current view.
5551
In most cases, a view has a short life-span: it is created to make
5552
a selected change and is deleted once that change is committed.
5553
At other times, you may wish to create one or more named views
5554
and switch between them.
5556
To disable the current view without deleting it, you can switch to
5557
the pseudo view called ``off``. This can be useful when you need
5558
to see the whole tree for an operation or two (e.g. merge) but
5559
want to switch back to your view after that.
5562
To define the current view::
5564
bzr view file1 dir1 ...
5566
To list the current view::
5570
To delete the current view::
5574
To disable the current view without deleting it::
5576
bzr view --switch off
5578
To define a named view and switch to it::
5580
bzr view --name view-name file1 dir1 ...
5582
To list a named view::
5584
bzr view --name view-name
5586
To delete a named view::
5588
bzr view --name view-name --delete
5590
To switch to a named view::
5592
bzr view --switch view-name
5594
To list all views defined::
5598
To delete all views::
5600
bzr view --delete --all
5604
takes_args = ['file*']
5607
help='Apply list or delete action to all views.',
5610
help='Delete the view.',
5613
help='Name of the view to define, list or delete.',
5617
help='Name of the view to switch to.',
5622
def run(self, file_list,
5628
tree, file_list = tree_files(file_list, apply_view=False)
5629
current_view, view_dict = tree.views.get_view_info()
5634
raise errors.BzrCommandError(
5635
"Both --delete and a file list specified")
5637
raise errors.BzrCommandError(
5638
"Both --delete and --switch specified")
5640
tree.views.set_view_info(None, {})
5641
self.outf.write("Deleted all views.\n")
5643
raise errors.BzrCommandError("No current view to delete")
5645
tree.views.delete_view(name)
5646
self.outf.write("Deleted '%s' view.\n" % name)
5649
raise errors.BzrCommandError(
5650
"Both --switch and a file list specified")
5652
raise errors.BzrCommandError(
5653
"Both --switch and --all specified")
5654
elif switch == 'off':
5655
if current_view is None:
5656
raise errors.BzrCommandError("No current view to disable")
5657
tree.views.set_view_info(None, view_dict)
5658
self.outf.write("Disabled '%s' view.\n" % (current_view))
5660
tree.views.set_view_info(switch, view_dict)
5661
view_str = views.view_display_str(tree.views.lookup_view())
5662
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5665
self.outf.write('Views defined:\n')
5666
for view in sorted(view_dict):
5667
if view == current_view:
5671
view_str = views.view_display_str(view_dict[view])
5672
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5674
self.outf.write('No views defined.\n')
5677
# No name given and no current view set
5680
raise errors.BzrCommandError(
5681
"Cannot change the 'off' pseudo view")
5682
tree.views.set_view(name, sorted(file_list))
5683
view_str = views.view_display_str(tree.views.lookup_view())
5684
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5688
# No name given and no current view set
5689
self.outf.write('No current view.\n')
5691
view_str = views.view_display_str(tree.views.lookup_view(name))
5692
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5695
class cmd_hooks(Command):
5701
for hook_key in sorted(hooks.known_hooks.keys()):
5702
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5703
self.outf.write("%s:\n" % type(some_hooks).__name__)
5704
for hook_name, hook_point in sorted(some_hooks.items()):
5705
self.outf.write(" %s:\n" % (hook_name,))
5706
found_hooks = list(hook_point)
5708
for hook in found_hooks:
5709
self.outf.write(" %s\n" %
5710
(some_hooks.get_hook_name(hook),))
5712
self.outf.write(" <no hooks installed>\n")
5715
class cmd_shelve(Command):
5716
"""Temporarily set aside some changes from the current tree.
5718
Shelve allows you to temporarily put changes you've made "on the shelf",
5719
ie. out of the way, until a later time when you can bring them back from
5720
the shelf with the 'unshelve' command. The changes are stored alongside
5721
your working tree, and so they aren't propagated along with your branch nor
5722
will they survive its deletion.
5724
If shelve --list is specified, previously-shelved changes are listed.
5726
Shelve is intended to help separate several sets of changes that have
5727
been inappropriately mingled. If you just want to get rid of all changes
5728
and you don't need to restore them later, use revert. If you want to
5729
shelve all text changes at once, use shelve --all.
5731
If filenames are specified, only the changes to those files will be
5732
shelved. Other files will be left untouched.
5734
If a revision is specified, changes since that revision will be shelved.
5736
You can put multiple items on the shelf, and by default, 'unshelve' will
5737
restore the most recently shelved changes.
5740
takes_args = ['file*']
5744
Option('all', help='Shelve all changes.'),
5746
RegistryOption('writer', 'Method to use for writing diffs.',
5747
bzrlib.option.diff_writer_registry,
5748
value_switches=True, enum_switch=False),
5750
Option('list', help='List shelved changes.'),
5752
help='Destroy removed changes instead of shelving them.'),
5754
_see_also = ['unshelve']
5756
def run(self, revision=None, all=False, file_list=None, message=None,
5757
writer=None, list=False, destroy=False):
5759
return self.run_for_list()
5760
from bzrlib.shelf_ui import Shelver
5762
writer = bzrlib.option.diff_writer_registry.get()
5764
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5765
file_list, message, destroy=destroy)
5770
except errors.UserAbort:
5773
def run_for_list(self):
5774
tree = WorkingTree.open_containing('.')[0]
5776
self.add_cleanup(tree.unlock)
5777
manager = tree.get_shelf_manager()
5778
shelves = manager.active_shelves()
5779
if len(shelves) == 0:
5780
note('No shelved changes.')
5782
for shelf_id in reversed(shelves):
5783
message = manager.get_metadata(shelf_id).get('message')
5785
message = '<no message>'
5786
self.outf.write('%3d: %s\n' % (shelf_id, message))
5790
class cmd_unshelve(Command):
5791
"""Restore shelved changes.
5793
By default, the most recently shelved changes are restored. However if you
5794
specify a shelf by id those changes will be restored instead. This works
5795
best when the changes don't depend on each other.
5798
takes_args = ['shelf_id?']
5800
RegistryOption.from_kwargs(
5801
'action', help="The action to perform.",
5802
enum_switch=False, value_switches=True,
5803
apply="Apply changes and remove from the shelf.",
5804
dry_run="Show changes, but do not apply or remove them.",
5805
preview="Instead of unshelving the changes, show the diff that "
5806
"would result from unshelving.",
5807
delete_only="Delete changes without applying them.",
5808
keep="Apply changes but don't delete them.",
5811
_see_also = ['shelve']
5813
def run(self, shelf_id=None, action='apply'):
5814
from bzrlib.shelf_ui import Unshelver
5815
unshelver = Unshelver.from_args(shelf_id, action)
5819
unshelver.tree.unlock()
5822
class cmd_clean_tree(Command):
5823
"""Remove unwanted files from working tree.
5825
By default, only unknown files, not ignored files, are deleted. Versioned
5826
files are never deleted.
5828
Another class is 'detritus', which includes files emitted by bzr during
5829
normal operations and selftests. (The value of these files decreases with
5832
If no options are specified, unknown files are deleted. Otherwise, option
5833
flags are respected, and may be combined.
5835
To check what clean-tree will do, use --dry-run.
5837
takes_options = [Option('ignored', help='Delete all ignored files.'),
5838
Option('detritus', help='Delete conflict files, merge'
5839
' backups, and failed selftest dirs.'),
5841
help='Delete files unknown to bzr (default).'),
5842
Option('dry-run', help='Show files to delete instead of'
5844
Option('force', help='Do not prompt before deleting.')]
5845
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5847
from bzrlib.clean_tree import clean_tree
5848
if not (unknown or ignored or detritus):
5852
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5853
dry_run=dry_run, no_prompt=force)
5856
class cmd_reference(Command):
5857
"""list, view and set branch locations for nested trees.
5859
If no arguments are provided, lists the branch locations for nested trees.
5860
If one argument is provided, display the branch location for that tree.
5861
If two arguments are provided, set the branch location for that tree.
5866
takes_args = ['path?', 'location?']
5868
def run(self, path=None, location=None):
5870
if path is not None:
5872
tree, branch, relpath =(
5873
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5874
if path is not None:
5877
tree = branch.basis_tree()
5879
info = branch._get_all_reference_info().iteritems()
5880
self._display_reference_info(tree, branch, info)
5882
file_id = tree.path2id(path)
5884
raise errors.NotVersionedError(path)
5885
if location is None:
5886
info = [(file_id, branch.get_reference_info(file_id))]
5887
self._display_reference_info(tree, branch, info)
5889
branch.set_reference_info(file_id, path, location)
5891
def _display_reference_info(self, tree, branch, info):
5893
for file_id, (path, location) in info:
5895
path = tree.id2path(file_id)
5896
except errors.NoSuchId:
5898
ref_list.append((path, location))
5899
for path, location in sorted(ref_list):
5900
self.outf.write('%s %s\n' % (path, location))
3527
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3528
self.outf.write('%-20s %s\n' % (tag_name, target))
3531
# command-line interpretation helper for merge-related commands
3532
def _merge_helper(other_revision, base_revision,
3533
check_clean=True, ignore_zero=False,
3534
this_dir=None, backup_files=False,
3536
file_list=None, show_base=False, reprocess=False,
3539
change_reporter=None,
3541
"""Merge changes into a tree.
3544
list(path, revno) Base for three-way merge.
3545
If [None, None] then a base will be automatically determined.
3547
list(path, revno) Other revision for three-way merge.
3549
Directory to merge changes into; '.' by default.
3551
If true, this_dir must have no uncommitted changes before the
3553
ignore_zero - If true, suppress the "zero conflicts" message when
3554
there are no conflicts; should be set when doing something we expect
3555
to complete perfectly.
3556
file_list - If supplied, merge only changes to selected files.
3558
All available ancestors of other_revision and base_revision are
3559
automatically pulled into the branch.
3561
The revno may be -1 to indicate the last revision on the branch, which is
3564
This function is intended for use from the command line; programmatic
3565
clients might prefer to call merge.merge_inner(), which has less magic
3568
# Loading it late, so that we don't always have to import bzrlib.merge
3569
if merge_type is None:
3570
merge_type = _mod_merge.Merge3Merger
3571
if this_dir is None:
3573
this_tree = WorkingTree.open_containing(this_dir)[0]
3574
if show_base and not merge_type is _mod_merge.Merge3Merger:
3575
raise errors.BzrCommandError("Show-base is not supported for this merge"
3576
" type. %s" % merge_type)
3577
if reprocess and not merge_type.supports_reprocess:
3578
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3579
" type %s." % merge_type)
3580
if reprocess and show_base:
3581
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3582
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3583
# only want to take out a lock_tree_write() if we don't have to pull
3584
# any ancestry. But merge might fetch ancestry in the middle, in
3585
# which case we would need a lock_write().
3586
# Because we cannot upgrade locks, for now we live with the fact that
3587
# the tree will be locked multiple times during a merge. (Maybe
3588
# read-only some of the time, but it means things will get read
3591
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3592
pb=pb, change_reporter=change_reporter)
3593
merger.pp = ProgressPhase("Merge phase", 5, pb)
3594
merger.pp.next_phase()
3595
merger.check_basis(check_clean)
3596
if other_rev_id is not None:
3597
merger.set_other_revision(other_rev_id, this_tree.branch)
3599
merger.set_other(other_revision)
3600
merger.pp.next_phase()
3601
merger.set_base(base_revision)
3602
if merger.base_rev_id == merger.other_rev_id:
3603
note('Nothing to do.')
3605
if file_list is None:
3606
if pull and merger.base_rev_id == merger.this_rev_id:
3607
# FIXME: deduplicate with pull
3608
result = merger.this_tree.pull(merger.this_branch,
3609
False, merger.other_rev_id)
3610
if result.old_revid == result.new_revid:
3611
note('No revisions to pull.')
3613
note('Now on revision %d.' % result.new_revno)
3615
merger.backup_files = backup_files
3616
merger.merge_type = merge_type
3617
merger.set_interesting_files(file_list)
3618
merger.show_base = show_base
3619
merger.reprocess = reprocess
3620
conflicts = merger.do_merge()
3621
if file_list is None:
3622
merger.set_pending()
3629
merge = _merge_helper
5903
3632
# these get imported and then picked up by the scan for cmd_*
5904
3633
# TODO: Some more consistent way to split command definitions across files;
5905
# we do need to load at least some information about them to know of
3634
# we do need to load at least some information about them to know of
5906
3635
# aliases. ideally we would avoid loading the implementation until the
5907
3636
# details were needed.
5908
3637
from bzrlib.cmd_version_info import cmd_version_info
5909
3638
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5910
from bzrlib.bundle.commands import (
5913
from bzrlib.foreign import cmd_dpush
3639
from bzrlib.bundle.commands import cmd_bundle_revisions
5914
3640
from bzrlib.sign_my_commits import cmd_sign_my_commits
5915
from bzrlib.weave_commands import cmd_versionedfile_list, \
3641
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
5916
3642
cmd_weave_plan_merge, cmd_weave_merge_text