13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""builtin bzr commands"""
20
from StringIO import StringIO
21
22
from bzrlib.lazy_import import lazy_import
22
23
lazy_import(globals(), """
29
31
from bzrlib import (
41
42
merge as _mod_merge,
46
47
revision as _mod_revision,
55
55
from bzrlib.branch import Branch
56
56
from bzrlib.conflicts import ConflictList
57
from bzrlib.transport import memory
58
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
57
from bzrlib.revisionspec import RevisionSpec
59
58
from bzrlib.smtp_connection import SMTPConnection
60
59
from bzrlib.workingtree import WorkingTree
63
62
from bzrlib.commands import Command, display_command
64
from bzrlib.option import (
71
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
74
def tree_files(file_list, default_branch=u'.', canonicalize=True,
63
from bzrlib.option import ListOption, Option, RegistryOption
64
from bzrlib.progress import DummyProgress, ProgressPhase
65
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
68
def tree_files(file_list, default_branch=u'.'):
77
return internal_tree_files(file_list, default_branch, canonicalize,
70
return internal_tree_files(file_list, default_branch)
79
71
except errors.FileInWrongBranch, e:
80
72
raise errors.BzrCommandError("%s is not in the same branch as %s" %
81
73
(e.path, file_list[0]))
84
def tree_files_for_add(file_list):
86
Return a tree and list of absolute paths from a file list.
88
Similar to tree_files, but add handles files a bit differently, so it a
89
custom implementation. In particular, MutableTreeTree.smart_add expects
90
absolute paths, which it immediately converts to relative paths.
92
# FIXME Would be nice to just return the relative paths like
93
# internal_tree_files does, but there are a large number of unit tests
94
# that assume the current interface to mutabletree.smart_add
96
tree, relpath = WorkingTree.open_containing(file_list[0])
97
if tree.supports_views():
98
view_files = tree.views.lookup_view()
100
for filename in file_list:
101
if not osutils.is_inside_any(view_files, filename):
102
raise errors.FileOutsideView(filename, view_files)
103
file_list = file_list[:]
104
file_list[0] = tree.abspath(relpath)
106
tree = WorkingTree.open_containing(u'.')[0]
107
if tree.supports_views():
108
view_files = tree.views.lookup_view()
110
file_list = view_files
111
view_str = views.view_display_str(view_files)
112
note("Ignoring files outside view. View is %s" % view_str)
113
return tree, file_list
116
def _get_one_revision(command_name, revisions):
117
if revisions is None:
119
if len(revisions) != 1:
120
raise errors.BzrCommandError(
121
'bzr %s --revision takes exactly one revision identifier' % (
126
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
127
"""Get a revision tree. Not suitable for commands that change the tree.
129
Specifically, the basis tree in dirstate trees is coupled to the dirstate
130
and doing a commit/uncommit/pull will at best fail due to changing the
133
If tree is passed in, it should be already locked, for lifetime management
134
of the trees internal cached state.
138
if revisions is None:
140
rev_tree = tree.basis_tree()
142
rev_tree = branch.basis_tree()
144
revision = _get_one_revision(command_name, revisions)
145
rev_tree = revision.as_tree(branch)
149
76
# XXX: Bad function name; should possibly also be a class method of
150
77
# WorkingTree rather than a function.
151
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
78
def internal_tree_files(file_list, default_branch=u'.'):
153
79
"""Convert command-line paths to a WorkingTree and relative paths.
155
81
This is typically used for command-line processors that take one or
788
522
takes_args = ['names*']
789
523
takes_options = [Option("after", help="Move only the bzr identifier"
790
524
" of the file, because the file has already been moved."),
791
Option('auto', help='Automatically guess renames.'),
792
Option('dry-run', help='Avoid making changes when guessing renames.'),
794
526
aliases = ['move', 'rename']
795
527
encoding_type = 'replace'
797
def run(self, names_list, after=False, auto=False, dry_run=False):
799
return self.run_auto(names_list, after, dry_run)
801
raise errors.BzrCommandError('--dry-run requires --auto.')
529
def run(self, names_list, after=False):
802
530
if names_list is None:
804
533
if len(names_list) < 2:
805
534
raise errors.BzrCommandError("missing file argument")
806
tree, rel_names = tree_files(names_list, canonicalize=False)
807
tree.lock_tree_write()
808
self.add_cleanup(tree.unlock)
809
self._run(tree, names_list, rel_names, after)
811
def run_auto(self, names_list, after, dry_run):
812
if names_list is not None and len(names_list) > 1:
813
raise errors.BzrCommandError('Only one path may be specified to'
816
raise errors.BzrCommandError('--after cannot be specified with'
818
work_tree, file_list = tree_files(names_list, default_branch='.')
819
work_tree.lock_tree_write()
820
self.add_cleanup(work_tree.unlock)
821
rename_map.RenameMap.guess_renames(work_tree, dry_run)
823
def _run(self, tree, names_list, rel_names, after):
824
into_existing = osutils.isdir(names_list[-1])
825
if into_existing and len(names_list) == 2:
827
# a. case-insensitive filesystem and change case of dir
828
# b. move directory after the fact (if the source used to be
829
# a directory, but now doesn't exist in the working tree
830
# and the target is an existing directory, just rename it)
831
if (not tree.case_sensitive
832
and rel_names[0].lower() == rel_names[1].lower()):
833
into_existing = False
836
# 'fix' the case of a potential 'from'
837
from_id = tree.path2id(
838
tree.get_canonical_inventory_path(rel_names[0]))
839
if (not osutils.lexists(names_list[0]) and
840
from_id and inv.get_file_kind(from_id) == "directory"):
841
into_existing = False
535
tree, rel_names = tree_files(names_list)
537
if os.path.isdir(names_list[-1]):
844
538
# move into existing directory
845
# All entries reference existing inventory items, so fix them up
846
# for cicp file-systems.
847
rel_names = tree.get_canonical_inventory_paths(rel_names)
848
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
850
self.outf.write("%s => %s\n" % (src, dest))
539
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
540
self.outf.write("%s => %s\n" % pair)
852
542
if len(names_list) != 2:
853
543
raise errors.BzrCommandError('to mv multiple files the'
854
544
' destination must be a versioned'
857
# for cicp file-systems: the src references an existing inventory
859
src = tree.get_canonical_inventory_path(rel_names[0])
860
# Find the canonical version of the destination: In all cases, the
861
# parent of the target must be in the inventory, so we fetch the
862
# canonical version from there (we do not always *use* the
863
# canonicalized tail portion - we may be attempting to rename the
865
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
866
dest_parent = osutils.dirname(canon_dest)
867
spec_tail = osutils.basename(rel_names[1])
868
# For a CICP file-system, we need to avoid creating 2 inventory
869
# entries that differ only by case. So regardless of the case
870
# we *want* to use (ie, specified by the user or the file-system),
871
# we must always choose to use the case of any existing inventory
872
# items. The only exception to this is when we are attempting a
873
# case-only rename (ie, canonical versions of src and dest are
875
dest_id = tree.path2id(canon_dest)
876
if dest_id is None or tree.path2id(src) == dest_id:
877
# No existing item we care about, so work out what case we
878
# are actually going to use.
880
# If 'after' is specified, the tail must refer to a file on disk.
882
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
884
# pathjoin with an empty tail adds a slash, which breaks
886
dest_parent_fq = tree.basedir
888
dest_tail = osutils.canonical_relpath(
890
osutils.pathjoin(dest_parent_fq, spec_tail))
892
# not 'after', so case as specified is used
893
dest_tail = spec_tail
895
# Use the existing item so 'mv' fails with AlreadyVersioned.
896
dest_tail = os.path.basename(canon_dest)
897
dest = osutils.pathjoin(dest_parent, dest_tail)
898
mutter("attempting to move %s => %s", src, dest)
899
tree.rename_one(src, dest, after=after)
901
self.outf.write("%s => %s\n" % (src, dest))
546
tree.rename_one(rel_names[0], rel_names[1], after=after)
547
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
904
550
class cmd_pull(Command):
905
551
"""Turn this branch into a mirror of another branch.
907
By default, this command only works on branches that have not diverged.
908
Branches are considered diverged if the destination branch's most recent
909
commit is one that has not been merged (directly or indirectly) into the
553
This command only works on branches that have not diverged. Branches are
554
considered diverged if the destination branch's most recent commit is one
555
that has not been merged (directly or indirectly) into the parent.
912
557
If branches have diverged, you can use 'bzr merge' to integrate the changes
913
558
from one into the other. Once one branch has merged, the other should
914
559
be able to pull it again.
916
If you want to replace your local changes and just want your branch to
917
match the remote one, use pull --overwrite. This will work even if the two
918
branches have diverged.
561
If you want to forget your local changes and just update your branch to
562
match the remote one, use pull --overwrite.
920
564
If there is no default location set, the first pull will set it. After
921
565
that, you can omit the location to use the default. To change the
922
566
default, use --remember. The value will only be saved if the remote
923
567
location can be accessed.
925
Note: The location can be specified either in the form of a branch,
926
or in the form of a path to a file containing a merge directive generated
930
_see_also = ['push', 'update', 'status-flags', 'send']
931
takes_options = ['remember', 'overwrite', 'revision',
932
custom_help('verbose',
933
help='Show logs of pulled revisions.'),
570
_see_also = ['push', 'update', 'status-flags']
571
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
934
572
Option('directory',
935
573
help='Branch to pull into, '
936
574
'rather than the one containing the working directory.',
941
help="Perform a local pull in a bound "
942
"branch. Local pulls are not applied to "
946
579
takes_args = ['location?']
947
580
encoding_type = 'replace'
949
582
def run(self, location=None, remember=False, overwrite=False,
950
583
revision=None, verbose=False,
951
directory=None, local=False):
952
585
# FIXME: too much stuff is in the command class
953
586
revision_id = None
1069
688
' directory exists, but does not already'
1070
689
' have a control directory. This flag will'
1071
690
' allow push to proceed.'),
1073
help='Create a stacked branch that references the public location '
1074
'of the parent branch.'),
1075
Option('stacked-on',
1076
help='Create a stacked branch that refers to another branch '
1077
'for the commit history. Only the work not present in the '
1078
'referenced branch is included in the branch created.',
1081
help='Refuse to push if there are uncommitted changes in'
1082
' the working tree, --no-strict disables the check.'),
1084
692
takes_args = ['location?']
1085
693
encoding_type = 'replace'
1087
695
def run(self, location=None, remember=False, overwrite=False,
1088
create_prefix=False, verbose=False, revision=None,
1089
use_existing_dir=False, directory=None, stacked_on=None,
1090
stacked=False, strict=None):
1091
from bzrlib.push import _show_push_branch
696
create_prefix=False, verbose=False,
697
use_existing_dir=False,
699
# FIXME: Way too big! Put this into a function called from the
1093
701
if directory is None:
1095
# Get the source branch
1097
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1099
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1100
if strict is None: strict = True # default value
1101
# Get the tip's revision_id
1102
revision = _get_one_revision('push', revision)
1103
if revision is not None:
1104
revision_id = revision.in_history(br_from).rev_id
1107
if strict and tree is not None and revision_id is None:
1108
if (tree.has_changes()):
1109
raise errors.UncommittedChanges(
1110
tree, more='Use --no-strict to force the push.')
1111
if tree.last_revision() != tree.branch.last_revision():
1112
# The tree has lost sync with its branch, there is little
1113
# chance that the user is aware of it but he can still force
1114
# the push with --no-strict
1115
raise errors.OutOfDateTree(
1116
tree, more='Use --no-strict to force the push.')
1118
# Get the stacked_on branch, if any
1119
if stacked_on is not None:
1120
stacked_on = urlutils.normalize_url(stacked_on)
1122
parent_url = br_from.get_parent()
1124
parent = Branch.open(parent_url)
1125
stacked_on = parent.get_public_branch()
1127
# I considered excluding non-http url's here, thus forcing
1128
# 'public' branches only, but that only works for some
1129
# users, so it's best to just depend on the user spotting an
1130
# error by the feedback given to them. RBC 20080227.
1131
stacked_on = parent_url
1133
raise errors.BzrCommandError(
1134
"Could not determine branch to refer to.")
1136
# Get the destination location
703
br_from = Branch.open_containing(directory)[0]
704
stored_loc = br_from.get_push_location()
1137
705
if location is None:
1138
stored_loc = br_from.get_push_location()
1139
706
if stored_loc is None:
1140
raise errors.BzrCommandError(
1141
"No push location known or specified.")
707
raise errors.BzrCommandError("No push location known or specified.")
1143
709
display_url = urlutils.unescape_for_display(stored_loc,
1144
710
self.outf.encoding)
1145
self.outf.write("Using saved push location: %s\n" % display_url)
711
self.outf.write("Using saved location: %s\n" % display_url)
1146
712
location = stored_loc
1148
_show_push_branch(br_from, revision_id, location, self.outf,
1149
verbose=verbose, overwrite=overwrite, remember=remember,
1150
stacked_on=stacked_on, create_prefix=create_prefix,
1151
use_existing_dir=use_existing_dir)
714
to_transport = transport.get_transport(location)
716
br_to = repository_to = dir_to = None
718
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
719
except errors.NotBranchError:
720
pass # Didn't find anything
722
# If we can open a branch, use its direct repository, otherwise see
723
# if there is a repository without a branch.
725
br_to = dir_to.open_branch()
726
except errors.NotBranchError:
727
# Didn't find a branch, can we find a repository?
729
repository_to = dir_to.find_repository()
730
except errors.NoRepositoryPresent:
733
# Found a branch, so we must have found a repository
734
repository_to = br_to.repository
739
# The destination doesn't exist; create it.
740
# XXX: Refactor the create_prefix/no_create_prefix code into a
741
# common helper function
743
to_transport.mkdir('.')
744
except errors.FileExists:
745
if not use_existing_dir:
746
raise errors.BzrCommandError("Target directory %s"
747
" already exists, but does not have a valid .bzr"
748
" directory. Supply --use-existing-dir to push"
749
" there anyway." % location)
750
except errors.NoSuchFile:
751
if not create_prefix:
752
raise errors.BzrCommandError("Parent directory of %s"
754
"\nYou may supply --create-prefix to create all"
755
" leading parent directories."
757
_create_prefix(to_transport)
759
# Now the target directory exists, but doesn't have a .bzr
760
# directory. So we need to create it, along with any work to create
761
# all of the dependent branches, etc.
762
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
763
revision_id=br_from.last_revision())
764
br_to = dir_to.open_branch()
765
# TODO: Some more useful message about what was copied
766
note('Created new branch.')
767
# We successfully created the target, remember it
768
if br_from.get_push_location() is None or remember:
769
br_from.set_push_location(br_to.base)
770
elif repository_to is None:
771
# we have a bzrdir but no branch or repository
772
# XXX: Figure out what to do other than complain.
773
raise errors.BzrCommandError("At %s you have a valid .bzr control"
774
" directory, but not a branch or repository. This is an"
775
" unsupported configuration. Please move the target directory"
776
" out of the way and try again."
779
# We have a repository but no branch, copy the revisions, and then
781
last_revision_id = br_from.last_revision()
782
repository_to.fetch(br_from.repository,
783
revision_id=last_revision_id)
784
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
785
note('Created new branch.')
786
if br_from.get_push_location() is None or remember:
787
br_from.set_push_location(br_to.base)
788
else: # We have a valid to branch
789
# We were able to connect to the remote location, so remember it
790
# we don't need to successfully push because of possible divergence.
791
if br_from.get_push_location() is None or remember:
792
br_from.set_push_location(br_to.base)
794
old_rh = br_to.revision_history()
797
tree_to = dir_to.open_workingtree()
798
except errors.NotLocalUrl:
799
warning("This transport does not update the working "
800
"tree of: %s. See 'bzr help working-trees' for "
801
"more information." % br_to.base)
802
push_result = br_from.push(br_to, overwrite)
803
except errors.NoWorkingTree:
804
push_result = br_from.push(br_to, overwrite)
808
push_result = br_from.push(tree_to.branch, overwrite)
812
except errors.DivergedBranches:
813
raise errors.BzrCommandError('These branches have diverged.'
814
' Try using "merge" and then "push".')
815
if push_result is not None:
816
push_result.report(self.outf)
818
new_rh = br_to.revision_history()
821
from bzrlib.log import show_changed_revisions
822
show_changed_revisions(br_to, old_rh, new_rh,
825
# we probably did a clone rather than a push, so a message was
1154
830
class cmd_branch(Command):
1155
"""Create a new branch that is a copy of an existing branch.
831
"""Create a new copy of a branch.
1157
833
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1158
834
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1168
844
_see_also = ['checkout']
1169
845
takes_args = ['from_location', 'to_location?']
1170
takes_options = ['revision', Option('hardlink',
1171
help='Hard-link working tree files where possible.'),
1173
help="Create a branch without a working-tree."),
1175
help="Switch the checkout in the current directory "
1176
"to the new branch."),
1178
help='Create a stacked branch referring to the source branch. '
1179
'The new branch will depend on the availability of the source '
1180
'branch for all operations.'),
1181
Option('standalone',
1182
help='Do not use a shared repository, even if available.'),
1183
Option('use-existing-dir',
1184
help='By default branch will fail if the target'
1185
' directory exists, but does not already'
1186
' have a control directory. This flag will'
1187
' allow branch to proceed.'),
1189
help="Bind new branch to from location."),
846
takes_options = ['revision']
1191
847
aliases = ['get', 'clone']
1193
def run(self, from_location, to_location=None, revision=None,
1194
hardlink=False, stacked=False, standalone=False, no_tree=False,
1195
use_existing_dir=False, switch=False, bind=False):
1196
from bzrlib import switch as _mod_switch
849
def run(self, from_location, to_location=None, revision=None):
1197
850
from bzrlib.tag import _merge_tags_if_possible
1198
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1200
revision = _get_one_revision('branch', revision)
853
elif len(revision) > 1:
854
raise errors.BzrCommandError(
855
'bzr branch --revision takes exactly 1 revision value')
857
br_from = Branch.open(from_location)
1201
858
br_from.lock_read()
1202
self.add_cleanup(br_from.unlock)
1203
if revision is not None:
1204
revision_id = revision.as_revision_id(br_from)
1206
# FIXME - wt.last_revision, fallback to branch, fall back to
1207
# None or perhaps NULL_REVISION to mean copy nothing
1209
revision_id = br_from.last_revision()
1210
if to_location is None:
1211
to_location = urlutils.derive_to_location(from_location)
1212
to_transport = transport.get_transport(to_location)
1214
to_transport.mkdir('.')
1215
except errors.FileExists:
1216
if not use_existing_dir:
1217
raise errors.BzrCommandError('Target directory "%s" '
1218
'already exists.' % to_location)
1221
bzrdir.BzrDir.open_from_transport(to_transport)
1222
except errors.NotBranchError:
1225
raise errors.AlreadyBranchError(to_location)
1226
except errors.NoSuchFile:
1227
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1230
# preserve whatever source format we have.
1231
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1232
possible_transports=[to_transport],
1233
accelerator_tree=accelerator_tree,
1234
hardlink=hardlink, stacked=stacked,
1235
force_new_repo=standalone,
1236
create_tree_if_local=not no_tree,
1237
source_branch=br_from)
1238
branch = dir.open_branch()
1239
except errors.NoSuchRevision:
1240
to_transport.delete_tree('.')
1241
msg = "The branch %s has no revision %s." % (from_location,
1243
raise errors.BzrCommandError(msg)
1244
_merge_tags_if_possible(br_from, branch)
1245
# If the source branch is stacked, the new branch may
1246
# be stacked whether we asked for that explicitly or not.
1247
# We therefore need a try/except here and not just 'if stacked:'
1249
note('Created new stacked branch referring to %s.' %
1250
branch.get_stacked_on_url())
1251
except (errors.NotStacked, errors.UnstackableBranchFormat,
1252
errors.UnstackableRepositoryFormat), e:
860
if len(revision) == 1 and revision[0] is not None:
861
revision_id = revision[0].in_history(br_from)[1]
863
# FIXME - wt.last_revision, fallback to branch, fall back to
864
# None or perhaps NULL_REVISION to mean copy nothing
866
revision_id = br_from.last_revision()
867
if to_location is None:
868
to_location = urlutils.derive_to_location(from_location)
871
name = os.path.basename(to_location) + '\n'
873
to_transport = transport.get_transport(to_location)
875
to_transport.mkdir('.')
876
except errors.FileExists:
877
raise errors.BzrCommandError('Target directory "%s" already'
878
' exists.' % to_location)
879
except errors.NoSuchFile:
880
raise errors.BzrCommandError('Parent of "%s" does not exist.'
883
# preserve whatever source format we have.
884
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
885
possible_transports=[to_transport])
886
branch = dir.open_branch()
887
except errors.NoSuchRevision:
888
to_transport.delete_tree('.')
889
msg = "The branch %s has no revision %s." % (from_location, revision[0])
890
raise errors.BzrCommandError(msg)
892
branch.control_files.put_utf8('branch-name', name)
893
_merge_tags_if_possible(br_from, branch)
1253
894
note('Branched %d revision(s).' % branch.revno())
1255
# Bind to the parent
1256
parent_branch = Branch.open(from_location)
1257
branch.bind(parent_branch)
1258
note('New branch bound to %s' % from_location)
1260
# Switch to the new branch
1261
wt, _ = WorkingTree.open_containing('.')
1262
_mod_switch.switch(wt.bzrdir, branch)
1263
note('Switched to branch: %s',
1264
urlutils.unescape_for_display(branch.base, 'utf-8'))
1267
899
class cmd_checkout(Command):
1346
985
def run(self, dir=u'.'):
1347
986
tree = WorkingTree.open_containing(dir)[0]
1348
987
tree.lock_read()
1349
self.add_cleanup(tree.unlock)
1350
new_inv = tree.inventory
1351
old_tree = tree.basis_tree()
1352
old_tree.lock_read()
1353
self.add_cleanup(old_tree.unlock)
1354
old_inv = old_tree.inventory
1356
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1357
for f, paths, c, v, p, n, k, e in iterator:
1358
if paths[0] == paths[1]:
1362
renames.append(paths)
1364
for old_name, new_name in renames:
1365
self.outf.write("%s => %s\n" % (old_name, new_name))
989
new_inv = tree.inventory
990
old_tree = tree.basis_tree()
993
old_inv = old_tree.inventory
994
renames = list(_mod_tree.find_renames(old_inv, new_inv))
996
for old_name, new_name in renames:
997
self.outf.write("%s => %s\n" % (old_name, new_name))
1368
1004
class cmd_update(Command):
1369
1005
"""Update a tree to have the latest code committed to its branch.
1371
1007
This will perform a merge into the working tree, and may generate
1372
conflicts. If you have any local changes, you will still
1008
conflicts. If you have any local changes, you will still
1373
1009
need to commit them after the update for the update to be complete.
1375
If you want to discard your local changes, you can just do a
1011
If you want to discard your local changes, you can just do a
1376
1012
'bzr revert' instead of 'bzr commit' after the update.
1378
If the tree's branch is bound to a master branch, it will also update
1379
the branch from the master.
1382
1015
_see_also = ['pull', 'working-trees', 'status-flags']
1383
1016
takes_args = ['dir?']
1384
takes_options = ['revision']
1385
1017
aliases = ['up']
1387
def run(self, dir='.', revision=None):
1388
if revision is not None and len(revision) != 1:
1389
raise errors.BzrCommandError(
1390
"bzr update --revision takes exactly one revision")
1019
def run(self, dir='.'):
1391
1020
tree = WorkingTree.open_containing(dir)[0]
1392
branch = tree.branch
1393
possible_transports = []
1394
master = branch.get_master_branch(
1395
possible_transports=possible_transports)
1021
master = tree.branch.get_master_branch()
1396
1022
if master is not None:
1397
1023
tree.lock_write()
1398
branch_location = master.base
1400
1025
tree.lock_tree_write()
1401
branch_location = tree.branch.base
1402
self.add_cleanup(tree.unlock)
1403
# get rid of the final '/' and be ready for display
1404
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1406
existing_pending_merges = tree.get_parent_ids()[1:]
1410
# may need to fetch data into a heavyweight checkout
1411
# XXX: this may take some time, maybe we should display a
1413
old_tip = branch.update(possible_transports)
1414
if revision is not None:
1415
revision_id = revision[0].as_revision_id(branch)
1417
revision_id = branch.last_revision()
1418
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1419
revno = branch.revision_id_to_revno(revision_id)
1420
note("Tree is up to date at revision %d of branch %s" %
1421
(revno, branch_location))
1423
view_info = _get_view_info_for_change_reporter(tree)
1424
change_reporter = delta._ChangeReporter(
1425
unversioned_filter=tree.is_ignored,
1426
view_info=view_info)
1428
conflicts = tree.update(
1430
possible_transports=possible_transports,
1431
revision=revision_id,
1433
except errors.NoSuchRevision, e:
1434
raise errors.BzrCommandError(
1435
"branch has no revision %s\n"
1436
"bzr update --revision only works"
1437
" for a revision in the branch history"
1439
revno = tree.branch.revision_id_to_revno(
1440
_mod_revision.ensure_null(tree.last_revision()))
1441
note('Updated to revision %d of branch %s' %
1442
(revno, branch_location))
1443
if tree.get_parent_ids()[1:] != existing_pending_merges:
1444
note('Your local commits will now show as pending merges with '
1445
"'bzr status', and can be committed with 'bzr commit'.")
1027
existing_pending_merges = tree.get_parent_ids()[1:]
1028
last_rev = _mod_revision.ensure_null(tree.last_revision())
1029
if last_rev == _mod_revision.ensure_null(
1030
tree.branch.last_revision()):
1031
# may be up to date, check master too.
1032
if master is None or last_rev == _mod_revision.ensure_null(
1033
master.last_revision()):
1034
revno = tree.branch.revision_id_to_revno(last_rev)
1035
note("Tree is up to date at revision %d." % (revno,))
1037
conflicts = tree.update(delta._ChangeReporter(
1038
unversioned_filter=tree.is_ignored))
1039
revno = tree.branch.revision_id_to_revno(
1040
_mod_revision.ensure_null(tree.last_revision()))
1041
note('Updated to revision %d.' % (revno,))
1042
if tree.get_parent_ids()[1:] != existing_pending_merges:
1043
note('Your local commits will now show as pending merges with '
1044
"'bzr status', and can be committed with 'bzr commit'.")
1452
1053
class cmd_info(Command):
1453
1054
"""Show information about a working tree, branch or repository.
1455
1056
This command will show all known locations and formats associated to the
1456
tree, branch or repository.
1458
In verbose mode, statistical information is included with each report.
1459
To see extended statistic information, use a verbosity level of 2 or
1460
higher by specifying the verbose option multiple times, e.g. -vv.
1057
tree, branch or repository. Statistical information is included with
1462
1060
Branches and working trees will also report any missing revisions.
1466
Display information on the format and related locations:
1470
Display the above together with extended format information and
1471
basic statistics (like the number of files in the working tree and
1472
number of revisions in the branch and repository):
1476
Display the above together with number of committers to the branch:
1480
1062
_see_also = ['revno', 'working-trees', 'repositories']
1481
1063
takes_args = ['location?']
1482
1064
takes_options = ['verbose']
1483
encoding_type = 'replace'
1485
1066
@display_command
1486
def run(self, location=None, verbose=False):
1488
noise_level = get_verbosity_level()
1067
def run(self, location=None, verbose=0):
1491
1068
from bzrlib.info import show_bzrdir_info
1492
1069
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1493
verbose=noise_level, outfile=self.outf)
1496
1073
class cmd_remove(Command):
1497
1074
"""Remove files or directories.
1499
This makes bzr stop tracking changes to the specified files. bzr will delete
1500
them if they can easily be recovered using revert. If no options or
1501
parameters are given bzr will scan for files that are being tracked by bzr
1502
but missing in your tree and stop tracking them for you.
1076
This makes bzr stop tracking changes to the specified files and
1077
delete them if they can easily be recovered using revert.
1079
You can specify one or more files, and/or --new. If you specify --new,
1080
only 'added' files will be removed. If you specify both, then new files
1081
in the specified directories will be removed. If the directories are
1082
also new, they will also be removed.
1504
1084
takes_args = ['file*']
1505
1085
takes_options = ['verbose',
1506
Option('new', help='Only remove files that have never been committed.'),
1086
Option('new', help='Remove newly-added files.'),
1507
1087
RegistryOption.from_kwargs('file-deletion-strategy',
1508
1088
'The file deletion mode to be used.',
1509
1089
title='Deletion Strategy', value_switches=True, enum_switch=False,
1510
1090
safe='Only delete files if they can be'
1511
1091
' safely recovered (default).',
1512
keep='Delete from bzr but leave the working copy.',
1092
keep="Don't delete any files.",
1513
1093
force='Delete all the specified files, even if they can not be '
1514
1094
'recovered and even if they are non-empty directories.')]
1515
aliases = ['rm', 'del']
1516
1096
encoding_type = 'replace'
1518
1098
def run(self, file_list, verbose=False, new=False,
2070
1599
raise errors.BzrCommandError(msg)
2073
def _parse_levels(s):
2077
msg = "The levels argument must be an integer."
2078
raise errors.BzrCommandError(msg)
2081
1602
class cmd_log(Command):
2082
"""Show historical log for a branch or subset of a branch.
2084
log is bzr's default tool for exploring the history of a branch.
2085
The branch to use is taken from the first parameter. If no parameters
2086
are given, the branch containing the working directory is logged.
2087
Here are some simple examples::
2089
bzr log log the current branch
2090
bzr log foo.py log a file in its branch
2091
bzr log http://server/branch log a branch on a server
2093
The filtering, ordering and information shown for each revision can
2094
be controlled as explained below. By default, all revisions are
2095
shown sorted (topologically) so that newer revisions appear before
2096
older ones and descendants always appear before ancestors. If displayed,
2097
merged revisions are shown indented under the revision in which they
2102
The log format controls how information about each revision is
2103
displayed. The standard log formats are called ``long``, ``short``
2104
and ``line``. The default is long. See ``bzr help log-formats``
2105
for more details on log formats.
2107
The following options can be used to control what information is
2110
-l N display a maximum of N revisions
2111
-n N display N levels of revisions (0 for all, 1 for collapsed)
2112
-v display a status summary (delta) for each revision
2113
-p display a diff (patch) for each revision
2114
--show-ids display revision-ids (and file-ids), not just revnos
2116
Note that the default number of levels to display is a function of the
2117
log format. If the -n option is not used, the standard log formats show
2118
just the top level (mainline).
2120
Status summaries are shown using status flags like A, M, etc. To see
2121
the changes explained using words like ``added`` and ``modified``
2122
instead, use the -vv option.
2126
To display revisions from oldest to newest, use the --forward option.
2127
In most cases, using this option will have little impact on the total
2128
time taken to produce a log, though --forward does not incrementally
2129
display revisions like --reverse does when it can.
2131
:Revision filtering:
2133
The -r option can be used to specify what revision or range of revisions
2134
to filter against. The various forms are shown below::
2136
-rX display revision X
2137
-rX.. display revision X and later
2138
-r..Y display up to and including revision Y
2139
-rX..Y display from X to Y inclusive
2141
See ``bzr help revisionspec`` for details on how to specify X and Y.
2142
Some common examples are given below::
2144
-r-1 show just the tip
2145
-r-10.. show the last 10 mainline revisions
2146
-rsubmit:.. show what's new on this branch
2147
-rancestor:path.. show changes since the common ancestor of this
2148
branch and the one at location path
2149
-rdate:yesterday.. show changes since yesterday
2151
When logging a range of revisions using -rX..Y, log starts at
2152
revision Y and searches back in history through the primary
2153
("left-hand") parents until it finds X. When logging just the
2154
top level (using -n1), an error is reported if X is not found
2155
along the way. If multi-level logging is used (-n0), X may be
2156
a nested merge revision and the log will be truncated accordingly.
2160
If parameters are given and the first one is not a branch, the log
2161
will be filtered to show only those revisions that changed the
2162
nominated files or directories.
2164
Filenames are interpreted within their historical context. To log a
2165
deleted file, specify a revision range so that the file existed at
2166
the end or start of the range.
2168
Historical context is also important when interpreting pathnames of
2169
renamed files/directories. Consider the following example:
2171
* revision 1: add tutorial.txt
2172
* revision 2: modify tutorial.txt
2173
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2177
* ``bzr log guide.txt`` will log the file added in revision 1
2179
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2181
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2182
the original file in revision 2.
2184
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2185
was no file called guide.txt in revision 2.
2187
Renames are always followed by log. By design, there is no need to
2188
explicitly ask for this (and no way to stop logging a file back
2189
until it was last renamed).
2193
The --message option can be used for finding revisions that match a
2194
regular expression in a commit message.
2198
GUI tools and IDEs are often better at exploring history than command
2199
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2200
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2201
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2202
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2204
You may find it useful to add the aliases below to ``bazaar.conf``::
2208
top = log -l10 --line
2211
``bzr tip`` will then show the latest revision while ``bzr top``
2212
will show the last 10 mainline revisions. To see the details of a
2213
particular revision X, ``bzr show -rX``.
2215
If you are interested in looking deeper into a particular merge X,
2216
use ``bzr log -n0 -rX``.
2218
``bzr log -v`` on a branch with lots of history is currently
2219
very slow. A fix for this issue is currently under development.
2220
With or without that fix, it is recommended that a revision range
2221
be given when using the -v option.
2223
bzr has a generic full-text matching plugin, bzr-search, that can be
2224
used to find revisions matching user names, commit messages, etc.
2225
Among other features, this plugin can find all revisions containing
2226
a list of words but not others.
2228
When exploring non-mainline history on large projects with deep
2229
history, the performance of log can be greatly improved by installing
2230
the historycache plugin. This plugin buffers historical information
2231
trading disk space for faster speed.
1603
"""Show log of a branch, file, or directory.
1605
By default show the log of the branch containing the working directory.
1607
To request a range of logs, you can use the command -r begin..end
1608
-r revision requests a specific revision, -r ..end or -r begin.. are
1612
Log the current branch::
1620
Log the last 10 revisions of a branch::
1622
bzr log -r -10.. http://server/branch
2233
takes_args = ['file*']
2234
_see_also = ['log-formats', 'revisionspec']
1625
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1627
takes_args = ['location?']
2235
1628
takes_options = [
2236
1629
Option('forward',
2237
1630
help='Show from oldest to newest.'),
2239
custom_help('verbose',
1633
help='Display timezone as local, original, or utc.'),
2240
1636
help='Show files changed in each revision.'),
2244
type=bzrlib.option._parse_revision_str,
2246
help='Show just the specified revision.'
2247
' See also "help revisionspec".'),
2251
help='Number of levels to display - 0 for all, 1 for flat.',
2253
type=_parse_levels),
2254
1640
Option('message',
2255
1641
short_name='m',
2256
1642
help='Show revisions whose message matches this '
2257
1643
'regular expression.',
2259
1645
Option('limit',
2261
1646
help='Limit the output to the first N revisions.',
2263
1648
type=_parse_limit),
2266
help='Show changes made in each revision as a patch.'),
2267
Option('include-merges',
2268
help='Show merged revisions like --levels 0 does.'),
2270
1650
encoding_type = 'replace'
2272
1652
@display_command
2273
def run(self, file_list=None, timezone='original',
1653
def run(self, location=None, timezone='original',
2275
1655
show_ids=False,
2279
1658
log_format=None,
2284
include_merges=False):
2285
from bzrlib.log import (
2287
make_log_request_dict,
2288
_get_info_for_log_files,
1661
from bzrlib.log import show_log
1662
assert message is None or isinstance(message, basestring), \
1663
"invalid message argument %r" % message
2290
1664
direction = (forward and 'forward') or 'reverse'
2295
raise errors.BzrCommandError(
2296
'--levels and --include-merges are mutually exclusive')
2298
if change is not None:
2300
raise errors.RangeInChangeOption()
2301
if revision is not None:
2302
raise errors.BzrCommandError(
2303
'--revision and --change are mutually exclusive')
2308
filter_by_dir = False
2310
# find the file ids to log and check for directory filtering
2311
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2312
revision, file_list)
2313
self.add_cleanup(b.unlock)
2314
for relpath, file_id, kind in file_info_list:
1669
# find the file id to log:
1671
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1675
tree = b.basis_tree()
1676
file_id = tree.path2id(fp)
2315
1677
if file_id is None:
2316
1678
raise errors.BzrCommandError(
2317
"Path unknown at end or start of revision range: %s" %
2319
# If the relpath is the top of the tree, we log everything
2324
file_ids.append(file_id)
2325
filter_by_dir = filter_by_dir or (
2326
kind in ['directory', 'tree-reference'])
1679
"Path does not have any revision history: %s" %
2329
# FIXME ? log the current subdir only RBC 20060203
1683
# FIXME ? log the current subdir only RBC 20060203
2330
1684
if revision is not None \
2331
1685
and len(revision) > 0 and revision[0].get_branch():
2332
1686
location = revision[0].get_branch()
2335
1689
dir, relpath = bzrdir.BzrDir.open_containing(location)
2336
1690
b = dir.open_branch()
2338
self.add_cleanup(b.unlock)
2339
rev1, rev2 = _get_revision_range(revision, b, self.name())
2341
# Decide on the type of delta & diff filtering to use
2342
# TODO: add an --all-files option to make this configurable & consistent
2350
diff_type = 'partial'
2354
# Build the log formatter
2355
if log_format is None:
2356
log_format = log.log_formatter_registry.get_default(b)
2357
# Make a non-encoding output to include the diffs - bug 328007
2358
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2359
lf = log_format(show_ids=show_ids, to_file=self.outf,
2360
to_exact_file=unencoded_output,
2361
show_timezone=timezone,
2362
delta_format=get_verbosity_level(),
2364
show_advice=levels is None)
2366
# Choose the algorithm for doing the logging. It's annoying
2367
# having multiple code paths like this but necessary until
2368
# the underlying repository format is faster at generating
2369
# deltas or can provide everything we need from the indices.
2370
# The default algorithm - match-using-deltas - works for
2371
# multiple files and directories and is faster for small
2372
# amounts of history (200 revisions say). However, it's too
2373
# slow for logging a single file in a repository with deep
2374
# history, i.e. > 10K revisions. In the spirit of "do no
2375
# evil when adding features", we continue to use the
2376
# original algorithm - per-file-graph - for the "single
2377
# file that isn't a directory without showing a delta" case.
2378
partial_history = revision and b.repository._format.supports_chks
2379
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2380
or delta_type or partial_history)
2382
# Build the LogRequest and execute it
2383
if len(file_ids) == 0:
2385
rqst = make_log_request_dict(
2386
direction=direction, specific_fileids=file_ids,
2387
start_revision=rev1, end_revision=rev2, limit=limit,
2388
message_search=message, delta_type=delta_type,
2389
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2390
Logger(b, rqst).show(lf)
2393
def _get_revision_range(revisionspec_list, branch, command_name):
2394
"""Take the input of a revision option and turn it into a revision range.
2396
It returns RevisionInfo objects which can be used to obtain the rev_id's
2397
of the desired revisions. It does some user input validations.
2399
if revisionspec_list is None:
2402
elif len(revisionspec_list) == 1:
2403
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2404
elif len(revisionspec_list) == 2:
2405
start_spec = revisionspec_list[0]
2406
end_spec = revisionspec_list[1]
2407
if end_spec.get_branch() != start_spec.get_branch():
2408
# b is taken from revision[0].get_branch(), and
2409
# show_log will use its revision_history. Having
2410
# different branches will lead to weird behaviors.
2411
raise errors.BzrCommandError(
2412
"bzr %s doesn't accept two revisions in different"
2413
" branches." % command_name)
2414
rev1 = start_spec.in_history(branch)
2415
# Avoid loading all of history when we know a missing
2416
# end of range means the last revision ...
2417
if end_spec.spec is None:
2418
last_revno, last_revision_id = branch.last_revision_info()
2419
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2421
rev2 = end_spec.in_history(branch)
2423
raise errors.BzrCommandError(
2424
'bzr %s --revision takes one or two values.' % command_name)
2428
def _revision_range_to_revid_range(revision_range):
2431
if revision_range[0] is not None:
2432
rev_id1 = revision_range[0].rev_id
2433
if revision_range[1] is not None:
2434
rev_id2 = revision_range[1].rev_id
2435
return rev_id1, rev_id2
1694
if revision is None:
1697
elif len(revision) == 1:
1698
rev1 = rev2 = revision[0].in_history(b)
1699
elif len(revision) == 2:
1700
if revision[1].get_branch() != revision[0].get_branch():
1701
# b is taken from revision[0].get_branch(), and
1702
# show_log will use its revision_history. Having
1703
# different branches will lead to weird behaviors.
1704
raise errors.BzrCommandError(
1705
"Log doesn't accept two revisions in different"
1707
rev1 = revision[0].in_history(b)
1708
rev2 = revision[1].in_history(b)
1710
raise errors.BzrCommandError(
1711
'bzr log --revision takes one or two values.')
1713
if log_format is None:
1714
log_format = log.log_formatter_registry.get_default(b)
1716
lf = log_format(show_ids=show_ids, to_file=self.outf,
1717
show_timezone=timezone)
1723
direction=direction,
1724
start_revision=rev1,
2437
1732
def get_log_format(long=False, short=False, line=False, default='long'):
2438
1733
log_format = default
3497
2510
short_name='x',
3498
2511
help='Exclude tests that match this regular'
3499
2512
' expression.'),
3501
help='Output test progress via subunit.'),
3502
2513
Option('strict', help='Fail on missing dependencies or '
3503
2514
'known failures.'),
3504
Option('load-list', type=str, argname='TESTLISTFILE',
3505
help='Load a test id list from a text file.'),
3506
ListOption('debugflag', type=str, short_name='E',
3507
help='Turn on a selftest debug flag.'),
3508
ListOption('starting-with', type=str, argname='TESTID',
3509
param_name='starting_with', short_name='s',
3511
'Load only the tests starting with TESTID.'),
3513
2516
encoding_type = 'replace'
3516
Command.__init__(self)
3517
self.additional_selftest_args = {}
3519
def run(self, testspecs_list=None, verbose=False, one=False,
2518
def run(self, testspecs_list=None, verbose=None, one=False,
3520
2519
transport=None, benchmark=None,
3521
2520
lsprof_timed=None, cache_dir=None,
3522
2521
first=False, list_only=False,
3523
randomize=None, exclude=None, strict=False,
3524
load_list=None, debugflag=None, starting_with=None, subunit=False,
3525
parallel=None, lsprof_tests=False):
2522
randomize=None, exclude=None, strict=False):
3526
2524
from bzrlib.tests import selftest
3527
2525
import bzrlib.benchmarks as benchmarks
3528
2526
from bzrlib.benchmarks import tree_creator
3530
# Make deprecation warnings visible, unless -Werror is set
3531
symbol_versioning.activate_deprecation_warnings(override=False)
2527
from bzrlib.version import show_version
3533
2529
if cache_dir is not None:
3534
2530
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2532
show_version(show_config=False, show_copyright=False)
3535
2534
if testspecs_list is not None:
3536
2535
pattern = '|'.join(testspecs_list)
3541
from bzrlib.tests import SubUnitBzrRunner
3543
raise errors.BzrCommandError("subunit not available. subunit "
3544
"needs to be installed to use --subunit.")
3545
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3547
self.additional_selftest_args.setdefault(
3548
'suite_decorators', []).append(parallel)
3550
2539
test_suite_factory = benchmarks.test_suite
3551
# Unless user explicitly asks for quiet, be verbose in benchmarks
3552
verbose = not is_quiet()
3553
2542
# TODO: should possibly lock the history file...
3554
2543
benchfile = open(".perf_history", "at", buffering=1)
3555
self.add_cleanup(benchfile.close)
3557
2545
test_suite_factory = None
3558
2548
benchfile = None
3559
selftest_kwargs = {"verbose": verbose,
3561
"stop_on_failure": one,
3562
"transport": transport,
3563
"test_suite_factory": test_suite_factory,
3564
"lsprof_timed": lsprof_timed,
3565
"lsprof_tests": lsprof_tests,
3566
"bench_history": benchfile,
3567
"matching_tests_first": first,
3568
"list_only": list_only,
3569
"random_seed": randomize,
3570
"exclude_pattern": exclude,
3572
"load_list": load_list,
3573
"debug_flags": debugflag,
3574
"starting_with": starting_with
3576
selftest_kwargs.update(self.additional_selftest_args)
3577
result = selftest(**selftest_kwargs)
2550
result = selftest(verbose=verbose,
2552
stop_on_failure=one,
2553
transport=transport,
2554
test_suite_factory=test_suite_factory,
2555
lsprof_timed=lsprof_timed,
2556
bench_history=benchfile,
2557
matching_tests_first=first,
2558
list_only=list_only,
2559
random_seed=randomize,
2560
exclude_pattern=exclude,
2564
if benchfile is not None:
2567
info('tests passed')
2569
info('tests failed')
3578
2570
return int(not result)
3581
2573
class cmd_version(Command):
3582
2574
"""Show version of bzr."""
3584
encoding_type = 'replace'
3586
Option("short", help="Print just the version number."),
3589
2576
@display_command
3590
def run(self, short=False):
3591
2578
from bzrlib.version import show_version
3593
self.outf.write(bzrlib.version_string + '\n')
3595
show_version(to_file=self.outf)
3598
2582
class cmd_rocks(Command):
3749
2702
allow_pending = True
3750
2703
verified = 'inapplicable'
3751
2704
tree = WorkingTree.open_containing(directory)[0]
3754
basis_tree = tree.revision_tree(tree.last_revision())
3755
except errors.NoSuchRevision:
3756
basis_tree = tree.basis_tree()
3758
# die as quickly as possible if there are uncommitted changes
3760
if tree.has_changes():
3761
raise errors.UncommittedChanges(tree)
3763
view_info = _get_view_info_for_change_reporter(tree)
3764
2705
change_reporter = delta._ChangeReporter(
3765
unversioned_filter=tree.is_ignored, view_info=view_info)
3766
pb = ui.ui_factory.nested_progress_bar()
3767
self.add_cleanup(pb.finished)
3769
self.add_cleanup(tree.unlock)
3770
if location is not None:
3772
mergeable = bundle.read_mergeable_from_url(location,
3773
possible_transports=possible_transports)
3774
except errors.NotABundle:
2706
unversioned_filter=tree.is_ignored)
2709
pb = ui.ui_factory.nested_progress_bar()
2710
cleanups.append(pb.finished)
2712
cleanups.append(tree.unlock)
2713
if location is not None:
2714
mergeable, other_transport = _get_mergeable_helper(location)
2717
raise errors.BzrCommandError('Cannot use --uncommitted'
2718
' with bundles or merge directives.')
2720
if revision is not None:
2721
raise errors.BzrCommandError(
2722
'Cannot use -r with merge directives or bundles')
2723
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2725
possible_transports.append(other_transport)
2727
if merger is None and uncommitted:
2728
if revision is not None and len(revision) > 0:
2729
raise errors.BzrCommandError('Cannot use --uncommitted and'
2730
' --revision at the same time.')
2731
location = self._select_branch_location(tree, location)[0]
2732
other_tree, other_path = WorkingTree.open_containing(location)
2733
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2735
allow_pending = False
2738
merger, allow_pending = self._get_merger_from_branch(tree,
2739
location, revision, remember, possible_transports, pb)
2741
merger.merge_type = merge_type
2742
merger.reprocess = reprocess
2743
merger.show_base = show_base
2744
merger.change_reporter = change_reporter
2745
self.sanity_check_merger(merger)
2746
if (merger.base_rev_id == merger.other_rev_id and
2747
merger.other_rev_id != None):
2748
note('Nothing to do.')
2751
if merger.interesting_files is not None:
2752
raise BzrCommandError('Cannot pull individual files')
2753
if (merger.base_rev_id == tree.last_revision()):
2754
result = tree.pull(merger.other_branch, False,
2755
merger.other_rev_id)
2756
result.report(self.outf)
2758
merger.check_basis(not force)
2759
conflict_count = merger.do_merge()
2761
merger.set_pending()
2762
if verified == 'failed':
2763
warning('Preview patch does not match changes')
2764
if conflict_count != 0:
3778
raise errors.BzrCommandError('Cannot use --uncommitted'
3779
' with bundles or merge directives.')
3781
if revision is not None:
3782
raise errors.BzrCommandError(
3783
'Cannot use -r with merge directives or bundles')
3784
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3787
if merger is None and uncommitted:
3788
if revision is not None and len(revision) > 0:
3789
raise errors.BzrCommandError('Cannot use --uncommitted and'
3790
' --revision at the same time.')
3791
merger = self.get_merger_from_uncommitted(tree, location, None)
3792
allow_pending = False
3795
merger, allow_pending = self._get_merger_from_branch(tree,
3796
location, revision, remember, possible_transports, None)
3798
merger.merge_type = merge_type
3799
merger.reprocess = reprocess
3800
merger.show_base = show_base
3801
self.sanity_check_merger(merger)
3802
if (merger.base_rev_id == merger.other_rev_id and
3803
merger.other_rev_id is not None):
3804
note('Nothing to do.')
3807
if merger.interesting_files is not None:
3808
raise errors.BzrCommandError('Cannot pull individual files')
3809
if (merger.base_rev_id == tree.last_revision()):
3810
result = tree.pull(merger.other_branch, False,
3811
merger.other_rev_id)
3812
result.report(self.outf)
3814
if merger.this_basis is None:
3815
raise errors.BzrCommandError(
3816
"This branch has no commits."
3817
" (perhaps you would prefer 'bzr pull')")
3819
return self._do_preview(merger)
3821
return self._do_interactive(merger)
3823
return self._do_merge(merger, change_reporter, allow_pending,
3826
def _get_preview(self, merger):
3827
tree_merger = merger.make_merger()
3828
tt = tree_merger.make_preview_transform()
3829
self.add_cleanup(tt.finalize)
3830
result_tree = tt.get_preview_tree()
3833
def _do_preview(self, merger):
3834
from bzrlib.diff import show_diff_trees
3835
result_tree = self._get_preview(merger)
3836
show_diff_trees(merger.this_tree, result_tree, self.outf,
3837
old_label='', new_label='')
3839
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3840
merger.change_reporter = change_reporter
3841
conflict_count = merger.do_merge()
3843
merger.set_pending()
3844
if verified == 'failed':
3845
warning('Preview patch does not match changes')
3846
if conflict_count != 0:
3851
def _do_interactive(self, merger):
3852
"""Perform an interactive merge.
3854
This works by generating a preview tree of the merge, then using
3855
Shelver to selectively remove the differences between the working tree
3856
and the preview tree.
3858
from bzrlib import shelf_ui
3859
result_tree = self._get_preview(merger)
3860
writer = bzrlib.option.diff_writer_registry.get()
3861
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3862
reporter=shelf_ui.ApplyReporter(),
3863
diff_writer=writer(sys.stdout))
2769
for cleanup in reversed(cleanups):
3869
2772
def sanity_check_merger(self, merger):
3870
2773
if (merger.show_base and
3871
2774
not merger.merge_type is _mod_merge.Merge3Merger):
3872
2775
raise errors.BzrCommandError("Show-base is not supported for this"
3873
2776
" merge type. %s" % merger.merge_type)
3874
if merger.reprocess is None:
3875
if merger.show_base:
3876
merger.reprocess = False
3878
# Use reprocess if the merger supports it
3879
merger.reprocess = merger.merge_type.supports_reprocess
3880
2777
if merger.reprocess and not merger.merge_type.supports_reprocess:
3881
2778
raise errors.BzrCommandError("Conflict reduction is not supported"
3882
2779
" for merge type %s." %
4028
2914
merge_type = _mod_merge.Merge3Merger
4029
2915
tree, file_list = tree_files(file_list)
4030
2916
tree.lock_write()
4031
self.add_cleanup(tree.unlock)
4032
parents = tree.get_parent_ids()
4033
if len(parents) != 2:
4034
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4035
" merges. Not cherrypicking or"
4037
repository = tree.branch.repository
4038
interesting_ids = None
4040
conflicts = tree.conflicts()
4041
if file_list is not None:
4042
interesting_ids = set()
4043
for filename in file_list:
4044
file_id = tree.path2id(filename)
4046
raise errors.NotVersionedError(filename)
4047
interesting_ids.add(file_id)
4048
if tree.kind(file_id) != "directory":
4051
for name, ie in tree.inventory.iter_entries(file_id):
4052
interesting_ids.add(ie.file_id)
4053
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4055
# Remerge only supports resolving contents conflicts
4056
allowed_conflicts = ('text conflict', 'contents conflict')
4057
restore_files = [c.path for c in conflicts
4058
if c.typestring in allowed_conflicts]
4059
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4060
tree.set_conflicts(ConflictList(new_conflicts))
4061
if file_list is not None:
4062
restore_files = file_list
4063
for filename in restore_files:
2918
parents = tree.get_parent_ids()
2919
if len(parents) != 2:
2920
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2921
" merges. Not cherrypicking or"
2923
repository = tree.branch.repository
2924
graph = repository.get_graph()
2925
base_revision = graph.find_unique_lca(parents[0], parents[1])
2926
base_tree = repository.revision_tree(base_revision)
2927
other_tree = repository.revision_tree(parents[1])
2928
interesting_ids = None
2930
conflicts = tree.conflicts()
2931
if file_list is not None:
2932
interesting_ids = set()
2933
for filename in file_list:
2934
file_id = tree.path2id(filename)
2936
raise errors.NotVersionedError(filename)
2937
interesting_ids.add(file_id)
2938
if tree.kind(file_id) != "directory":
2941
for name, ie in tree.inventory.iter_entries(file_id):
2942
interesting_ids.add(ie.file_id)
2943
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2945
# Remerge only supports resolving contents conflicts
2946
allowed_conflicts = ('text conflict', 'contents conflict')
2947
restore_files = [c.path for c in conflicts
2948
if c.typestring in allowed_conflicts]
2949
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2950
tree.set_conflicts(ConflictList(new_conflicts))
2951
if file_list is not None:
2952
restore_files = file_list
2953
for filename in restore_files:
2955
restore(tree.abspath(filename))
2956
except errors.NotConflicted:
2958
# Disable pending merges, because the file texts we are remerging
2959
# have not had those merges performed. If we use the wrong parents
2960
# list, we imply that the working tree text has seen and rejected
2961
# all the changes from the other tree, when in fact those changes
2962
# have not yet been seen.
2963
tree.set_parent_ids(parents[:1])
4065
restore(tree.abspath(filename))
4066
except errors.NotConflicted:
4068
# Disable pending merges, because the file texts we are remerging
4069
# have not had those merges performed. If we use the wrong parents
4070
# list, we imply that the working tree text has seen and rejected
4071
# all the changes from the other tree, when in fact those changes
4072
# have not yet been seen.
4073
tree.set_parent_ids(parents[:1])
4075
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4076
merger.interesting_ids = interesting_ids
4077
merger.merge_type = merge_type
4078
merger.show_base = show_base
4079
merger.reprocess = reprocess
4080
conflicts = merger.do_merge()
2965
conflicts = _mod_merge.merge_inner(
2966
tree.branch, other_tree, base_tree,
2968
interesting_ids=interesting_ids,
2969
other_rev_id=parents[1],
2970
merge_type=merge_type,
2971
show_base=show_base,
2972
reprocess=reprocess)
2974
tree.set_parent_ids(parents)
4082
tree.set_parent_ids(parents)
4083
2977
if conflicts > 0:
5114
3827
'rather than the one containing the working directory.',
5115
3828
short_name='f',
5117
Option('output', short_name='o',
5118
help='Write merge directive to this file; '
5119
'use - for stdout.',
5122
help='Refuse to send if there are uncommitted changes in'
5123
' the working tree, --no-strict disables the check.'),
5124
Option('mail-to', help='Mail the request to this address.',
3830
Option('output', short_name='o', help='Write directive to this file.',
5128
Option('body', help='Body for the email.', type=unicode),
5129
RegistryOption('format',
5130
help='Use the specified output format.',
5131
lazy_registry=('bzrlib.send', 'format_registry')),
3833
RegistryOption.from_kwargs('format',
3834
'Use the specified output format.',
3835
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
3836
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5134
3839
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5135
3840
no_patch=False, revision=None, remember=False, output=None,
5136
format=None, mail_to=None, message=None, body=None,
5137
strict=None, **kwargs):
5138
from bzrlib.send import send
5139
return send(submit_branch, revision, public_branch, remember,
5140
format, no_bundle, no_patch, output,
5141
kwargs.get('from', '.'), mail_to, message, body,
3841
format='4', **kwargs):
3843
raise errors.BzrCommandError('File must be specified with'
3845
return self._run(submit_branch, revision, public_branch, remember,
3846
format, no_bundle, no_patch, output,
3847
kwargs.get('from', '.'))
3849
def _run(self, submit_branch, revision, public_branch, remember, format,
3850
no_bundle, no_patch, output, from_,):
3851
from bzrlib.revision import ensure_null, NULL_REVISION
3855
outfile = open(output, 'wb')
3857
branch = Branch.open_containing(from_)[0]
3858
if remember and submit_branch is None:
3859
raise errors.BzrCommandError(
3860
'--remember requires a branch to be specified.')
3861
stored_submit_branch = branch.get_submit_branch()
3862
remembered_submit_branch = False
3863
if submit_branch is None:
3864
submit_branch = stored_submit_branch
3865
remembered_submit_branch = True
3867
if stored_submit_branch is None or remember:
3868
branch.set_submit_branch(submit_branch)
3869
if submit_branch is None:
3870
submit_branch = branch.get_parent()
3871
remembered_submit_branch = True
3872
if submit_branch is None:
3873
raise errors.BzrCommandError('No submit branch known or'
3875
if remembered_submit_branch:
3876
note('Using saved location: %s', submit_branch)
3878
stored_public_branch = branch.get_public_branch()
3879
if public_branch is None:
3880
public_branch = stored_public_branch
3881
elif stored_public_branch is None or remember:
3882
branch.set_public_branch(public_branch)
3883
if no_bundle and public_branch is None:
3884
raise errors.BzrCommandError('No public branch specified or'
3886
base_revision_id = None
3887
if revision is not None:
3888
if len(revision) > 2:
3889
raise errors.BzrCommandError('bzr send takes '
3890
'at most two one revision identifiers')
3891
revision_id = revision[-1].in_history(branch).rev_id
3892
if len(revision) == 2:
3893
base_revision_id = revision[0].in_history(branch).rev_id
3894
base_revision_id = ensure_null(base_revision_id)
3896
revision_id = branch.last_revision()
3897
revision_id = ensure_null(revision_id)
3898
if revision_id == NULL_REVISION:
3899
raise errors.BzrCommandError('No revisions to submit.')
3901
directive = merge_directive.MergeDirective2.from_objects(
3902
branch.repository, revision_id, time.time(),
3903
osutils.local_time_offset(), submit_branch,
3904
public_branch=public_branch, include_patch=not no_patch,
3905
include_bundle=not no_bundle, message=None,
3906
base_revision_id=base_revision_id)
3907
elif format == '0.9':
3910
patch_type = 'bundle'
3912
raise errors.BzrCommandError('Format 0.9 does not'
3913
' permit bundle with no patch')
3919
directive = merge_directive.MergeDirective.from_objects(
3920
branch.repository, revision_id, time.time(),
3921
osutils.local_time_offset(), submit_branch,
3922
public_branch=public_branch, patch_type=patch_type,
3925
outfile.writelines(directive.to_lines())
5146
3931
class cmd_bundle_revisions(cmd_send):
5147
"""Create a merge-directive for submitting changes.
3933
"""Create a merge-directive for submiting changes.
5149
3935
A merge directive provides many things needed for requesting merges:
5290
4051
short_name='d',
5293
RegistryOption.from_kwargs('sort',
5294
'Sort tags by different criteria.', title='Sorting',
5295
alpha='Sort tags lexicographically (default).',
5296
time='Sort tags chronologically.',
5302
4056
@display_command
5309
4060
branch, relpath = Branch.open_containing(directory)
5311
tags = branch.tags.get_tag_dict().items()
5316
self.add_cleanup(branch.unlock)
5318
graph = branch.repository.get_graph()
5319
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5320
revid1, revid2 = rev1.rev_id, rev2.rev_id
5321
# only show revisions between revid1 and revid2 (inclusive)
5322
tags = [(tag, revid) for tag, revid in tags if
5323
graph.is_between(revid, revid1, revid2)]
5326
elif sort == 'time':
5328
for tag, revid in tags:
5330
revobj = branch.repository.get_revision(revid)
5331
except errors.NoSuchRevision:
5332
timestamp = sys.maxint # place them at the end
5334
timestamp = revobj.timestamp
5335
timestamps[revid] = timestamp
5336
tags.sort(key=lambda x: timestamps[x[1]])
5338
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5339
for index, (tag, revid) in enumerate(tags):
5341
revno = branch.revision_id_to_dotted_revno(revid)
5342
if isinstance(revno, tuple):
5343
revno = '.'.join(map(str, revno))
5344
except errors.NoSuchRevision:
5345
# Bad tag data/merges can lead to tagged revisions
5346
# which are not in this branch. Fail gracefully ...
5348
tags[index] = (tag, revno)
5350
for tag, revspec in tags:
5351
self.outf.write('%-20s %s\n' % (tag, revspec))
5354
class cmd_reconfigure(Command):
5355
"""Reconfigure the type of a bzr directory.
5357
A target configuration must be specified.
5359
For checkouts, the bind-to location will be auto-detected if not specified.
5360
The order of preference is
5361
1. For a lightweight checkout, the current bound location.
5362
2. For branches that used to be checkouts, the previously-bound location.
5363
3. The push location.
5364
4. The parent location.
5365
If none of these is available, --bind-to must be specified.
5368
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5369
takes_args = ['location?']
5371
RegistryOption.from_kwargs(
5373
title='Target type',
5374
help='The type to reconfigure the directory to.',
5375
value_switches=True, enum_switch=False,
5376
branch='Reconfigure to be an unbound branch with no working tree.',
5377
tree='Reconfigure to be an unbound branch with a working tree.',
5378
checkout='Reconfigure to be a bound branch with a working tree.',
5379
lightweight_checkout='Reconfigure to be a lightweight'
5380
' checkout (with no local history).',
5381
standalone='Reconfigure to be a standalone branch '
5382
'(i.e. stop using shared repository).',
5383
use_shared='Reconfigure to use a shared repository.',
5384
with_trees='Reconfigure repository to create '
5385
'working trees on branches by default.',
5386
with_no_trees='Reconfigure repository to not create '
5387
'working trees on branches by default.'
5389
Option('bind-to', help='Branch to bind checkout to.', type=str),
5391
help='Perform reconfiguration even if local changes'
5393
Option('stacked-on',
5394
help='Reconfigure a branch to be stacked on another branch.',
5398
help='Reconfigure a branch to be unstacked. This '
5399
'may require copying substantial data into it.',
5403
def run(self, location=None, target_type=None, bind_to=None, force=False,
5406
directory = bzrdir.BzrDir.open(location)
5407
if stacked_on and unstacked:
5408
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5409
elif stacked_on is not None:
5410
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5412
reconfigure.ReconfigureUnstacked().apply(directory)
5413
# At the moment you can use --stacked-on and a different
5414
# reconfiguration shape at the same time; there seems no good reason
5416
if target_type is None:
5417
if stacked_on or unstacked:
5420
raise errors.BzrCommandError('No target configuration '
5422
elif target_type == 'branch':
5423
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5424
elif target_type == 'tree':
5425
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5426
elif target_type == 'checkout':
5427
reconfiguration = reconfigure.Reconfigure.to_checkout(
5429
elif target_type == 'lightweight-checkout':
5430
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5432
elif target_type == 'use-shared':
5433
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5434
elif target_type == 'standalone':
5435
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5436
elif target_type == 'with-trees':
5437
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5439
elif target_type == 'with-no-trees':
5440
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5442
reconfiguration.apply(force)
5445
class cmd_switch(Command):
5446
"""Set the branch of a checkout and update.
5448
For lightweight checkouts, this changes the branch being referenced.
5449
For heavyweight checkouts, this checks that there are no local commits
5450
versus the current bound branch, then it makes the local branch a mirror
5451
of the new location and binds to it.
5453
In both cases, the working tree is updated and uncommitted changes
5454
are merged. The user can commit or revert these as they desire.
5456
Pending merges need to be committed or reverted before using switch.
5458
The path to the branch to switch to can be specified relative to the parent
5459
directory of the current branch. For example, if you are currently in a
5460
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5463
Bound branches use the nickname of its master branch unless it is set
5464
locally, in which case switching will update the local nickname to be
5468
takes_args = ['to_location?']
5469
takes_options = [Option('force',
5470
help='Switch even if local commits will be lost.'),
5472
Option('create-branch', short_name='b',
5473
help='Create the target branch from this one before'
5474
' switching to it.'),
5477
def run(self, to_location=None, force=False, create_branch=False,
5479
from bzrlib import switch
5481
revision = _get_one_revision('switch', revision)
5482
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5483
if to_location is None:
5484
if revision is None:
5485
raise errors.BzrCommandError('You must supply either a'
5486
' revision or a location')
5489
branch = control_dir.open_branch()
5490
had_explicit_nick = branch.get_config().has_explicit_nickname()
5491
except errors.NotBranchError:
5493
had_explicit_nick = False
5496
raise errors.BzrCommandError('cannot create branch without'
5498
to_location = directory_service.directories.dereference(
5500
if '/' not in to_location and '\\' not in to_location:
5501
# This path is meant to be relative to the existing branch
5502
this_url = self._get_branch_location(control_dir)
5503
to_location = urlutils.join(this_url, '..', to_location)
5504
to_branch = branch.bzrdir.sprout(to_location,
5505
possible_transports=[branch.bzrdir.root_transport],
5506
source_branch=branch).open_branch()
5509
to_branch = Branch.open(to_location)
5510
except errors.NotBranchError:
5511
this_url = self._get_branch_location(control_dir)
5512
to_branch = Branch.open(
5513
urlutils.join(this_url, '..', to_location))
5514
if revision is not None:
5515
revision = revision.as_revision_id(to_branch)
5516
switch.switch(control_dir, to_branch, force, revision_id=revision)
5517
if had_explicit_nick:
5518
branch = control_dir.open_branch() #get the new branch!
5519
branch.nick = to_branch.nick
5520
note('Switched to branch: %s',
5521
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5523
def _get_branch_location(self, control_dir):
5524
"""Return location of branch for this control dir."""
5526
this_branch = control_dir.open_branch()
5527
# This may be a heavy checkout, where we want the master branch
5528
master_location = this_branch.get_bound_location()
5529
if master_location is not None:
5530
return master_location
5531
# If not, use a local sibling
5532
return this_branch.base
5533
except errors.NotBranchError:
5534
format = control_dir.find_branch_format()
5535
if getattr(format, 'get_reference', None) is not None:
5536
return format.get_reference(control_dir)
5538
return control_dir.root_transport.base
5541
class cmd_view(Command):
5542
"""Manage filtered views.
5544
Views provide a mask over the tree so that users can focus on
5545
a subset of a tree when doing their work. After creating a view,
5546
commands that support a list of files - status, diff, commit, etc -
5547
effectively have that list of files implicitly given each time.
5548
An explicit list of files can still be given but those files
5549
must be within the current view.
5551
In most cases, a view has a short life-span: it is created to make
5552
a selected change and is deleted once that change is committed.
5553
At other times, you may wish to create one or more named views
5554
and switch between them.
5556
To disable the current view without deleting it, you can switch to
5557
the pseudo view called ``off``. This can be useful when you need
5558
to see the whole tree for an operation or two (e.g. merge) but
5559
want to switch back to your view after that.
5562
To define the current view::
5564
bzr view file1 dir1 ...
5566
To list the current view::
5570
To delete the current view::
5574
To disable the current view without deleting it::
5576
bzr view --switch off
5578
To define a named view and switch to it::
5580
bzr view --name view-name file1 dir1 ...
5582
To list a named view::
5584
bzr view --name view-name
5586
To delete a named view::
5588
bzr view --name view-name --delete
5590
To switch to a named view::
5592
bzr view --switch view-name
5594
To list all views defined::
5598
To delete all views::
5600
bzr view --delete --all
5604
takes_args = ['file*']
5607
help='Apply list or delete action to all views.',
5610
help='Delete the view.',
5613
help='Name of the view to define, list or delete.',
5617
help='Name of the view to switch to.',
5622
def run(self, file_list,
5628
tree, file_list = tree_files(file_list, apply_view=False)
5629
current_view, view_dict = tree.views.get_view_info()
5634
raise errors.BzrCommandError(
5635
"Both --delete and a file list specified")
5637
raise errors.BzrCommandError(
5638
"Both --delete and --switch specified")
5640
tree.views.set_view_info(None, {})
5641
self.outf.write("Deleted all views.\n")
5643
raise errors.BzrCommandError("No current view to delete")
5645
tree.views.delete_view(name)
5646
self.outf.write("Deleted '%s' view.\n" % name)
5649
raise errors.BzrCommandError(
5650
"Both --switch and a file list specified")
5652
raise errors.BzrCommandError(
5653
"Both --switch and --all specified")
5654
elif switch == 'off':
5655
if current_view is None:
5656
raise errors.BzrCommandError("No current view to disable")
5657
tree.views.set_view_info(None, view_dict)
5658
self.outf.write("Disabled '%s' view.\n" % (current_view))
5660
tree.views.set_view_info(switch, view_dict)
5661
view_str = views.view_display_str(tree.views.lookup_view())
5662
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5665
self.outf.write('Views defined:\n')
5666
for view in sorted(view_dict):
5667
if view == current_view:
5671
view_str = views.view_display_str(view_dict[view])
5672
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5674
self.outf.write('No views defined.\n')
5677
# No name given and no current view set
5680
raise errors.BzrCommandError(
5681
"Cannot change the 'off' pseudo view")
5682
tree.views.set_view(name, sorted(file_list))
5683
view_str = views.view_display_str(tree.views.lookup_view())
5684
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5688
# No name given and no current view set
5689
self.outf.write('No current view.\n')
5691
view_str = views.view_display_str(tree.views.lookup_view(name))
5692
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5695
class cmd_hooks(Command):
5701
for hook_key in sorted(hooks.known_hooks.keys()):
5702
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5703
self.outf.write("%s:\n" % type(some_hooks).__name__)
5704
for hook_name, hook_point in sorted(some_hooks.items()):
5705
self.outf.write(" %s:\n" % (hook_name,))
5706
found_hooks = list(hook_point)
5708
for hook in found_hooks:
5709
self.outf.write(" %s\n" %
5710
(some_hooks.get_hook_name(hook),))
5712
self.outf.write(" <no hooks installed>\n")
5715
class cmd_shelve(Command):
5716
"""Temporarily set aside some changes from the current tree.
5718
Shelve allows you to temporarily put changes you've made "on the shelf",
5719
ie. out of the way, until a later time when you can bring them back from
5720
the shelf with the 'unshelve' command. The changes are stored alongside
5721
your working tree, and so they aren't propagated along with your branch nor
5722
will they survive its deletion.
5724
If shelve --list is specified, previously-shelved changes are listed.
5726
Shelve is intended to help separate several sets of changes that have
5727
been inappropriately mingled. If you just want to get rid of all changes
5728
and you don't need to restore them later, use revert. If you want to
5729
shelve all text changes at once, use shelve --all.
5731
If filenames are specified, only the changes to those files will be
5732
shelved. Other files will be left untouched.
5734
If a revision is specified, changes since that revision will be shelved.
5736
You can put multiple items on the shelf, and by default, 'unshelve' will
5737
restore the most recently shelved changes.
5740
takes_args = ['file*']
5744
Option('all', help='Shelve all changes.'),
5746
RegistryOption('writer', 'Method to use for writing diffs.',
5747
bzrlib.option.diff_writer_registry,
5748
value_switches=True, enum_switch=False),
5750
Option('list', help='List shelved changes.'),
5752
help='Destroy removed changes instead of shelving them.'),
5754
_see_also = ['unshelve']
5756
def run(self, revision=None, all=False, file_list=None, message=None,
5757
writer=None, list=False, destroy=False):
5759
return self.run_for_list()
5760
from bzrlib.shelf_ui import Shelver
5762
writer = bzrlib.option.diff_writer_registry.get()
5764
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5765
file_list, message, destroy=destroy)
5770
except errors.UserAbort:
5773
def run_for_list(self):
5774
tree = WorkingTree.open_containing('.')[0]
5776
self.add_cleanup(tree.unlock)
5777
manager = tree.get_shelf_manager()
5778
shelves = manager.active_shelves()
5779
if len(shelves) == 0:
5780
note('No shelved changes.')
5782
for shelf_id in reversed(shelves):
5783
message = manager.get_metadata(shelf_id).get('message')
5785
message = '<no message>'
5786
self.outf.write('%3d: %s\n' % (shelf_id, message))
5790
class cmd_unshelve(Command):
5791
"""Restore shelved changes.
5793
By default, the most recently shelved changes are restored. However if you
5794
specify a shelf by id those changes will be restored instead. This works
5795
best when the changes don't depend on each other.
5798
takes_args = ['shelf_id?']
5800
RegistryOption.from_kwargs(
5801
'action', help="The action to perform.",
5802
enum_switch=False, value_switches=True,
5803
apply="Apply changes and remove from the shelf.",
5804
dry_run="Show changes, but do not apply or remove them.",
5805
preview="Instead of unshelving the changes, show the diff that "
5806
"would result from unshelving.",
5807
delete_only="Delete changes without applying them.",
5808
keep="Apply changes but don't delete them.",
5811
_see_also = ['shelve']
5813
def run(self, shelf_id=None, action='apply'):
5814
from bzrlib.shelf_ui import Unshelver
5815
unshelver = Unshelver.from_args(shelf_id, action)
5819
unshelver.tree.unlock()
5822
class cmd_clean_tree(Command):
5823
"""Remove unwanted files from working tree.
5825
By default, only unknown files, not ignored files, are deleted. Versioned
5826
files are never deleted.
5828
Another class is 'detritus', which includes files emitted by bzr during
5829
normal operations and selftests. (The value of these files decreases with
5832
If no options are specified, unknown files are deleted. Otherwise, option
5833
flags are respected, and may be combined.
5835
To check what clean-tree will do, use --dry-run.
5837
takes_options = [Option('ignored', help='Delete all ignored files.'),
5838
Option('detritus', help='Delete conflict files, merge'
5839
' backups, and failed selftest dirs.'),
5841
help='Delete files unknown to bzr (default).'),
5842
Option('dry-run', help='Show files to delete instead of'
5844
Option('force', help='Do not prompt before deleting.')]
5845
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5847
from bzrlib.clean_tree import clean_tree
5848
if not (unknown or ignored or detritus):
5852
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5853
dry_run=dry_run, no_prompt=force)
5856
class cmd_reference(Command):
5857
"""list, view and set branch locations for nested trees.
5859
If no arguments are provided, lists the branch locations for nested trees.
5860
If one argument is provided, display the branch location for that tree.
5861
If two arguments are provided, set the branch location for that tree.
5866
takes_args = ['path?', 'location?']
5868
def run(self, path=None, location=None):
5870
if path is not None:
5872
tree, branch, relpath =(
5873
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5874
if path is not None:
5877
tree = branch.basis_tree()
5879
info = branch._get_all_reference_info().iteritems()
5880
self._display_reference_info(tree, branch, info)
5882
file_id = tree.path2id(path)
5884
raise errors.NotVersionedError(path)
5885
if location is None:
5886
info = [(file_id, branch.get_reference_info(file_id))]
5887
self._display_reference_info(tree, branch, info)
5889
branch.set_reference_info(file_id, path, location)
5891
def _display_reference_info(self, tree, branch, info):
5893
for file_id, (path, location) in info:
5895
path = tree.id2path(file_id)
5896
except errors.NoSuchId:
5898
ref_list.append((path, location))
5899
for path, location in sorted(ref_list):
5900
self.outf.write('%s %s\n' % (path, location))
4061
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
4062
self.outf.write('%-20s %s\n' % (tag_name, target))
4065
def _create_prefix(cur_transport):
4066
needed = [cur_transport]
4067
# Recurse upwards until we can create a directory successfully
4069
new_transport = cur_transport.clone('..')
4070
if new_transport.base == cur_transport.base:
4071
raise errors.BzrCommandError(
4072
"Failed to create path prefix for %s."
4073
% cur_transport.base)
4075
new_transport.mkdir('.')
4076
except errors.NoSuchFile:
4077
needed.append(new_transport)
4078
cur_transport = new_transport
4081
# Now we only need to create child directories
4083
cur_transport = needed.pop()
4084
cur_transport.ensure_base()
4087
def _get_mergeable_helper(location):
4088
"""Get a merge directive or bundle if 'location' points to one.
4090
Try try to identify a bundle and returns its mergeable form. If it's not,
4091
we return the tried transport anyway so that it can reused to access the
4094
:param location: can point to a bundle or a branch.
4096
:return: mergeable, transport
4099
url = urlutils.normalize_url(location)
4100
url, filename = urlutils.split(url, exclude_trailing_slash=False)
4101
location_transport = transport.get_transport(url)
4104
# There may be redirections but we ignore the intermediate
4105
# and final transports used
4106
read = bundle.read_mergeable_from_transport
4107
mergeable, t = read(location_transport, filename)
4108
except errors.NotABundle:
4109
# Continue on considering this url a Branch but adjust the
4110
# location_transport
4111
location_transport = location_transport.clone(filename)
4112
return mergeable, location_transport
5903
4115
# these get imported and then picked up by the scan for cmd_*
5904
4116
# TODO: Some more consistent way to split command definitions across files;
5905
# we do need to load at least some information about them to know of
4117
# we do need to load at least some information about them to know of
5906
4118
# aliases. ideally we would avoid loading the implementation until the
5907
4119
# details were needed.
5908
4120
from bzrlib.cmd_version_info import cmd_version_info