41
39
merge as _mod_merge,
46
43
revision as _mod_revision,
55
50
from bzrlib.branch import Branch
56
51
from bzrlib.conflicts import ConflictList
57
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
52
from bzrlib.revisionspec import RevisionSpec
58
53
from bzrlib.smtp_connection import SMTPConnection
59
54
from bzrlib.workingtree import WorkingTree
62
57
from bzrlib.commands import Command, display_command
63
from bzrlib.option import (
70
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
73
def tree_files(file_list, default_branch=u'.', canonicalize=True,
58
from bzrlib.option import ListOption, Option, RegistryOption, custom_help
59
from bzrlib.trace import mutter, note, warning, is_quiet
62
def tree_files(file_list, default_branch=u'.'):
76
return internal_tree_files(file_list, default_branch, canonicalize,
64
return internal_tree_files(file_list, default_branch)
78
65
except errors.FileInWrongBranch, e:
79
66
raise errors.BzrCommandError("%s is not in the same branch as %s" %
80
67
(e.path, file_list[0]))
83
def tree_files_for_add(file_list):
85
Return a tree and list of absolute paths from a file list.
87
Similar to tree_files, but add handles files a bit differently, so it a
88
custom implementation. In particular, MutableTreeTree.smart_add expects
89
absolute paths, which it immediately converts to relative paths.
91
# FIXME Would be nice to just return the relative paths like
92
# internal_tree_files does, but there are a large number of unit tests
93
# that assume the current interface to mutabletree.smart_add
95
tree, relpath = WorkingTree.open_containing(file_list[0])
96
if tree.supports_views():
97
view_files = tree.views.lookup_view()
99
for filename in file_list:
100
if not osutils.is_inside_any(view_files, filename):
101
raise errors.FileOutsideView(filename, view_files)
102
file_list = file_list[:]
103
file_list[0] = tree.abspath(relpath)
105
tree = WorkingTree.open_containing(u'.')[0]
106
if tree.supports_views():
107
view_files = tree.views.lookup_view()
109
file_list = view_files
110
view_str = views.view_display_str(view_files)
111
note("Ignoring files outside view. View is %s" % view_str)
112
return tree, file_list
115
def _get_one_revision(command_name, revisions):
116
if revisions is None:
118
if len(revisions) != 1:
119
raise errors.BzrCommandError(
120
'bzr %s --revision takes exactly one revision identifier' % (
125
70
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
126
"""Get a revision tree. Not suitable for commands that change the tree.
128
Specifically, the basis tree in dirstate trees is coupled to the dirstate
129
and doing a commit/uncommit/pull will at best fail due to changing the
132
If tree is passed in, it should be already locked, for lifetime management
133
of the trees internal cached state.
135
71
if branch is None:
136
72
branch = tree.branch
137
73
if revisions is None:
828
667
into_existing = False
830
669
inv = tree.inventory
831
# 'fix' the case of a potential 'from'
832
from_id = tree.path2id(
833
tree.get_canonical_inventory_path(rel_names[0]))
670
from_id = tree.path2id(rel_names[0])
834
671
if (not osutils.lexists(names_list[0]) and
835
672
from_id and inv.get_file_kind(from_id) == "directory"):
836
673
into_existing = False
838
675
if into_existing:
839
676
# move into existing directory
840
# All entries reference existing inventory items, so fix them up
841
# for cicp file-systems.
842
rel_names = tree.get_canonical_inventory_paths(rel_names)
843
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
845
self.outf.write("%s => %s\n" % (src, dest))
677
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
678
self.outf.write("%s => %s\n" % pair)
847
680
if len(names_list) != 2:
848
681
raise errors.BzrCommandError('to mv multiple files the'
849
682
' 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))
684
tree.rename_one(rel_names[0], rel_names[1], after=after)
685
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
899
688
class cmd_pull(Command):
900
689
"""Turn this branch into a mirror of another branch.
902
By default, this command only works on branches that have not diverged.
903
Branches are considered diverged if the destination branch's most recent
904
commit is one that has not been merged (directly or indirectly) into the
691
This command only works on branches that have not diverged. Branches are
692
considered diverged if the destination branch's most recent commit is one
693
that has not been merged (directly or indirectly) into the parent.
907
695
If branches have diverged, you can use 'bzr merge' to integrate the changes
908
696
from one into the other. Once one branch has merged, the other should
909
697
be able to pull it again.
911
If you want to replace your local changes and just want your branch to
912
match the remote one, use pull --overwrite. This will work even if the two
913
branches have diverged.
699
If you want to forget your local changes and just update your branch to
700
match the remote one, use pull --overwrite.
915
702
If there is no default location set, the first pull will set it. After
916
703
that, you can omit the location to use the default. To change the
1164
931
takes_args = ['from_location', 'to_location?']
1165
932
takes_options = ['revision', Option('hardlink',
1166
933
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."),
1172
934
Option('stacked',
1173
935
help='Create a stacked branch referring to the source branch. '
1174
936
'The new branch will depend on the availability of the source '
1175
937
'branch for all operations.'),
1176
938
Option('standalone',
1177
939
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."),
1186
941
aliases = ['get', 'clone']
1188
943
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
944
hardlink=False, stacked=False, standalone=False):
1192
945
from bzrlib.tag import _merge_tags_if_possible
948
elif len(revision) > 1:
949
raise errors.BzrCommandError(
950
'bzr branch --revision takes exactly 1 revision value')
1193
952
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1195
revision = _get_one_revision('branch', revision)
1196
954
br_from.lock_read()
1197
self.add_cleanup(br_from.unlock)
1198
if revision is not None:
1199
revision_id = revision.as_revision_id(br_from)
1201
# FIXME - wt.last_revision, fallback to branch, fall back to
1202
# None or perhaps NULL_REVISION to mean copy nothing
1204
revision_id = br_from.last_revision()
1205
if to_location is None:
1206
to_location = urlutils.derive_to_location(from_location)
1207
to_transport = transport.get_transport(to_location)
1209
to_transport.mkdir('.')
1210
except errors.FileExists:
1211
if not use_existing_dir:
1212
raise errors.BzrCommandError('Target directory "%s" '
1213
'already exists.' % to_location)
956
if len(revision) == 1 and revision[0] is not None:
957
revision_id = revision[0].as_revision_id(br_from)
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:
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'))
959
# FIXME - wt.last_revision, fallback to branch, fall back to
960
# None or perhaps NULL_REVISION to mean copy nothing
962
revision_id = br_from.last_revision()
963
if to_location is None:
964
to_location = urlutils.derive_to_location(from_location)
965
to_transport = transport.get_transport(to_location)
967
to_transport.mkdir('.')
968
except errors.FileExists:
969
raise errors.BzrCommandError('Target directory "%s" already'
970
' exists.' % to_location)
971
except errors.NoSuchFile:
972
raise errors.BzrCommandError('Parent of "%s" does not exist.'
975
# preserve whatever source format we have.
976
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
977
possible_transports=[to_transport],
978
accelerator_tree=accelerator_tree,
979
hardlink=hardlink, stacked=stacked,
980
force_new_repo=standalone)
981
branch = dir.open_branch()
982
except errors.NoSuchRevision:
983
to_transport.delete_tree('.')
984
msg = "The branch %s has no revision %s." % (from_location,
986
raise errors.BzrCommandError(msg)
987
_merge_tags_if_possible(br_from, branch)
988
# If the source branch is stacked, the new branch may
989
# be stacked whether we asked for that explicitly or not.
990
# We therefore need a try/except here and not just 'if stacked:'
992
note('Created new stacked branch referring to %s.' %
993
branch.get_stacked_on_url())
994
except (errors.NotStacked, errors.UnstackableBranchFormat,
995
errors.UnstackableRepositoryFormat), e:
996
note('Branched %d revision(s).' % branch.revno())
1262
1001
class cmd_checkout(Command):
1341
1084
def run(self, dir=u'.'):
1342
1085
tree = WorkingTree.open_containing(dir)[0]
1343
1086
tree.lock_read()
1344
self.add_cleanup(tree.unlock)
1345
new_inv = tree.inventory
1346
old_tree = tree.basis_tree()
1347
old_tree.lock_read()
1348
self.add_cleanup(old_tree.unlock)
1349
old_inv = old_tree.inventory
1351
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1352
for f, paths, c, v, p, n, k, e in iterator:
1353
if paths[0] == paths[1]:
1357
renames.append(paths)
1359
for old_name, new_name in renames:
1360
self.outf.write("%s => %s\n" % (old_name, new_name))
1088
new_inv = tree.inventory
1089
old_tree = tree.basis_tree()
1090
old_tree.lock_read()
1092
old_inv = old_tree.inventory
1094
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1095
for f, paths, c, v, p, n, k, e in iterator:
1096
if paths[0] == paths[1]:
1100
renames.append(paths)
1102
for old_name, new_name in renames:
1103
self.outf.write("%s => %s\n" % (old_name, new_name))
1363
1110
class cmd_update(Command):
1364
1111
"""Update a tree to have the latest code committed to its branch.
1366
1113
This will perform a merge into the working tree, and may generate
1367
conflicts. If you have any local changes, you will still
1114
conflicts. If you have any local changes, you will still
1368
1115
need to commit them after the update for the update to be complete.
1370
If you want to discard your local changes, you can just do a
1117
If you want to discard your local changes, you can just do a
1371
1118
'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
1121
_see_also = ['pull', 'working-trees', 'status-flags']
1378
1122
takes_args = ['dir?']
1379
takes_options = ['revision']
1380
1123
aliases = ['up']
1382
def run(self, dir='.', revision=None):
1383
if revision is not None and len(revision) != 1:
1384
raise errors.BzrCommandError(
1385
"bzr update --revision takes exactly one revision")
1125
def run(self, dir='.'):
1386
1126
tree = WorkingTree.open_containing(dir)[0]
1387
branch = tree.branch
1388
1127
possible_transports = []
1389
master = branch.get_master_branch(
1128
master = tree.branch.get_master_branch(
1390
1129
possible_transports=possible_transports)
1391
1130
if master is not None:
1392
1131
tree.lock_write()
1393
branch_location = master.base
1395
1133
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)
1135
existing_pending_merges = tree.get_parent_ids()[1:]
1136
last_rev = _mod_revision.ensure_null(tree.last_revision())
1137
if last_rev == _mod_revision.ensure_null(
1138
tree.branch.last_revision()):
1139
# may be up to date, check master too.
1140
if master is None or last_rev == _mod_revision.ensure_null(
1141
master.last_revision()):
1142
revno = tree.branch.revision_id_to_revno(last_rev)
1143
note("Tree is up to date at revision %d." % (revno,))
1423
1145
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'.")
1146
delta._ChangeReporter(unversioned_filter=tree.is_ignored),
1147
possible_transports=possible_transports)
1148
revno = tree.branch.revision_id_to_revno(
1149
_mod_revision.ensure_null(tree.last_revision()))
1150
note('Updated to revision %d.' % (revno,))
1151
if tree.get_parent_ids()[1:] != existing_pending_merges:
1152
note('Your local commits will now show as pending merges with '
1153
"'bzr status', and can be committed with 'bzr commit'.")
1447
1162
class cmd_info(Command):
1448
1163
"""Show information about a working tree, branch or repository.
1450
1165
This command will show all known locations and formats associated to the
1451
tree, branch or repository.
1453
In verbose mode, statistical information is included with each report.
1454
To see extended statistic information, use a verbosity level of 2 or
1455
higher by specifying the verbose option multiple times, e.g. -vv.
1166
tree, branch or repository. Statistical information is included with
1457
1169
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
1171
_see_also = ['revno', 'working-trees', 'repositories']
1476
1172
takes_args = ['location?']
2065
1734
raise errors.BzrCommandError(msg)
2068
def _parse_levels(s):
2072
msg = "The levels argument must be an integer."
2073
raise errors.BzrCommandError(msg)
2076
1737
class cmd_log(Command):
2077
"""Show historical log for a branch or subset of a branch.
2079
log is bzr's default tool for exploring the history of a branch.
2080
The branch to use is taken from the first parameter. If no parameters
2081
are given, the branch containing the working directory is logged.
2082
Here are some simple examples::
2084
bzr log log the current branch
2085
bzr log foo.py log a file in its branch
2086
bzr log http://server/branch log a branch on a server
2088
The filtering, ordering and information shown for each revision can
2089
be controlled as explained below. By default, all revisions are
2090
shown sorted (topologically) so that newer revisions appear before
2091
older ones and descendants always appear before ancestors. If displayed,
2092
merged revisions are shown indented under the revision in which they
2097
The log format controls how information about each revision is
2098
displayed. The standard log formats are called ``long``, ``short``
2099
and ``line``. The default is long. See ``bzr help log-formats``
2100
for more details on log formats.
2102
The following options can be used to control what information is
2105
-l N display a maximum of N revisions
2106
-n N display N levels of revisions (0 for all, 1 for collapsed)
2107
-v display a status summary (delta) for each revision
2108
-p display a diff (patch) for each revision
2109
--show-ids display revision-ids (and file-ids), not just revnos
2111
Note that the default number of levels to display is a function of the
2112
log format. If the -n option is not used, the standard log formats show
2113
just the top level (mainline).
2115
Status summaries are shown using status flags like A, M, etc. To see
2116
the changes explained using words like ``added`` and ``modified``
2117
instead, use the -vv option.
2121
To display revisions from oldest to newest, use the --forward option.
2122
In most cases, using this option will have little impact on the total
2123
time taken to produce a log, though --forward does not incrementally
2124
display revisions like --reverse does when it can.
2126
:Revision filtering:
2128
The -r option can be used to specify what revision or range of revisions
2129
to filter against. The various forms are shown below::
2131
-rX display revision X
2132
-rX.. display revision X and later
2133
-r..Y display up to and including revision Y
2134
-rX..Y display from X to Y inclusive
2136
See ``bzr help revisionspec`` for details on how to specify X and Y.
2137
Some common examples are given below::
2139
-r-1 show just the tip
2140
-r-10.. show the last 10 mainline revisions
2141
-rsubmit:.. show what's new on this branch
2142
-rancestor:path.. show changes since the common ancestor of this
2143
branch and the one at location path
2144
-rdate:yesterday.. show changes since yesterday
2146
When logging a range of revisions using -rX..Y, log starts at
2147
revision Y and searches back in history through the primary
2148
("left-hand") parents until it finds X. When logging just the
2149
top level (using -n1), an error is reported if X is not found
2150
along the way. If multi-level logging is used (-n0), X may be
2151
a nested merge revision and the log will be truncated accordingly.
2155
If parameters are given and the first one is not a branch, the log
2156
will be filtered to show only those revisions that changed the
2157
nominated files or directories.
2159
Filenames are interpreted within their historical context. To log a
2160
deleted file, specify a revision range so that the file existed at
2161
the end or start of the range.
2163
Historical context is also important when interpreting pathnames of
2164
renamed files/directories. Consider the following example:
2166
* revision 1: add tutorial.txt
2167
* revision 2: modify tutorial.txt
2168
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2172
* ``bzr log guide.txt`` will log the file added in revision 1
2174
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2176
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2177
the original file in revision 2.
2179
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2180
was no file called guide.txt in revision 2.
2182
Renames are always followed by log. By design, there is no need to
2183
explicitly ask for this (and no way to stop logging a file back
2184
until it was last renamed).
2188
The --message option can be used for finding revisions that match a
2189
regular expression in a commit message.
2193
GUI tools and IDEs are often better at exploring history than command
2194
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2195
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2196
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2197
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2199
You may find it useful to add the aliases below to ``bazaar.conf``::
2203
top = log -l10 --line
2206
``bzr tip`` will then show the latest revision while ``bzr top``
2207
will show the last 10 mainline revisions. To see the details of a
2208
particular revision X, ``bzr show -rX``.
2210
If you are interested in looking deeper into a particular merge X,
2211
use ``bzr log -n0 -rX``.
2213
``bzr log -v`` on a branch with lots of history is currently
2214
very slow. A fix for this issue is currently under development.
2215
With or without that fix, it is recommended that a revision range
2216
be given when using the -v option.
2218
bzr has a generic full-text matching plugin, bzr-search, that can be
2219
used to find revisions matching user names, commit messages, etc.
2220
Among other features, this plugin can find all revisions containing
2221
a list of words but not others.
2223
When exploring non-mainline history on large projects with deep
2224
history, the performance of log can be greatly improved by installing
2225
the historycache plugin. This plugin buffers historical information
2226
trading disk space for faster speed.
1738
"""Show log of a branch, file, or directory.
1740
By default show the log of the branch containing the working directory.
1742
To request a range of logs, you can use the command -r begin..end
1743
-r revision requests a specific revision, -r ..end or -r begin.. are
1747
Log the current branch::
1755
Log the last 10 revisions of a branch::
1757
bzr log -r -10.. http://server/branch
2228
takes_args = ['file*']
2229
_see_also = ['log-formats', 'revisionspec']
1760
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1762
takes_args = ['location?']
2230
1763
takes_options = [
2231
1764
Option('forward',
2232
1765
help='Show from oldest to newest.'),
2330
1835
dir, relpath = bzrdir.BzrDir.open_containing(location)
2331
1836
b = dir.open_branch()
2333
self.add_cleanup(b.unlock)
2334
rev1, rev2 = _get_revision_range(revision, b, self.name())
2336
# Decide on the type of delta & diff filtering to use
2337
# TODO: add an --all-files option to make this configurable & consistent
2345
diff_type = 'partial'
2349
# Build the log formatter
2350
if log_format is None:
2351
log_format = log.log_formatter_registry.get_default(b)
2352
# Make a non-encoding output to include the diffs - bug 328007
2353
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2354
lf = log_format(show_ids=show_ids, to_file=self.outf,
2355
to_exact_file=unencoded_output,
2356
show_timezone=timezone,
2357
delta_format=get_verbosity_level(),
2359
show_advice=levels is None)
2361
# Choose the algorithm for doing the logging. It's annoying
2362
# having multiple code paths like this but necessary until
2363
# the underlying repository format is faster at generating
2364
# deltas or can provide everything we need from the indices.
2365
# The default algorithm - match-using-deltas - works for
2366
# multiple files and directories and is faster for small
2367
# amounts of history (200 revisions say). However, it's too
2368
# slow for logging a single file in a repository with deep
2369
# history, i.e. > 10K revisions. In the spirit of "do no
2370
# evil when adding features", we continue to use the
2371
# original algorithm - per-file-graph - for the "single
2372
# file that isn't a directory without showing a delta" case.
2373
partial_history = revision and b.repository._format.supports_chks
2374
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2375
or delta_type or partial_history)
2377
# Build the LogRequest and execute it
2378
if len(file_ids) == 0:
2380
rqst = make_log_request_dict(
2381
direction=direction, specific_fileids=file_ids,
2382
start_revision=rev1, end_revision=rev2, limit=limit,
2383
message_search=message, delta_type=delta_type,
2384
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2385
Logger(b, rqst).show(lf)
2388
def _get_revision_range(revisionspec_list, branch, command_name):
2389
"""Take the input of a revision option and turn it into a revision range.
2391
It returns RevisionInfo objects which can be used to obtain the rev_id's
2392
of the desired revisions. It does some user input validations.
2394
if revisionspec_list is None:
2397
elif len(revisionspec_list) == 1:
2398
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2399
elif len(revisionspec_list) == 2:
2400
start_spec = revisionspec_list[0]
2401
end_spec = revisionspec_list[1]
2402
if end_spec.get_branch() != start_spec.get_branch():
2403
# b is taken from revision[0].get_branch(), and
2404
# show_log will use its revision_history. Having
2405
# different branches will lead to weird behaviors.
2406
raise errors.BzrCommandError(
2407
"bzr %s doesn't accept two revisions in different"
2408
" branches." % command_name)
2409
rev1 = start_spec.in_history(branch)
2410
# Avoid loading all of history when we know a missing
2411
# end of range means the last revision ...
2412
if end_spec.spec is None:
2413
last_revno, last_revision_id = branch.last_revision_info()
2414
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2416
rev2 = end_spec.in_history(branch)
2418
raise errors.BzrCommandError(
2419
'bzr %s --revision takes one or two values.' % command_name)
2423
def _revision_range_to_revid_range(revision_range):
2426
if revision_range[0] is not None:
2427
rev_id1 = revision_range[0].rev_id
2428
if revision_range[1] is not None:
2429
rev_id2 = revision_range[1].rev_id
2430
return rev_id1, rev_id2
1840
if revision is None:
1843
elif len(revision) == 1:
1844
rev1 = rev2 = revision[0].in_history(b)
1845
elif len(revision) == 2:
1846
if revision[1].get_branch() != revision[0].get_branch():
1847
# b is taken from revision[0].get_branch(), and
1848
# show_log will use its revision_history. Having
1849
# different branches will lead to weird behaviors.
1850
raise errors.BzrCommandError(
1851
"Log doesn't accept two revisions in different"
1853
rev1 = revision[0].in_history(b)
1854
rev2 = revision[1].in_history(b)
1856
raise errors.BzrCommandError(
1857
'bzr log --revision takes one or two values.')
1859
if log_format is None:
1860
log_format = log.log_formatter_registry.get_default(b)
1862
lf = log_format(show_ids=show_ids, to_file=self.outf,
1863
show_timezone=timezone)
1869
direction=direction,
1870
start_revision=rev1,
2432
1878
def get_log_format(long=False, short=False, line=False, default='long'):
2433
1879
log_format = default
2804
2200
If no revision is nominated, the last revision is used.
2806
2202
Note: Take care to redirect standard output when using this command on a
2810
2206
_see_also = ['ls']
2811
2207
takes_options = [
2812
2208
Option('name-from-revision', help='The path name in the old tree.'),
2813
Option('filters', help='Apply content filters to display the '
2814
'convenience form.'),
2817
2211
takes_args = ['filename']
2818
2212
encoding_type = 'exact'
2820
2214
@display_command
2821
def run(self, filename, revision=None, name_from_revision=False,
2215
def run(self, filename, revision=None, name_from_revision=False):
2823
2216
if revision is not None and len(revision) != 1:
2824
2217
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2825
2218
" one revision specifier")
2826
2219
tree, branch, relpath = \
2827
2220
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2828
2221
branch.lock_read()
2829
self.add_cleanup(branch.unlock)
2830
return self._run(tree, branch, relpath, filename, revision,
2831
name_from_revision, filters)
2223
return self._run(tree, branch, relpath, filename, revision,
2833
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2228
def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2835
2229
if tree is None:
2836
2230
tree = b.basis_tree()
2837
2231
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2838
rev_tree.lock_read()
2839
self.add_cleanup(rev_tree.unlock)
2233
cur_file_id = tree.path2id(relpath)
2841
2234
old_file_id = rev_tree.path2id(relpath)
2843
2236
if name_from_revision:
2844
# Try in revision if requested
2845
2237
if old_file_id is None:
2846
2238
raise errors.BzrCommandError(
2847
2239
"%r is not present in revision %s" % (
2848
2240
filename, rev_tree.get_revision_id()))
2850
2242
content = rev_tree.get_file_text(old_file_id)
2852
cur_file_id = tree.path2id(relpath)
2854
if cur_file_id is not None:
2855
# Then try with the actual file id
2857
content = rev_tree.get_file_text(cur_file_id)
2859
except errors.NoSuchId:
2860
# The actual file id didn't exist at that time
2862
if not found and old_file_id is not None:
2863
# Finally try with the old file id
2864
content = rev_tree.get_file_text(old_file_id)
2867
# Can't be found anywhere
2868
raise errors.BzrCommandError(
2869
"%r is not present in revision %s" % (
2870
filename, rev_tree.get_revision_id()))
2872
from bzrlib.filters import (
2873
ContentFilterContext,
2874
filtered_output_bytes,
2876
filters = rev_tree._content_filter_stack(relpath)
2877
chunks = content.splitlines(True)
2878
content = filtered_output_bytes(chunks, filters,
2879
ContentFilterContext(relpath, rev_tree))
2881
self.outf.writelines(content)
2884
self.outf.write(content)
2243
elif cur_file_id is not None:
2244
content = rev_tree.get_file_text(cur_file_id)
2245
elif old_file_id is not None:
2246
content = rev_tree.get_file_text(old_file_id)
2248
raise errors.BzrCommandError(
2249
"%r is not present in revision %s" % (
2250
filename, rev_tree.get_revision_id()))
2251
self.outf.write(content)
2887
2254
class cmd_local_time_offset(Command):
2888
2255
"""Show the offset in seconds from GMT to local time."""
2890
2257
@display_command
2892
2259
print osutils.local_time_offset()
2896
2263
class cmd_commit(Command):
2897
2264
"""Commit changes into a new revision.
2899
An explanatory message needs to be given for each commit. This is
2900
often done by using the --message option (getting the message from the
2901
command line) or by using the --file option (getting the message from
2902
a file). If neither of these options is given, an editor is opened for
2903
the user to enter the message. To see the changed files in the
2904
boilerplate text loaded into the editor, use the --show-diff option.
2906
By default, the entire tree is committed and the person doing the
2907
commit is assumed to be the author. These defaults can be overridden
2912
If selected files are specified, only changes to those files are
2913
committed. If a directory is specified then the directory and
2914
everything within it is committed.
2916
When excludes are given, they take precedence over selected files.
2917
For example, to commit only changes within foo, but not changes
2920
bzr commit foo -x foo/bar
2922
A selective commit after a merge is not yet supported.
2926
If the author of the change is not the same person as the committer,
2927
you can specify the author's name using the --author option. The
2928
name should be in the same format as a committer-id, e.g.
2929
"John Doe <jdoe@example.com>". If there is more than one author of
2930
the change you can specify the option multiple times, once for each
2935
A common mistake is to forget to add a new file or directory before
2936
running the commit command. The --strict option checks for unknown
2937
files and aborts the commit if any are found. More advanced pre-commit
2938
checks can be implemented by defining hooks. See ``bzr help hooks``
2943
If you accidentially commit the wrong changes or make a spelling
2944
mistake in the commit message say, you can use the uncommit command
2945
to undo it. See ``bzr help uncommit`` for details.
2947
Hooks can also be configured to run after a commit. This allows you
2948
to trigger updates to external systems like bug trackers. The --fixes
2949
option can be used to record the association between a revision and
2950
one or more bugs. See ``bzr help bugs`` for details.
2952
A selective commit may fail in some cases where the committed
2953
tree would be invalid. Consider::
2958
bzr commit foo -m "committing foo"
2959
bzr mv foo/bar foo/baz
2962
bzr commit foo/bar -m "committing bar but not baz"
2964
In the example above, the last commit will fail by design. This gives
2965
the user the opportunity to decide whether they want to commit the
2966
rename at the same time, separately first, or not at all. (As a general
2967
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2266
If no arguments are given, the entire tree is committed.
2268
If selected files are specified, only changes to those files are
2269
committed. If a directory is specified then the directory and everything
2270
within it is committed.
2272
When excludes are given, they take precedence over selected files.
2273
For example, too commit only changes within foo, but not changes within
2276
bzr commit foo -x foo/bar
2278
If author of the change is not the same person as the committer, you can
2279
specify the author's name using the --author option. The name should be
2280
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2282
A selected-file commit may fail in some cases where the committed
2283
tree would be invalid. Consider::
2288
bzr commit foo -m "committing foo"
2289
bzr mv foo/bar foo/baz
2292
bzr commit foo/bar -m "committing bar but not baz"
2294
In the example above, the last commit will fail by design. This gives
2295
the user the opportunity to decide whether they want to commit the
2296
rename at the same time, separately first, or not at all. (As a general
2297
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2299
Note: A selected-file commit after a merge is not yet supported.
2969
2301
# TODO: Run hooks on tree to-be-committed, and after commit.
3744
3000
allow_pending = True
3745
3001
verified = 'inapplicable'
3746
3002
tree = WorkingTree.open_containing(directory)[0]
3003
change_reporter = delta._ChangeReporter(
3004
unversioned_filter=tree.is_ignored)
3749
basis_tree = tree.revision_tree(tree.last_revision())
3750
except errors.NoSuchRevision:
3751
basis_tree = tree.basis_tree()
3753
# die as quickly as possible if there are uncommitted changes
3755
if tree.has_changes():
3756
raise errors.UncommittedChanges(tree)
3758
view_info = _get_view_info_for_change_reporter(tree)
3759
change_reporter = delta._ChangeReporter(
3760
unversioned_filter=tree.is_ignored, view_info=view_info)
3761
pb = ui.ui_factory.nested_progress_bar()
3762
self.add_cleanup(pb.finished)
3764
self.add_cleanup(tree.unlock)
3765
if location is not None:
3767
mergeable = bundle.read_mergeable_from_url(location,
3768
possible_transports=possible_transports)
3769
except errors.NotABundle:
3007
pb = ui.ui_factory.nested_progress_bar()
3008
cleanups.append(pb.finished)
3010
cleanups.append(tree.unlock)
3011
if location is not None:
3013
mergeable = bundle.read_mergeable_from_url(location,
3014
possible_transports=possible_transports)
3015
except errors.NotABundle:
3019
raise errors.BzrCommandError('Cannot use --uncommitted'
3020
' with bundles or merge directives.')
3022
if revision is not None:
3023
raise errors.BzrCommandError(
3024
'Cannot use -r with merge directives or bundles')
3025
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3028
if merger is None and uncommitted:
3029
if revision is not None and len(revision) > 0:
3030
raise errors.BzrCommandError('Cannot use --uncommitted and'
3031
' --revision at the same time.')
3032
location = self._select_branch_location(tree, location)[0]
3033
other_tree, other_path = WorkingTree.open_containing(location)
3034
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3036
allow_pending = False
3037
if other_path != '':
3038
merger.interesting_files = [other_path]
3041
merger, allow_pending = self._get_merger_from_branch(tree,
3042
location, revision, remember, possible_transports, pb)
3044
merger.merge_type = merge_type
3045
merger.reprocess = reprocess
3046
merger.show_base = show_base
3047
self.sanity_check_merger(merger)
3048
if (merger.base_rev_id == merger.other_rev_id and
3049
merger.other_rev_id is not None):
3050
note('Nothing to do.')
3053
if merger.interesting_files is not None:
3054
raise errors.BzrCommandError('Cannot pull individual files')
3055
if (merger.base_rev_id == tree.last_revision()):
3056
result = tree.pull(merger.other_branch, False,
3057
merger.other_rev_id)
3058
result.report(self.outf)
3060
merger.check_basis(not force)
3062
return self._do_preview(merger)
3773
raise errors.BzrCommandError('Cannot use --uncommitted'
3774
' with bundles or merge directives.')
3776
if revision is not None:
3777
raise errors.BzrCommandError(
3778
'Cannot use -r with merge directives or bundles')
3779
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3782
if merger is None and uncommitted:
3783
if revision is not None and len(revision) > 0:
3784
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
3787
allow_pending = False
3790
merger, allow_pending = self._get_merger_from_branch(tree,
3791
location, revision, remember, possible_transports, pb)
3793
merger.merge_type = merge_type
3794
merger.reprocess = reprocess
3795
merger.show_base = show_base
3796
self.sanity_check_merger(merger)
3797
if (merger.base_rev_id == merger.other_rev_id and
3798
merger.other_rev_id is not None):
3799
note('Nothing to do.')
3802
if merger.interesting_files is not None:
3803
raise errors.BzrCommandError('Cannot pull individual files')
3804
if (merger.base_rev_id == tree.last_revision()):
3805
result = tree.pull(merger.other_branch, False,
3806
merger.other_rev_id)
3807
result.report(self.outf)
3809
if merger.this_basis is None:
3810
raise errors.BzrCommandError(
3811
"This branch has no commits."
3812
" (perhaps you would prefer 'bzr pull')")
3814
return self._do_preview(merger)
3816
return self._do_interactive(merger)
3818
return self._do_merge(merger, change_reporter, allow_pending,
3821
def _get_preview(self, merger):
3064
return self._do_merge(merger, change_reporter, allow_pending,
3067
for cleanup in reversed(cleanups):
3070
def _do_preview(self, merger):
3071
from bzrlib.diff import show_diff_trees
3822
3072
tree_merger = merger.make_merger()
3823
3073
tt = tree_merger.make_preview_transform()
3824
self.add_cleanup(tt.finalize)
3825
result_tree = tt.get_preview_tree()
3828
def _do_preview(self, merger):
3829
from bzrlib.diff import show_diff_trees
3830
result_tree = self._get_preview(merger)
3831
show_diff_trees(merger.this_tree, result_tree, self.outf,
3832
old_label='', new_label='')
3075
result_tree = tt.get_preview_tree()
3076
show_diff_trees(merger.this_tree, result_tree, self.outf,
3077
old_label='', new_label='')
3834
3081
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3835
3082
merger.change_reporter = change_reporter
4023
3238
merge_type = _mod_merge.Merge3Merger
4024
3239
tree, file_list = tree_files(file_list)
4025
3240
tree.lock_write()
4026
self.add_cleanup(tree.unlock)
4027
parents = tree.get_parent_ids()
4028
if len(parents) != 2:
4029
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4030
" merges. Not cherrypicking or"
4032
repository = tree.branch.repository
4033
interesting_ids = None
4035
conflicts = tree.conflicts()
4036
if file_list is not None:
4037
interesting_ids = set()
4038
for filename in file_list:
4039
file_id = tree.path2id(filename)
4041
raise errors.NotVersionedError(filename)
4042
interesting_ids.add(file_id)
4043
if tree.kind(file_id) != "directory":
4046
for name, ie in tree.inventory.iter_entries(file_id):
4047
interesting_ids.add(ie.file_id)
4048
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4050
# Remerge only supports resolving contents conflicts
4051
allowed_conflicts = ('text conflict', 'contents conflict')
4052
restore_files = [c.path for c in conflicts
4053
if c.typestring in allowed_conflicts]
4054
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4055
tree.set_conflicts(ConflictList(new_conflicts))
4056
if file_list is not None:
4057
restore_files = file_list
4058
for filename in restore_files:
3242
parents = tree.get_parent_ids()
3243
if len(parents) != 2:
3244
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3245
" merges. Not cherrypicking or"
3247
repository = tree.branch.repository
3248
interesting_ids = None
3250
conflicts = tree.conflicts()
3251
if file_list is not None:
3252
interesting_ids = set()
3253
for filename in file_list:
3254
file_id = tree.path2id(filename)
3256
raise errors.NotVersionedError(filename)
3257
interesting_ids.add(file_id)
3258
if tree.kind(file_id) != "directory":
3261
for name, ie in tree.inventory.iter_entries(file_id):
3262
interesting_ids.add(ie.file_id)
3263
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3265
# Remerge only supports resolving contents conflicts
3266
allowed_conflicts = ('text conflict', 'contents conflict')
3267
restore_files = [c.path for c in conflicts
3268
if c.typestring in allowed_conflicts]
3269
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3270
tree.set_conflicts(ConflictList(new_conflicts))
3271
if file_list is not None:
3272
restore_files = file_list
3273
for filename in restore_files:
3275
restore(tree.abspath(filename))
3276
except errors.NotConflicted:
3278
# Disable pending merges, because the file texts we are remerging
3279
# have not had those merges performed. If we use the wrong parents
3280
# list, we imply that the working tree text has seen and rejected
3281
# all the changes from the other tree, when in fact those changes
3282
# have not yet been seen.
3283
pb = ui.ui_factory.nested_progress_bar()
3284
tree.set_parent_ids(parents[:1])
4060
restore(tree.abspath(filename))
4061
except errors.NotConflicted:
4063
# Disable pending merges, because the file texts we are remerging
4064
# have not had those merges performed. If we use the wrong parents
4065
# list, we imply that the working tree text has seen and rejected
4066
# all the changes from the other tree, when in fact those changes
4067
# have not yet been seen.
4068
pb = ui.ui_factory.nested_progress_bar()
4069
tree.set_parent_ids(parents[:1])
4071
merger = _mod_merge.Merger.from_revision_ids(pb,
4073
merger.interesting_ids = interesting_ids
4074
merger.merge_type = merge_type
4075
merger.show_base = show_base
4076
merger.reprocess = reprocess
4077
conflicts = merger.do_merge()
3286
merger = _mod_merge.Merger.from_revision_ids(pb,
3288
merger.interesting_ids = interesting_ids
3289
merger.merge_type = merge_type
3290
merger.show_base = show_base
3291
merger.reprocess = reprocess
3292
conflicts = merger.do_merge()
3294
tree.set_parent_ids(parents)
4079
tree.set_parent_ids(parents)
4081
3298
if conflicts > 0:
4297
3464
" or specified.")
4298
3465
display_url = urlutils.unescape_for_display(parent,
4299
3466
self.outf.encoding)
4300
message("Using saved parent location: "
3467
self.outf.write("Using saved parent location: "
4301
3468
+ display_url + "\n")
4303
3470
remote_branch = Branch.open(other_branch)
4304
3471
if remote_branch.base == local_branch.base:
4305
3472
remote_branch = local_branch
4307
3473
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4309
local_revid_range = _revision_range_to_revid_range(
4310
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4315
remote_revid_range = _revision_range_to_revid_range(
4316
_get_revision_range(revision,
4317
remote_branch, self.name()))
4319
local_extra, remote_extra = find_unmerged(
4320
local_branch, remote_branch, restrict,
4321
backward=not reverse,
4322
include_merges=include_merges,
4323
local_revid_range=local_revid_range,
4324
remote_revid_range=remote_revid_range)
4326
if log_format is None:
4327
registry = log.log_formatter_registry
4328
log_format = registry.get_default(local_branch)
4329
lf = log_format(to_file=self.outf,
4331
show_timezone='original')
4334
if local_extra and not theirs_only:
4335
message("You have %d extra revision(s):\n" %
4337
for revision in iter_log_revisions(local_extra,
4338
local_branch.repository,
4340
lf.log_revision(revision)
4341
printed_local = True
4344
printed_local = False
4346
if remote_extra and not mine_only:
4347
if printed_local is True:
4349
message("You are missing %d revision(s):\n" %
4351
for revision in iter_log_revisions(remote_extra,
4352
remote_branch.repository,
4354
lf.log_revision(revision)
4357
if mine_only and not local_extra:
4358
# We checked local, and found nothing extra
4359
message('This branch is up to date.\n')
4360
elif theirs_only and not remote_extra:
4361
# We checked remote, and found nothing extra
4362
message('Other branch is up to date.\n')
4363
elif not (mine_only or theirs_only or local_extra or
4365
# We checked both branches, and neither one had extra
4367
message("Branches are up to date.\n")
3475
remote_branch.lock_read()
3477
local_extra, remote_extra = find_unmerged(
3478
local_branch, remote_branch, restrict,
3479
backward=not reverse,
3480
include_merges=include_merges)
3482
if log_format is None:
3483
registry = log.log_formatter_registry
3484
log_format = registry.get_default(local_branch)
3485
lf = log_format(to_file=self.outf,
3487
show_timezone='original')
3490
if local_extra and not theirs_only:
3491
self.outf.write("You have %d extra revision(s):\n" %
3493
for revision in iter_log_revisions(local_extra,
3494
local_branch.repository,
3496
lf.log_revision(revision)
3497
printed_local = True
3500
printed_local = False
3502
if remote_extra and not mine_only:
3503
if printed_local is True:
3504
self.outf.write("\n\n\n")
3505
self.outf.write("You are missing %d revision(s):\n" %
3507
for revision in iter_log_revisions(remote_extra,
3508
remote_branch.repository,
3510
lf.log_revision(revision)
3513
if mine_only and not local_extra:
3514
# We checked local, and found nothing extra
3515
self.outf.write('This branch is up to date.\n')
3516
elif theirs_only and not remote_extra:
3517
# We checked remote, and found nothing extra
3518
self.outf.write('Other branch is up to date.\n')
3519
elif not (mine_only or theirs_only or local_extra or
3521
# We checked both branches, and neither one had extra
3523
self.outf.write("Branches are up to date.\n")
3525
remote_branch.unlock()
3527
local_branch.unlock()
4369
3528
if not status_code and parent is None and other_branch is not None:
4370
3529
local_branch.lock_write()
4371
self.add_cleanup(local_branch.unlock)
4372
# handle race conditions - a parent might be set while we run.
4373
if local_branch.get_parent() is None:
4374
local_branch.set_parent(remote_branch.base)
3531
# handle race conditions - a parent might be set while we run.
3532
if local_branch.get_parent() is None:
3533
local_branch.set_parent(remote_branch.base)
3535
local_branch.unlock()
4375
3536
return status_code
4813
3973
Option('allow-writes',
4814
3974
help='By default the server is a readonly server. Supplying '
4815
3975
'--allow-writes enables write access to the contents of '
4816
'the served directory and below. Note that ``bzr serve`` '
4817
'does not perform authentication, so unless some form of '
4818
'external authentication is arranged supplying this '
4819
'option leads to global uncontrolled write access to your '
3976
'the served directory and below.'
4824
def get_host_and_port(self, port):
4825
"""Return the host and port to run the smart server on.
4827
If 'port' is None, None will be returned for the host and port.
4829
If 'port' has a colon in it, the string before the colon will be
4830
interpreted as the host.
4832
:param port: A string of the port to run the server on.
4833
:return: A tuple of (host, port), where 'host' is a host name or IP,
4834
and port is an integer TCP/IP port.
4837
if port is not None:
4839
host, port = port.split(':')
4843
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4845
from bzrlib.transport import get_transport, transport_server_registry
3980
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3981
from bzrlib import lockdir
3982
from bzrlib.smart import medium, server
3983
from bzrlib.transport import get_transport
3984
from bzrlib.transport.chroot import ChrootServer
4846
3985
if directory is None:
4847
3986
directory = os.getcwd()
4848
if protocol is None:
4849
protocol = transport_server_registry.get()
4850
host, port = self.get_host_and_port(port)
4851
3987
url = urlutils.local_path_to_url(directory)
4852
3988
if not allow_writes:
4853
3989
url = 'readonly+' + url
4854
transport = get_transport(url)
4855
protocol(transport, host, port, inet)
3990
chroot_server = ChrootServer(get_transport(url))
3991
chroot_server.setUp()
3992
t = get_transport(chroot_server.get_url())
3994
smart_server = medium.SmartServerPipeStreamMedium(
3995
sys.stdin, sys.stdout, t)
3997
host = medium.BZR_DEFAULT_INTERFACE
3999
port = medium.BZR_DEFAULT_PORT
4002
host, port = port.split(':')
4004
smart_server = server.SmartTCPServer(t, host=host, port=port)
4005
print 'listening on port: ', smart_server.port
4007
# for the duration of this server, no UI output is permitted.
4008
# note that this may cause problems with blackbox tests. This should
4009
# be changed with care though, as we dont want to use bandwidth sending
4010
# progress over stderr to smart server clients!
4011
old_factory = ui.ui_factory
4012
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
4014
ui.ui_factory = ui.SilentUIFactory()
4015
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
4016
smart_server.serve()
4018
ui.ui_factory = old_factory
4019
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4858
4022
class cmd_join(Command):
4859
"""Combine a tree into its containing tree.
4861
This command requires the target tree to be in a rich-root format.
4023
"""Combine a subtree into its containing tree.
4025
This command is for experimental use only. It requires the target tree
4026
to be in dirstate-with-subtree format, which cannot be converted into
4863
4029
The TREE argument should be an independent tree, inside another tree, but
4864
4030
not part of it. (Such trees can be produced by "bzr split", but also by
5039
4212
directly from the merge directive, without retrieving data from a
5042
`bzr send` creates a compact data set that, when applied using bzr
5043
merge, has the same effect as merging from the source branch.
5045
By default the merge directive is self-contained and can be applied to any
5046
branch containing submit_branch in its ancestory without needing access to
5049
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5050
revisions, but only a structured request to merge from the
5051
public_location. In that case the public_branch is needed and it must be
5052
up-to-date and accessible to the recipient. The public_branch is always
5053
included if known, so that people can check it later.
5055
The submit branch defaults to the parent of the source branch, but can be
5056
overridden. Both submit branch and public branch will be remembered in
5057
branch.conf the first time they are used for a particular branch. The
5058
source branch defaults to that containing the working directory, but can
5059
be changed using --from.
5061
In order to calculate those changes, bzr must analyse the submit branch.
5062
Therefore it is most efficient for the submit branch to be a local mirror.
5063
If a public location is known for the submit_branch, that location is used
5064
in the merge directive.
5066
The default behaviour is to send the merge directive by mail, unless -o is
5067
given, in which case it is sent to a file.
4215
If --no-bundle is specified, then public_branch is needed (and must be
4216
up-to-date), so that the receiver can perform the merge using the
4217
public_branch. The public_branch is always included if known, so that
4218
people can check it later.
4220
The submit branch defaults to the parent, but can be overridden. Both
4221
submit branch and public branch will be remembered if supplied.
4223
If a public_branch is known for the submit_branch, that public submit
4224
branch is used in the merge instructions. This means that a local mirror
4225
can be used as your actual submit branch, once you have set public_branch
5069
4228
Mail is sent using your preferred mail program. This should be transparent
5070
4229
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5071
4230
If the preferred client can't be found (or used), your editor will be used.
5073
4232
To use a specific mail program, set the mail_client configuration option.
5074
4233
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5075
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5076
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5077
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
4234
specific clients are "evolution", "kmail", "mutt", and "thunderbird";
4235
generic options are "default", "editor", "emacsclient", "mapi", and
4236
"xdg-email". Plugins may also add supported clients.
5080
4238
If mail is being sent, a to address is required. This can be supplied
5081
4239
either on the commandline, by setting the submit_to configuration
5082
option in the branch itself or the child_submit_to configuration option
4240
option in the branch itself or the child_submit_to configuration option
5083
4241
in the submit branch.
5085
4243
Two formats are currently supported: "4" uses revision bundle format 4 and
5118
4271
help='Write merge directive to this file; '
5119
4272
'use - for stdout.',
5122
help='Refuse to send if there are uncommitted changes in'
5123
' the working tree, --no-strict disables the check.'),
5124
4274
Option('mail-to', help='Mail the request to this address.',
5128
Option('body', help='Body for the email.', type=unicode),
5129
RegistryOption('format',
5130
help='Use the specified output format.',
5131
lazy_registry=('bzrlib.send', 'format_registry')),
4278
RegistryOption.from_kwargs('format',
4279
'Use the specified output format.',
4280
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4281
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5134
4284
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5135
4285
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,
4286
format='4', mail_to=None, message=None, **kwargs):
4287
return self._run(submit_branch, revision, public_branch, remember,
4288
format, no_bundle, no_patch, output,
4289
kwargs.get('from', '.'), mail_to, message)
4291
def _run(self, submit_branch, revision, public_branch, remember, format,
4292
no_bundle, no_patch, output, from_, mail_to, message):
4293
from bzrlib.revision import NULL_REVISION
4294
branch = Branch.open_containing(from_)[0]
4296
outfile = cStringIO.StringIO()
4300
outfile = open(output, 'wb')
4301
# we may need to write data into branch's repository to calculate
4306
config = branch.get_config()
4308
mail_to = config.get_user_option('submit_to')
4309
mail_client = config.get_mail_client()
4310
if remember and submit_branch is None:
4311
raise errors.BzrCommandError(
4312
'--remember requires a branch to be specified.')
4313
stored_submit_branch = branch.get_submit_branch()
4314
remembered_submit_branch = None
4315
if submit_branch is None:
4316
submit_branch = stored_submit_branch
4317
remembered_submit_branch = "submit"
4319
if stored_submit_branch is None or remember:
4320
branch.set_submit_branch(submit_branch)
4321
if submit_branch is None:
4322
submit_branch = branch.get_parent()
4323
remembered_submit_branch = "parent"
4324
if submit_branch is None:
4325
raise errors.BzrCommandError('No submit branch known or'
4327
if remembered_submit_branch is not None:
4328
note('Using saved %s location "%s" to determine what '
4329
'changes to submit.', remembered_submit_branch,
4333
submit_config = Branch.open(submit_branch).get_config()
4334
mail_to = submit_config.get_user_option("child_submit_to")
4336
stored_public_branch = branch.get_public_branch()
4337
if public_branch is None:
4338
public_branch = stored_public_branch
4339
elif stored_public_branch is None or remember:
4340
branch.set_public_branch(public_branch)
4341
if no_bundle and public_branch is None:
4342
raise errors.BzrCommandError('No public branch specified or'
4344
base_revision_id = None
4346
if revision is not None:
4347
if len(revision) > 2:
4348
raise errors.BzrCommandError('bzr send takes '
4349
'at most two one revision identifiers')
4350
revision_id = revision[-1].as_revision_id(branch)
4351
if len(revision) == 2:
4352
base_revision_id = revision[0].as_revision_id(branch)
4353
if revision_id is None:
4354
revision_id = branch.last_revision()
4355
if revision_id == NULL_REVISION:
4356
raise errors.BzrCommandError('No revisions to submit.')
4358
directive = merge_directive.MergeDirective2.from_objects(
4359
branch.repository, revision_id, time.time(),
4360
osutils.local_time_offset(), submit_branch,
4361
public_branch=public_branch, include_patch=not no_patch,
4362
include_bundle=not no_bundle, message=message,
4363
base_revision_id=base_revision_id)
4364
elif format == '0.9':
4367
patch_type = 'bundle'
4369
raise errors.BzrCommandError('Format 0.9 does not'
4370
' permit bundle with no patch')
4376
directive = merge_directive.MergeDirective.from_objects(
4377
branch.repository, revision_id, time.time(),
4378
osutils.local_time_offset(), submit_branch,
4379
public_branch=public_branch, patch_type=patch_type,
4382
outfile.writelines(directive.to_lines())
4384
subject = '[MERGE] '
4385
if message is not None:
4388
revision = branch.repository.get_revision(revision_id)
4389
subject += revision.get_summary()
4390
basename = directive.get_disk_name(branch)
4391
mail_client.compose_merge_request(mail_to, subject,
4392
outfile.getvalue(), basename)
5146
4399
class cmd_bundle_revisions(cmd_send):
5147
"""Create a merge-directive for submitting changes.
4401
"""Create a merge-directive for submiting changes.
5149
4403
A merge directive provides many things needed for requesting merges:
5368
4599
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5369
4600
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.',
4601
takes_options = [RegistryOption.from_kwargs('target_type',
4602
title='Target type',
4603
help='The type to reconfigure the directory to.',
4604
value_switches=True, enum_switch=False,
4605
branch='Reconfigure to be an unbound branch '
4606
'with no working tree.',
4607
tree='Reconfigure to be an unbound branch '
4608
'with a working tree.',
4609
checkout='Reconfigure to be a bound branch '
4610
'with a working tree.',
4611
lightweight_checkout='Reconfigure to be a lightweight'
4612
' checkout (with no local history).',
4613
standalone='Reconfigure to be a standalone branch '
4614
'(i.e. stop using shared repository).',
4615
use_shared='Reconfigure to use a shared repository.'),
4616
Option('bind-to', help='Branch to bind checkout to.',
4619
help='Perform reconfiguration even if local changes'
5403
def run(self, location=None, target_type=None, bind_to=None, force=False,
4623
def run(self, location=None, target_type=None, bind_to=None, force=False):
5406
4624
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
4625
if target_type is None:
5417
if stacked_on or unstacked:
5420
raise errors.BzrCommandError('No target configuration '
4626
raise errors.BzrCommandError('No target configuration specified')
5422
4627
elif target_type == 'branch':
5423
4628
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5424
4629
elif target_type == 'tree':
5425
4630
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5426
4631
elif target_type == 'checkout':
5427
reconfiguration = reconfigure.Reconfigure.to_checkout(
4632
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
5429
4634
elif target_type == 'lightweight-checkout':
5430
4635
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5431
4636
directory, bind_to)
5459
4658
directory of the current branch. For example, if you are currently in a
5460
4659
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5461
4660
/path/to/newbranch.
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?']
4663
takes_args = ['to_location']
5469
4664
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.'),
4665
help='Switch even if local commits will be lost.')
5477
def run(self, to_location=None, force=False, create_branch=False,
4668
def run(self, to_location, force=False):
5479
4669
from bzrlib import switch
5480
4670
tree_location = '.'
5481
revision = _get_one_revision('switch', revision)
5482
4671
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()
4673
to_branch = Branch.open(to_location)
5491
4674
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
4675
this_branch = control_dir.open_branch()
5527
4676
# 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
4677
this_url = this_branch.get_bound_location()
5531
4678
# 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))
4679
if this_url is None:
4680
this_url = this_branch.base
4681
to_branch = Branch.open(
4682
urlutils.join(this_url, '..', to_location))
4683
switch.switch(control_dir, to_branch, force)
4684
note('Switched to branch: %s',
4685
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5695
4688
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()
4689
"""Show a branch's currently registered hooks.
4693
takes_args = ['path?']
4695
def run(self, path=None):
5878
4696
if path is None:
5879
info = branch._get_all_reference_info().iteritems()
5880
self._display_reference_info(tree, branch, info)
4698
branch_hooks = Branch.open(path).hooks
4699
for hook_type in branch_hooks:
4700
hooks = branch_hooks[hook_type]
4701
self.outf.write("%s:\n" % (hook_type,))
4704
self.outf.write(" %s\n" %
4705
(branch_hooks.get_hook_name(hook),))
4707
self.outf.write(" <no hooks installed>\n")
4710
def _create_prefix(cur_transport):
4711
needed = [cur_transport]
4712
# Recurse upwards until we can create a directory successfully
4714
new_transport = cur_transport.clone('..')
4715
if new_transport.base == cur_transport.base:
4716
raise errors.BzrCommandError(
4717
"Failed to create path prefix for %s."
4718
% cur_transport.base)
4720
new_transport.mkdir('.')
4721
except errors.NoSuchFile:
4722
needed.append(new_transport)
4723
cur_transport = new_transport
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))
4726
# Now we only need to create child directories
4728
cur_transport = needed.pop()
4729
cur_transport.ensure_base()
5903
4732
# these get imported and then picked up by the scan for cmd_*
5904
4733
# 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
4734
# we do need to load at least some information about them to know of
5906
4735
# aliases. ideally we would avoid loading the implementation until the
5907
4736
# details were needed.
5908
4737
from bzrlib.cmd_version_info import cmd_version_info