240
362
' --revision or a revision_id')
241
363
b = WorkingTree.open_containing(u'.')[0].branch
243
# TODO: jam 20060112 should cat-revision always output utf-8?
244
if revision_id is not None:
245
revision_id = osutils.safe_revision_id(revision_id, warn=False)
365
revisions = b.repository.revisions
366
if revisions is None:
367
raise errors.BzrCommandError('Repository %r does not support '
368
'access to raw revision texts')
370
b.repository.lock_read()
372
# TODO: jam 20060112 should cat-revision always output utf-8?
373
if revision_id is not None:
374
revision_id = osutils.safe_revision_id(revision_id, warn=False)
376
self.print_revision(revisions, revision_id)
377
except errors.NoSuchRevision:
378
msg = "The repository %s contains no revision %s." % (
379
b.repository.base, revision_id)
380
raise errors.BzrCommandError(msg)
381
elif revision is not None:
384
raise errors.BzrCommandError(
385
'You cannot specify a NULL revision.')
386
rev_id = rev.as_revision_id(b)
387
self.print_revision(revisions, rev_id)
389
b.repository.unlock()
392
class cmd_dump_btree(Command):
393
"""Dump the contents of a btree index file to stdout.
395
PATH is a btree index file, it can be any URL. This includes things like
396
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
398
By default, the tuples stored in the index file will be displayed. With
399
--raw, we will uncompress the pages, but otherwise display the raw bytes
403
# TODO: Do we want to dump the internal nodes as well?
404
# TODO: It would be nice to be able to dump the un-parsed information,
405
# rather than only going through iter_all_entries. However, this is
406
# good enough for a start
408
encoding_type = 'exact'
409
takes_args = ['path']
410
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
411
' rather than the parsed tuples.'),
414
def run(self, path, raw=False):
415
dirname, basename = osutils.split(path)
416
t = transport.get_transport(dirname)
418
self._dump_raw_bytes(t, basename)
420
self._dump_entries(t, basename)
422
def _get_index_and_bytes(self, trans, basename):
423
"""Create a BTreeGraphIndex and raw bytes."""
424
bt = btree_index.BTreeGraphIndex(trans, basename, None)
425
bytes = trans.get_bytes(basename)
426
bt._file = cStringIO.StringIO(bytes)
427
bt._size = len(bytes)
430
def _dump_raw_bytes(self, trans, basename):
433
# We need to parse at least the root node.
434
# This is because the first page of every row starts with an
435
# uncompressed header.
436
bt, bytes = self._get_index_and_bytes(trans, basename)
437
for page_idx, page_start in enumerate(xrange(0, len(bytes),
438
btree_index._PAGE_SIZE)):
439
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
440
page_bytes = bytes[page_start:page_end]
442
self.outf.write('Root node:\n')
443
header_end, data = bt._parse_header_from_bytes(page_bytes)
444
self.outf.write(page_bytes[:header_end])
446
self.outf.write('\nPage %d\n' % (page_idx,))
447
decomp_bytes = zlib.decompress(page_bytes)
448
self.outf.write(decomp_bytes)
449
self.outf.write('\n')
451
def _dump_entries(self, trans, basename):
453
st = trans.stat(basename)
454
except errors.TransportNotPossible:
455
# We can't stat, so we'll fake it because we have to do the 'get()'
457
bt, _ = self._get_index_and_bytes(trans, basename)
459
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
460
for node in bt.iter_all_entries():
461
# Node is made up of:
462
# (index, key, value, [references])
247
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
248
except errors.NoSuchRevision:
249
msg = "The repository %s contains no revision %s." % (b.repository.base,
251
raise errors.BzrCommandError(msg)
252
elif revision is not None:
255
raise errors.BzrCommandError('You cannot specify a NULL'
257
rev_id = rev.as_revision_id(b)
258
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
466
refs_as_tuples = None
468
refs_as_tuples = static_tuple.as_tuples(refs)
469
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
470
self.outf.write('%s\n' % (as_tuple,))
261
473
class cmd_remove_tree(Command):
262
474
"""Remove the working tree from a given branch/checkout.
593
864
into_existing = False
595
866
inv = tree.inventory
596
from_id = tree.path2id(rel_names[0])
867
# 'fix' the case of a potential 'from'
868
from_id = tree.path2id(
869
tree.get_canonical_inventory_path(rel_names[0]))
597
870
if (not osutils.lexists(names_list[0]) and
598
871
from_id and inv.get_file_kind(from_id) == "directory"):
599
872
into_existing = False
601
874
if into_existing:
602
875
# move into existing directory
603
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
604
self.outf.write("%s => %s\n" % pair)
876
# All entries reference existing inventory items, so fix them up
877
# for cicp file-systems.
878
rel_names = tree.get_canonical_inventory_paths(rel_names)
879
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
881
self.outf.write("%s => %s\n" % (src, dest))
606
883
if len(names_list) != 2:
607
884
raise errors.BzrCommandError('to mv multiple files the'
608
885
' destination must be a versioned'
610
tree.rename_one(rel_names[0], rel_names[1], after=after)
611
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
888
# for cicp file-systems: the src references an existing inventory
890
src = tree.get_canonical_inventory_path(rel_names[0])
891
# Find the canonical version of the destination: In all cases, the
892
# parent of the target must be in the inventory, so we fetch the
893
# canonical version from there (we do not always *use* the
894
# canonicalized tail portion - we may be attempting to rename the
896
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
897
dest_parent = osutils.dirname(canon_dest)
898
spec_tail = osutils.basename(rel_names[1])
899
# For a CICP file-system, we need to avoid creating 2 inventory
900
# entries that differ only by case. So regardless of the case
901
# we *want* to use (ie, specified by the user or the file-system),
902
# we must always choose to use the case of any existing inventory
903
# items. The only exception to this is when we are attempting a
904
# case-only rename (ie, canonical versions of src and dest are
906
dest_id = tree.path2id(canon_dest)
907
if dest_id is None or tree.path2id(src) == dest_id:
908
# No existing item we care about, so work out what case we
909
# are actually going to use.
911
# If 'after' is specified, the tail must refer to a file on disk.
913
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
915
# pathjoin with an empty tail adds a slash, which breaks
917
dest_parent_fq = tree.basedir
919
dest_tail = osutils.canonical_relpath(
921
osutils.pathjoin(dest_parent_fq, spec_tail))
923
# not 'after', so case as specified is used
924
dest_tail = spec_tail
926
# Use the existing item so 'mv' fails with AlreadyVersioned.
927
dest_tail = os.path.basename(canon_dest)
928
dest = osutils.pathjoin(dest_parent, dest_tail)
929
mutter("attempting to move %s => %s", src, dest)
930
tree.rename_one(src, dest, after=after)
932
self.outf.write("%s => %s\n" % (src, dest))
614
935
class cmd_pull(Command):
615
936
"""Turn this branch into a mirror of another branch.
617
This command only works on branches that have not diverged. Branches are
618
considered diverged if the destination branch's most recent commit is one
619
that has not been merged (directly or indirectly) into the parent.
938
By default, this command only works on branches that have not diverged.
939
Branches are considered diverged if the destination branch's most recent
940
commit is one that has not been merged (directly or indirectly) into the
621
943
If branches have diverged, you can use 'bzr merge' to integrate the changes
622
944
from one into the other. Once one branch has merged, the other should
623
945
be able to pull it again.
625
If you want to forget your local changes and just update your branch to
626
match the remote one, use pull --overwrite.
947
If you want to replace your local changes and just want your branch to
948
match the remote one, use pull --overwrite. This will work even if the two
949
branches have diverged.
628
951
If there is no default location set, the first pull will set it. After
629
952
that, you can omit the location to use the default. To change the
857
1190
takes_args = ['from_location', 'to_location?']
858
1191
takes_options = ['revision', Option('hardlink',
859
1192
help='Hard-link working tree files where possible.'),
1194
help="Create a branch without a working-tree."),
1196
help="Switch the checkout in the current directory "
1197
"to the new branch."),
860
1198
Option('stacked',
861
1199
help='Create a stacked branch referring to the source branch. '
862
1200
'The new branch will depend on the availability of the source '
863
1201
'branch for all operations.'),
864
1202
Option('standalone',
865
1203
help='Do not use a shared repository, even if available.'),
1204
Option('use-existing-dir',
1205
help='By default branch will fail if the target'
1206
' directory exists, but does not already'
1207
' have a control directory. This flag will'
1208
' allow branch to proceed.'),
1210
help="Bind new branch to from location."),
867
1212
aliases = ['get', 'clone']
869
1214
def run(self, from_location, to_location=None, revision=None,
870
hardlink=False, stacked=False, standalone=False):
1215
hardlink=False, stacked=False, standalone=False, no_tree=False,
1216
use_existing_dir=False, switch=False, bind=False):
1217
from bzrlib import switch as _mod_switch
871
1218
from bzrlib.tag import _merge_tags_if_possible
874
elif len(revision) > 1:
875
raise errors.BzrCommandError(
876
'bzr branch --revision takes exactly 1 revision value')
878
1219
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1221
revision = _get_one_revision('branch', revision)
880
1222
br_from.lock_read()
1223
self.add_cleanup(br_from.unlock)
1224
if revision is not None:
1225
revision_id = revision.as_revision_id(br_from)
1227
# FIXME - wt.last_revision, fallback to branch, fall back to
1228
# None or perhaps NULL_REVISION to mean copy nothing
1230
revision_id = br_from.last_revision()
1231
if to_location is None:
1232
to_location = urlutils.derive_to_location(from_location)
1233
to_transport = transport.get_transport(to_location)
882
if len(revision) == 1 and revision[0] is not None:
883
revision_id = revision[0].as_revision_id(br_from)
1235
to_transport.mkdir('.')
1236
except errors.FileExists:
1237
if not use_existing_dir:
1238
raise errors.BzrCommandError('Target directory "%s" '
1239
'already exists.' % to_location)
885
# FIXME - wt.last_revision, fallback to branch, fall back to
886
# None or perhaps NULL_REVISION to mean copy nothing
888
revision_id = br_from.last_revision()
889
if to_location is None:
890
to_location = urlutils.derive_to_location(from_location)
891
to_transport = transport.get_transport(to_location)
893
to_transport.mkdir('.')
894
except errors.FileExists:
895
raise errors.BzrCommandError('Target directory "%s" already'
896
' exists.' % to_location)
897
except errors.NoSuchFile:
898
raise errors.BzrCommandError('Parent of "%s" does not exist.'
901
# preserve whatever source format we have.
902
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
903
possible_transports=[to_transport],
904
accelerator_tree=accelerator_tree,
905
hardlink=hardlink, stacked=stacked,
906
force_new_repo=standalone)
907
branch = dir.open_branch()
908
except errors.NoSuchRevision:
909
to_transport.delete_tree('.')
910
msg = "The branch %s has no revision %s." % (from_location,
912
raise errors.BzrCommandError(msg)
913
_merge_tags_if_possible(br_from, branch)
914
# If the source branch is stacked, the new branch may
915
# be stacked whether we asked for that explicitly or not.
916
# We therefore need a try/except here and not just 'if stacked:'
918
note('Created new stacked branch referring to %s.' %
919
branch.get_stacked_on_url())
920
except (errors.NotStacked, errors.UnstackableBranchFormat,
921
errors.UnstackableRepositoryFormat), e:
922
note('Branched %d revision(s).' % branch.revno())
1242
bzrdir.BzrDir.open_from_transport(to_transport)
1243
except errors.NotBranchError:
1246
raise errors.AlreadyBranchError(to_location)
1247
except errors.NoSuchFile:
1248
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1251
# preserve whatever source format we have.
1252
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1253
possible_transports=[to_transport],
1254
accelerator_tree=accelerator_tree,
1255
hardlink=hardlink, stacked=stacked,
1256
force_new_repo=standalone,
1257
create_tree_if_local=not no_tree,
1258
source_branch=br_from)
1259
branch = dir.open_branch()
1260
except errors.NoSuchRevision:
1261
to_transport.delete_tree('.')
1262
msg = "The branch %s has no revision %s." % (from_location,
1264
raise errors.BzrCommandError(msg)
1265
_merge_tags_if_possible(br_from, branch)
1266
# If the source branch is stacked, the new branch may
1267
# be stacked whether we asked for that explicitly or not.
1268
# We therefore need a try/except here and not just 'if stacked:'
1270
note('Created new stacked branch referring to %s.' %
1271
branch.get_stacked_on_url())
1272
except (errors.NotStacked, errors.UnstackableBranchFormat,
1273
errors.UnstackableRepositoryFormat), e:
1274
note('Branched %d revision(s).' % branch.revno())
1276
# Bind to the parent
1277
parent_branch = Branch.open(from_location)
1278
branch.bind(parent_branch)
1279
note('New branch bound to %s' % from_location)
1281
# Switch to the new branch
1282
wt, _ = WorkingTree.open_containing('.')
1283
_mod_switch.switch(wt.bzrdir, branch)
1284
note('Switched to branch: %s',
1285
urlutils.unescape_for_display(branch.base, 'utf-8'))
927
1288
class cmd_checkout(Command):
1010
1367
def run(self, dir=u'.'):
1011
1368
tree = WorkingTree.open_containing(dir)[0]
1012
1369
tree.lock_read()
1014
new_inv = tree.inventory
1015
old_tree = tree.basis_tree()
1016
old_tree.lock_read()
1018
old_inv = old_tree.inventory
1019
renames = list(_mod_tree.find_renames(old_inv, new_inv))
1021
for old_name, new_name in renames:
1022
self.outf.write("%s => %s\n" % (old_name, new_name))
1370
self.add_cleanup(tree.unlock)
1371
new_inv = tree.inventory
1372
old_tree = tree.basis_tree()
1373
old_tree.lock_read()
1374
self.add_cleanup(old_tree.unlock)
1375
old_inv = old_tree.inventory
1377
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1378
for f, paths, c, v, p, n, k, e in iterator:
1379
if paths[0] == paths[1]:
1383
renames.append(paths)
1385
for old_name, new_name in renames:
1386
self.outf.write("%s => %s\n" % (old_name, new_name))
1029
1389
class cmd_update(Command):
1030
1390
"""Update a tree to have the latest code committed to its branch.
1032
1392
This will perform a merge into the working tree, and may generate
1033
conflicts. If you have any local changes, you will still
1393
conflicts. If you have any local changes, you will still
1034
1394
need to commit them after the update for the update to be complete.
1036
If you want to discard your local changes, you can just do a
1396
If you want to discard your local changes, you can just do a
1037
1397
'bzr revert' instead of 'bzr commit' after the update.
1399
If the tree's branch is bound to a master branch, it will also update
1400
the branch from the master.
1040
1403
_see_also = ['pull', 'working-trees', 'status-flags']
1041
1404
takes_args = ['dir?']
1405
takes_options = ['revision']
1042
1406
aliases = ['up']
1044
def run(self, dir='.'):
1408
def run(self, dir='.', revision=None):
1409
if revision is not None and len(revision) != 1:
1410
raise errors.BzrCommandError(
1411
"bzr update --revision takes exactly one revision")
1045
1412
tree = WorkingTree.open_containing(dir)[0]
1413
branch = tree.branch
1046
1414
possible_transports = []
1047
master = tree.branch.get_master_branch(
1415
master = branch.get_master_branch(
1048
1416
possible_transports=possible_transports)
1049
1417
if master is not None:
1050
1418
tree.lock_write()
1419
branch_location = master.base
1052
1421
tree.lock_tree_write()
1422
branch_location = tree.branch.base
1423
self.add_cleanup(tree.unlock)
1424
# get rid of the final '/' and be ready for display
1425
branch_location = urlutils.unescape_for_display(
1426
branch_location.rstrip('/'),
1428
existing_pending_merges = tree.get_parent_ids()[1:]
1432
# may need to fetch data into a heavyweight checkout
1433
# XXX: this may take some time, maybe we should display a
1435
old_tip = branch.update(possible_transports)
1436
if revision is not None:
1437
revision_id = revision[0].as_revision_id(branch)
1439
revision_id = branch.last_revision()
1440
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1441
revno = branch.revision_id_to_dotted_revno(revision_id)
1442
note("Tree is up to date at revision %s of branch %s" %
1443
('.'.join(map(str, revno)), branch_location))
1445
view_info = _get_view_info_for_change_reporter(tree)
1446
change_reporter = delta._ChangeReporter(
1447
unversioned_filter=tree.is_ignored,
1448
view_info=view_info)
1054
existing_pending_merges = tree.get_parent_ids()[1:]
1055
last_rev = _mod_revision.ensure_null(tree.last_revision())
1056
if last_rev == _mod_revision.ensure_null(
1057
tree.branch.last_revision()):
1058
# may be up to date, check master too.
1059
if master is None or last_rev == _mod_revision.ensure_null(
1060
master.last_revision()):
1061
revno = tree.branch.revision_id_to_revno(last_rev)
1062
note("Tree is up to date at revision %d." % (revno,))
1064
1450
conflicts = tree.update(
1065
delta._ChangeReporter(unversioned_filter=tree.is_ignored),
1066
possible_transports=possible_transports)
1067
revno = tree.branch.revision_id_to_revno(
1068
_mod_revision.ensure_null(tree.last_revision()))
1069
note('Updated to revision %d.' % (revno,))
1070
if tree.get_parent_ids()[1:] != existing_pending_merges:
1071
note('Your local commits will now show as pending merges with '
1072
"'bzr status', and can be committed with 'bzr commit'.")
1452
possible_transports=possible_transports,
1453
revision=revision_id,
1455
except errors.NoSuchRevision, e:
1456
raise errors.BzrCommandError(
1457
"branch has no revision %s\n"
1458
"bzr update --revision only works"
1459
" for a revision in the branch history"
1461
revno = tree.branch.revision_id_to_dotted_revno(
1462
_mod_revision.ensure_null(tree.last_revision()))
1463
note('Updated to revision %s of branch %s' %
1464
('.'.join(map(str, revno)), branch_location))
1465
parent_ids = tree.get_parent_ids()
1466
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1467
note('Your local commits will now show as pending merges with '
1468
"'bzr status', and can be committed with 'bzr commit'.")
1081
1475
class cmd_info(Command):
1082
1476
"""Show information about a working tree, branch or repository.
1084
1478
This command will show all known locations and formats associated to the
1085
tree, branch or repository. Statistical information is included with
1479
tree, branch or repository.
1481
In verbose mode, statistical information is included with each report.
1482
To see extended statistic information, use a verbosity level of 2 or
1483
higher by specifying the verbose option multiple times, e.g. -vv.
1088
1485
Branches and working trees will also report any missing revisions.
1489
Display information on the format and related locations:
1493
Display the above together with extended format information and
1494
basic statistics (like the number of files in the working tree and
1495
number of revisions in the branch and repository):
1499
Display the above together with number of committers to the branch:
1090
1503
_see_also = ['revno', 'working-trees', 'repositories']
1091
1504
takes_args = ['location?']
1653
2103
raise errors.BzrCommandError(msg)
2106
def _parse_levels(s):
2110
msg = "The levels argument must be an integer."
2111
raise errors.BzrCommandError(msg)
1656
2114
class cmd_log(Command):
1657
"""Show log of a branch, file, or directory.
1659
By default show the log of the branch containing the working directory.
1661
To request a range of logs, you can use the command -r begin..end
1662
-r revision requests a specific revision, -r ..end or -r begin.. are
1666
Log the current branch::
1674
Log the last 10 revisions of a branch::
1676
bzr log -r -10.. http://server/branch
2115
"""Show historical log for a branch or subset of a branch.
2117
log is bzr's default tool for exploring the history of a branch.
2118
The branch to use is taken from the first parameter. If no parameters
2119
are given, the branch containing the working directory is logged.
2120
Here are some simple examples::
2122
bzr log log the current branch
2123
bzr log foo.py log a file in its branch
2124
bzr log http://server/branch log a branch on a server
2126
The filtering, ordering and information shown for each revision can
2127
be controlled as explained below. By default, all revisions are
2128
shown sorted (topologically) so that newer revisions appear before
2129
older ones and descendants always appear before ancestors. If displayed,
2130
merged revisions are shown indented under the revision in which they
2135
The log format controls how information about each revision is
2136
displayed. The standard log formats are called ``long``, ``short``
2137
and ``line``. The default is long. See ``bzr help log-formats``
2138
for more details on log formats.
2140
The following options can be used to control what information is
2143
-l N display a maximum of N revisions
2144
-n N display N levels of revisions (0 for all, 1 for collapsed)
2145
-v display a status summary (delta) for each revision
2146
-p display a diff (patch) for each revision
2147
--show-ids display revision-ids (and file-ids), not just revnos
2149
Note that the default number of levels to display is a function of the
2150
log format. If the -n option is not used, the standard log formats show
2151
just the top level (mainline).
2153
Status summaries are shown using status flags like A, M, etc. To see
2154
the changes explained using words like ``added`` and ``modified``
2155
instead, use the -vv option.
2159
To display revisions from oldest to newest, use the --forward option.
2160
In most cases, using this option will have little impact on the total
2161
time taken to produce a log, though --forward does not incrementally
2162
display revisions like --reverse does when it can.
2164
:Revision filtering:
2166
The -r option can be used to specify what revision or range of revisions
2167
to filter against. The various forms are shown below::
2169
-rX display revision X
2170
-rX.. display revision X and later
2171
-r..Y display up to and including revision Y
2172
-rX..Y display from X to Y inclusive
2174
See ``bzr help revisionspec`` for details on how to specify X and Y.
2175
Some common examples are given below::
2177
-r-1 show just the tip
2178
-r-10.. show the last 10 mainline revisions
2179
-rsubmit:.. show what's new on this branch
2180
-rancestor:path.. show changes since the common ancestor of this
2181
branch and the one at location path
2182
-rdate:yesterday.. show changes since yesterday
2184
When logging a range of revisions using -rX..Y, log starts at
2185
revision Y and searches back in history through the primary
2186
("left-hand") parents until it finds X. When logging just the
2187
top level (using -n1), an error is reported if X is not found
2188
along the way. If multi-level logging is used (-n0), X may be
2189
a nested merge revision and the log will be truncated accordingly.
2193
If parameters are given and the first one is not a branch, the log
2194
will be filtered to show only those revisions that changed the
2195
nominated files or directories.
2197
Filenames are interpreted within their historical context. To log a
2198
deleted file, specify a revision range so that the file existed at
2199
the end or start of the range.
2201
Historical context is also important when interpreting pathnames of
2202
renamed files/directories. Consider the following example:
2204
* revision 1: add tutorial.txt
2205
* revision 2: modify tutorial.txt
2206
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2210
* ``bzr log guide.txt`` will log the file added in revision 1
2212
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2214
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2215
the original file in revision 2.
2217
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2218
was no file called guide.txt in revision 2.
2220
Renames are always followed by log. By design, there is no need to
2221
explicitly ask for this (and no way to stop logging a file back
2222
until it was last renamed).
2226
The --message option can be used for finding revisions that match a
2227
regular expression in a commit message.
2231
GUI tools and IDEs are often better at exploring history than command
2232
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2233
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2234
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2235
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2237
You may find it useful to add the aliases below to ``bazaar.conf``::
2241
top = log -l10 --line
2244
``bzr tip`` will then show the latest revision while ``bzr top``
2245
will show the last 10 mainline revisions. To see the details of a
2246
particular revision X, ``bzr show -rX``.
2248
If you are interested in looking deeper into a particular merge X,
2249
use ``bzr log -n0 -rX``.
2251
``bzr log -v`` on a branch with lots of history is currently
2252
very slow. A fix for this issue is currently under development.
2253
With or without that fix, it is recommended that a revision range
2254
be given when using the -v option.
2256
bzr has a generic full-text matching plugin, bzr-search, that can be
2257
used to find revisions matching user names, commit messages, etc.
2258
Among other features, this plugin can find all revisions containing
2259
a list of words but not others.
2261
When exploring non-mainline history on large projects with deep
2262
history, the performance of log can be greatly improved by installing
2263
the historycache plugin. This plugin buffers historical information
2264
trading disk space for faster speed.
1679
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1681
takes_args = ['location?']
2266
takes_args = ['file*']
2267
_see_also = ['log-formats', 'revisionspec']
1682
2268
takes_options = [
1683
2269
Option('forward',
1684
2270
help='Show from oldest to newest.'),
1687
help='Display timezone as local, original, or utc.'),
1688
2272
custom_help('verbose',
1689
2273
help='Show files changed in each revision.'),
1756
2368
dir, relpath = bzrdir.BzrDir.open_containing(location)
1757
2369
b = dir.open_branch()
1761
if revision is None:
1764
elif len(revision) == 1:
1765
rev1 = rev2 = revision[0].in_history(b)
1766
elif len(revision) == 2:
1767
if revision[1].get_branch() != revision[0].get_branch():
1768
# b is taken from revision[0].get_branch(), and
1769
# show_log will use its revision_history. Having
1770
# different branches will lead to weird behaviors.
1771
raise errors.BzrCommandError(
1772
"Log doesn't accept two revisions in different"
1774
rev1 = revision[0].in_history(b)
1775
rev2 = revision[1].in_history(b)
1777
raise errors.BzrCommandError(
1778
'bzr log --revision takes one or two values.')
1780
if log_format is None:
1781
log_format = log.log_formatter_registry.get_default(b)
1783
lf = log_format(show_ids=show_ids, to_file=self.outf,
1784
show_timezone=timezone)
1790
direction=direction,
1791
start_revision=rev1,
2371
self.add_cleanup(b.unlock)
2372
rev1, rev2 = _get_revision_range(revision, b, self.name())
2374
# Decide on the type of delta & diff filtering to use
2375
# TODO: add an --all-files option to make this configurable & consistent
2383
diff_type = 'partial'
2387
# Build the log formatter
2388
if log_format is None:
2389
log_format = log.log_formatter_registry.get_default(b)
2390
# Make a non-encoding output to include the diffs - bug 328007
2391
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2392
lf = log_format(show_ids=show_ids, to_file=self.outf,
2393
to_exact_file=unencoded_output,
2394
show_timezone=timezone,
2395
delta_format=get_verbosity_level(),
2397
show_advice=levels is None)
2399
# Choose the algorithm for doing the logging. It's annoying
2400
# having multiple code paths like this but necessary until
2401
# the underlying repository format is faster at generating
2402
# deltas or can provide everything we need from the indices.
2403
# The default algorithm - match-using-deltas - works for
2404
# multiple files and directories and is faster for small
2405
# amounts of history (200 revisions say). However, it's too
2406
# slow for logging a single file in a repository with deep
2407
# history, i.e. > 10K revisions. In the spirit of "do no
2408
# evil when adding features", we continue to use the
2409
# original algorithm - per-file-graph - for the "single
2410
# file that isn't a directory without showing a delta" case.
2411
partial_history = revision and b.repository._format.supports_chks
2412
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2413
or delta_type or partial_history)
2415
# Build the LogRequest and execute it
2416
if len(file_ids) == 0:
2418
rqst = make_log_request_dict(
2419
direction=direction, specific_fileids=file_ids,
2420
start_revision=rev1, end_revision=rev2, limit=limit,
2421
message_search=message, delta_type=delta_type,
2422
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2423
Logger(b, rqst).show(lf)
2426
def _get_revision_range(revisionspec_list, branch, command_name):
2427
"""Take the input of a revision option and turn it into a revision range.
2429
It returns RevisionInfo objects which can be used to obtain the rev_id's
2430
of the desired revisions. It does some user input validations.
2432
if revisionspec_list is None:
2435
elif len(revisionspec_list) == 1:
2436
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2437
elif len(revisionspec_list) == 2:
2438
start_spec = revisionspec_list[0]
2439
end_spec = revisionspec_list[1]
2440
if end_spec.get_branch() != start_spec.get_branch():
2441
# b is taken from revision[0].get_branch(), and
2442
# show_log will use its revision_history. Having
2443
# different branches will lead to weird behaviors.
2444
raise errors.BzrCommandError(
2445
"bzr %s doesn't accept two revisions in different"
2446
" branches." % command_name)
2447
if start_spec.spec is None:
2448
# Avoid loading all the history.
2449
rev1 = RevisionInfo(branch, None, None)
2451
rev1 = start_spec.in_history(branch)
2452
# Avoid loading all of history when we know a missing
2453
# end of range means the last revision ...
2454
if end_spec.spec is None:
2455
last_revno, last_revision_id = branch.last_revision_info()
2456
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2458
rev2 = end_spec.in_history(branch)
2460
raise errors.BzrCommandError(
2461
'bzr %s --revision takes one or two values.' % command_name)
2465
def _revision_range_to_revid_range(revision_range):
2468
if revision_range[0] is not None:
2469
rev_id1 = revision_range[0].rev_id
2470
if revision_range[1] is not None:
2471
rev_id2 = revision_range[1].rev_id
2472
return rev_id1, rev_id2
1799
2474
def get_log_format(long=False, short=False, line=False, default='long'):
1800
2475
log_format = default
2121
2851
If no revision is nominated, the last revision is used.
2123
2853
Note: Take care to redirect standard output when using this command on a
2127
2857
_see_also = ['ls']
2128
2858
takes_options = [
2129
2859
Option('name-from-revision', help='The path name in the old tree.'),
2860
Option('filters', help='Apply content filters to display the '
2861
'convenience form.'),
2132
2864
takes_args = ['filename']
2133
2865
encoding_type = 'exact'
2135
2867
@display_command
2136
def run(self, filename, revision=None, name_from_revision=False):
2868
def run(self, filename, revision=None, name_from_revision=False,
2137
2870
if revision is not None and len(revision) != 1:
2138
2871
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2139
2872
" one revision specifier")
2140
2873
tree, branch, relpath = \
2141
2874
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2142
2875
branch.lock_read()
2144
return self._run(tree, branch, relpath, filename, revision,
2876
self.add_cleanup(branch.unlock)
2877
return self._run(tree, branch, relpath, filename, revision,
2878
name_from_revision, filters)
2149
def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2880
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2150
2882
if tree is None:
2151
2883
tree = b.basis_tree()
2152
2884
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2885
rev_tree.lock_read()
2886
self.add_cleanup(rev_tree.unlock)
2154
cur_file_id = tree.path2id(relpath)
2155
2888
old_file_id = rev_tree.path2id(relpath)
2157
2890
if name_from_revision:
2891
# Try in revision if requested
2158
2892
if old_file_id is None:
2159
2893
raise errors.BzrCommandError(
2160
2894
"%r is not present in revision %s" % (
2161
2895
filename, rev_tree.get_revision_id()))
2163
2897
content = rev_tree.get_file_text(old_file_id)
2164
elif cur_file_id is not None:
2165
content = rev_tree.get_file_text(cur_file_id)
2166
elif old_file_id is not None:
2167
content = rev_tree.get_file_text(old_file_id)
2169
raise errors.BzrCommandError(
2170
"%r is not present in revision %s" % (
2171
filename, rev_tree.get_revision_id()))
2172
self.outf.write(content)
2899
cur_file_id = tree.path2id(relpath)
2901
if cur_file_id is not None:
2902
# Then try with the actual file id
2904
content = rev_tree.get_file_text(cur_file_id)
2906
except errors.NoSuchId:
2907
# The actual file id didn't exist at that time
2909
if not found and old_file_id is not None:
2910
# Finally try with the old file id
2911
content = rev_tree.get_file_text(old_file_id)
2914
# Can't be found anywhere
2915
raise errors.BzrCommandError(
2916
"%r is not present in revision %s" % (
2917
filename, rev_tree.get_revision_id()))
2919
from bzrlib.filters import (
2920
ContentFilterContext,
2921
filtered_output_bytes,
2923
filters = rev_tree._content_filter_stack(relpath)
2924
chunks = content.splitlines(True)
2925
content = filtered_output_bytes(chunks, filters,
2926
ContentFilterContext(relpath, rev_tree))
2928
self.outf.writelines(content)
2931
self.outf.write(content)
2175
2934
class cmd_local_time_offset(Command):
2176
2935
"""Show the offset in seconds from GMT to local time."""
2178
2937
@display_command
2180
print osutils.local_time_offset()
2939
self.outf.write("%s\n" % osutils.local_time_offset())
2184
2943
class cmd_commit(Command):
2185
2944
"""Commit changes into a new revision.
2187
If no arguments are given, the entire tree is committed.
2189
If selected files are specified, only changes to those files are
2190
committed. If a directory is specified then the directory and everything
2191
within it is committed.
2193
When excludes are given, they take precedence over selected files.
2194
For example, too commit only changes within foo, but not changes within
2197
bzr commit foo -x foo/bar
2199
If author of the change is not the same person as the committer, you can
2200
specify the author's name using the --author option. The name should be
2201
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2203
A selected-file commit may fail in some cases where the committed
2204
tree would be invalid. Consider::
2209
bzr commit foo -m "committing foo"
2210
bzr mv foo/bar foo/baz
2213
bzr commit foo/bar -m "committing bar but not baz"
2215
In the example above, the last commit will fail by design. This gives
2216
the user the opportunity to decide whether they want to commit the
2217
rename at the same time, separately first, or not at all. (As a general
2218
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2220
Note: A selected-file commit after a merge is not yet supported.
2946
An explanatory message needs to be given for each commit. This is
2947
often done by using the --message option (getting the message from the
2948
command line) or by using the --file option (getting the message from
2949
a file). If neither of these options is given, an editor is opened for
2950
the user to enter the message. To see the changed files in the
2951
boilerplate text loaded into the editor, use the --show-diff option.
2953
By default, the entire tree is committed and the person doing the
2954
commit is assumed to be the author. These defaults can be overridden
2959
If selected files are specified, only changes to those files are
2960
committed. If a directory is specified then the directory and
2961
everything within it is committed.
2963
When excludes are given, they take precedence over selected files.
2964
For example, to commit only changes within foo, but not changes
2967
bzr commit foo -x foo/bar
2969
A selective commit after a merge is not yet supported.
2973
If the author of the change is not the same person as the committer,
2974
you can specify the author's name using the --author option. The
2975
name should be in the same format as a committer-id, e.g.
2976
"John Doe <jdoe@example.com>". If there is more than one author of
2977
the change you can specify the option multiple times, once for each
2982
A common mistake is to forget to add a new file or directory before
2983
running the commit command. The --strict option checks for unknown
2984
files and aborts the commit if any are found. More advanced pre-commit
2985
checks can be implemented by defining hooks. See ``bzr help hooks``
2990
If you accidentially commit the wrong changes or make a spelling
2991
mistake in the commit message say, you can use the uncommit command
2992
to undo it. See ``bzr help uncommit`` for details.
2994
Hooks can also be configured to run after a commit. This allows you
2995
to trigger updates to external systems like bug trackers. The --fixes
2996
option can be used to record the association between a revision and
2997
one or more bugs. See ``bzr help bugs`` for details.
2999
A selective commit may fail in some cases where the committed
3000
tree would be invalid. Consider::
3005
bzr commit foo -m "committing foo"
3006
bzr mv foo/bar foo/baz
3009
bzr commit foo/bar -m "committing bar but not baz"
3011
In the example above, the last commit will fail by design. This gives
3012
the user the opportunity to decide whether they want to commit the
3013
rename at the same time, separately first, or not at all. (As a general
3014
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2222
3016
# TODO: Run hooks on tree to-be-committed, and after commit.
2316
3120
if fixes is None:
2318
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
3122
bug_property = bugtracker.encode_fixes_bug_urls(
3123
self._iter_bug_fix_urls(fixes, tree.branch))
2319
3124
if bug_property:
2320
3125
properties['bugs'] = bug_property
2322
3127
if local and not tree.branch.get_bound_location():
2323
3128
raise errors.LocalRequiresBoundBranch()
3130
if message is not None:
3132
file_exists = osutils.lexists(message)
3133
except UnicodeError:
3134
# The commit message contains unicode characters that can't be
3135
# represented in the filesystem encoding, so that can't be a
3140
'The commit message is a file name: "%(f)s".\n'
3141
'(use --file "%(f)s" to take commit message from that file)'
3143
ui.ui_factory.show_warning(warning_msg)
3145
message = message.replace('\r\n', '\n')
3146
message = message.replace('\r', '\n')
3148
raise errors.BzrCommandError(
3149
"please specify either --message or --file")
2325
3151
def get_message(commit_obj):
2326
3152
"""Callback to get commit message"""
2327
my_message = message
2328
if my_message is None and not file:
2329
t = make_commit_message_template_encoded(tree,
3154
my_message = codecs.open(
3155
file, 'rt', osutils.get_user_encoding()).read()
3156
elif message is not None:
3157
my_message = message
3159
# No message supplied: make one up.
3160
# text is the status of the tree
3161
text = make_commit_message_template_encoded(tree,
2330
3162
selected_list, diff=show_diff,
2331
output_encoding=bzrlib.user_encoding)
2332
my_message = edit_commit_message_encoded(t)
3163
output_encoding=osutils.get_user_encoding())
3164
# start_message is the template generated from hooks
3165
# XXX: Warning - looks like hooks return unicode,
3166
# make_commit_message_template_encoded returns user encoding.
3167
# We probably want to be using edit_commit_message instead to
3169
start_message = generate_commit_message_template(commit_obj)
3170
my_message = edit_commit_message_encoded(text,
3171
start_message=start_message)
2333
3172
if my_message is None:
2334
3173
raise errors.BzrCommandError("please specify a commit"
2335
3174
" message with either --message or --file")
2336
elif my_message and file:
2337
raise errors.BzrCommandError(
2338
"please specify either --message or --file")
2340
my_message = codecs.open(file, 'rt',
2341
bzrlib.user_encoding).read()
2342
3175
if my_message == "":
2343
3176
raise errors.BzrCommandError("empty commit message specified")
2344
3177
return my_message
3179
# The API permits a commit with a filter of [] to mean 'select nothing'
3180
# but the command line should not do that.
3181
if not selected_list:
3182
selected_list = None
2347
3184
tree.commit(message_callback=get_message,
2348
3185
specific_files=selected_list,
2349
3186
allow_pointless=unchanged, strict=strict, local=local,
2350
3187
reporter=None, verbose=verbose, revprops=properties,
3188
authors=author, timestamp=commit_stamp,
2352
3190
exclude=safe_relpath_files(tree, exclude))
2353
3191
except PointlessCommit:
2354
# FIXME: This should really happen before the file is read in;
2355
# perhaps prepare the commit; get the message; then actually commit
2356
raise errors.BzrCommandError("no changes to commit."
2357
" use --unchanged to commit anyhow")
3192
raise errors.BzrCommandError("No changes to commit."
3193
" Use --unchanged to commit anyhow.")
2358
3194
except ConflictsInTree:
2359
3195
raise errors.BzrCommandError('Conflicts detected in working '
2360
3196
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
2922
3798
allow_pending = True
2923
3799
verified = 'inapplicable'
2924
3800
tree = WorkingTree.open_containing(directory)[0]
3803
basis_tree = tree.revision_tree(tree.last_revision())
3804
except errors.NoSuchRevision:
3805
basis_tree = tree.basis_tree()
3807
# die as quickly as possible if there are uncommitted changes
3809
if tree.has_changes():
3810
raise errors.UncommittedChanges(tree)
3812
view_info = _get_view_info_for_change_reporter(tree)
2925
3813
change_reporter = delta._ChangeReporter(
2926
unversioned_filter=tree.is_ignored)
2929
pb = ui.ui_factory.nested_progress_bar()
2930
cleanups.append(pb.finished)
2932
cleanups.append(tree.unlock)
2933
if location is not None:
2935
mergeable = bundle.read_mergeable_from_url(location,
2936
possible_transports=possible_transports)
2937
except errors.NotABundle:
2941
raise errors.BzrCommandError('Cannot use --uncommitted'
2942
' with bundles or merge directives.')
2944
if revision is not None:
2945
raise errors.BzrCommandError(
2946
'Cannot use -r with merge directives or bundles')
2947
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2950
if merger is None and uncommitted:
2951
if revision is not None and len(revision) > 0:
2952
raise errors.BzrCommandError('Cannot use --uncommitted and'
2953
' --revision at the same time.')
2954
location = self._select_branch_location(tree, location)[0]
2955
other_tree, other_path = WorkingTree.open_containing(location)
2956
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2958
allow_pending = False
2959
if other_path != '':
2960
merger.interesting_files = [other_path]
2963
merger, allow_pending = self._get_merger_from_branch(tree,
2964
location, revision, remember, possible_transports, pb)
2966
merger.merge_type = merge_type
2967
merger.reprocess = reprocess
2968
merger.show_base = show_base
2969
self.sanity_check_merger(merger)
2970
if (merger.base_rev_id == merger.other_rev_id and
2971
merger.other_rev_id is not None):
2972
note('Nothing to do.')
3814
unversioned_filter=tree.is_ignored, view_info=view_info)
3815
pb = ui.ui_factory.nested_progress_bar()
3816
self.add_cleanup(pb.finished)
3818
self.add_cleanup(tree.unlock)
3819
if location is not None:
3821
mergeable = bundle.read_mergeable_from_url(location,
3822
possible_transports=possible_transports)
3823
except errors.NotABundle:
3827
raise errors.BzrCommandError('Cannot use --uncommitted'
3828
' with bundles or merge directives.')
3830
if revision is not None:
3831
raise errors.BzrCommandError(
3832
'Cannot use -r with merge directives or bundles')
3833
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3836
if merger is None and uncommitted:
3837
if revision is not None and len(revision) > 0:
3838
raise errors.BzrCommandError('Cannot use --uncommitted and'
3839
' --revision at the same time.')
3840
merger = self.get_merger_from_uncommitted(tree, location, None)
3841
allow_pending = False
3844
merger, allow_pending = self._get_merger_from_branch(tree,
3845
location, revision, remember, possible_transports, None)
3847
merger.merge_type = merge_type
3848
merger.reprocess = reprocess
3849
merger.show_base = show_base
3850
self.sanity_check_merger(merger)
3851
if (merger.base_rev_id == merger.other_rev_id and
3852
merger.other_rev_id is not None):
3853
note('Nothing to do.')
3856
if merger.interesting_files is not None:
3857
raise errors.BzrCommandError('Cannot pull individual files')
3858
if (merger.base_rev_id == tree.last_revision()):
3859
result = tree.pull(merger.other_branch, False,
3860
merger.other_rev_id)
3861
result.report(self.outf)
2975
if merger.interesting_files is not None:
2976
raise errors.BzrCommandError('Cannot pull individual files')
2977
if (merger.base_rev_id == tree.last_revision()):
2978
result = tree.pull(merger.other_branch, False,
2979
merger.other_rev_id)
2980
result.report(self.outf)
2982
merger.check_basis(not force)
2984
return self._do_preview(merger)
2986
return self._do_merge(merger, change_reporter, allow_pending,
2989
for cleanup in reversed(cleanups):
3863
if merger.this_basis is None:
3864
raise errors.BzrCommandError(
3865
"This branch has no commits."
3866
" (perhaps you would prefer 'bzr pull')")
3868
return self._do_preview(merger)
3870
return self._do_interactive(merger)
3872
return self._do_merge(merger, change_reporter, allow_pending,
3875
def _get_preview(self, merger):
3876
tree_merger = merger.make_merger()
3877
tt = tree_merger.make_preview_transform()
3878
self.add_cleanup(tt.finalize)
3879
result_tree = tt.get_preview_tree()
2992
3882
def _do_preview(self, merger):
2993
3883
from bzrlib.diff import show_diff_trees
2994
tree_merger = merger.make_merger()
2995
tt = tree_merger.make_preview_transform()
2997
result_tree = tt.get_preview_tree()
2998
show_diff_trees(merger.this_tree, result_tree, self.outf,
2999
old_label='', new_label='')
3884
result_tree = self._get_preview(merger)
3885
show_diff_trees(merger.this_tree, result_tree, self.outf,
3886
old_label='', new_label='')
3003
3888
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3004
3889
merger.change_reporter = change_reporter
3151
4074
def run(self, file_list=None, merge_type=None, show_base=False,
3152
4075
reprocess=False):
4076
from bzrlib.conflicts import restore
3153
4077
if merge_type is None:
3154
4078
merge_type = _mod_merge.Merge3Merger
3155
4079
tree, file_list = tree_files(file_list)
3156
4080
tree.lock_write()
4081
self.add_cleanup(tree.unlock)
4082
parents = tree.get_parent_ids()
4083
if len(parents) != 2:
4084
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4085
" merges. Not cherrypicking or"
4087
repository = tree.branch.repository
4088
interesting_ids = None
4090
conflicts = tree.conflicts()
4091
if file_list is not None:
4092
interesting_ids = set()
4093
for filename in file_list:
4094
file_id = tree.path2id(filename)
4096
raise errors.NotVersionedError(filename)
4097
interesting_ids.add(file_id)
4098
if tree.kind(file_id) != "directory":
4101
for name, ie in tree.inventory.iter_entries(file_id):
4102
interesting_ids.add(ie.file_id)
4103
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4105
# Remerge only supports resolving contents conflicts
4106
allowed_conflicts = ('text conflict', 'contents conflict')
4107
restore_files = [c.path for c in conflicts
4108
if c.typestring in allowed_conflicts]
4109
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4110
tree.set_conflicts(ConflictList(new_conflicts))
4111
if file_list is not None:
4112
restore_files = file_list
4113
for filename in restore_files:
4115
restore(tree.abspath(filename))
4116
except errors.NotConflicted:
4118
# Disable pending merges, because the file texts we are remerging
4119
# have not had those merges performed. If we use the wrong parents
4120
# list, we imply that the working tree text has seen and rejected
4121
# all the changes from the other tree, when in fact those changes
4122
# have not yet been seen.
4123
tree.set_parent_ids(parents[:1])
3158
parents = tree.get_parent_ids()
3159
if len(parents) != 2:
3160
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3161
" merges. Not cherrypicking or"
3163
repository = tree.branch.repository
3164
interesting_ids = None
3166
conflicts = tree.conflicts()
3167
if file_list is not None:
3168
interesting_ids = set()
3169
for filename in file_list:
3170
file_id = tree.path2id(filename)
3172
raise errors.NotVersionedError(filename)
3173
interesting_ids.add(file_id)
3174
if tree.kind(file_id) != "directory":
3177
for name, ie in tree.inventory.iter_entries(file_id):
3178
interesting_ids.add(ie.file_id)
3179
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3181
# Remerge only supports resolving contents conflicts
3182
allowed_conflicts = ('text conflict', 'contents conflict')
3183
restore_files = [c.path for c in conflicts
3184
if c.typestring in allowed_conflicts]
3185
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3186
tree.set_conflicts(ConflictList(new_conflicts))
3187
if file_list is not None:
3188
restore_files = file_list
3189
for filename in restore_files:
3191
restore(tree.abspath(filename))
3192
except errors.NotConflicted:
3194
# Disable pending merges, because the file texts we are remerging
3195
# have not had those merges performed. If we use the wrong parents
3196
# list, we imply that the working tree text has seen and rejected
3197
# all the changes from the other tree, when in fact those changes
3198
# have not yet been seen.
3199
pb = ui.ui_factory.nested_progress_bar()
3200
tree.set_parent_ids(parents[:1])
3202
merger = _mod_merge.Merger.from_revision_ids(pb,
3204
merger.interesting_ids = interesting_ids
3205
merger.merge_type = merge_type
3206
merger.show_base = show_base
3207
merger.reprocess = reprocess
3208
conflicts = merger.do_merge()
3210
tree.set_parent_ids(parents)
4125
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4126
merger.interesting_ids = interesting_ids
4127
merger.merge_type = merge_type
4128
merger.show_base = show_base
4129
merger.reprocess = reprocess
4130
conflicts = merger.do_merge()
4132
tree.set_parent_ids(parents)
3214
4133
if conflicts > 0:
3380
4348
" or specified.")
3381
4349
display_url = urlutils.unescape_for_display(parent,
3382
4350
self.outf.encoding)
3383
self.outf.write("Using saved parent location: "
4351
message("Using saved parent location: "
3384
4352
+ display_url + "\n")
3386
4354
remote_branch = Branch.open(other_branch)
3387
4355
if remote_branch.base == local_branch.base:
3388
4356
remote_branch = local_branch
3389
local_branch.lock_read()
3391
4358
remote_branch.lock_read()
3393
local_extra, remote_extra = find_unmerged(
3394
local_branch, remote_branch, restrict,
3395
backward=not reverse,
3396
include_merges=include_merges)
3398
if log_format is None:
3399
registry = log.log_formatter_registry
3400
log_format = registry.get_default(local_branch)
3401
lf = log_format(to_file=self.outf,
3403
show_timezone='original')
3406
if local_extra and not theirs_only:
3407
self.outf.write("You have %d extra revision(s):\n" %
3409
for revision in iter_log_revisions(local_extra,
3410
local_branch.repository,
3412
lf.log_revision(revision)
3413
printed_local = True
3416
printed_local = False
3418
if remote_extra and not mine_only:
3419
if printed_local is True:
3420
self.outf.write("\n\n\n")
3421
self.outf.write("You are missing %d revision(s):\n" %
3423
for revision in iter_log_revisions(remote_extra,
3424
remote_branch.repository,
3426
lf.log_revision(revision)
3429
if mine_only and not local_extra:
3430
# We checked local, and found nothing extra
3431
self.outf.write('This branch is up to date.\n')
3432
elif theirs_only and not remote_extra:
3433
# We checked remote, and found nothing extra
3434
self.outf.write('Other branch is up to date.\n')
3435
elif not (mine_only or theirs_only or local_extra or
3437
# We checked both branches, and neither one had extra
3439
self.outf.write("Branches are up to date.\n")
3441
remote_branch.unlock()
3443
local_branch.unlock()
4359
self.add_cleanup(remote_branch.unlock)
4361
local_revid_range = _revision_range_to_revid_range(
4362
_get_revision_range(my_revision, local_branch,
4365
remote_revid_range = _revision_range_to_revid_range(
4366
_get_revision_range(revision,
4367
remote_branch, self.name()))
4369
local_extra, remote_extra = find_unmerged(
4370
local_branch, remote_branch, restrict,
4371
backward=not reverse,
4372
include_merges=include_merges,
4373
local_revid_range=local_revid_range,
4374
remote_revid_range=remote_revid_range)
4376
if log_format is None:
4377
registry = log.log_formatter_registry
4378
log_format = registry.get_default(local_branch)
4379
lf = log_format(to_file=self.outf,
4381
show_timezone='original')
4384
if local_extra and not theirs_only:
4385
message("You have %d extra revision(s):\n" %
4387
for revision in iter_log_revisions(local_extra,
4388
local_branch.repository,
4390
lf.log_revision(revision)
4391
printed_local = True
4394
printed_local = False
4396
if remote_extra and not mine_only:
4397
if printed_local is True:
4399
message("You are missing %d revision(s):\n" %
4401
for revision in iter_log_revisions(remote_extra,
4402
remote_branch.repository,
4404
lf.log_revision(revision)
4407
if mine_only and not local_extra:
4408
# We checked local, and found nothing extra
4409
message('This branch is up to date.\n')
4410
elif theirs_only and not remote_extra:
4411
# We checked remote, and found nothing extra
4412
message('Other branch is up to date.\n')
4413
elif not (mine_only or theirs_only or local_extra or
4415
# We checked both branches, and neither one had extra
4417
message("Branches are up to date.\n")
3444
4419
if not status_code and parent is None and other_branch is not None:
3445
4420
local_branch.lock_write()
3447
# handle race conditions - a parent might be set while we run.
3448
if local_branch.get_parent() is None:
3449
local_branch.set_parent(remote_branch.base)
3451
local_branch.unlock()
4421
self.add_cleanup(local_branch.unlock)
4422
# handle race conditions - a parent might be set while we run.
4423
if local_branch.get_parent() is None:
4424
local_branch.set_parent(remote_branch.base)
3452
4425
return status_code
3455
4428
class cmd_pack(Command):
3456
"""Compress the data within a repository."""
4429
"""Compress the data within a repository.
4431
This operation compresses the data within a bazaar repository. As
4432
bazaar supports automatic packing of repository, this operation is
4433
normally not required to be done manually.
4435
During the pack operation, bazaar takes a backup of existing repository
4436
data, i.e. pack files. This backup is eventually removed by bazaar
4437
automatically when it is safe to do so. To save disk space by removing
4438
the backed up pack files, the --clean-obsolete-packs option may be
4441
Warning: If you use --clean-obsolete-packs and your machine crashes
4442
during or immediately after repacking, you may be left with a state
4443
where the deletion has been written to disk but the new packs have not
4444
been. In this case the repository may be unusable.
3458
4447
_see_also = ['repositories']
3459
4448
takes_args = ['branch_or_repo?']
4450
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
3461
def run(self, branch_or_repo='.'):
4453
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
3462
4454
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3464
4456
branch = dir.open_branch()
3465
4457
repository = branch.repository
3466
4458
except errors.NotBranchError:
3467
4459
repository = dir.open_repository()
4460
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
3471
4463
class cmd_plugins(Command):
3472
4464
"""List the installed plugins.
3474
4466
This command displays the list of installed plugins including
3475
4467
version of plugin and a short description of each.
4184
5186
short_name='f',
4186
5188
Option('output', short_name='o',
4187
help='Write merge directive to this file; '
5189
help='Write merge directive to this file or directory; '
4188
5190
'use - for stdout.',
5193
help='Refuse to send if there are uncommitted changes in'
5194
' the working tree, --no-strict disables the check.'),
4190
5195
Option('mail-to', help='Mail the request to this address.',
4194
RegistryOption.from_kwargs('format',
4195
'Use the specified output format.',
4196
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4197
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5199
Option('body', help='Body for the email.', type=unicode),
5200
RegistryOption('format',
5201
help='Use the specified output format.',
5202
lazy_registry=('bzrlib.send', 'format_registry')),
4200
5205
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4201
5206
no_patch=False, revision=None, remember=False, output=None,
4202
format='4', mail_to=None, message=None, **kwargs):
4203
return self._run(submit_branch, revision, public_branch, remember,
4204
format, no_bundle, no_patch, output,
4205
kwargs.get('from', '.'), mail_to, message)
4207
def _run(self, submit_branch, revision, public_branch, remember, format,
4208
no_bundle, no_patch, output, from_, mail_to, message):
4209
from bzrlib.revision import NULL_REVISION
4210
branch = Branch.open_containing(from_)[0]
4212
outfile = StringIO()
4216
outfile = open(output, 'wb')
4217
# we may need to write data into branch's repository to calculate
4222
config = branch.get_config()
4224
mail_to = config.get_user_option('submit_to')
4225
mail_client = config.get_mail_client()
4226
if remember and submit_branch is None:
4227
raise errors.BzrCommandError(
4228
'--remember requires a branch to be specified.')
4229
stored_submit_branch = branch.get_submit_branch()
4230
remembered_submit_branch = None
4231
if submit_branch is None:
4232
submit_branch = stored_submit_branch
4233
remembered_submit_branch = "submit"
4235
if stored_submit_branch is None or remember:
4236
branch.set_submit_branch(submit_branch)
4237
if submit_branch is None:
4238
submit_branch = branch.get_parent()
4239
remembered_submit_branch = "parent"
4240
if submit_branch is None:
4241
raise errors.BzrCommandError('No submit branch known or'
4243
if remembered_submit_branch is not None:
4244
note('Using saved %s location "%s" to determine what '
4245
'changes to submit.', remembered_submit_branch,
4249
submit_config = Branch.open(submit_branch).get_config()
4250
mail_to = submit_config.get_user_option("child_submit_to")
4252
stored_public_branch = branch.get_public_branch()
4253
if public_branch is None:
4254
public_branch = stored_public_branch
4255
elif stored_public_branch is None or remember:
4256
branch.set_public_branch(public_branch)
4257
if no_bundle and public_branch is None:
4258
raise errors.BzrCommandError('No public branch specified or'
4260
base_revision_id = None
4262
if revision is not None:
4263
if len(revision) > 2:
4264
raise errors.BzrCommandError('bzr send takes '
4265
'at most two one revision identifiers')
4266
revision_id = revision[-1].as_revision_id(branch)
4267
if len(revision) == 2:
4268
base_revision_id = revision[0].as_revision_id(branch)
4269
if revision_id is None:
4270
revision_id = branch.last_revision()
4271
if revision_id == NULL_REVISION:
4272
raise errors.BzrCommandError('No revisions to submit.')
4274
directive = merge_directive.MergeDirective2.from_objects(
4275
branch.repository, revision_id, time.time(),
4276
osutils.local_time_offset(), submit_branch,
4277
public_branch=public_branch, include_patch=not no_patch,
4278
include_bundle=not no_bundle, message=message,
4279
base_revision_id=base_revision_id)
4280
elif format == '0.9':
4283
patch_type = 'bundle'
4285
raise errors.BzrCommandError('Format 0.9 does not'
4286
' permit bundle with no patch')
4292
directive = merge_directive.MergeDirective.from_objects(
4293
branch.repository, revision_id, time.time(),
4294
osutils.local_time_offset(), submit_branch,
4295
public_branch=public_branch, patch_type=patch_type,
4298
outfile.writelines(directive.to_lines())
4300
subject = '[MERGE] '
4301
if message is not None:
4304
revision = branch.repository.get_revision(revision_id)
4305
subject += revision.get_summary()
4306
basename = directive.get_disk_name(branch)
4307
mail_client.compose_merge_request(mail_to, subject,
4308
outfile.getvalue(), basename)
5207
format=None, mail_to=None, message=None, body=None,
5208
strict=None, **kwargs):
5209
from bzrlib.send import send
5210
return send(submit_branch, revision, public_branch, remember,
5211
format, no_bundle, no_patch, output,
5212
kwargs.get('from', '.'), mail_to, message, body,
4315
5217
class cmd_bundle_revisions(cmd_send):
4317
"""Create a merge-directive for submiting changes.
5218
"""Create a merge-directive for submitting changes.
4319
5220
A merge directive provides many things needed for requesting merges:
4515
5451
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
4516
5452
takes_args = ['location?']
4517
takes_options = [RegistryOption.from_kwargs('target_type',
4518
title='Target type',
4519
help='The type to reconfigure the directory to.',
4520
value_switches=True, enum_switch=False,
4521
branch='Reconfigure to be an unbound branch '
4522
'with no working tree.',
4523
tree='Reconfigure to be an unbound branch '
4524
'with a working tree.',
4525
checkout='Reconfigure to be a bound branch '
4526
'with a working tree.',
4527
lightweight_checkout='Reconfigure to be a lightweight'
4528
' checkout (with no local history).',
4529
standalone='Reconfigure to be a standalone branch '
4530
'(i.e. stop using shared repository).',
4531
use_shared='Reconfigure to use a shared repository.'),
4532
Option('bind-to', help='Branch to bind checkout to.',
4535
help='Perform reconfiguration even if local changes'
5454
RegistryOption.from_kwargs(
5456
title='Target type',
5457
help='The type to reconfigure the directory to.',
5458
value_switches=True, enum_switch=False,
5459
branch='Reconfigure to be an unbound branch with no working tree.',
5460
tree='Reconfigure to be an unbound branch with a working tree.',
5461
checkout='Reconfigure to be a bound branch with a working tree.',
5462
lightweight_checkout='Reconfigure to be a lightweight'
5463
' checkout (with no local history).',
5464
standalone='Reconfigure to be a standalone branch '
5465
'(i.e. stop using shared repository).',
5466
use_shared='Reconfigure to use a shared repository.',
5467
with_trees='Reconfigure repository to create '
5468
'working trees on branches by default.',
5469
with_no_trees='Reconfigure repository to not create '
5470
'working trees on branches by default.'
5472
Option('bind-to', help='Branch to bind checkout to.', type=str),
5474
help='Perform reconfiguration even if local changes'
5476
Option('stacked-on',
5477
help='Reconfigure a branch to be stacked on another branch.',
5481
help='Reconfigure a branch to be unstacked. This '
5482
'may require copying substantial data into it.',
4539
def run(self, location=None, target_type=None, bind_to=None, force=False):
5486
def run(self, location=None, target_type=None, bind_to=None, force=False,
4540
5489
directory = bzrdir.BzrDir.open(location)
5490
if stacked_on and unstacked:
5491
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5492
elif stacked_on is not None:
5493
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5495
reconfigure.ReconfigureUnstacked().apply(directory)
5496
# At the moment you can use --stacked-on and a different
5497
# reconfiguration shape at the same time; there seems no good reason
4541
5499
if target_type is None:
4542
raise errors.BzrCommandError('No target configuration specified')
5500
if stacked_on or unstacked:
5503
raise errors.BzrCommandError('No target configuration '
4543
5505
elif target_type == 'branch':
4544
5506
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4545
5507
elif target_type == 'tree':
4546
5508
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4547
5509
elif target_type == 'checkout':
4548
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
5510
reconfiguration = reconfigure.Reconfigure.to_checkout(
4550
5512
elif target_type == 'lightweight-checkout':
4551
5513
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4552
5514
directory, bind_to)
4574
5542
directory of the current branch. For example, if you are currently in a
4575
5543
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4576
5544
/path/to/newbranch.
5546
Bound branches use the nickname of its master branch unless it is set
5547
locally, in which case switching will update the local nickname to be
4579
takes_args = ['to_location']
5551
takes_args = ['to_location?']
4580
5552
takes_options = [Option('force',
4581
help='Switch even if local commits will be lost.')
5553
help='Switch even if local commits will be lost.'),
5555
Option('create-branch', short_name='b',
5556
help='Create the target branch from this one before'
5557
' switching to it.'),
4584
def run(self, to_location, force=False):
5560
def run(self, to_location=None, force=False, create_branch=False,
4585
5562
from bzrlib import switch
4586
5563
tree_location = '.'
5564
revision = _get_one_revision('switch', revision)
4587
5565
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5566
if to_location is None:
5567
if revision is None:
5568
raise errors.BzrCommandError('You must supply either a'
5569
' revision or a location')
4589
to_branch = Branch.open(to_location)
5572
branch = control_dir.open_branch()
5573
had_explicit_nick = branch.get_config().has_explicit_nickname()
4590
5574
except errors.NotBranchError:
5576
had_explicit_nick = False
5579
raise errors.BzrCommandError('cannot create branch without'
5581
to_location = directory_service.directories.dereference(
5583
if '/' not in to_location and '\\' not in to_location:
5584
# This path is meant to be relative to the existing branch
5585
this_url = self._get_branch_location(control_dir)
5586
to_location = urlutils.join(this_url, '..', to_location)
5587
to_branch = branch.bzrdir.sprout(to_location,
5588
possible_transports=[branch.bzrdir.root_transport],
5589
source_branch=branch).open_branch()
5592
to_branch = Branch.open(to_location)
5593
except errors.NotBranchError:
5594
this_url = self._get_branch_location(control_dir)
5595
to_branch = Branch.open(
5596
urlutils.join(this_url, '..', to_location))
5597
if revision is not None:
5598
revision = revision.as_revision_id(to_branch)
5599
switch.switch(control_dir, to_branch, force, revision_id=revision)
5600
if had_explicit_nick:
5601
branch = control_dir.open_branch() #get the new branch!
5602
branch.nick = to_branch.nick
5603
note('Switched to branch: %s',
5604
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5606
def _get_branch_location(self, control_dir):
5607
"""Return location of branch for this control dir."""
4591
5609
this_branch = control_dir.open_branch()
4592
5610
# This may be a heavy checkout, where we want the master branch
4593
this_url = this_branch.get_bound_location()
5611
master_location = this_branch.get_bound_location()
5612
if master_location is not None:
5613
return master_location
4594
5614
# If not, use a local sibling
4595
if this_url is None:
4596
this_url = this_branch.base
4597
to_branch = Branch.open(
4598
urlutils.join(this_url, '..', to_location))
4599
switch.switch(control_dir, to_branch, force)
4600
note('Switched to branch: %s',
4601
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5615
return this_branch.base
5616
except errors.NotBranchError:
5617
format = control_dir.find_branch_format()
5618
if getattr(format, 'get_reference', None) is not None:
5619
return format.get_reference(control_dir)
5621
return control_dir.root_transport.base
5624
class cmd_view(Command):
5625
"""Manage filtered views.
5627
Views provide a mask over the tree so that users can focus on
5628
a subset of a tree when doing their work. After creating a view,
5629
commands that support a list of files - status, diff, commit, etc -
5630
effectively have that list of files implicitly given each time.
5631
An explicit list of files can still be given but those files
5632
must be within the current view.
5634
In most cases, a view has a short life-span: it is created to make
5635
a selected change and is deleted once that change is committed.
5636
At other times, you may wish to create one or more named views
5637
and switch between them.
5639
To disable the current view without deleting it, you can switch to
5640
the pseudo view called ``off``. This can be useful when you need
5641
to see the whole tree for an operation or two (e.g. merge) but
5642
want to switch back to your view after that.
5645
To define the current view::
5647
bzr view file1 dir1 ...
5649
To list the current view::
5653
To delete the current view::
5657
To disable the current view without deleting it::
5659
bzr view --switch off
5661
To define a named view and switch to it::
5663
bzr view --name view-name file1 dir1 ...
5665
To list a named view::
5667
bzr view --name view-name
5669
To delete a named view::
5671
bzr view --name view-name --delete
5673
To switch to a named view::
5675
bzr view --switch view-name
5677
To list all views defined::
5681
To delete all views::
5683
bzr view --delete --all
5687
takes_args = ['file*']
5690
help='Apply list or delete action to all views.',
5693
help='Delete the view.',
5696
help='Name of the view to define, list or delete.',
5700
help='Name of the view to switch to.',
5705
def run(self, file_list,
5711
tree, file_list = tree_files(file_list, apply_view=False)
5712
current_view, view_dict = tree.views.get_view_info()
5717
raise errors.BzrCommandError(
5718
"Both --delete and a file list specified")
5720
raise errors.BzrCommandError(
5721
"Both --delete and --switch specified")
5723
tree.views.set_view_info(None, {})
5724
self.outf.write("Deleted all views.\n")
5726
raise errors.BzrCommandError("No current view to delete")
5728
tree.views.delete_view(name)
5729
self.outf.write("Deleted '%s' view.\n" % name)
5732
raise errors.BzrCommandError(
5733
"Both --switch and a file list specified")
5735
raise errors.BzrCommandError(
5736
"Both --switch and --all specified")
5737
elif switch == 'off':
5738
if current_view is None:
5739
raise errors.BzrCommandError("No current view to disable")
5740
tree.views.set_view_info(None, view_dict)
5741
self.outf.write("Disabled '%s' view.\n" % (current_view))
5743
tree.views.set_view_info(switch, view_dict)
5744
view_str = views.view_display_str(tree.views.lookup_view())
5745
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5748
self.outf.write('Views defined:\n')
5749
for view in sorted(view_dict):
5750
if view == current_view:
5754
view_str = views.view_display_str(view_dict[view])
5755
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5757
self.outf.write('No views defined.\n')
5760
# No name given and no current view set
5763
raise errors.BzrCommandError(
5764
"Cannot change the 'off' pseudo view")
5765
tree.views.set_view(name, sorted(file_list))
5766
view_str = views.view_display_str(tree.views.lookup_view())
5767
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5771
# No name given and no current view set
5772
self.outf.write('No current view.\n')
5774
view_str = views.view_display_str(tree.views.lookup_view(name))
5775
self.outf.write("'%s' view is: %s\n" % (name, view_str))
4604
5778
class cmd_hooks(Command):
4605
"""Show a branch's currently registered hooks.
4609
takes_args = ['path?']
4611
def run(self, path=None):
5784
for hook_key in sorted(hooks.known_hooks.keys()):
5785
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5786
self.outf.write("%s:\n" % type(some_hooks).__name__)
5787
for hook_name, hook_point in sorted(some_hooks.items()):
5788
self.outf.write(" %s:\n" % (hook_name,))
5789
found_hooks = list(hook_point)
5791
for hook in found_hooks:
5792
self.outf.write(" %s\n" %
5793
(some_hooks.get_hook_name(hook),))
5795
self.outf.write(" <no hooks installed>\n")
5798
class cmd_remove_branch(Command):
5801
This will remove the branch from the specified location but
5802
will keep any working tree or repository in place.
5806
Remove the branch at repo/trunk::
5808
bzr remove-branch repo/trunk
5812
takes_args = ["location?"]
5814
aliases = ["rmbranch"]
5816
def run(self, location=None):
5817
if location is None:
5819
branch = Branch.open_containing(location)[0]
5820
branch.bzrdir.destroy_branch()
5823
class cmd_shelve(Command):
5824
"""Temporarily set aside some changes from the current tree.
5826
Shelve allows you to temporarily put changes you've made "on the shelf",
5827
ie. out of the way, until a later time when you can bring them back from
5828
the shelf with the 'unshelve' command. The changes are stored alongside
5829
your working tree, and so they aren't propagated along with your branch nor
5830
will they survive its deletion.
5832
If shelve --list is specified, previously-shelved changes are listed.
5834
Shelve is intended to help separate several sets of changes that have
5835
been inappropriately mingled. If you just want to get rid of all changes
5836
and you don't need to restore them later, use revert. If you want to
5837
shelve all text changes at once, use shelve --all.
5839
If filenames are specified, only the changes to those files will be
5840
shelved. Other files will be left untouched.
5842
If a revision is specified, changes since that revision will be shelved.
5844
You can put multiple items on the shelf, and by default, 'unshelve' will
5845
restore the most recently shelved changes.
5848
takes_args = ['file*']
5852
Option('all', help='Shelve all changes.'),
5854
RegistryOption('writer', 'Method to use for writing diffs.',
5855
bzrlib.option.diff_writer_registry,
5856
value_switches=True, enum_switch=False),
5858
Option('list', help='List shelved changes.'),
5860
help='Destroy removed changes instead of shelving them.'),
5862
_see_also = ['unshelve']
5864
def run(self, revision=None, all=False, file_list=None, message=None,
5865
writer=None, list=False, destroy=False):
5867
return self.run_for_list()
5868
from bzrlib.shelf_ui import Shelver
5870
writer = bzrlib.option.diff_writer_registry.get()
5872
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5873
file_list, message, destroy=destroy)
5878
except errors.UserAbort:
5881
def run_for_list(self):
5882
tree = WorkingTree.open_containing('.')[0]
5884
self.add_cleanup(tree.unlock)
5885
manager = tree.get_shelf_manager()
5886
shelves = manager.active_shelves()
5887
if len(shelves) == 0:
5888
note('No shelved changes.')
5890
for shelf_id in reversed(shelves):
5891
message = manager.get_metadata(shelf_id).get('message')
5893
message = '<no message>'
5894
self.outf.write('%3d: %s\n' % (shelf_id, message))
5898
class cmd_unshelve(Command):
5899
"""Restore shelved changes.
5901
By default, the most recently shelved changes are restored. However if you
5902
specify a shelf by id those changes will be restored instead. This works
5903
best when the changes don't depend on each other.
5906
takes_args = ['shelf_id?']
5908
RegistryOption.from_kwargs(
5909
'action', help="The action to perform.",
5910
enum_switch=False, value_switches=True,
5911
apply="Apply changes and remove from the shelf.",
5912
dry_run="Show changes, but do not apply or remove them.",
5913
preview="Instead of unshelving the changes, show the diff that "
5914
"would result from unshelving.",
5915
delete_only="Delete changes without applying them.",
5916
keep="Apply changes but don't delete them.",
5919
_see_also = ['shelve']
5921
def run(self, shelf_id=None, action='apply'):
5922
from bzrlib.shelf_ui import Unshelver
5923
unshelver = Unshelver.from_args(shelf_id, action)
5927
unshelver.tree.unlock()
5930
class cmd_clean_tree(Command):
5931
"""Remove unwanted files from working tree.
5933
By default, only unknown files, not ignored files, are deleted. Versioned
5934
files are never deleted.
5936
Another class is 'detritus', which includes files emitted by bzr during
5937
normal operations and selftests. (The value of these files decreases with
5940
If no options are specified, unknown files are deleted. Otherwise, option
5941
flags are respected, and may be combined.
5943
To check what clean-tree will do, use --dry-run.
5945
takes_options = [Option('ignored', help='Delete all ignored files.'),
5946
Option('detritus', help='Delete conflict files, merge'
5947
' backups, and failed selftest dirs.'),
5949
help='Delete files unknown to bzr (default).'),
5950
Option('dry-run', help='Show files to delete instead of'
5952
Option('force', help='Do not prompt before deleting.')]
5953
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5955
from bzrlib.clean_tree import clean_tree
5956
if not (unknown or ignored or detritus):
5960
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5961
dry_run=dry_run, no_prompt=force)
5964
class cmd_reference(Command):
5965
"""list, view and set branch locations for nested trees.
5967
If no arguments are provided, lists the branch locations for nested trees.
5968
If one argument is provided, display the branch location for that tree.
5969
If two arguments are provided, set the branch location for that tree.
5974
takes_args = ['path?', 'location?']
5976
def run(self, path=None, location=None):
5978
if path is not None:
5980
tree, branch, relpath =(
5981
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5982
if path is not None:
5985
tree = branch.basis_tree()
4612
5986
if path is None:
4614
branch_hooks = Branch.open(path).hooks
4615
for hook_type in branch_hooks:
4616
hooks = branch_hooks[hook_type]
4617
self.outf.write("%s:\n" % (hook_type,))
4620
self.outf.write(" %s\n" %
4621
(branch_hooks.get_hook_name(hook),))
5987
info = branch._get_all_reference_info().iteritems()
5988
self._display_reference_info(tree, branch, info)
5990
file_id = tree.path2id(path)
5992
raise errors.NotVersionedError(path)
5993
if location is None:
5994
info = [(file_id, branch.get_reference_info(file_id))]
5995
self._display_reference_info(tree, branch, info)
4623
self.outf.write(" <no hooks installed>\n")
4626
def _create_prefix(cur_transport):
4627
needed = [cur_transport]
4628
# Recurse upwards until we can create a directory successfully
4630
new_transport = cur_transport.clone('..')
4631
if new_transport.base == cur_transport.base:
4632
raise errors.BzrCommandError(
4633
"Failed to create path prefix for %s."
4634
% cur_transport.base)
4636
new_transport.mkdir('.')
4637
except errors.NoSuchFile:
4638
needed.append(new_transport)
4639
cur_transport = new_transport
4642
# Now we only need to create child directories
4644
cur_transport = needed.pop()
4645
cur_transport.ensure_base()
4648
# these get imported and then picked up by the scan for cmd_*
4649
# TODO: Some more consistent way to split command definitions across files;
4650
# we do need to load at least some information about them to know of
4651
# aliases. ideally we would avoid loading the implementation until the
4652
# details were needed.
4653
from bzrlib.cmd_version_info import cmd_version_info
4654
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
4655
from bzrlib.bundle.commands import (
4658
from bzrlib.sign_my_commits import cmd_sign_my_commits
4659
from bzrlib.weave_commands import cmd_versionedfile_list, \
4660
cmd_weave_plan_merge, cmd_weave_merge_text
5997
branch.set_reference_info(file_id, path, location)
5999
def _display_reference_info(self, tree, branch, info):
6001
for file_id, (path, location) in info:
6003
path = tree.id2path(file_id)
6004
except errors.NoSuchId:
6006
ref_list.append((path, location))
6007
for path, location in sorted(ref_list):
6008
self.outf.write('%s %s\n' % (path, location))
6011
def _register_lazy_builtins():
6012
# register lazy builtins from other modules; called at startup and should
6013
# be only called once.
6014
for (name, aliases, module_name) in [
6015
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6016
('cmd_dpush', [], 'bzrlib.foreign'),
6017
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6018
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6019
('cmd_conflicts', [], 'bzrlib.conflicts'),
6020
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6022
builtin_command_registry.register_lazy(name, aliases, module_name)