393
762
class cmd_mv(Command):
394
763
"""Move or rename a file.
397
766
bzr mv OLDNAME NEWNAME
398
768
bzr mv SOURCE... DESTINATION
400
770
If the last argument is a versioned directory, all the other names
401
771
are moved into it. Otherwise, there must be exactly two arguments
402
and the file is changed to a new name, which must not already exist.
772
and the file is changed to a new name.
774
If OLDNAME does not exist on the filesystem but is versioned and
775
NEWNAME does exist on the filesystem but is not versioned, mv
776
assumes that the file has been manually moved and only updates
777
its internal inventory to reflect that change.
778
The same is valid when moving many SOURCE files to a DESTINATION.
404
780
Files cannot be moved between branches.
407
783
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.'),
408
789
aliases = ['move', 'rename']
409
790
encoding_type = 'replace'
411
def run(self, names_list):
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.')
412
797
if names_list is None:
415
799
if len(names_list) < 2:
416
raise BzrCommandError("missing file argument")
417
tree, rel_names = tree_files(names_list)
419
if os.path.isdir(names_list[-1]):
800
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
420
839
# move into existing directory
421
for pair in tree.move(rel_names[:-1], rel_names[-1]):
422
self.outf.write("%s => %s\n" % pair)
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))
424
847
if len(names_list) != 2:
425
raise BzrCommandError('to mv multiple files the destination '
426
'must be a versioned directory')
427
tree.rename_one(rel_names[0], rel_names[1])
428
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
848
raise errors.BzrCommandError('to mv multiple files the'
849
' 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))
431
899
class cmd_pull(Command):
432
900
"""Turn this branch into a mirror of another branch.
434
This command only works on branches that have not diverged. Branches are
435
considered diverged if the destination branch's most recent commit is one
436
that has not been merged (directly or indirectly) into the parent.
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
438
907
If branches have diverged, you can use 'bzr merge' to integrate the changes
439
908
from one into the other. Once one branch has merged, the other should
440
909
be able to pull it again.
442
If you want to forget your local changes and just update your branch to
443
match the remote one, use pull --overwrite.
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.
445
915
If there is no default location set, the first pull will set it. After
446
916
that, you can omit the location to use the default. To change the
447
917
default, use --remember. The value will only be saved if the remote
448
918
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
451
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
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.'),
930
help='Branch to pull into, '
931
'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 "
452
941
takes_args = ['location?']
453
942
encoding_type = 'replace'
455
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
944
def run(self, location=None, remember=False, overwrite=False,
945
revision=None, verbose=False,
946
directory=None, local=False):
456
947
# FIXME: too much stuff is in the command class
950
if directory is None:
458
tree_to = WorkingTree.open_containing(u'.')[0]
953
tree_to = WorkingTree.open_containing(directory)[0]
459
954
branch_to = tree_to.branch
460
except NoWorkingTree:
955
except errors.NoWorkingTree:
462
branch_to = Branch.open_containing(u'.')[0]
957
branch_to = Branch.open_containing(directory)[0]
959
if local and not branch_to.get_bound_location():
960
raise errors.LocalRequiresBoundBranch()
962
possible_transports = []
465
963
if location is not None:
467
reader = bundle.read_bundle_from_url(location)
469
pass # Continue on considering this url a Branch
965
mergeable = bundle.read_mergeable_from_url(location,
966
possible_transports=possible_transports)
967
except errors.NotABundle:
471
970
stored_loc = branch_to.get_parent()
472
971
if location is None:
473
972
if stored_loc is None:
474
raise BzrCommandError("No pull location known or specified.")
973
raise errors.BzrCommandError("No pull location known or"
476
976
display_url = urlutils.unescape_for_display(stored_loc,
477
977
self.outf.encoding)
478
self.outf.write("Using saved location: %s\n" % display_url)
979
self.outf.write("Using saved parent location: %s\n" % display_url)
479
980
location = stored_loc
482
if reader is not None:
483
install_bundle(branch_to.repository, reader)
982
revision = _get_one_revision('pull', revision)
983
if mergeable is not None:
984
if revision is not None:
985
raise errors.BzrCommandError(
986
'Cannot use -r with merge directives or bundles')
987
mergeable.install_revisions(branch_to.repository)
988
base_revision_id, revision_id, verified = \
989
mergeable.get_merge_request(branch_to.repository)
484
990
branch_from = branch_to
486
branch_from = Branch.open(location)
992
branch_from = Branch.open(location,
993
possible_transports=possible_transports)
488
995
if branch_to.get_parent() is None or remember:
489
996
branch_to.set_parent(branch_from.base)
493
if reader is not None:
494
rev_id = reader.target
495
elif len(revision) == 1:
496
rev_id = revision[0].in_history(branch_from).rev_id
498
raise BzrCommandError('bzr pull --revision takes one value.')
998
if branch_from is not branch_to:
999
branch_from.lock_read()
1000
self.add_cleanup(branch_from.unlock)
1001
if revision is not None:
1002
revision_id = revision.as_revision_id(branch_from)
500
old_rh = branch_to.revision_history()
1004
branch_to.lock_write()
1005
self.add_cleanup(branch_to.unlock)
501
1006
if tree_to is not None:
502
count = tree_to.pull(branch_from, overwrite, rev_id)
1007
view_info = _get_view_info_for_change_reporter(tree_to)
1008
change_reporter = delta._ChangeReporter(
1009
unversioned_filter=tree_to.is_ignored,
1010
view_info=view_info)
1011
result = tree_to.pull(
1012
branch_from, overwrite, revision_id, change_reporter,
1013
possible_transports=possible_transports, local=local)
504
count = branch_to.pull(branch_from, overwrite, rev_id)
505
note('%d revision(s) pulled.' % (count,))
1015
result = branch_to.pull(
1016
branch_from, overwrite, revision_id, local=local)
508
new_rh = branch_to.revision_history()
511
from bzrlib.log import show_changed_revisions
512
show_changed_revisions(branch_to, old_rh, new_rh,
1018
result.report(self.outf)
1019
if verbose and result.old_revid != result.new_revid:
1020
log.show_branch_change(
1021
branch_to, self.outf, result.old_revno,
516
1025
class cmd_push(Command):
517
1026
"""Update a mirror of this branch.
519
1028
The target branch will not have its working tree populated because this
520
1029
is both expensive, and is not supported on remote file systems.
522
1031
Some smart servers or protocols *may* put the working tree in place in
539
1048
location can be accessed.
542
takes_options = ['remember', 'overwrite', 'verbose',
543
Option('create-prefix',
544
help='Create the path leading up to the branch '
545
'if it does not already exist')]
1051
_see_also = ['pull', 'update', 'working-trees']
1052
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1053
Option('create-prefix',
1054
help='Create the path leading up to the branch '
1055
'if it does not already exist.'),
1057
help='Branch to push from, '
1058
'rather than the one containing the working directory.',
1062
Option('use-existing-dir',
1063
help='By default push will fail if the target'
1064
' directory exists, but does not already'
1065
' have a control directory. This flag will'
1066
' 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.'),
546
1079
takes_args = ['location?']
547
1080
encoding_type = 'replace'
549
1082
def run(self, location=None, remember=False, overwrite=False,
550
create_prefix=False, verbose=False):
551
# FIXME: Way too big! Put this into a function called from the
554
br_from = Branch.open_containing('.')[0]
555
stored_loc = br_from.get_push_location()
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
1088
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
556
1132
if location is None:
1133
stored_loc = br_from.get_push_location()
557
1134
if stored_loc is None:
558
raise BzrCommandError("No push location known or specified.")
1135
raise errors.BzrCommandError(
1136
"No push location known or specified.")
560
1138
display_url = urlutils.unescape_for_display(stored_loc,
561
1139
self.outf.encoding)
562
self.outf.write("Using saved location: %s\n" % display_url)
1140
self.outf.write("Using saved push location: %s\n" % display_url)
563
1141
location = stored_loc
565
to_transport = transport.get_transport(location)
566
location_url = to_transport.base
570
dir_to = bzrdir.BzrDir.open(location_url)
571
br_to = dir_to.open_branch()
572
except NotBranchError:
574
to_transport = to_transport.clone('..')
575
if not create_prefix:
577
relurl = to_transport.relpath(location_url)
578
mutter('creating directory %s => %s', location_url, relurl)
579
to_transport.mkdir(relurl)
581
raise BzrCommandError("Parent directory of %s "
582
"does not exist." % location)
584
current = to_transport.base
585
needed = [(to_transport, to_transport.relpath(location_url))]
588
to_transport, relpath = needed[-1]
589
to_transport.mkdir(relpath)
592
new_transport = to_transport.clone('..')
593
needed.append((new_transport,
594
new_transport.relpath(to_transport.base)))
595
if new_transport.base == to_transport.base:
596
raise BzrCommandError("Could not create "
598
dir_to = br_from.bzrdir.clone(location_url,
599
revision_id=br_from.last_revision())
600
br_to = dir_to.open_branch()
601
count = len(br_to.revision_history())
602
# We successfully created the target, remember it
603
if br_from.get_push_location() is None or remember:
604
br_from.set_push_location(br_to.base)
606
# We were able to connect to the remote location, so remember it
607
# we don't need to successfully push because of possible divergence.
608
if br_from.get_push_location() is None or remember:
609
br_from.set_push_location(br_to.base)
610
old_rh = br_to.revision_history()
613
tree_to = dir_to.open_workingtree()
614
except errors.NotLocalUrl:
615
warning('This transport does not update the working '
616
'tree of: %s' % (br_to.base,))
617
count = br_to.pull(br_from, overwrite)
618
except NoWorkingTree:
619
count = br_to.pull(br_from, overwrite)
621
count = tree_to.pull(br_from, overwrite)
622
except DivergedBranches:
623
raise BzrCommandError("These branches have diverged."
624
" Try a merge then push with overwrite.")
625
note('%d revision(s) pushed.' % (count,))
628
new_rh = br_to.revision_history()
631
from bzrlib.log import show_changed_revisions
632
show_changed_revisions(br_to, old_rh, new_rh,
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)
636
1149
class cmd_branch(Command):
637
"""Create a new copy of a branch.
1150
"""Create a new branch that is a copy of an existing branch.
639
1152
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
640
1153
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
642
1159
To retrieve the branch as of a particular revision, supply the --revision
643
1160
parameter, as in "branch foo/bar -r 5".
645
--basis is to speed up branching from remote branches. When specified, it
646
copies all the file-contents, inventory and revision data from the basis
647
branch before copying anything from the remote branch.
1163
_see_also = ['checkout']
649
1164
takes_args = ['from_location', 'to_location?']
650
takes_options = ['revision', 'basis']
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."),
651
1186
aliases = ['get', 'clone']
653
def run(self, from_location, to_location=None, revision=None, basis=None):
656
elif len(revision) > 1:
657
raise BzrCommandError(
658
'bzr branch --revision takes exactly 1 revision value')
660
br_from = Branch.open(from_location)
662
if e.errno == errno.ENOENT:
663
raise BzrCommandError('Source location "%s" does not'
664
' exist.' % to_location)
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
1192
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)
667
1196
br_from.lock_read()
669
if basis is not None:
670
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
673
if len(revision) == 1 and revision[0] is not None:
674
revision_id = revision[0].in_history(br_from)[1]
676
# FIXME - wt.last_revision, fallback to branch, fall back to
677
# None or perhaps NULL_REVISION to mean copy nothing
679
revision_id = br_from.last_revision()
680
if to_location is None:
681
to_location = os.path.basename(from_location.rstrip("/\\"))
684
name = os.path.basename(to_location) + '\n'
686
to_transport = transport.get_transport(to_location)
688
to_transport.mkdir('.')
689
except errors.FileExists:
690
raise BzrCommandError('Target directory "%s" already'
691
' exists.' % to_location)
692
except errors.NoSuchFile:
693
raise BzrCommandError('Parent of "%s" does not exist.' %
696
# preserve whatever source format we have.
697
dir = br_from.bzrdir.sprout(to_transport.base,
698
revision_id, basis_dir)
699
branch = dir.open_branch()
700
except errors.NoSuchRevision:
701
to_transport.delete_tree('.')
702
msg = "The branch %s has no revision %s." % (from_location, revision[0])
703
raise BzrCommandError(msg)
704
except errors.UnlistableBranch:
705
osutils.rmtree(to_location)
706
msg = "The branch %s cannot be used as a --basis" % (basis,)
707
raise BzrCommandError(msg)
709
branch.control_files.put_utf8('branch-name', name)
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:
710
1248
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'))
715
1262
class cmd_checkout(Command):
813
1363
class cmd_update(Command):
814
1364
"""Update a tree to have the latest code committed to its branch.
816
1366
This will perform a merge into the working tree, and may generate
817
conflicts. If you have any local changes, you will still
1367
conflicts. If you have any local changes, you will still
818
1368
need to commit them after the update for the update to be complete.
820
If you want to discard your local changes, you can just do a
1370
If you want to discard your local changes, you can just do a
821
1371
'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']
823
1378
takes_args = ['dir?']
1379
takes_options = ['revision']
824
1380
aliases = ['up']
826
def run(self, dir='.'):
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")
827
1386
tree = WorkingTree.open_containing(dir)[0]
1387
branch = tree.branch
1388
possible_transports = []
1389
master = branch.get_master_branch(
1390
possible_transports=possible_transports)
1391
if master is not None:
1393
branch_location = master.base
1395
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)
830
existing_pending_merges = tree.pending_merges()
831
last_rev = tree.last_revision()
832
if last_rev == tree.branch.last_revision():
833
# may be up to date, check master too.
834
master = tree.branch.get_master_branch()
835
if master is None or last_rev == master.last_revision():
836
revno = tree.branch.revision_id_to_revno(last_rev)
837
note("Tree is up to date at revision %d." % (revno,))
839
conflicts = tree.update()
840
revno = tree.branch.revision_id_to_revno(tree.last_revision())
841
note('Updated to revision %d.' % (revno,))
842
if tree.pending_merges() != existing_pending_merges:
843
note('Your local commits will now show as pending merges with '
844
"'bzr status', and can be committed with 'bzr commit'.")
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'.")
853
1447
class cmd_info(Command):
854
1448
"""Show information about a working tree, branch or repository.
856
1450
This command will show all known locations and formats associated to the
857
tree, branch or repository. Statistical information is included with
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.
860
1457
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']
862
1476
takes_args = ['location?']
863
1477
takes_options = ['verbose']
1478
encoding_type = 'replace'
865
1480
@display_command
866
1481
def run(self, location=None, verbose=False):
1483
noise_level = get_verbosity_level()
867
1486
from bzrlib.info import show_bzrdir_info
868
1487
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1488
verbose=noise_level, outfile=self.outf)
872
1491
class cmd_remove(Command):
873
"""Make a file unversioned.
875
This makes bzr stop tracking changes to a versioned file. It does
876
not delete the working copy.
878
You can specify one or more files, and/or --new. If you specify --new,
879
only 'added' files will be removed. If you specify both, then new files
880
in the specified directories will be removed. If the directories are
881
also new, they will also be removed.
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.
883
1499
takes_args = ['file*']
884
takes_options = ['verbose', Option('new', help='remove newly-added files')]
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']
886
1511
encoding_type = 'replace'
888
def run(self, file_list, verbose=False, new=False):
1513
def run(self, file_list, verbose=False, new=False,
1514
file_deletion_strategy='safe'):
889
1515
tree, file_list = tree_files(file_list)
891
if file_list is None:
892
raise BzrCommandError('Specify one or more files to remove, or'
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
895
1525
added = tree.changes_from(tree.basis_tree(),
896
1526
specific_files=file_list).added
897
1527
file_list = sorted([f[0] for f in added], reverse=True)
898
1528
if len(file_list) == 0:
899
raise BzrCommandError('No matching files.')
900
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1529
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')
903
1545
class cmd_file_id(Command):
1049
1710
# Just using os.mkdir, since I don't
1050
1711
# believe that we want to create a bunch of
1051
1712
# locations if the user supplies an extended path
1052
# TODO: create-prefix
1054
to_transport.mkdir('.')
1055
except errors.FileExists:
1059
existing_bzrdir = bzrdir.BzrDir.open(location)
1060
except NotBranchError:
1714
to_transport.ensure_base()
1715
except errors.NoSuchFile:
1716
if not create_prefix:
1717
raise errors.BzrCommandError("Parent directory of %s"
1719
"\nYou may supply --create-prefix to create all"
1720
" leading parent directories."
1722
to_transport.create_prefix()
1725
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1726
except errors.NotBranchError:
1061
1727
# really a NotBzrDir error...
1062
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1728
create_branch = bzrdir.BzrDir.create_branch_convenience
1729
branch = create_branch(to_transport.base, format=format,
1730
possible_transports=[to_transport])
1731
a_bzrdir = branch.bzrdir
1064
if existing_bzrdir.has_branch():
1733
from bzrlib.transport.local import LocalTransport
1734
if a_bzrdir.has_branch():
1065
1735
if (isinstance(to_transport, LocalTransport)
1066
and not existing_bzrdir.has_workingtree()):
1736
and not a_bzrdir.has_workingtree()):
1067
1737
raise errors.BranchExistsWithoutWorkingTree(location)
1068
1738
raise errors.AlreadyBranchError(location)
1070
existing_bzrdir.create_branch()
1071
existing_bzrdir.create_workingtree()
1739
branch = a_bzrdir.create_branch()
1740
a_bzrdir.create_workingtree()
1741
if append_revisions_only:
1743
branch.set_append_revisions_only(True)
1744
except errors.UpgradeRequired:
1745
raise errors.BzrCommandError('This branch format cannot be set'
1746
' to append-revisions-only. Try --default.')
1748
from bzrlib.info import describe_layout, describe_format
1750
tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
1751
except (errors.NoWorkingTree, errors.NotLocalUrl):
1753
repository = branch.repository
1754
layout = describe_layout(repository, branch, tree).lower()
1755
format = describe_format(a_bzrdir, repository, branch, tree)
1756
self.outf.write("Created a %s (format: %s)\n" % (layout, format))
1757
if repository.is_shared():
1758
#XXX: maybe this can be refactored into transport.path_or_url()
1759
url = repository.bzrdir.root_transport.external_url()
1761
url = urlutils.local_path_from_url(url)
1762
except errors.InvalidURL:
1764
self.outf.write("Using shared repository: %s\n" % url)
1074
1767
class cmd_init_repository(Command):
1075
"""Create a shared repository to hold branches.
1077
New branches created under the repository directory will store their revisions
1078
in the repository, not in the branch directory, if the branch format supports
1084
bzr checkout --lightweight repo/trunk trunk-checkout
1768
"""Create a shared repository for branches to share storage space.
1770
New branches created under the repository directory will store their
1771
revisions in the repository, not in the branch directory. For branches
1772
with shared history, this reduces the amount of storage needed and
1773
speeds up the creation of new branches.
1775
If the --no-trees option is given then the branches in the repository
1776
will not have working trees by default. They will still exist as
1777
directories on disk, but they will not have separate copies of the
1778
files at a certain revision. This can be useful for repositories that
1779
store branches which are interacted with through checkouts or remote
1780
branches, such as on a server.
1783
Create a shared repository holding just branches::
1785
bzr init-repo --no-trees repo
1788
Make a lightweight checkout elsewhere::
1790
bzr checkout --lightweight repo/trunk trunk-checkout
1088
takes_args = ["location"]
1089
takes_options = [Option('format',
1090
help='Specify a format for this repository.'
1091
' Current formats are: default, knit,'
1092
' metaweave and weave. Default is knit;'
1093
' metaweave and weave are deprecated',
1094
type=get_format_type),
1096
help='Allows branches in repository to have'
1795
_see_also = ['init', 'branch', 'checkout', 'repositories']
1796
takes_args = ["location"]
1797
takes_options = [RegistryOption('format',
1798
help='Specify a format for this repository. See'
1799
' "bzr help formats" for details.',
1800
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1801
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1802
value_switches=True, title='Repository format'),
1804
help='Branches in the repository will default to'
1805
' not having a working tree.'),
1098
1807
aliases = ["init-repo"]
1099
def run(self, location, format=None, trees=False):
1809
def run(self, location, format=None, no_trees=False):
1100
1810
if format is None:
1101
format = get_format_type('default')
1811
format = bzrdir.format_registry.make_bzrdir('default')
1103
1813
if location is None:
1106
1816
to_transport = transport.get_transport(location)
1108
to_transport.mkdir('.')
1109
except errors.FileExists:
1817
to_transport.ensure_base()
1112
1819
newdir = format.initialize_on_transport(to_transport)
1113
1820
repo = newdir.create_repository(shared=True)
1114
repo.set_make_working_trees(trees)
1821
repo.set_make_working_trees(not no_trees)
1823
from bzrlib.info import show_bzrdir_info
1824
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
1117
1827
class cmd_diff(Command):
1118
"""Show differences in the working tree or between revisions.
1120
If files are listed, only the changes in those files are listed.
1121
Otherwise, all changes for the tree are listed.
1828
"""Show differences in the working tree, between revisions or branches.
1830
If no arguments are given, all changes for the current tree are listed.
1831
If files are given, only the changes in those files are listed.
1832
Remote and multiple branches can be compared by using the --old and
1833
--new options. If not provided, the default for both is derived from
1834
the first argument, if any, or the current tree if no arguments are
1123
1837
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1124
1838
produces patches suitable for "patch -p1".
1128
Shows the difference in the working tree versus the last commit
1130
Difference between the working tree and revision 1
1132
Difference between revision 2 and revision 1
1133
bzr diff --diff-prefix old/:new/
1134
Same as 'bzr diff' but prefix paths with old/ and new/
1135
bzr diff bzr.mine bzr.dev
1136
Show the differences between the two working trees
1138
Show just the differences for 'foo.c'
1842
2 - unrepresentable changes
1847
Shows the difference in the working tree versus the last commit::
1851
Difference between the working tree and revision 1::
1855
Difference between revision 3 and revision 1::
1859
Difference between revision 3 and revision 1 for branch xxx::
1863
To see the changes introduced in revision X::
1867
Note that in the case of a merge, the -c option shows the changes
1868
compared to the left hand parent. To see the changes against
1869
another parent, use::
1871
bzr diff -r<chosen_parent>..X
1873
The changes introduced by revision 2 (equivalent to -r1..2)::
1877
Show just the differences for file NEWS::
1881
Show the differences in working tree xxx for file NEWS::
1885
Show the differences from branch xxx to this working tree:
1889
Show the differences between two branches for file NEWS::
1891
bzr diff --old xxx --new yyy NEWS
1893
Same as 'bzr diff' but prefix paths with old/ and new/::
1895
bzr diff --prefix old/:new/
1140
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1141
# or a graphical diff.
1143
# TODO: Python difflib is not exactly the same as unidiff; should
1144
# either fix it up or prefer to use an external diff.
1146
# TODO: Selected-file diff is inefficient and doesn't show you
1149
# TODO: This probably handles non-Unix newlines poorly.
1897
_see_also = ['status']
1151
1898
takes_args = ['file*']
1152
takes_options = ['revision', 'diff-options', 'prefix']
1900
Option('diff-options', type=str,
1901
help='Pass these options to the external diff program.'),
1902
Option('prefix', type=str,
1904
help='Set prefixes added to old and new filenames, as '
1905
'two values separated by a colon. (eg "old/:new/").'),
1907
help='Branch/tree to compare from.',
1911
help='Branch/tree to compare to.',
1917
help='Use this command to compare files.',
1153
1921
aliases = ['di', 'dif']
1154
1922
encoding_type = 'exact'
1156
1924
@display_command
1157
1925
def run(self, revision=None, file_list=None, diff_options=None,
1159
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1926
prefix=None, old=None, new=None, using=None):
1927
from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
1161
1929
if (prefix is None) or (prefix == '0'):
1162
1930
# diff -p0 format
1283
2057
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)
1286
2076
class cmd_log(Command):
1287
"""Show log of a branch, file, or directory.
1289
By default show the log of the branch containing the working directory.
1291
To request a range of logs, you can use the command -r begin..end
1292
-r revision requests a specific revision, -r ..end or -r begin.. are
1298
bzr log -r -10.. http://server/branch
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 glog from the QBzr and Bzr-Gtk packages
2195
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2196
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2198
Web interfaces are often better at exploring history than command line
2199
tools, particularly for branches on servers. You may prefer Loggerhead
2200
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2202
You may find it useful to add the aliases below to ``bazaar.conf``::
2206
top = log -l10 --line
2209
``bzr tip`` will then show the latest revision while ``bzr top``
2210
will show the last 10 mainline revisions. To see the details of a
2211
particular revision X, ``bzr show -rX``.
2213
If you are interested in looking deeper into a particular merge X,
2214
use ``bzr log -n0 -rX``.
2216
``bzr log -v`` on a branch with lots of history is currently
2217
very slow. A fix for this issue is currently under development.
2218
With or without that fix, it is recommended that a revision range
2219
be given when using the -v option.
2221
bzr has a generic full-text matching plugin, bzr-search, that can be
2222
used to find revisions matching user names, commit messages, etc.
2223
Among other features, this plugin can find all revisions containing
2224
a list of words but not others.
2226
When exploring non-mainline history on large projects with deep
2227
history, the performance of log can be greatly improved by installing
2228
the historycache plugin. This plugin buffers historical information
2229
trading disk space for faster speed.
1301
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1303
takes_args = ['location?']
1304
takes_options = [Option('forward',
1305
help='show from oldest to newest'),
1308
help='show files changed in each revision'),
1309
'show-ids', 'revision',
1313
help='show revisions whose message matches this regexp',
2231
takes_args = ['file*']
2232
_see_also = ['log-formats', 'revisionspec']
2235
help='Show from oldest to newest.'),
2237
custom_help('verbose',
2238
help='Show files changed in each revision.'),
2242
type=bzrlib.option._parse_revision_str,
2244
help='Show just the specified revision.'
2245
' See also "help revisionspec".'),
2249
help='Number of levels to display - 0 for all, 1 for flat.',
2251
type=_parse_levels),
2254
help='Show revisions whose message matches this '
2255
'regular expression.',
2259
help='Limit the output to the first N revisions.',
2264
help='Show changes made in each revision as a patch.'),
2265
Option('include-merges',
2266
help='Show merged revisions like --levels 0 does.'),
1317
2268
encoding_type = 'replace'
1319
2270
@display_command
1320
def run(self, location=None, timezone='original',
2271
def run(self, file_list=None, timezone='original',
1322
2273
show_ids=False,
1325
2277
log_format=None,
1330
from bzrlib.log import log_formatter, show_log
1331
assert message is None or isinstance(message, basestring), \
1332
"invalid message argument %r" % message
2282
include_merges=False):
2283
from bzrlib.log import (
2285
make_log_request_dict,
2286
_get_info_for_log_files,
1333
2288
direction = (forward and 'forward') or 'reverse'
1338
# find the file id to log:
1340
dir, fp = bzrdir.BzrDir.open_containing(location)
1341
b = dir.open_branch()
1345
inv = dir.open_workingtree().inventory
1346
except (errors.NotBranchError, errors.NotLocalUrl):
1347
# either no tree, or is remote.
1348
inv = b.basis_tree().inventory
1349
file_id = inv.path2id(fp)
2293
raise errors.BzrCommandError(
2294
'--levels and --include-merges are mutually exclusive')
2296
if change is not None:
2298
raise errors.RangeInChangeOption()
2299
if revision is not None:
2300
raise errors.BzrCommandError(
2301
'--revision and --change are mutually exclusive')
2306
filter_by_dir = False
2308
# find the file ids to log and check for directory filtering
2309
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2310
revision, file_list)
2311
self.add_cleanup(b.unlock)
2312
for relpath, file_id, kind in file_info_list:
2314
raise errors.BzrCommandError(
2315
"Path unknown at end or start of revision range: %s" %
2317
# If the relpath is the top of the tree, we log everything
2322
file_ids.append(file_id)
2323
filter_by_dir = filter_by_dir or (
2324
kind in ['directory', 'tree-reference'])
1352
# FIXME ? log the current subdir only RBC 20060203
2327
# FIXME ? log the current subdir only RBC 20060203
1353
2328
if revision is not None \
1354
2329
and len(revision) > 0 and revision[0].get_branch():
1355
2330
location = revision[0].get_branch()
2101
3642
default, use --remember. The value will only be saved if the remote
2102
3643
location can be accessed.
2106
To merge the latest revision from bzr.dev
2107
bzr merge ../bzr.dev
2109
To merge changes up to and including revision 82 from bzr.dev
2110
bzr merge -r 82 ../bzr.dev
2112
To merge the changes introduced by 82, without previous changes:
2113
bzr merge -r 81..82 ../bzr.dev
3645
The results of the merge are placed into the destination working
3646
directory, where they can be reviewed (with bzr diff), tested, and then
3647
committed to record the result of the merge.
2115
3649
merge refuses to run if there are any uncommitted changes, unless
2116
3650
--force is given.
2118
The following merge types are available:
3652
To select only some changes to merge, use "merge -i", which will prompt
3653
you to apply each diff hunk and file change, similar to "shelve".
3656
To merge the latest revision from bzr.dev::
3658
bzr merge ../bzr.dev
3660
To merge changes up to and including revision 82 from bzr.dev::
3662
bzr merge -r 82 ../bzr.dev
3664
To merge the changes introduced by 82, without previous changes::
3666
bzr merge -r 81..82 ../bzr.dev
3668
To apply a merge directive contained in /tmp/merge::
3670
bzr merge /tmp/merge
2120
takes_args = ['branch?']
2121
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2122
Option('show-base', help="Show base revision text in "
2124
Option('uncommitted', help='Apply uncommitted changes'
2125
' from a working copy, instead of branch changes')]
2128
from merge import merge_type_help
2129
from inspect import getdoc
2130
return getdoc(self) + '\n' + merge_type_help()
2132
def run(self, branch=None, revision=None, force=False, merge_type=None,
2133
show_base=False, reprocess=False, remember=False,
3673
encoding_type = 'exact'
3674
_see_also = ['update', 'remerge', 'status-flags', 'send']
3675
takes_args = ['location?']
3680
help='Merge even if the destination tree has uncommitted changes.'),
3684
Option('show-base', help="Show base revision text in "
3686
Option('uncommitted', help='Apply uncommitted changes'
3687
' from a working copy, instead of branch changes.'),
3688
Option('pull', help='If the destination is already'
3689
' completely merged into the source, pull from the'
3690
' source rather than merging. When this happens,'
3691
' you do not need to commit the result.'),
3693
help='Branch to merge into, '
3694
'rather than the one containing the working directory.',
3698
Option('preview', help='Instead of merging, show a diff of the'
3700
Option('interactive', help='Select changes interactively.',
3704
def run(self, location=None, revision=None, force=False,
3705
merge_type=None, show_base=False, reprocess=None, remember=False,
3706
uncommitted=False, pull=False,
2135
3711
if merge_type is None:
2136
merge_type = Merge3Merger
2138
tree = WorkingTree.open_containing(u'.')[0]
2140
if branch is not None:
2142
reader = bundle.read_bundle_from_url(branch)
2144
pass # Continue on considering this url a Branch
2146
conflicts = merge_bundle(reader, tree, not force, merge_type,
2147
reprocess, show_base)
2153
if revision is None \
2154
or len(revision) < 1 or revision[0].needs_branch():
2155
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2157
if revision is None or len(revision) < 1:
2160
other = [branch, None]
2163
other = [branch, -1]
2164
other_branch, path = Branch.open_containing(branch)
2167
raise BzrCommandError('Cannot use --uncommitted and --revision'
2168
' at the same time.')
2169
branch = revision[0].get_branch() or branch
2170
if len(revision) == 1:
2172
other_branch, path = Branch.open_containing(branch)
2173
revno = revision[0].in_history(other_branch).revno
2174
other = [branch, revno]
2176
assert len(revision) == 2
2177
if None in revision:
2178
raise BzrCommandError(
2179
"Merge doesn't permit empty revision specifier.")
2180
base_branch, path = Branch.open_containing(branch)
2181
branch1 = revision[1].get_branch() or branch
2182
other_branch, path1 = Branch.open_containing(branch1)
2183
if revision[0].get_branch() is not None:
2184
# then path was obtained from it, and is None.
2187
base = [branch, revision[0].in_history(base_branch).revno]
2188
other = [branch1, revision[1].in_history(other_branch).revno]
2190
if tree.branch.get_parent() is None or remember:
2191
tree.branch.set_parent(other_branch.base)
2194
interesting_files = [path]
2196
interesting_files = None
3712
merge_type = _mod_merge.Merge3Merger
3714
if directory is None: directory = u'.'
3715
possible_transports = []
3717
allow_pending = True
3718
verified = 'inapplicable'
3719
tree = WorkingTree.open_containing(directory)[0]
3722
basis_tree = tree.revision_tree(tree.last_revision())
3723
except errors.NoSuchRevision:
3724
basis_tree = tree.basis_tree()
3726
# die as quickly as possible if there are uncommitted changes
3728
if tree.has_changes():
3729
raise errors.UncommittedChanges(tree)
3731
view_info = _get_view_info_for_change_reporter(tree)
3732
change_reporter = delta._ChangeReporter(
3733
unversioned_filter=tree.is_ignored, view_info=view_info)
2197
3734
pb = ui.ui_factory.nested_progress_bar()
3735
self.add_cleanup(pb.finished)
3737
self.add_cleanup(tree.unlock)
3738
if location is not None:
2200
conflict_count = merge(other, base, check_clean=(not force),
2201
merge_type=merge_type,
2202
reprocess=reprocess,
2203
show_base=show_base,
2204
pb=pb, file_list=interesting_files)
2207
if conflict_count != 0:
3740
mergeable = bundle.read_mergeable_from_url(location,
3741
possible_transports=possible_transports)
3742
except errors.NotABundle:
3746
raise errors.BzrCommandError('Cannot use --uncommitted'
3747
' with bundles or merge directives.')
3749
if revision is not None:
3750
raise errors.BzrCommandError(
3751
'Cannot use -r with merge directives or bundles')
3752
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3755
if merger is None and uncommitted:
3756
if revision is not None and len(revision) > 0:
3757
raise errors.BzrCommandError('Cannot use --uncommitted and'
3758
' --revision at the same time.')
3759
merger = self.get_merger_from_uncommitted(tree, location, pb)
3760
allow_pending = False
3763
merger, allow_pending = self._get_merger_from_branch(tree,
3764
location, revision, remember, possible_transports, pb)
3766
merger.merge_type = merge_type
3767
merger.reprocess = reprocess
3768
merger.show_base = show_base
3769
self.sanity_check_merger(merger)
3770
if (merger.base_rev_id == merger.other_rev_id and
3771
merger.other_rev_id is not None):
3772
note('Nothing to do.')
3775
if merger.interesting_files is not None:
3776
raise errors.BzrCommandError('Cannot pull individual files')
3777
if (merger.base_rev_id == tree.last_revision()):
3778
result = tree.pull(merger.other_branch, False,
3779
merger.other_rev_id)
3780
result.report(self.outf)
2211
except errors.AmbiguousBase, e:
2212
m = ("sorry, bzr can't determine the right merge base yet\n"
2213
"candidates are:\n "
2214
+ "\n ".join(e.bases)
2216
"please specify an explicit base with -r,\n"
2217
"and (if you want) report this to the bzr developers\n")
2220
# TODO: move up to common parent; this isn't merge-specific anymore.
2221
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3782
if merger.this_basis is None:
3783
raise errors.BzrCommandError(
3784
"This branch has no commits."
3785
" (perhaps you would prefer 'bzr pull')")
3787
return self._do_preview(merger)
3789
return self._do_interactive(merger)
3791
return self._do_merge(merger, change_reporter, allow_pending,
3794
def _get_preview(self, merger):
3795
tree_merger = merger.make_merger()
3796
tt = tree_merger.make_preview_transform()
3797
self.add_cleanup(tt.finalize)
3798
result_tree = tt.get_preview_tree()
3801
def _do_preview(self, merger):
3802
from bzrlib.diff import show_diff_trees
3803
result_tree = self._get_preview(merger)
3804
show_diff_trees(merger.this_tree, result_tree, self.outf,
3805
old_label='', new_label='')
3807
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3808
merger.change_reporter = change_reporter
3809
conflict_count = merger.do_merge()
3811
merger.set_pending()
3812
if verified == 'failed':
3813
warning('Preview patch does not match changes')
3814
if conflict_count != 0:
3819
def _do_interactive(self, merger):
3820
"""Perform an interactive merge.
3822
This works by generating a preview tree of the merge, then using
3823
Shelver to selectively remove the differences between the working tree
3824
and the preview tree.
3826
from bzrlib import shelf_ui
3827
result_tree = self._get_preview(merger)
3828
writer = bzrlib.option.diff_writer_registry.get()
3829
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3830
reporter=shelf_ui.ApplyReporter(),
3831
diff_writer=writer(sys.stdout))
3837
def sanity_check_merger(self, merger):
3838
if (merger.show_base and
3839
not merger.merge_type is _mod_merge.Merge3Merger):
3840
raise errors.BzrCommandError("Show-base is not supported for this"
3841
" merge type. %s" % merger.merge_type)
3842
if merger.reprocess is None:
3843
if merger.show_base:
3844
merger.reprocess = False
3846
# Use reprocess if the merger supports it
3847
merger.reprocess = merger.merge_type.supports_reprocess
3848
if merger.reprocess and not merger.merge_type.supports_reprocess:
3849
raise errors.BzrCommandError("Conflict reduction is not supported"
3850
" for merge type %s." %
3852
if merger.reprocess and merger.show_base:
3853
raise errors.BzrCommandError("Cannot do conflict reduction and"
3856
def _get_merger_from_branch(self, tree, location, revision, remember,
3857
possible_transports, pb):
3858
"""Produce a merger from a location, assuming it refers to a branch."""
3859
from bzrlib.tag import _merge_tags_if_possible
3860
# find the branch locations
3861
other_loc, user_location = self._select_branch_location(tree, location,
3863
if revision is not None and len(revision) == 2:
3864
base_loc, _unused = self._select_branch_location(tree,
3865
location, revision, 0)
3867
base_loc = other_loc
3869
other_branch, other_path = Branch.open_containing(other_loc,
3870
possible_transports)
3871
if base_loc == other_loc:
3872
base_branch = other_branch
3874
base_branch, base_path = Branch.open_containing(base_loc,
3875
possible_transports)
3876
# Find the revision ids
3877
other_revision_id = None
3878
base_revision_id = None
3879
if revision is not None:
3880
if len(revision) >= 1:
3881
other_revision_id = revision[-1].as_revision_id(other_branch)
3882
if len(revision) == 2:
3883
base_revision_id = revision[0].as_revision_id(base_branch)
3884
if other_revision_id is None:
3885
other_revision_id = _mod_revision.ensure_null(
3886
other_branch.last_revision())
3887
# Remember where we merge from
3888
if ((remember or tree.branch.get_submit_branch() is None) and
3889
user_location is not None):
3890
tree.branch.set_submit_branch(other_branch.base)
3891
_merge_tags_if_possible(other_branch, tree.branch)
3892
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3893
other_revision_id, base_revision_id, other_branch, base_branch)
3894
if other_path != '':
3895
allow_pending = False
3896
merger.interesting_files = [other_path]
3898
allow_pending = True
3899
return merger, allow_pending
3901
def get_merger_from_uncommitted(self, tree, location, pb):
3902
"""Get a merger for uncommitted changes.
3904
:param tree: The tree the merger should apply to.
3905
:param location: The location containing uncommitted changes.
3906
:param pb: The progress bar to use for showing progress.
3908
location = self._select_branch_location(tree, location)[0]
3909
other_tree, other_path = WorkingTree.open_containing(location)
3910
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
3911
if other_path != '':
3912
merger.interesting_files = [other_path]
3915
def _select_branch_location(self, tree, user_location, revision=None,
3917
"""Select a branch location, according to possible inputs.
3919
If provided, branches from ``revision`` are preferred. (Both
3920
``revision`` and ``index`` must be supplied.)
3922
Otherwise, the ``location`` parameter is used. If it is None, then the
3923
``submit`` or ``parent`` location is used, and a note is printed.
3925
:param tree: The working tree to select a branch for merging into
3926
:param location: The location entered by the user
3927
:param revision: The revision parameter to the command
3928
:param index: The index to use for the revision parameter. Negative
3929
indices are permitted.
3930
:return: (selected_location, user_location). The default location
3931
will be the user-entered location.
3933
if (revision is not None and index is not None
3934
and revision[index] is not None):
3935
branch = revision[index].get_branch()
3936
if branch is not None:
3937
return branch, branch
3938
if user_location is None:
3939
location = self._get_remembered(tree, 'Merging from')
3941
location = user_location
3942
return location, user_location
3944
def _get_remembered(self, tree, verb_string):
2222
3945
"""Use tree.branch's parent if none was supplied.
2224
3947
Report if the remembered location was used.
2226
if supplied_location is not None:
2227
return supplied_location
2228
stored_location = tree.branch.get_parent()
3949
stored_location = tree.branch.get_submit_branch()
3950
stored_location_type = "submit"
3951
if stored_location is None:
3952
stored_location = tree.branch.get_parent()
3953
stored_location_type = "parent"
2229
3954
mutter("%s", stored_location)
2230
3955
if stored_location is None:
2231
raise BzrCommandError("No location specified or remembered")
2232
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2233
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3956
raise errors.BzrCommandError("No location specified or remembered")
3957
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3958
note(u"%s remembered %s location %s", verb_string,
3959
stored_location_type, display_url)
2234
3960
return stored_location
2238
3964
"""Redo a merge.
2240
3966
Use this if you want to try a different merge technique while resolving
2241
conflicts. Some merge techniques are better than others, and remerge
3967
conflicts. Some merge techniques are better than others, and remerge
2242
3968
lets you try different ones on different files.
2244
3970
The options for remerge have the same meaning and defaults as the ones for
2245
3971
merge. The difference is that remerge can (only) be run when there is a
2246
3972
pending merge, and it lets you specify particular files.
2249
$ bzr remerge --show-base
2250
3975
Re-do the merge of all conflicted files, and show the base text in
2251
conflict regions, in addition to the usual THIS and OTHER texts.
2253
$ bzr remerge --merge-type weave --reprocess foobar
3976
conflict regions, in addition to the usual THIS and OTHER texts::
3978
bzr remerge --show-base
2254
3980
Re-do the merge of "foobar", using the weave merge algorithm, with
2255
additional processing to reduce the size of conflict regions.
2257
The following merge types are available:"""
3981
additional processing to reduce the size of conflict regions::
3983
bzr remerge --merge-type weave --reprocess foobar
2258
3985
takes_args = ['file*']
2259
takes_options = ['merge-type', 'reprocess',
2260
Option('show-base', help="Show base revision text in "
2264
from merge import merge_type_help
2265
from inspect import getdoc
2266
return getdoc(self) + '\n' + merge_type_help()
3990
help="Show base revision text in conflicts."),
2268
3993
def run(self, file_list=None, merge_type=None, show_base=False,
2269
3994
reprocess=False):
2270
from bzrlib.merge import merge_inner, transform_tree
2271
3995
if merge_type is None:
2272
merge_type = Merge3Merger
3996
merge_type = _mod_merge.Merge3Merger
2273
3997
tree, file_list = tree_files(file_list)
2274
3998
tree.lock_write()
3999
self.add_cleanup(tree.unlock)
4000
parents = tree.get_parent_ids()
4001
if len(parents) != 2:
4002
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4003
" merges. Not cherrypicking or"
4005
repository = tree.branch.repository
4006
interesting_ids = None
4008
conflicts = tree.conflicts()
4009
if file_list is not None:
4010
interesting_ids = set()
4011
for filename in file_list:
4012
file_id = tree.path2id(filename)
4014
raise errors.NotVersionedError(filename)
4015
interesting_ids.add(file_id)
4016
if tree.kind(file_id) != "directory":
4019
for name, ie in tree.inventory.iter_entries(file_id):
4020
interesting_ids.add(ie.file_id)
4021
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4023
# Remerge only supports resolving contents conflicts
4024
allowed_conflicts = ('text conflict', 'contents conflict')
4025
restore_files = [c.path for c in conflicts
4026
if c.typestring in allowed_conflicts]
4027
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4028
tree.set_conflicts(ConflictList(new_conflicts))
4029
if file_list is not None:
4030
restore_files = file_list
4031
for filename in restore_files:
4033
restore(tree.abspath(filename))
4034
except errors.NotConflicted:
4036
# Disable pending merges, because the file texts we are remerging
4037
# have not had those merges performed. If we use the wrong parents
4038
# list, we imply that the working tree text has seen and rejected
4039
# all the changes from the other tree, when in fact those changes
4040
# have not yet been seen.
4041
pb = ui.ui_factory.nested_progress_bar()
4042
tree.set_parent_ids(parents[:1])
2276
parents = tree.get_parent_ids()
2277
if len(parents) != 2:
2278
raise BzrCommandError("Sorry, remerge only works after normal"
2279
" merges. Not cherrypicking or"
2281
repository = tree.branch.repository
2282
base_revision = common_ancestor(parents[0],
2283
parents[1], repository)
2284
base_tree = repository.revision_tree(base_revision)
2285
other_tree = repository.revision_tree(parents[1])
2286
interesting_ids = None
2288
conflicts = tree.conflicts()
2289
if file_list is not None:
2290
interesting_ids = set()
2291
for filename in file_list:
2292
file_id = tree.path2id(filename)
2294
raise NotVersionedError(filename)
2295
interesting_ids.add(file_id)
2296
if tree.kind(file_id) != "directory":
2299
for name, ie in tree.inventory.iter_entries(file_id):
2300
interesting_ids.add(ie.file_id)
2301
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2302
transform_tree(tree, tree.basis_tree(), interesting_ids)
2303
tree.set_conflicts(ConflictList(new_conflicts))
2304
if file_list is None:
2305
restore_files = list(tree.iter_conflicts())
2307
restore_files = file_list
2308
for filename in restore_files:
2310
restore(tree.abspath(filename))
2311
except NotConflicted:
2313
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2315
interesting_ids=interesting_ids,
2316
other_rev_id=parents[1],
2317
merge_type=merge_type,
2318
show_base=show_base,
2319
reprocess=reprocess)
4044
merger = _mod_merge.Merger.from_revision_ids(pb,
4046
merger.interesting_ids = interesting_ids
4047
merger.merge_type = merge_type
4048
merger.show_base = show_base
4049
merger.reprocess = reprocess
4050
conflicts = merger.do_merge()
4052
tree.set_parent_ids(parents)
2322
4054
if conflicts > 0:
2327
4060
class cmd_revert(Command):
2328
"""Reverse all changes since the last commit.
2330
Only versioned files are affected. Specify filenames to revert only
2331
those files. By default, any files that are changed will be backed up
2332
first. Backup files have a '~' appended to their name.
4061
"""Revert files to a previous revision.
4063
Giving a list of files will revert only those files. Otherwise, all files
4064
will be reverted. If the revision is not specified with '--revision', the
4065
last committed revision is used.
4067
To remove only some changes, without reverting to a prior version, use
4068
merge instead. For example, "merge . --revision -2..-3" will remove the
4069
changes introduced by -2, without affecting the changes introduced by -1.
4070
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4072
By default, any files that have been manually changed will be backed up
4073
first. (Files changed only by merge are not backed up.) Backup files have
4074
'.~#~' appended to their name, where # is a number.
4076
When you provide files, you can use their current pathname or the pathname
4077
from the target revision. So you can use revert to "undelete" a file by
4078
name. If you name a directory, all the contents of that directory will be
4081
If you have newly added files since the target revision, they will be
4082
removed. If the files to be removed have been changed, backups will be
4083
created as above. Directories containing unknown files will not be
4086
The working tree contains a list of pending merged revisions, which will
4087
be included as parents in the next commit. Normally, revert clears that
4088
list as well as reverting the files. If any files are specified, revert
4089
leaves the pending merge list alone and reverts only the files. Use "bzr
4090
revert ." in the tree root to revert all files but keep the merge record,
4091
and "bzr revert --forget-merges" to clear the pending merge list without
4092
reverting any files.
4094
Using "bzr revert --forget-merges", it is possible to apply the changes
4095
from an arbitrary merge as a single revision. To do this, perform the
4096
merge as desired. Then doing revert with the "--forget-merges" option will
4097
keep the content of the tree as it was, but it will clear the list of
4098
pending merges. The next commit will then contain all of the changes that
4099
would have been in the merge, but without any mention of the other parent
4100
revisions. Because this technique forgets where these changes originated,
4101
it may cause additional conflicts on later merges involving the source and
2334
takes_options = ['revision', 'no-backup']
4105
_see_also = ['cat', 'export']
4108
Option('no-backup', "Do not save backups of reverted files."),
4109
Option('forget-merges',
4110
'Remove pending merge marker, without changing any files.'),
2335
4112
takes_args = ['file*']
2336
aliases = ['merge-revert']
2338
def run(self, revision=None, no_backup=False, file_list=None):
2339
from bzrlib.commands import parse_spec
2340
if file_list is not None:
2341
if len(file_list) == 0:
2342
raise BzrCommandError("No files specified")
4114
def run(self, revision=None, no_backup=False, file_list=None,
4115
forget_merges=None):
2346
4116
tree, file_list = tree_files(file_list)
2347
if revision is None:
2348
# FIXME should be tree.last_revision
2349
rev_id = tree.last_revision()
2350
elif len(revision) != 1:
2351
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
4118
self.add_cleanup(tree.unlock)
4120
tree.set_parent_ids(tree.get_parent_ids()[:1])
2353
rev_id = revision[0].in_history(tree.branch).rev_id
4122
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4125
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4126
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
2354
4127
pb = ui.ui_factory.nested_progress_bar()
2356
tree.revert(file_list,
2357
tree.branch.repository.revision_tree(rev_id),
4129
tree.revert(file_list, rev_tree, not no_backup, pb,
4130
report_changes=True)
2363
4135
class cmd_assert_fail(Command):
2364
4136
"""Test reporting of assertion failures"""
4137
# intended just for use in testing
2367
assert False, "always fails"
4142
raise AssertionError("always fails")
2370
4145
class cmd_help(Command):
2371
4146
"""Show help on a command or other topic.
2373
For a list of all available commands, say 'bzr help commands'."""
2374
takes_options = [Option('long', 'show help on all commands')]
4149
_see_also = ['topics']
4151
Option('long', 'Show help on all commands.'),
2375
4153
takes_args = ['topic?']
2376
4154
aliases = ['?', '--help', '-?', '-h']
2378
4156
@display_command
2379
4157
def run(self, topic=None, long=False):
2381
4159
if topic is None and long:
2382
4160
topic = "commands"
4161
bzrlib.help.help(topic)
2386
4164
class cmd_shell_complete(Command):
2387
4165
"""Show appropriate completions for context.
2389
For a list of all available commands, say 'bzr shell-complete'."""
4167
For a list of all available commands, say 'bzr shell-complete'.
2390
4169
takes_args = ['context?']
2391
4170
aliases = ['s-c']
2394
4173
@display_command
2395
4174
def run(self, context=None):
2396
4175
import shellcomplete
2397
4176
shellcomplete.shellcomplete(context)
2400
class cmd_fetch(Command):
2401
"""Copy in history from another branch but don't merge it.
2403
This is an internal method used for pull and merge."""
2405
takes_args = ['from_branch', 'to_branch']
2406
def run(self, from_branch, to_branch):
2407
from bzrlib.fetch import Fetcher
2408
from_b = Branch.open(from_branch)
2409
to_b = Branch.open(to_branch)
2410
Fetcher(to_b, from_b)
2413
4179
class cmd_missing(Command):
2414
4180
"""Show unmerged/unpulled revisions between two branches.
2416
OTHER_BRANCH may be local or remote."""
4182
OTHER_BRANCH may be local or remote.
4184
To filter on a range of revisions, you can use the command -r begin..end
4185
-r revision requests a specific revision, -r ..end or -r begin.. are
4189
1 - some missing revisions
4190
0 - no missing revisions
4194
Determine the missing revisions between this and the branch at the
4195
remembered pull location::
4199
Determine the missing revisions between this and another branch::
4201
bzr missing http://server/branch
4203
Determine the missing revisions up to a specific revision on the other
4206
bzr missing -r ..-10
4208
Determine the missing revisions up to a specific revision on this
4211
bzr missing --my-revision ..-10
4214
_see_also = ['merge', 'pull']
2417
4215
takes_args = ['other_branch?']
2418
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2420
'Display changes in the local branch only'),
2421
Option('theirs-only',
2422
'Display changes in the remote branch only'),
4217
Option('reverse', 'Reverse the order of revisions.'),
4219
'Display changes in the local branch only.'),
4220
Option('this' , 'Same as --mine-only.'),
4221
Option('theirs-only',
4222
'Display changes in the remote branch only.'),
4223
Option('other', 'Same as --theirs-only.'),
4227
custom_help('revision',
4228
help='Filter on other branch revisions (inclusive). '
4229
'See "help revisionspec" for details.'),
4230
Option('my-revision',
4231
type=_parse_revision_str,
4232
help='Filter on local branch revisions (inclusive). '
4233
'See "help revisionspec" for details.'),
4234
Option('include-merges',
4235
'Show all revisions in addition to the mainline ones.'),
2430
4237
encoding_type = 'replace'
2432
4239
@display_command
2433
4240
def run(self, other_branch=None, reverse=False, mine_only=False,
2434
theirs_only=False, log_format=None, long=False, short=False, line=False,
2435
show_ids=False, verbose=False):
2436
from bzrlib.missing import find_unmerged, iter_log_data
2437
from bzrlib.log import log_formatter
4242
log_format=None, long=False, short=False, line=False,
4243
show_ids=False, verbose=False, this=False, other=False,
4244
include_merges=False, revision=None, my_revision=None):
4245
from bzrlib.missing import find_unmerged, iter_log_revisions
4254
# TODO: We should probably check that we don't have mine-only and
4255
# theirs-only set, but it gets complicated because we also have
4256
# this and other which could be used.
2438
4263
local_branch = Branch.open_containing(u".")[0]
2439
4264
parent = local_branch.get_parent()
2440
4265
if other_branch is None:
2441
4266
other_branch = parent
2442
4267
if other_branch is None:
2443
raise BzrCommandError("No peer location known or specified.")
2444
print "Using last location: " + local_branch.get_parent()
4268
raise errors.BzrCommandError("No peer location known"
4270
display_url = urlutils.unescape_for_display(parent,
4272
message("Using saved parent location: "
4273
+ display_url + "\n")
2445
4275
remote_branch = Branch.open(other_branch)
2446
4276
if remote_branch.base == local_branch.base:
2447
4277
remote_branch = local_branch
2448
4279
local_branch.lock_read()
2450
remote_branch.lock_read()
2452
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2453
if (log_format is None):
2454
default = local_branch.get_config().log_format()
2455
log_format = get_log_format(long=long, short=short,
2456
line=line, default=default)
2457
lf = log_formatter(log_format,
2460
show_timezone='original')
2461
if reverse is False:
2462
local_extra.reverse()
2463
remote_extra.reverse()
2464
if local_extra and not theirs_only:
2465
print "You have %d extra revision(s):" % len(local_extra)
2466
for data in iter_log_data(local_extra, local_branch.repository,
2469
printed_local = True
2471
printed_local = False
2472
if remote_extra and not mine_only:
2473
if printed_local is True:
2475
print "You are missing %d revision(s):" % len(remote_extra)
2476
for data in iter_log_data(remote_extra, remote_branch.repository,
2479
if not remote_extra and not local_extra:
2481
print "Branches are up to date."
2485
remote_branch.unlock()
2487
local_branch.unlock()
4280
self.add_cleanup(local_branch.unlock)
4281
local_revid_range = _revision_range_to_revid_range(
4282
_get_revision_range(my_revision, local_branch,
4285
remote_branch.lock_read()
4286
self.add_cleanup(remote_branch.unlock)
4287
remote_revid_range = _revision_range_to_revid_range(
4288
_get_revision_range(revision,
4289
remote_branch, self.name()))
4291
local_extra, remote_extra = find_unmerged(
4292
local_branch, remote_branch, restrict,
4293
backward=not reverse,
4294
include_merges=include_merges,
4295
local_revid_range=local_revid_range,
4296
remote_revid_range=remote_revid_range)
4298
if log_format is None:
4299
registry = log.log_formatter_registry
4300
log_format = registry.get_default(local_branch)
4301
lf = log_format(to_file=self.outf,
4303
show_timezone='original')
4306
if local_extra and not theirs_only:
4307
message("You have %d extra revision(s):\n" %
4309
for revision in iter_log_revisions(local_extra,
4310
local_branch.repository,
4312
lf.log_revision(revision)
4313
printed_local = True
4316
printed_local = False
4318
if remote_extra and not mine_only:
4319
if printed_local is True:
4321
message("You are missing %d revision(s):\n" %
4323
for revision in iter_log_revisions(remote_extra,
4324
remote_branch.repository,
4326
lf.log_revision(revision)
4329
if mine_only and not local_extra:
4330
# We checked local, and found nothing extra
4331
message('This branch is up to date.\n')
4332
elif theirs_only and not remote_extra:
4333
# We checked remote, and found nothing extra
4334
message('Other branch is up to date.\n')
4335
elif not (mine_only or theirs_only or local_extra or
4337
# We checked both branches, and neither one had extra
4339
message("Branches are up to date.\n")
2488
4341
if not status_code and parent is None and other_branch is not None:
2489
4342
local_branch.lock_write()
2491
# handle race conditions - a parent might be set while we run.
2492
if local_branch.get_parent() is None:
2493
local_branch.set_parent(remote_branch.base)
2495
local_branch.unlock()
4343
self.add_cleanup(local_branch.unlock)
4344
# handle race conditions - a parent might be set while we run.
4345
if local_branch.get_parent() is None:
4346
local_branch.set_parent(remote_branch.base)
2496
4347
return status_code
4350
class cmd_pack(Command):
4351
"""Compress the data within a repository."""
4353
_see_also = ['repositories']
4354
takes_args = ['branch_or_repo?']
4356
def run(self, branch_or_repo='.'):
4357
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4359
branch = dir.open_branch()
4360
repository = branch.repository
4361
except errors.NotBranchError:
4362
repository = dir.open_repository()
2499
4366
class cmd_plugins(Command):
4367
"""List the installed plugins.
4369
This command displays the list of installed plugins including
4370
version of plugin and a short description of each.
4372
--verbose shows the path where each plugin is located.
4374
A plugin is an external component for Bazaar that extends the
4375
revision control system, by adding or replacing code in Bazaar.
4376
Plugins can do a variety of things, including overriding commands,
4377
adding new commands, providing additional network transports and
4378
customizing log output.
4380
See the Bazaar web site, http://bazaar-vcs.org, for further
4381
information on plugins including where to find them and how to
4382
install them. Instructions are also provided there on how to
4383
write new plugins using the Python programming language.
4385
takes_options = ['verbose']
2502
4387
@display_command
4388
def run(self, verbose=False):
2504
4389
import bzrlib.plugin
2505
4390
from inspect import getdoc
2506
for name, plugin in bzrlib.plugin.all_plugins().items():
2507
if getattr(plugin, '__path__', None) is not None:
2508
print plugin.__path__[0]
2509
elif getattr(plugin, '__file__', None) is not None:
2510
print plugin.__file__
4392
for name, plugin in bzrlib.plugin.plugins().items():
4393
version = plugin.__version__
4394
if version == 'unknown':
4396
name_ver = '%s %s' % (name, version)
4397
d = getdoc(plugin.module)
2516
print '\t', d.split('\n')[0]
4399
doc = d.split('\n')[0]
4401
doc = '(no description)'
4402
result.append((name_ver, doc, plugin.path()))
4403
for name_ver, doc, path in sorted(result):
2519
4411
class cmd_testament(Command):
2520
4412
"""Show testament (signing-form) of a revision."""
2521
takes_options = ['revision',
2522
Option('long', help='Produce long-format testament'),
2523
Option('strict', help='Produce a strict-format'
4415
Option('long', help='Produce long-format testament.'),
4417
help='Produce a strict-format testament.')]
2525
4418
takes_args = ['branch?']
2526
4419
@display_command
2527
4420
def run(self, branch=u'.', revision=None, long=False, strict=False):
2765
4743
control.break_lock()
2766
4744
except NotImplementedError:
2771
# command-line interpretation helper for merge-related commands
2772
def merge(other_revision, base_revision,
2773
check_clean=True, ignore_zero=False,
2774
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2775
file_list=None, show_base=False, reprocess=False,
2776
pb=DummyProgress()):
2777
"""Merge changes into a tree.
2780
list(path, revno) Base for three-way merge.
2781
If [None, None] then a base will be automatically determined.
2783
list(path, revno) Other revision for three-way merge.
2785
Directory to merge changes into; '.' by default.
2787
If true, this_dir must have no uncommitted changes before the
2789
ignore_zero - If true, suppress the "zero conflicts" message when
2790
there are no conflicts; should be set when doing something we expect
2791
to complete perfectly.
2792
file_list - If supplied, merge only changes to selected files.
2794
All available ancestors of other_revision and base_revision are
2795
automatically pulled into the branch.
2797
The revno may be -1 to indicate the last revision on the branch, which is
2800
This function is intended for use from the command line; programmatic
2801
clients might prefer to call merge.merge_inner(), which has less magic
2804
from bzrlib.merge import Merger
2805
if this_dir is None:
2807
this_tree = WorkingTree.open_containing(this_dir)[0]
2808
if show_base and not merge_type is Merge3Merger:
2809
raise BzrCommandError("Show-base is not supported for this merge"
2810
" type. %s" % merge_type)
2811
if reprocess and not merge_type.supports_reprocess:
2812
raise BzrCommandError("Conflict reduction is not supported for merge"
2813
" type %s." % merge_type)
2814
if reprocess and show_base:
2815
raise BzrCommandError("Cannot do conflict reduction and show base.")
2817
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2818
merger.pp = ProgressPhase("Merge phase", 5, pb)
2819
merger.pp.next_phase()
2820
merger.check_basis(check_clean)
2821
merger.set_other(other_revision)
2822
merger.pp.next_phase()
2823
merger.set_base(base_revision)
2824
if merger.base_rev_id == merger.other_rev_id:
2825
note('Nothing to do.')
2827
merger.backup_files = backup_files
2828
merger.merge_type = merge_type
2829
merger.set_interesting_files(file_list)
2830
merger.show_base = show_base
2831
merger.reprocess = reprocess
2832
conflicts = merger.do_merge()
2833
if file_list is None:
2834
merger.set_pending()
4748
class cmd_wait_until_signalled(Command):
4749
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4751
This just prints a line to signal when it is ready, then blocks on stdin.
4757
sys.stdout.write("running\n")
4759
sys.stdin.readline()
4762
class cmd_serve(Command):
4763
"""Run the bzr server."""
4765
aliases = ['server']
4769
help='Serve on stdin/out for use from inetd or sshd.'),
4770
RegistryOption('protocol',
4771
help="Protocol to serve.",
4772
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
4773
value_switches=True),
4775
help='Listen for connections on nominated port of the form '
4776
'[hostname:]portnumber. Passing 0 as the port number will '
4777
'result in a dynamically allocated port. The default port '
4778
'depends on the protocol.',
4781
help='Serve contents of this directory.',
4783
Option('allow-writes',
4784
help='By default the server is a readonly server. Supplying '
4785
'--allow-writes enables write access to the contents of '
4786
'the served directory and below. Note that ``bzr serve`` '
4787
'does not perform authentication, so unless some form of '
4788
'external authentication is arranged supplying this '
4789
'option leads to global uncontrolled write access to your '
4794
def get_host_and_port(self, port):
4795
"""Return the host and port to run the smart server on.
4797
If 'port' is None, None will be returned for the host and port.
4799
If 'port' has a colon in it, the string before the colon will be
4800
interpreted as the host.
4802
:param port: A string of the port to run the server on.
4803
:return: A tuple of (host, port), where 'host' is a host name or IP,
4804
and port is an integer TCP/IP port.
4807
if port is not None:
4809
host, port = port.split(':')
4813
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4815
from bzrlib.transport import get_transport, transport_server_registry
4816
if directory is None:
4817
directory = os.getcwd()
4818
if protocol is None:
4819
protocol = transport_server_registry.get()
4820
host, port = self.get_host_and_port(port)
4821
url = urlutils.local_path_to_url(directory)
4822
if not allow_writes:
4823
url = 'readonly+' + url
4824
transport = get_transport(url)
4825
protocol(transport, host, port, inet)
4828
class cmd_join(Command):
4829
"""Combine a tree into its containing tree.
4831
This command requires the target tree to be in a rich-root format.
4833
The TREE argument should be an independent tree, inside another tree, but
4834
not part of it. (Such trees can be produced by "bzr split", but also by
4835
running "bzr branch" with the target inside a tree.)
4837
The result is a combined tree, with the subtree no longer an independant
4838
part. This is marked as a merge of the subtree into the containing tree,
4839
and all history is preserved.
4842
_see_also = ['split']
4843
takes_args = ['tree']
4845
Option('reference', help='Join by reference.', hidden=True),
4848
def run(self, tree, reference=False):
4849
sub_tree = WorkingTree.open(tree)
4850
parent_dir = osutils.dirname(sub_tree.basedir)
4851
containing_tree = WorkingTree.open_containing(parent_dir)[0]
4852
repo = containing_tree.branch.repository
4853
if not repo.supports_rich_root():
4854
raise errors.BzrCommandError(
4855
"Can't join trees because %s doesn't support rich root data.\n"
4856
"You can use bzr upgrade on the repository."
4860
containing_tree.add_reference(sub_tree)
4861
except errors.BadReferenceTarget, e:
4862
# XXX: Would be better to just raise a nicely printable
4863
# exception from the real origin. Also below. mbp 20070306
4864
raise errors.BzrCommandError("Cannot join %s. %s" %
4868
containing_tree.subsume(sub_tree)
4869
except errors.BadSubsumeSource, e:
4870
raise errors.BzrCommandError("Cannot join %s. %s" %
4874
class cmd_split(Command):
4875
"""Split a subdirectory of a tree into a separate tree.
4877
This command will produce a target tree in a format that supports
4878
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4879
converted into earlier formats like 'dirstate-tags'.
4881
The TREE argument should be a subdirectory of a working tree. That
4882
subdirectory will be converted into an independent tree, with its own
4883
branch. Commits in the top-level tree will not apply to the new subtree.
4886
_see_also = ['join']
4887
takes_args = ['tree']
4889
def run(self, tree):
4890
containing_tree, subdir = WorkingTree.open_containing(tree)
4891
sub_id = containing_tree.path2id(subdir)
4893
raise errors.NotVersionedError(subdir)
4895
containing_tree.extract(sub_id)
4896
except errors.RootNotRich:
4897
raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
4900
class cmd_merge_directive(Command):
4901
"""Generate a merge directive for auto-merge tools.
4903
A directive requests a merge to be performed, and also provides all the
4904
information necessary to do so. This means it must either include a
4905
revision bundle, or the location of a branch containing the desired
4908
A submit branch (the location to merge into) must be supplied the first
4909
time the command is issued. After it has been supplied once, it will
4910
be remembered as the default.
4912
A public branch is optional if a revision bundle is supplied, but required
4913
if --diff or --plain is specified. It will be remembered as the default
4914
after the first use.
4917
takes_args = ['submit_branch?', 'public_branch?']
4921
_see_also = ['send']
4924
RegistryOption.from_kwargs('patch-type',
4925
'The type of patch to include in the directive.',
4927
value_switches=True,
4929
bundle='Bazaar revision bundle (default).',
4930
diff='Normal unified diff.',
4931
plain='No patch, just directive.'),
4932
Option('sign', help='GPG-sign the directive.'), 'revision',
4933
Option('mail-to', type=str,
4934
help='Instead of printing the directive, email to this address.'),
4935
Option('message', type=str, short_name='m',
4936
help='Message to use when committing this merge.')
4939
encoding_type = 'exact'
4941
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
4942
sign=False, revision=None, mail_to=None, message=None):
4943
from bzrlib.revision import ensure_null, NULL_REVISION
4944
include_patch, include_bundle = {
4945
'plain': (False, False),
4946
'diff': (True, False),
4947
'bundle': (True, True),
4949
branch = Branch.open('.')
4950
stored_submit_branch = branch.get_submit_branch()
4951
if submit_branch is None:
4952
submit_branch = stored_submit_branch
4954
if stored_submit_branch is None:
4955
branch.set_submit_branch(submit_branch)
4956
if submit_branch is None:
4957
submit_branch = branch.get_parent()
4958
if submit_branch is None:
4959
raise errors.BzrCommandError('No submit branch specified or known')
4961
stored_public_branch = branch.get_public_branch()
4962
if public_branch is None:
4963
public_branch = stored_public_branch
4964
elif stored_public_branch is None:
4965
branch.set_public_branch(public_branch)
4966
if not include_bundle and public_branch is None:
4967
raise errors.BzrCommandError('No public branch specified or'
4969
base_revision_id = None
4970
if revision is not None:
4971
if len(revision) > 2:
4972
raise errors.BzrCommandError('bzr merge-directive takes '
4973
'at most two one revision identifiers')
4974
revision_id = revision[-1].as_revision_id(branch)
4975
if len(revision) == 2:
4976
base_revision_id = revision[0].as_revision_id(branch)
4978
revision_id = branch.last_revision()
4979
revision_id = ensure_null(revision_id)
4980
if revision_id == NULL_REVISION:
4981
raise errors.BzrCommandError('No revisions to bundle.')
4982
directive = merge_directive.MergeDirective2.from_objects(
4983
branch.repository, revision_id, time.time(),
4984
osutils.local_time_offset(), submit_branch,
4985
public_branch=public_branch, include_patch=include_patch,
4986
include_bundle=include_bundle, message=message,
4987
base_revision_id=base_revision_id)
4990
self.outf.write(directive.to_signed(branch))
4992
self.outf.writelines(directive.to_lines())
4994
message = directive.to_email(mail_to, branch, sign)
4995
s = SMTPConnection(branch.get_config())
4996
s.send_email(message)
4999
class cmd_send(Command):
5000
"""Mail or create a merge-directive for submitting changes.
5002
A merge directive provides many things needed for requesting merges:
5004
* A machine-readable description of the merge to perform
5006
* An optional patch that is a preview of the changes requested
5008
* An optional bundle of revision data, so that the changes can be applied
5009
directly from the merge directive, without retrieving data from a
5012
If --no-bundle is specified, then public_branch is needed (and must be
5013
up-to-date), so that the receiver can perform the merge using the
5014
public_branch. The public_branch is always included if known, so that
5015
people can check it later.
5017
The submit branch defaults to the parent, but can be overridden. Both
5018
submit branch and public branch will be remembered if supplied.
5020
If a public_branch is known for the submit_branch, that public submit
5021
branch is used in the merge instructions. This means that a local mirror
5022
can be used as your actual submit branch, once you have set public_branch
5025
Mail is sent using your preferred mail program. This should be transparent
5026
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5027
If the preferred client can't be found (or used), your editor will be used.
5029
To use a specific mail program, set the mail_client configuration option.
5030
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5031
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5032
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5033
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5036
If mail is being sent, a to address is required. This can be supplied
5037
either on the commandline, by setting the submit_to configuration
5038
option in the branch itself or the child_submit_to configuration option
5039
in the submit branch.
5041
Two formats are currently supported: "4" uses revision bundle format 4 and
5042
merge directive format 2. It is significantly faster and smaller than
5043
older formats. It is compatible with Bazaar 0.19 and later. It is the
5044
default. "0.9" uses revision bundle format 0.9 and merge directive
5045
format 1. It is compatible with Bazaar 0.12 - 0.18.
5047
The merge directives created by bzr send may be applied using bzr merge or
5048
bzr pull by specifying a file containing a merge directive as the location.
5051
encoding_type = 'exact'
5053
_see_also = ['merge', 'pull']
5055
takes_args = ['submit_branch?', 'public_branch?']
5059
help='Do not include a bundle in the merge directive.'),
5060
Option('no-patch', help='Do not include a preview patch in the merge'
5063
help='Remember submit and public branch.'),
5065
help='Branch to generate the submission from, '
5066
'rather than the one containing the working directory.',
5069
Option('output', short_name='o',
5070
help='Write merge directive to this file; '
5071
'use - for stdout.',
5074
help='Refuse to send if there are uncommitted changes in'
5075
' the working tree, --no-strict disables the check.'),
5076
Option('mail-to', help='Mail the request to this address.',
5080
Option('body', help='Body for the email.', type=unicode),
5081
RegistryOption('format',
5082
help='Use the specified output format.',
5083
lazy_registry=('bzrlib.send', 'format_registry')),
5086
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5087
no_patch=False, revision=None, remember=False, output=None,
5088
format=None, mail_to=None, message=None, body=None,
5089
strict=None, **kwargs):
5090
from bzrlib.send import send
5091
return send(submit_branch, revision, public_branch, remember,
5092
format, no_bundle, no_patch, output,
5093
kwargs.get('from', '.'), mail_to, message, body,
5098
class cmd_bundle_revisions(cmd_send):
5099
"""Create a merge-directive for submitting changes.
5101
A merge directive provides many things needed for requesting merges:
5103
* A machine-readable description of the merge to perform
5105
* An optional patch that is a preview of the changes requested
5107
* An optional bundle of revision data, so that the changes can be applied
5108
directly from the merge directive, without retrieving data from a
5111
If --no-bundle is specified, then public_branch is needed (and must be
5112
up-to-date), so that the receiver can perform the merge using the
5113
public_branch. The public_branch is always included if known, so that
5114
people can check it later.
5116
The submit branch defaults to the parent, but can be overridden. Both
5117
submit branch and public branch will be remembered if supplied.
5119
If a public_branch is known for the submit_branch, that public submit
5120
branch is used in the merge instructions. This means that a local mirror
5121
can be used as your actual submit branch, once you have set public_branch
5124
Two formats are currently supported: "4" uses revision bundle format 4 and
5125
merge directive format 2. It is significantly faster and smaller than
5126
older formats. It is compatible with Bazaar 0.19 and later. It is the
5127
default. "0.9" uses revision bundle format 0.9 and merge directive
5128
format 1. It is compatible with Bazaar 0.12 - 0.18.
5133
help='Do not include a bundle in the merge directive.'),
5134
Option('no-patch', help='Do not include a preview patch in the merge'
5137
help='Remember submit and public branch.'),
5139
help='Branch to generate the submission from, '
5140
'rather than the one containing the working directory.',
5143
Option('output', short_name='o', help='Write directive to this file.',
5146
help='Refuse to bundle revisions if there are uncommitted'
5147
' changes in the working tree, --no-strict disables the check.'),
5149
RegistryOption('format',
5150
help='Use the specified output format.',
5151
lazy_registry=('bzrlib.send', 'format_registry')),
5153
aliases = ['bundle']
5155
_see_also = ['send', 'merge']
5159
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5160
no_patch=False, revision=None, remember=False, output=None,
5161
format=None, strict=None, **kwargs):
5164
from bzrlib.send import send
5165
return send(submit_branch, revision, public_branch, remember,
5166
format, no_bundle, no_patch, output,
5167
kwargs.get('from', '.'), None, None, None,
5168
self.outf, strict=strict)
5171
class cmd_tag(Command):
5172
"""Create, remove or modify a tag naming a revision.
5174
Tags give human-meaningful names to revisions. Commands that take a -r
5175
(--revision) option can be given -rtag:X, where X is any previously
5178
Tags are stored in the branch. Tags are copied from one branch to another
5179
along when you branch, push, pull or merge.
5181
It is an error to give a tag name that already exists unless you pass
5182
--force, in which case the tag is moved to point to the new revision.
5184
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5185
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5188
_see_also = ['commit', 'tags']
5189
takes_args = ['tag_name']
5192
help='Delete this tag rather than placing it.',
5195
help='Branch in which to place the tag.',
5200
help='Replace existing tags.',
5205
def run(self, tag_name,
5211
branch, relpath = Branch.open_containing(directory)
5213
self.add_cleanup(branch.unlock)
5215
branch.tags.delete_tag(tag_name)
5216
self.outf.write('Deleted tag %s.\n' % tag_name)
5219
if len(revision) != 1:
5220
raise errors.BzrCommandError(
5221
"Tags can only be placed on a single revision, "
5223
revision_id = revision[0].as_revision_id(branch)
5225
revision_id = branch.last_revision()
5226
if (not force) and branch.tags.has_tag(tag_name):
5227
raise errors.TagAlreadyExists(tag_name)
5228
branch.tags.set_tag(tag_name, revision_id)
5229
self.outf.write('Created tag %s.\n' % tag_name)
5232
class cmd_tags(Command):
5235
This command shows a table of tag names and the revisions they reference.
5241
help='Branch whose tags should be displayed.',
5245
RegistryOption.from_kwargs('sort',
5246
'Sort tags by different criteria.', title='Sorting',
5247
alpha='Sort tags lexicographically (default).',
5248
time='Sort tags chronologically.',
5261
branch, relpath = Branch.open_containing(directory)
5263
tags = branch.tags.get_tag_dict().items()
5268
self.add_cleanup(branch.unlock)
5270
graph = branch.repository.get_graph()
5271
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5272
revid1, revid2 = rev1.rev_id, rev2.rev_id
5273
# only show revisions between revid1 and revid2 (inclusive)
5274
tags = [(tag, revid) for tag, revid in tags if
5275
graph.is_between(revid, revid1, revid2)]
5278
elif sort == 'time':
5280
for tag, revid in tags:
5282
revobj = branch.repository.get_revision(revid)
5283
except errors.NoSuchRevision:
5284
timestamp = sys.maxint # place them at the end
5286
timestamp = revobj.timestamp
5287
timestamps[revid] = timestamp
5288
tags.sort(key=lambda x: timestamps[x[1]])
5290
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5291
for index, (tag, revid) in enumerate(tags):
5293
revno = branch.revision_id_to_dotted_revno(revid)
5294
if isinstance(revno, tuple):
5295
revno = '.'.join(map(str, revno))
5296
except errors.NoSuchRevision:
5297
# Bad tag data/merges can lead to tagged revisions
5298
# which are not in this branch. Fail gracefully ...
5300
tags[index] = (tag, revno)
5302
for tag, revspec in tags:
5303
self.outf.write('%-20s %s\n' % (tag, revspec))
5306
class cmd_reconfigure(Command):
5307
"""Reconfigure the type of a bzr directory.
5309
A target configuration must be specified.
5311
For checkouts, the bind-to location will be auto-detected if not specified.
5312
The order of preference is
5313
1. For a lightweight checkout, the current bound location.
5314
2. For branches that used to be checkouts, the previously-bound location.
5315
3. The push location.
5316
4. The parent location.
5317
If none of these is available, --bind-to must be specified.
5320
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5321
takes_args = ['location?']
5323
RegistryOption.from_kwargs(
5325
title='Target type',
5326
help='The type to reconfigure the directory to.',
5327
value_switches=True, enum_switch=False,
5328
branch='Reconfigure to be an unbound branch with no working tree.',
5329
tree='Reconfigure to be an unbound branch with a working tree.',
5330
checkout='Reconfigure to be a bound branch with a working tree.',
5331
lightweight_checkout='Reconfigure to be a lightweight'
5332
' checkout (with no local history).',
5333
standalone='Reconfigure to be a standalone branch '
5334
'(i.e. stop using shared repository).',
5335
use_shared='Reconfigure to use a shared repository.',
5336
with_trees='Reconfigure repository to create '
5337
'working trees on branches by default.',
5338
with_no_trees='Reconfigure repository to not create '
5339
'working trees on branches by default.'
5341
Option('bind-to', help='Branch to bind checkout to.', type=str),
5343
help='Perform reconfiguration even if local changes'
5345
Option('stacked-on',
5346
help='Reconfigure a branch to be stacked on another branch.',
5350
help='Reconfigure a branch to be unstacked. This '
5351
'may require copying substantial data into it.',
5355
def run(self, location=None, target_type=None, bind_to=None, force=False,
5358
directory = bzrdir.BzrDir.open(location)
5359
if stacked_on and unstacked:
5360
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5361
elif stacked_on is not None:
5362
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5364
reconfigure.ReconfigureUnstacked().apply(directory)
5365
# At the moment you can use --stacked-on and a different
5366
# reconfiguration shape at the same time; there seems no good reason
5368
if target_type is None:
5369
if stacked_on or unstacked:
5372
raise errors.BzrCommandError('No target configuration '
5374
elif target_type == 'branch':
5375
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5376
elif target_type == 'tree':
5377
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5378
elif target_type == 'checkout':
5379
reconfiguration = reconfigure.Reconfigure.to_checkout(
5381
elif target_type == 'lightweight-checkout':
5382
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5384
elif target_type == 'use-shared':
5385
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5386
elif target_type == 'standalone':
5387
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5388
elif target_type == 'with-trees':
5389
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5391
elif target_type == 'with-no-trees':
5392
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5394
reconfiguration.apply(force)
5397
class cmd_switch(Command):
5398
"""Set the branch of a checkout and update.
5400
For lightweight checkouts, this changes the branch being referenced.
5401
For heavyweight checkouts, this checks that there are no local commits
5402
versus the current bound branch, then it makes the local branch a mirror
5403
of the new location and binds to it.
5405
In both cases, the working tree is updated and uncommitted changes
5406
are merged. The user can commit or revert these as they desire.
5408
Pending merges need to be committed or reverted before using switch.
5410
The path to the branch to switch to can be specified relative to the parent
5411
directory of the current branch. For example, if you are currently in a
5412
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5415
Bound branches use the nickname of its master branch unless it is set
5416
locally, in which case switching will update the local nickname to be
5420
takes_args = ['to_location']
5421
takes_options = [Option('force',
5422
help='Switch even if local commits will be lost.'),
5423
Option('create-branch', short_name='b',
5424
help='Create the target branch from this one before'
5425
' switching to it.'),
5428
def run(self, to_location, force=False, create_branch=False):
5429
from bzrlib import switch
5431
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5433
branch = control_dir.open_branch()
5434
had_explicit_nick = branch.get_config().has_explicit_nickname()
5435
except errors.NotBranchError:
5437
had_explicit_nick = False
5440
raise errors.BzrCommandError('cannot create branch without'
5442
to_location = directory_service.directories.dereference(
5444
if '/' not in to_location and '\\' not in to_location:
5445
# This path is meant to be relative to the existing branch
5446
this_url = self._get_branch_location(control_dir)
5447
to_location = urlutils.join(this_url, '..', to_location)
5448
to_branch = branch.bzrdir.sprout(to_location,
5449
possible_transports=[branch.bzrdir.root_transport],
5450
source_branch=branch).open_branch()
5452
# from_branch = control_dir.open_branch()
5453
# except errors.NotBranchError:
5454
# raise BzrCommandError('Cannot create a branch from this'
5455
# ' location when we cannot open this branch')
5456
# from_branch.bzrdir.sprout(
5460
to_branch = Branch.open(to_location)
5461
except errors.NotBranchError:
5462
this_url = self._get_branch_location(control_dir)
5463
to_branch = Branch.open(
5464
urlutils.join(this_url, '..', to_location))
5465
switch.switch(control_dir, to_branch, force)
5466
if had_explicit_nick:
5467
branch = control_dir.open_branch() #get the new branch!
5468
branch.nick = to_branch.nick
5469
note('Switched to branch: %s',
5470
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5472
def _get_branch_location(self, control_dir):
5473
"""Return location of branch for this control dir."""
5475
this_branch = control_dir.open_branch()
5476
# This may be a heavy checkout, where we want the master branch
5477
master_location = this_branch.get_bound_location()
5478
if master_location is not None:
5479
return master_location
5480
# If not, use a local sibling
5481
return this_branch.base
5482
except errors.NotBranchError:
5483
format = control_dir.find_branch_format()
5484
if getattr(format, 'get_reference', None) is not None:
5485
return format.get_reference(control_dir)
5487
return control_dir.root_transport.base
5490
class cmd_view(Command):
5491
"""Manage filtered views.
5493
Views provide a mask over the tree so that users can focus on
5494
a subset of a tree when doing their work. After creating a view,
5495
commands that support a list of files - status, diff, commit, etc -
5496
effectively have that list of files implicitly given each time.
5497
An explicit list of files can still be given but those files
5498
must be within the current view.
5500
In most cases, a view has a short life-span: it is created to make
5501
a selected change and is deleted once that change is committed.
5502
At other times, you may wish to create one or more named views
5503
and switch between them.
5505
To disable the current view without deleting it, you can switch to
5506
the pseudo view called ``off``. This can be useful when you need
5507
to see the whole tree for an operation or two (e.g. merge) but
5508
want to switch back to your view after that.
5511
To define the current view::
5513
bzr view file1 dir1 ...
5515
To list the current view::
5519
To delete the current view::
5523
To disable the current view without deleting it::
5525
bzr view --switch off
5527
To define a named view and switch to it::
5529
bzr view --name view-name file1 dir1 ...
5531
To list a named view::
5533
bzr view --name view-name
5535
To delete a named view::
5537
bzr view --name view-name --delete
5539
To switch to a named view::
5541
bzr view --switch view-name
5543
To list all views defined::
5547
To delete all views::
5549
bzr view --delete --all
5553
takes_args = ['file*']
5556
help='Apply list or delete action to all views.',
5559
help='Delete the view.',
5562
help='Name of the view to define, list or delete.',
5566
help='Name of the view to switch to.',
5571
def run(self, file_list,
5577
tree, file_list = tree_files(file_list, apply_view=False)
5578
current_view, view_dict = tree.views.get_view_info()
5583
raise errors.BzrCommandError(
5584
"Both --delete and a file list specified")
5586
raise errors.BzrCommandError(
5587
"Both --delete and --switch specified")
5589
tree.views.set_view_info(None, {})
5590
self.outf.write("Deleted all views.\n")
5592
raise errors.BzrCommandError("No current view to delete")
5594
tree.views.delete_view(name)
5595
self.outf.write("Deleted '%s' view.\n" % name)
5598
raise errors.BzrCommandError(
5599
"Both --switch and a file list specified")
5601
raise errors.BzrCommandError(
5602
"Both --switch and --all specified")
5603
elif switch == 'off':
5604
if current_view is None:
5605
raise errors.BzrCommandError("No current view to disable")
5606
tree.views.set_view_info(None, view_dict)
5607
self.outf.write("Disabled '%s' view.\n" % (current_view))
5609
tree.views.set_view_info(switch, view_dict)
5610
view_str = views.view_display_str(tree.views.lookup_view())
5611
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5614
self.outf.write('Views defined:\n')
5615
for view in sorted(view_dict):
5616
if view == current_view:
5620
view_str = views.view_display_str(view_dict[view])
5621
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5623
self.outf.write('No views defined.\n')
5626
# No name given and no current view set
5629
raise errors.BzrCommandError(
5630
"Cannot change the 'off' pseudo view")
5631
tree.views.set_view(name, sorted(file_list))
5632
view_str = views.view_display_str(tree.views.lookup_view())
5633
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5637
# No name given and no current view set
5638
self.outf.write('No current view.\n')
5640
view_str = views.view_display_str(tree.views.lookup_view(name))
5641
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5644
class cmd_hooks(Command):
5650
for hook_key in sorted(hooks.known_hooks.keys()):
5651
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5652
self.outf.write("%s:\n" % type(some_hooks).__name__)
5653
for hook_name, hook_point in sorted(some_hooks.items()):
5654
self.outf.write(" %s:\n" % (hook_name,))
5655
found_hooks = list(hook_point)
5657
for hook in found_hooks:
5658
self.outf.write(" %s\n" %
5659
(some_hooks.get_hook_name(hook),))
5661
self.outf.write(" <no hooks installed>\n")
5664
class cmd_shelve(Command):
5665
"""Temporarily set aside some changes from the current tree.
5667
Shelve allows you to temporarily put changes you've made "on the shelf",
5668
ie. out of the way, until a later time when you can bring them back from
5669
the shelf with the 'unshelve' command. The changes are stored alongside
5670
your working tree, and so they aren't propagated along with your branch nor
5671
will they survive its deletion.
5673
If shelve --list is specified, previously-shelved changes are listed.
5675
Shelve is intended to help separate several sets of changes that have
5676
been inappropriately mingled. If you just want to get rid of all changes
5677
and you don't need to restore them later, use revert. If you want to
5678
shelve all text changes at once, use shelve --all.
5680
If filenames are specified, only the changes to those files will be
5681
shelved. Other files will be left untouched.
5683
If a revision is specified, changes since that revision will be shelved.
5685
You can put multiple items on the shelf, and by default, 'unshelve' will
5686
restore the most recently shelved changes.
5689
takes_args = ['file*']
5693
Option('all', help='Shelve all changes.'),
5695
RegistryOption('writer', 'Method to use for writing diffs.',
5696
bzrlib.option.diff_writer_registry,
5697
value_switches=True, enum_switch=False),
5699
Option('list', help='List shelved changes.'),
5701
help='Destroy removed changes instead of shelving them.'),
5703
_see_also = ['unshelve']
5705
def run(self, revision=None, all=False, file_list=None, message=None,
5706
writer=None, list=False, destroy=False):
5708
return self.run_for_list()
5709
from bzrlib.shelf_ui import Shelver
5711
writer = bzrlib.option.diff_writer_registry.get()
5713
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5714
file_list, message, destroy=destroy)
5719
except errors.UserAbort:
5722
def run_for_list(self):
5723
tree = WorkingTree.open_containing('.')[0]
5725
self.add_cleanup(tree.unlock)
5726
manager = tree.get_shelf_manager()
5727
shelves = manager.active_shelves()
5728
if len(shelves) == 0:
5729
note('No shelved changes.')
5731
for shelf_id in reversed(shelves):
5732
message = manager.get_metadata(shelf_id).get('message')
5734
message = '<no message>'
5735
self.outf.write('%3d: %s\n' % (shelf_id, message))
5739
class cmd_unshelve(Command):
5740
"""Restore shelved changes.
5742
By default, the most recently shelved changes are restored. However if you
5743
specify a shelf by id those changes will be restored instead. This works
5744
best when the changes don't depend on each other.
5747
takes_args = ['shelf_id?']
5749
RegistryOption.from_kwargs(
5750
'action', help="The action to perform.",
5751
enum_switch=False, value_switches=True,
5752
apply="Apply changes and remove from the shelf.",
5753
dry_run="Show changes, but do not apply or remove them.",
5754
preview="Instead of unshelving the changes, show the diff that "
5755
"would result from unshelving.",
5756
delete_only="Delete changes without applying them.",
5757
keep="Apply changes but don't delete them.",
5760
_see_also = ['shelve']
5762
def run(self, shelf_id=None, action='apply'):
5763
from bzrlib.shelf_ui import Unshelver
5764
unshelver = Unshelver.from_args(shelf_id, action)
5768
unshelver.tree.unlock()
5771
class cmd_clean_tree(Command):
5772
"""Remove unwanted files from working tree.
5774
By default, only unknown files, not ignored files, are deleted. Versioned
5775
files are never deleted.
5777
Another class is 'detritus', which includes files emitted by bzr during
5778
normal operations and selftests. (The value of these files decreases with
5781
If no options are specified, unknown files are deleted. Otherwise, option
5782
flags are respected, and may be combined.
5784
To check what clean-tree will do, use --dry-run.
5786
takes_options = [Option('ignored', help='Delete all ignored files.'),
5787
Option('detritus', help='Delete conflict files, merge'
5788
' backups, and failed selftest dirs.'),
5790
help='Delete files unknown to bzr (default).'),
5791
Option('dry-run', help='Show files to delete instead of'
5793
Option('force', help='Do not prompt before deleting.')]
5794
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5796
from bzrlib.clean_tree import clean_tree
5797
if not (unknown or ignored or detritus):
5801
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5802
dry_run=dry_run, no_prompt=force)
5805
class cmd_reference(Command):
5806
"""list, view and set branch locations for nested trees.
5808
If no arguments are provided, lists the branch locations for nested trees.
5809
If one argument is provided, display the branch location for that tree.
5810
If two arguments are provided, set the branch location for that tree.
5815
takes_args = ['path?', 'location?']
5817
def run(self, path=None, location=None):
5819
if path is not None:
5821
tree, branch, relpath =(
5822
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5823
if path is not None:
5826
tree = branch.basis_tree()
5828
info = branch._get_all_reference_info().iteritems()
5829
self._display_reference_info(tree, branch, info)
5831
file_id = tree.path2id(path)
5833
raise errors.NotVersionedError(path)
5834
if location is None:
5835
info = [(file_id, branch.get_reference_info(file_id))]
5836
self._display_reference_info(tree, branch, info)
5838
branch.set_reference_info(file_id, path, location)
5840
def _display_reference_info(self, tree, branch, info):
5842
for file_id, (path, location) in info:
5844
path = tree.id2path(file_id)
5845
except errors.NoSuchId:
5847
ref_list.append((path, location))
5848
for path, location in sorted(ref_list):
5849
self.outf.write('%s %s\n' % (path, location))
2840
5852
# these get imported and then picked up by the scan for cmd_*
2841
5853
# TODO: Some more consistent way to split command definitions across files;
2842
# we do need to load at least some information about them to know of
5854
# we do need to load at least some information about them to know of
2843
5855
# aliases. ideally we would avoid loading the implementation until the
2844
5856
# details were needed.
5857
from bzrlib.cmd_version_info import cmd_version_info
2845
5858
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2846
from bzrlib.bundle.commands import cmd_bundle_revisions
5859
from bzrlib.bundle.commands import (
5862
from bzrlib.foreign import cmd_dpush
2847
5863
from bzrlib.sign_my_commits import cmd_sign_my_commits
2848
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
5864
from bzrlib.weave_commands import cmd_versionedfile_list, \
2849
5865
cmd_weave_plan_merge, cmd_weave_merge_text