29
28
from bzrlib import (
35
config as _mod_config,
39
40
merge as _mod_merge,
43
45
revision as _mod_revision,
50
54
from bzrlib.branch import Branch
51
55
from bzrlib.conflicts import ConflictList
52
from bzrlib.revisionspec import RevisionSpec
56
from bzrlib.transport import memory
57
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
53
58
from bzrlib.smtp_connection import SMTPConnection
54
59
from bzrlib.workingtree import WorkingTree
57
from bzrlib.commands import Command, display_command
58
from bzrlib.option import ListOption, Option, RegistryOption, custom_help
59
from bzrlib.trace import mutter, note, warning, is_quiet, info
62
def tree_files(file_list, default_branch=u'.'):
64
return internal_tree_files(file_list, default_branch)
65
except errors.FileInWrongBranch, e:
66
raise errors.BzrCommandError("%s is not in the same branch as %s" %
67
(e.path, file_list[0]))
62
from bzrlib.commands import (
64
builtin_command_registry,
67
from bzrlib.option import (
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
80
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
81
def tree_files(file_list, default_branch=u'.', canonicalize=True,
83
return internal_tree_files(file_list, default_branch, canonicalize,
87
def tree_files_for_add(file_list):
89
Return a tree and list of absolute paths from a file list.
91
Similar to tree_files, but add handles files a bit differently, so it a
92
custom implementation. In particular, MutableTreeTree.smart_add expects
93
absolute paths, which it immediately converts to relative paths.
95
# FIXME Would be nice to just return the relative paths like
96
# internal_tree_files does, but there are a large number of unit tests
97
# that assume the current interface to mutabletree.smart_add
99
tree, relpath = WorkingTree.open_containing(file_list[0])
100
if tree.supports_views():
101
view_files = tree.views.lookup_view()
103
for filename in file_list:
104
if not osutils.is_inside_any(view_files, filename):
105
raise errors.FileOutsideView(filename, view_files)
106
file_list = file_list[:]
107
file_list[0] = tree.abspath(relpath)
109
tree = WorkingTree.open_containing(u'.')[0]
110
if tree.supports_views():
111
view_files = tree.views.lookup_view()
113
file_list = view_files
114
view_str = views.view_display_str(view_files)
115
note("Ignoring files outside view. View is %s" % view_str)
116
return tree, file_list
119
def _get_one_revision(command_name, revisions):
120
if revisions is None:
122
if len(revisions) != 1:
123
raise errors.BzrCommandError(
124
'bzr %s --revision takes exactly one revision identifier' % (
129
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
130
"""Get a revision tree. Not suitable for commands that change the tree.
132
Specifically, the basis tree in dirstate trees is coupled to the dirstate
133
and doing a commit/uncommit/pull will at best fail due to changing the
136
If tree is passed in, it should be already locked, for lifetime management
137
of the trees internal cached state.
141
if revisions is None:
143
rev_tree = tree.basis_tree()
145
rev_tree = branch.basis_tree()
147
revision = _get_one_revision(command_name, revisions)
148
rev_tree = revision.as_tree(branch)
70
152
# XXX: Bad function name; should possibly also be a class method of
71
153
# WorkingTree rather than a function.
72
def internal_tree_files(file_list, default_branch=u'.'):
154
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
155
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
73
157
"""Convert command-line paths to a WorkingTree and relative paths.
159
Deprecated: use WorkingTree.open_containing_paths instead.
75
161
This is typically used for command-line processors that take one or
76
162
more filenames, and infer the workingtree that contains them.
78
164
The filenames given are not required to exist.
80
:param file_list: Filenames to convert.
166
:param file_list: Filenames to convert.
82
168
:param default_branch: Fallback tree path to use if file_list is empty or
171
:param apply_view: if True and a view is set, apply it or check that
172
specified files are within it
85
174
:return: workingtree, [relative_paths]
87
if file_list is None or len(file_list) == 0:
88
return WorkingTree.open_containing(default_branch)[0], file_list
89
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
90
return tree, safe_relpath_files(tree, file_list)
93
def safe_relpath_files(tree, file_list):
94
"""Convert file_list into a list of relpaths in tree.
96
:param tree: A tree to operate on.
97
:param file_list: A list of user provided paths or None.
98
:return: A list of relative paths.
99
:raises errors.PathNotChild: When a provided path is in a different tree
102
if file_list is None:
105
for filename in file_list:
107
new_list.append(tree.relpath(osutils.dereference_path(filename)))
108
except errors.PathNotChild:
109
raise errors.FileInWrongBranch(tree.branch, filename)
176
return WorkingTree.open_containing_paths(
177
file_list, default_directory='.',
182
def _get_view_info_for_change_reporter(tree):
183
"""Get the view information from a tree for change reporting."""
186
current_view = tree.views.get_view_info()[0]
187
if current_view is not None:
188
view_info = (current_view, tree.views.lookup_view())
189
except errors.ViewsNotSupported:
194
def _open_directory_or_containing_tree_or_branch(filename, directory):
195
"""Open the tree or branch containing the specified file, unless
196
the --directory option is used to specify a different branch."""
197
if directory is not None:
198
return (None, Branch.open(directory), filename)
199
return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
113
202
# TODO: Make sure no commands unconditionally use the working directory as a
197
304
show_tree_status(tree, show_ids=show_ids,
198
305
specific_files=relfile_list, revision=revision,
199
306
to_file=self.outf, short=short, versioned=versioned,
200
show_pending=(not no_pending))
307
show_pending=(not no_pending), verbose=verbose,
308
classify=not no_classify)
203
311
class cmd_cat_revision(Command):
204
"""Write out metadata for a revision.
312
__doc__ = """Write out metadata for a revision.
206
314
The revision to print can either be specified by a specific
207
315
revision identifier, or you can use --revision.
211
319
takes_args = ['revision_id?']
212
takes_options = ['revision']
320
takes_options = ['directory', 'revision']
213
321
# cat-revision is more for frontends so should be exact
214
322
encoding = 'strict'
324
def print_revision(self, revisions, revid):
325
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
326
record = stream.next()
327
if record.storage_kind == 'absent':
328
raise errors.NoSuchRevision(revisions, revid)
329
revtext = record.get_bytes_as('fulltext')
330
self.outf.write(revtext.decode('utf-8'))
217
def run(self, revision_id=None, revision=None):
333
def run(self, revision_id=None, revision=None, directory=u'.'):
218
334
if revision_id is not None and revision is not None:
219
335
raise errors.BzrCommandError('You can only supply one of'
220
336
' revision_id or --revision')
221
337
if revision_id is None and revision is None:
222
338
raise errors.BzrCommandError('You must supply either'
223
339
' --revision or a revision_id')
224
b = WorkingTree.open_containing(u'.')[0].branch
226
# TODO: jam 20060112 should cat-revision always output utf-8?
227
if revision_id is not None:
228
revision_id = osutils.safe_revision_id(revision_id, warn=False)
341
b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
343
revisions = b.repository.revisions
344
if revisions is None:
345
raise errors.BzrCommandError('Repository %r does not support '
346
'access to raw revision texts')
348
b.repository.lock_read()
350
# TODO: jam 20060112 should cat-revision always output utf-8?
351
if revision_id is not None:
352
revision_id = osutils.safe_revision_id(revision_id, warn=False)
354
self.print_revision(revisions, revision_id)
355
except errors.NoSuchRevision:
356
msg = "The repository %s contains no revision %s." % (
357
b.repository.base, revision_id)
358
raise errors.BzrCommandError(msg)
359
elif revision is not None:
362
raise errors.BzrCommandError(
363
'You cannot specify a NULL revision.')
364
rev_id = rev.as_revision_id(b)
365
self.print_revision(revisions, rev_id)
367
b.repository.unlock()
370
class cmd_dump_btree(Command):
371
__doc__ = """Dump the contents of a btree index file to stdout.
373
PATH is a btree index file, it can be any URL. This includes things like
374
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
376
By default, the tuples stored in the index file will be displayed. With
377
--raw, we will uncompress the pages, but otherwise display the raw bytes
381
# TODO: Do we want to dump the internal nodes as well?
382
# TODO: It would be nice to be able to dump the un-parsed information,
383
# rather than only going through iter_all_entries. However, this is
384
# good enough for a start
386
encoding_type = 'exact'
387
takes_args = ['path']
388
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
389
' rather than the parsed tuples.'),
392
def run(self, path, raw=False):
393
dirname, basename = osutils.split(path)
394
t = transport.get_transport(dirname)
396
self._dump_raw_bytes(t, basename)
398
self._dump_entries(t, basename)
400
def _get_index_and_bytes(self, trans, basename):
401
"""Create a BTreeGraphIndex and raw bytes."""
402
bt = btree_index.BTreeGraphIndex(trans, basename, None)
403
bytes = trans.get_bytes(basename)
404
bt._file = cStringIO.StringIO(bytes)
405
bt._size = len(bytes)
408
def _dump_raw_bytes(self, trans, basename):
411
# We need to parse at least the root node.
412
# This is because the first page of every row starts with an
413
# uncompressed header.
414
bt, bytes = self._get_index_and_bytes(trans, basename)
415
for page_idx, page_start in enumerate(xrange(0, len(bytes),
416
btree_index._PAGE_SIZE)):
417
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
418
page_bytes = bytes[page_start:page_end]
420
self.outf.write('Root node:\n')
421
header_end, data = bt._parse_header_from_bytes(page_bytes)
422
self.outf.write(page_bytes[:header_end])
424
self.outf.write('\nPage %d\n' % (page_idx,))
425
if len(page_bytes) == 0:
426
self.outf.write('(empty)\n');
428
decomp_bytes = zlib.decompress(page_bytes)
429
self.outf.write(decomp_bytes)
430
self.outf.write('\n')
432
def _dump_entries(self, trans, basename):
434
st = trans.stat(basename)
435
except errors.TransportNotPossible:
436
# We can't stat, so we'll fake it because we have to do the 'get()'
438
bt, _ = self._get_index_and_bytes(trans, basename)
440
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
441
for node in bt.iter_all_entries():
442
# Node is made up of:
443
# (index, key, value, [references])
230
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
231
except errors.NoSuchRevision:
232
msg = "The repository %s contains no revision %s." % (b.repository.base,
234
raise errors.BzrCommandError(msg)
235
elif revision is not None:
238
raise errors.BzrCommandError('You cannot specify a NULL'
240
rev_id = rev.as_revision_id(b)
241
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
447
refs_as_tuples = None
449
refs_as_tuples = static_tuple.as_tuples(refs)
450
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
451
self.outf.write('%s\n' % (as_tuple,))
244
454
class cmd_remove_tree(Command):
245
"""Remove the working tree from a given branch/checkout.
455
__doc__ = """Remove the working tree from a given branch/checkout.
247
457
Since a lightweight checkout is little more than a working tree
248
458
this will refuse to run against one.
250
460
To re-create the working tree, use "bzr checkout".
252
462
_see_also = ['checkout', 'working-trees']
254
takes_args = ['location?']
256
def run(self, location='.'):
257
d = bzrdir.BzrDir.open(location)
463
takes_args = ['location*']
466
help='Remove the working tree even if it has '
467
'uncommitted or shelved changes.'),
470
def run(self, location_list, force=False):
471
if not location_list:
474
for location in location_list:
475
d = bzrdir.BzrDir.open(location)
478
working = d.open_workingtree()
479
except errors.NoWorkingTree:
480
raise errors.BzrCommandError("No working tree to remove")
481
except errors.NotLocalUrl:
482
raise errors.BzrCommandError("You cannot remove the working tree"
485
if (working.has_changes()):
486
raise errors.UncommittedChanges(working)
487
if working.get_shelf_manager().last_shelf() is not None:
488
raise errors.ShelvedChanges(working)
490
if working.user_url != working.branch.user_url:
491
raise errors.BzrCommandError("You cannot remove the working tree"
492
" from a lightweight checkout")
494
d.destroy_workingtree()
497
class cmd_repair_workingtree(Command):
498
__doc__ = """Reset the working tree state file.
500
This is not meant to be used normally, but more as a way to recover from
501
filesystem corruption, etc. This rebuilds the working inventory back to a
502
'known good' state. Any new modifications (adding a file, renaming, etc)
503
will be lost, though modified files will still be detected as such.
505
Most users will want something more like "bzr revert" or "bzr update"
506
unless the state file has become corrupted.
508
By default this attempts to recover the current state by looking at the
509
headers of the state file. If the state file is too corrupted to even do
510
that, you can supply --revision to force the state of the tree.
513
takes_options = ['revision', 'directory',
515
help='Reset the tree even if it doesn\'t appear to be'
520
def run(self, revision=None, directory='.', force=False):
521
tree, _ = WorkingTree.open_containing(directory)
522
self.add_cleanup(tree.lock_tree_write().unlock)
526
except errors.BzrError:
527
pass # There seems to be a real error here, so we'll reset
530
raise errors.BzrCommandError(
531
'The tree does not appear to be corrupt. You probably'
532
' want "bzr revert" instead. Use "--force" if you are'
533
' sure you want to reset the working tree.')
537
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
260
working = d.open_workingtree()
261
except errors.NoWorkingTree:
262
raise errors.BzrCommandError("No working tree to remove")
263
except errors.NotLocalUrl:
264
raise errors.BzrCommandError("You cannot remove the working tree of a "
267
working_path = working.bzrdir.root_transport.base
268
branch_path = working.branch.bzrdir.root_transport.base
269
if working_path != branch_path:
270
raise errors.BzrCommandError("You cannot remove the working tree from "
271
"a lightweight checkout")
273
d.destroy_workingtree()
539
tree.reset_state(revision_ids)
540
except errors.BzrError, e:
541
if revision_ids is None:
542
extra = (', the header appears corrupt, try passing -r -1'
543
' to set the state to the last commit')
546
raise errors.BzrCommandError('failed to reset the tree state'
276
550
class cmd_revno(Command):
277
"""Show current revision number.
551
__doc__ = """Show current revision number.
279
553
This is equal to the number of revisions on this branch.
282
556
_see_also = ['info']
283
557
takes_args = ['location?']
559
Option('tree', help='Show revno of working tree'),
286
def run(self, location=u'.'):
287
self.outf.write(str(Branch.open_containing(location)[0].revno()))
288
self.outf.write('\n')
563
def run(self, tree=False, location=u'.'):
566
wt = WorkingTree.open_containing(location)[0]
567
self.add_cleanup(wt.lock_read().unlock)
568
except (errors.NoWorkingTree, errors.NotLocalUrl):
569
raise errors.NoWorkingTree(location)
570
revid = wt.last_revision()
572
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
573
except errors.NoSuchRevision:
575
revno = ".".join(str(n) for n in revno_t)
577
b = Branch.open_containing(location)[0]
578
self.add_cleanup(b.lock_read().unlock)
581
self.outf.write(str(revno) + '\n')
291
584
class cmd_revision_info(Command):
292
"""Show revision number and revision id for a given revision identifier.
585
__doc__ = """Show revision number and revision id for a given revision identifier.
295
588
takes_args = ['revision_info*']
296
takes_options = ['revision']
591
custom_help('directory',
592
help='Branch to examine, '
593
'rather than the one containing the working directory.'),
594
Option('tree', help='Show revno of working tree'),
299
def run(self, revision=None, revision_info_list=[]):
598
def run(self, revision=None, directory=u'.', tree=False,
599
revision_info_list=[]):
602
wt = WorkingTree.open_containing(directory)[0]
604
self.add_cleanup(wt.lock_read().unlock)
605
except (errors.NoWorkingTree, errors.NotLocalUrl):
607
b = Branch.open_containing(directory)[0]
608
self.add_cleanup(b.lock_read().unlock)
302
610
if revision is not None:
303
revs.extend(revision)
611
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
304
612
if revision_info_list is not None:
305
for rev in revision_info_list:
306
revs.append(RevisionSpec.from_string(rev))
308
b = Branch.open_containing(u'.')[0]
311
revs.append(RevisionSpec.from_string('-1'))
314
revision_id = rev.as_revision_id(b)
613
for rev_str in revision_info_list:
614
rev_spec = RevisionSpec.from_string(rev_str)
615
revision_ids.append(rev_spec.as_revision_id(b))
616
# No arguments supplied, default to the last revision
617
if len(revision_ids) == 0:
620
raise errors.NoWorkingTree(directory)
621
revision_ids.append(wt.last_revision())
623
revision_ids.append(b.last_revision())
627
for revision_id in revision_ids:
316
revno = '%4d' % (b.revision_id_to_revno(revision_id))
629
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
630
revno = '.'.join(str(i) for i in dotted_revno)
317
631
except errors.NoSuchRevision:
318
dotted_map = b.get_revision_id_to_revno_map()
319
revno = '.'.join(str(i) for i in dotted_map[revision_id])
320
print '%s %s' % (revno, revision_id)
633
maxlen = max(maxlen, len(revno))
634
revinfos.append([revno, revision_id])
638
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
323
641
class cmd_add(Command):
324
"""Add specified files or directories.
642
__doc__ = """Add specified files or directories.
326
644
In non-recursive mode, all the named items are added, regardless
327
645
of whether they were previously ignored. A warning is given if
569
888
into_existing = False
571
890
inv = tree.inventory
572
from_id = tree.path2id(rel_names[0])
891
# 'fix' the case of a potential 'from'
892
from_id = tree.path2id(
893
tree.get_canonical_inventory_path(rel_names[0]))
573
894
if (not osutils.lexists(names_list[0]) and
574
895
from_id and inv.get_file_kind(from_id) == "directory"):
575
896
into_existing = False
577
898
if into_existing:
578
899
# move into existing directory
579
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
580
self.outf.write("%s => %s\n" % pair)
900
# All entries reference existing inventory items, so fix them up
901
# for cicp file-systems.
902
rel_names = tree.get_canonical_inventory_paths(rel_names)
903
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
905
self.outf.write("%s => %s\n" % (src, dest))
582
907
if len(names_list) != 2:
583
908
raise errors.BzrCommandError('to mv multiple files the'
584
909
' destination must be a versioned'
586
tree.rename_one(rel_names[0], rel_names[1], after=after)
587
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
912
# for cicp file-systems: the src references an existing inventory
914
src = tree.get_canonical_inventory_path(rel_names[0])
915
# Find the canonical version of the destination: In all cases, the
916
# parent of the target must be in the inventory, so we fetch the
917
# canonical version from there (we do not always *use* the
918
# canonicalized tail portion - we may be attempting to rename the
920
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
921
dest_parent = osutils.dirname(canon_dest)
922
spec_tail = osutils.basename(rel_names[1])
923
# For a CICP file-system, we need to avoid creating 2 inventory
924
# entries that differ only by case. So regardless of the case
925
# we *want* to use (ie, specified by the user or the file-system),
926
# we must always choose to use the case of any existing inventory
927
# items. The only exception to this is when we are attempting a
928
# case-only rename (ie, canonical versions of src and dest are
930
dest_id = tree.path2id(canon_dest)
931
if dest_id is None or tree.path2id(src) == dest_id:
932
# No existing item we care about, so work out what case we
933
# are actually going to use.
935
# If 'after' is specified, the tail must refer to a file on disk.
937
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
939
# pathjoin with an empty tail adds a slash, which breaks
941
dest_parent_fq = tree.basedir
943
dest_tail = osutils.canonical_relpath(
945
osutils.pathjoin(dest_parent_fq, spec_tail))
947
# not 'after', so case as specified is used
948
dest_tail = spec_tail
950
# Use the existing item so 'mv' fails with AlreadyVersioned.
951
dest_tail = os.path.basename(canon_dest)
952
dest = osutils.pathjoin(dest_parent, dest_tail)
953
mutter("attempting to move %s => %s", src, dest)
954
tree.rename_one(src, dest, after=after)
956
self.outf.write("%s => %s\n" % (src, dest))
590
959
class cmd_pull(Command):
591
"""Turn this branch into a mirror of another branch.
960
__doc__ = """Turn this branch into a mirror of another branch.
593
This command only works on branches that have not diverged. Branches are
594
considered diverged if the destination branch's most recent commit is one
595
that has not been merged (directly or indirectly) into the parent.
962
By default, this command only works on branches that have not diverged.
963
Branches are considered diverged if the destination branch's most recent
964
commit is one that has not been merged (directly or indirectly) into the
597
967
If branches have diverged, you can use 'bzr merge' to integrate the changes
598
968
from one into the other. Once one branch has merged, the other should
599
969
be able to pull it again.
601
If you want to forget your local changes and just update your branch to
602
match the remote one, use pull --overwrite.
971
If you want to replace your local changes and just want your branch to
972
match the remote one, use pull --overwrite. This will work even if the two
973
branches have diverged.
604
If there is no default location set, the first pull will set it. After
605
that, you can omit the location to use the default. To change the
606
default, use --remember. The value will only be saved if the remote
607
location can be accessed.
975
If there is no default location set, the first pull will set it (use
976
--no-remember to avoid settting it). After that, you can omit the
977
location to use the default. To change the default, use --remember. The
978
value will only be saved if the remote location can be accessed.
609
980
Note: The location can be specified either in the form of a branch,
610
981
or in the form of a path to a file containing a merge directive generated
614
_see_also = ['push', 'update', 'status-flags']
985
_see_also = ['push', 'update', 'status-flags', 'send']
615
986
takes_options = ['remember', 'overwrite', 'revision',
616
987
custom_help('verbose',
617
988
help='Show logs of pulled revisions.'),
989
custom_help('directory',
619
990
help='Branch to pull into, '
620
'rather than the one containing the working directory.',
991
'rather than the one containing the working directory.'),
993
help="Perform a local pull in a bound "
994
"branch. Local pulls are not applied to "
998
help="Show base revision text in conflicts.")
625
1000
takes_args = ['location?']
626
1001
encoding_type = 'replace'
628
def run(self, location=None, remember=False, overwrite=False,
1003
def run(self, location=None, remember=None, overwrite=False,
629
1004
revision=None, verbose=False,
1005
directory=None, local=False,
631
1007
# FIXME: too much stuff is in the command class
632
1008
revision_id = None
633
1009
mergeable = None
828
1217
To retrieve the branch as of a particular revision, supply the --revision
829
1218
parameter, as in "branch foo/bar -r 5".
1220
The synonyms 'clone' and 'get' for this command are deprecated.
832
1223
_see_also = ['checkout']
833
1224
takes_args = ['from_location', 'to_location?']
834
takes_options = ['revision', Option('hardlink',
835
help='Hard-link working tree files where possible.'),
1225
takes_options = ['revision',
1226
Option('hardlink', help='Hard-link working tree files where possible.'),
1227
Option('files-from', type=str,
1228
help="Get file contents from this tree."),
1230
help="Create a branch without a working-tree."),
1232
help="Switch the checkout in the current directory "
1233
"to the new branch."),
836
1234
Option('stacked',
837
1235
help='Create a stacked branch referring to the source branch. '
838
1236
'The new branch will depend on the availability of the source '
839
1237
'branch for all operations.'),
1238
Option('standalone',
1239
help='Do not use a shared repository, even if available.'),
1240
Option('use-existing-dir',
1241
help='By default branch will fail if the target'
1242
' directory exists, but does not already'
1243
' have a control directory. This flag will'
1244
' allow branch to proceed.'),
1246
help="Bind new branch to from location."),
841
1248
aliases = ['get', 'clone']
843
1250
def run(self, from_location, to_location=None, revision=None,
844
hardlink=False, stacked=False):
1251
hardlink=False, stacked=False, standalone=False, no_tree=False,
1252
use_existing_dir=False, switch=False, bind=False,
1254
from bzrlib import switch as _mod_switch
845
1255
from bzrlib.tag import _merge_tags_if_possible
848
elif len(revision) > 1:
849
raise errors.BzrCommandError(
850
'bzr branch --revision takes exactly 1 revision value')
1256
if self.invoked_as in ['get', 'clone']:
1257
ui.ui_factory.show_user_warning(
1258
'deprecated_command',
1259
deprecated_name=self.invoked_as,
1260
recommended_name='branch',
1261
deprecated_in_version='2.4')
852
1262
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1264
if not (hardlink or files_from):
1265
# accelerator_tree is usually slower because you have to read N
1266
# files (no readahead, lots of seeks, etc), but allow the user to
1267
# explicitly request it
1268
accelerator_tree = None
1269
if files_from is not None and files_from != from_location:
1270
accelerator_tree = WorkingTree.open(files_from)
1271
revision = _get_one_revision('branch', revision)
1272
self.add_cleanup(br_from.lock_read().unlock)
1273
if revision is not None:
1274
revision_id = revision.as_revision_id(br_from)
1276
# FIXME - wt.last_revision, fallback to branch, fall back to
1277
# None or perhaps NULL_REVISION to mean copy nothing
1279
revision_id = br_from.last_revision()
1280
if to_location is None:
1281
to_location = urlutils.derive_to_location(from_location)
1282
to_transport = transport.get_transport(to_location)
856
if len(revision) == 1 and revision[0] is not None:
857
revision_id = revision[0].as_revision_id(br_from)
1284
to_transport.mkdir('.')
1285
except errors.FileExists:
1286
if not use_existing_dir:
1287
raise errors.BzrCommandError('Target directory "%s" '
1288
'already exists.' % to_location)
859
# FIXME - wt.last_revision, fallback to branch, fall back to
860
# None or perhaps NULL_REVISION to mean copy nothing
862
revision_id = br_from.last_revision()
863
if to_location is None:
864
to_location = urlutils.derive_to_location(from_location)
865
to_transport = transport.get_transport(to_location)
867
to_transport.mkdir('.')
868
except errors.FileExists:
869
raise errors.BzrCommandError('Target directory "%s" already'
870
' exists.' % to_location)
871
except errors.NoSuchFile:
872
raise errors.BzrCommandError('Parent of "%s" does not exist.'
875
# preserve whatever source format we have.
876
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
877
possible_transports=[to_transport],
878
accelerator_tree=accelerator_tree,
879
hardlink=hardlink, stacked=stacked)
880
branch = dir.open_branch()
881
except errors.NoSuchRevision:
882
to_transport.delete_tree('.')
883
msg = "The branch %s has no revision %s." % (from_location,
885
raise errors.BzrCommandError(msg)
886
_merge_tags_if_possible(br_from, branch)
887
# If the source branch is stacked, the new branch may
888
# be stacked whether we asked for that explicitly or not.
889
# We therefore need a try/except here and not just 'if stacked:'
891
note('Created new stacked branch referring to %s.' %
892
branch.get_stacked_on_url())
893
except (errors.NotStacked, errors.UnstackableBranchFormat,
894
errors.UnstackableRepositoryFormat), e:
895
note('Branched %d revision(s).' % branch.revno())
1291
bzrdir.BzrDir.open_from_transport(to_transport)
1292
except errors.NotBranchError:
1295
raise errors.AlreadyBranchError(to_location)
1296
except errors.NoSuchFile:
1297
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1300
# preserve whatever source format we have.
1301
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1302
possible_transports=[to_transport],
1303
accelerator_tree=accelerator_tree,
1304
hardlink=hardlink, stacked=stacked,
1305
force_new_repo=standalone,
1306
create_tree_if_local=not no_tree,
1307
source_branch=br_from)
1308
branch = dir.open_branch()
1309
except errors.NoSuchRevision:
1310
to_transport.delete_tree('.')
1311
msg = "The branch %s has no revision %s." % (from_location,
1313
raise errors.BzrCommandError(msg)
1314
_merge_tags_if_possible(br_from, branch)
1315
# If the source branch is stacked, the new branch may
1316
# be stacked whether we asked for that explicitly or not.
1317
# We therefore need a try/except here and not just 'if stacked:'
1319
note('Created new stacked branch referring to %s.' %
1320
branch.get_stacked_on_url())
1321
except (errors.NotStacked, errors.UnstackableBranchFormat,
1322
errors.UnstackableRepositoryFormat), e:
1323
note('Branched %d revision(s).' % branch.revno())
1325
# Bind to the parent
1326
parent_branch = Branch.open(from_location)
1327
branch.bind(parent_branch)
1328
note('New branch bound to %s' % from_location)
1330
# Switch to the new branch
1331
wt, _ = WorkingTree.open_containing('.')
1332
_mod_switch.switch(wt.bzrdir, branch)
1333
note('Switched to branch: %s',
1334
urlutils.unescape_for_display(branch.base, 'utf-8'))
900
1337
class cmd_checkout(Command):
901
"""Create a new checkout of an existing branch.
1338
__doc__ = """Create a new checkout of an existing branch.
903
1340
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
904
1341
the branch found in '.'. This is useful if you have removed the working tree
905
1342
or if it was never created - i.e. if you pushed the branch to its current
906
1343
location using SFTP.
908
1345
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
909
1346
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
910
1347
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
982
1420
@display_command
983
1421
def run(self, dir=u'.'):
984
1422
tree = WorkingTree.open_containing(dir)[0]
987
new_inv = tree.inventory
988
old_tree = tree.basis_tree()
991
old_inv = old_tree.inventory
992
renames = list(_mod_tree.find_renames(old_inv, new_inv))
994
for old_name, new_name in renames:
995
self.outf.write("%s => %s\n" % (old_name, new_name))
1423
self.add_cleanup(tree.lock_read().unlock)
1424
new_inv = tree.inventory
1425
old_tree = tree.basis_tree()
1426
self.add_cleanup(old_tree.lock_read().unlock)
1427
old_inv = old_tree.inventory
1429
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1430
for f, paths, c, v, p, n, k, e in iterator:
1431
if paths[0] == paths[1]:
1435
renames.append(paths)
1437
for old_name, new_name in renames:
1438
self.outf.write("%s => %s\n" % (old_name, new_name))
1002
1441
class cmd_update(Command):
1003
"""Update a tree to have the latest code committed to its branch.
1442
__doc__ = """Update a tree to have the latest code committed to its branch.
1005
1444
This will perform a merge into the working tree, and may generate
1006
conflicts. If you have any local changes, you will still
1445
conflicts. If you have any local changes, you will still
1007
1446
need to commit them after the update for the update to be complete.
1009
If you want to discard your local changes, you can just do a
1448
If you want to discard your local changes, you can just do a
1010
1449
'bzr revert' instead of 'bzr commit' after the update.
1451
If you want to restore a file that has been removed locally, use
1452
'bzr revert' instead of 'bzr update'.
1454
If the tree's branch is bound to a master branch, it will also update
1455
the branch from the master.
1013
1458
_see_also = ['pull', 'working-trees', 'status-flags']
1014
1459
takes_args = ['dir?']
1460
takes_options = ['revision',
1462
help="Show base revision text in conflicts."),
1015
1464
aliases = ['up']
1017
def run(self, dir='.'):
1466
def run(self, dir='.', revision=None, show_base=None):
1467
if revision is not None and len(revision) != 1:
1468
raise errors.BzrCommandError(
1469
"bzr update --revision takes exactly one revision")
1018
1470
tree = WorkingTree.open_containing(dir)[0]
1471
branch = tree.branch
1019
1472
possible_transports = []
1020
master = tree.branch.get_master_branch(
1473
master = branch.get_master_branch(
1021
1474
possible_transports=possible_transports)
1022
1475
if master is not None:
1476
branch_location = master.base
1023
1477
tree.lock_write()
1479
branch_location = tree.branch.base
1025
1480
tree.lock_tree_write()
1481
self.add_cleanup(tree.unlock)
1482
# get rid of the final '/' and be ready for display
1483
branch_location = urlutils.unescape_for_display(
1484
branch_location.rstrip('/'),
1486
existing_pending_merges = tree.get_parent_ids()[1:]
1490
# may need to fetch data into a heavyweight checkout
1491
# XXX: this may take some time, maybe we should display a
1493
old_tip = branch.update(possible_transports)
1494
if revision is not None:
1495
revision_id = revision[0].as_revision_id(branch)
1497
revision_id = branch.last_revision()
1498
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1499
revno = branch.revision_id_to_dotted_revno(revision_id)
1500
note("Tree is up to date at revision %s of branch %s" %
1501
('.'.join(map(str, revno)), branch_location))
1503
view_info = _get_view_info_for_change_reporter(tree)
1504
change_reporter = delta._ChangeReporter(
1505
unversioned_filter=tree.is_ignored,
1506
view_info=view_info)
1027
existing_pending_merges = tree.get_parent_ids()[1:]
1028
last_rev = _mod_revision.ensure_null(tree.last_revision())
1029
if last_rev == _mod_revision.ensure_null(
1030
tree.branch.last_revision()):
1031
# may be up to date, check master too.
1032
if master is None or last_rev == _mod_revision.ensure_null(
1033
master.last_revision()):
1034
revno = tree.branch.revision_id_to_revno(last_rev)
1035
note("Tree is up to date at revision %d." % (revno,))
1037
1508
conflicts = tree.update(
1038
delta._ChangeReporter(unversioned_filter=tree.is_ignored),
1039
possible_transports=possible_transports)
1040
revno = tree.branch.revision_id_to_revno(
1041
_mod_revision.ensure_null(tree.last_revision()))
1042
note('Updated to revision %d.' % (revno,))
1043
if tree.get_parent_ids()[1:] != existing_pending_merges:
1044
note('Your local commits will now show as pending merges with '
1045
"'bzr status', and can be committed with 'bzr commit'.")
1510
possible_transports=possible_transports,
1511
revision=revision_id,
1513
show_base=show_base)
1514
except errors.NoSuchRevision, e:
1515
raise errors.BzrCommandError(
1516
"branch has no revision %s\n"
1517
"bzr update --revision only works"
1518
" for a revision in the branch history"
1520
revno = tree.branch.revision_id_to_dotted_revno(
1521
_mod_revision.ensure_null(tree.last_revision()))
1522
note('Updated to revision %s of branch %s' %
1523
('.'.join(map(str, revno)), branch_location))
1524
parent_ids = tree.get_parent_ids()
1525
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1526
note('Your local commits will now show as pending merges with '
1527
"'bzr status', and can be committed with 'bzr commit'.")
1054
1534
class cmd_info(Command):
1055
"""Show information about a working tree, branch or repository.
1535
__doc__ = """Show information about a working tree, branch or repository.
1057
1537
This command will show all known locations and formats associated to the
1058
tree, branch or repository. Statistical information is included with
1538
tree, branch or repository.
1540
In verbose mode, statistical information is included with each report.
1541
To see extended statistic information, use a verbosity level of 2 or
1542
higher by specifying the verbose option multiple times, e.g. -vv.
1061
1544
Branches and working trees will also report any missing revisions.
1548
Display information on the format and related locations:
1552
Display the above together with extended format information and
1553
basic statistics (like the number of files in the working tree and
1554
number of revisions in the branch and repository):
1558
Display the above together with number of committers to the branch:
1063
1562
_see_also = ['revno', 'working-trees', 'repositories']
1064
1563
takes_args = ['location?']
1090
1590
RegistryOption.from_kwargs('file-deletion-strategy',
1091
1591
'The file deletion mode to be used.',
1092
1592
title='Deletion Strategy', value_switches=True, enum_switch=False,
1093
safe='Only delete files if they can be'
1094
' safely recovered (default).',
1095
keep="Don't delete any files.",
1593
safe='Backup changed files (default).',
1594
keep='Delete from bzr but leave the working copy.',
1595
no_backup='Don\'t backup changed files.',
1096
1596
force='Delete all the specified files, even if they can not be '
1097
'recovered and even if they are non-empty directories.')]
1597
'recovered and even if they are non-empty directories. '
1598
'(deprecated, use no-backup)')]
1098
1599
aliases = ['rm', 'del']
1099
1600
encoding_type = 'replace'
1101
1602
def run(self, file_list, verbose=False, new=False,
1102
1603
file_deletion_strategy='safe'):
1103
tree, file_list = tree_files(file_list)
1604
if file_deletion_strategy == 'force':
1605
note("(The --force option is deprecated, rather use --no-backup "
1607
file_deletion_strategy = 'no-backup'
1609
tree, file_list = WorkingTree.open_containing_paths(file_list)
1105
1611
if file_list is not None:
1106
1612
file_list = [f for f in file_list]
1110
# Heuristics should probably all move into tree.remove_smart or
1113
added = tree.changes_from(tree.basis_tree(),
1114
specific_files=file_list).added
1115
file_list = sorted([f[0] for f in added], reverse=True)
1116
if len(file_list) == 0:
1117
raise errors.BzrCommandError('No matching files.')
1118
elif file_list is None:
1119
# missing files show up in iter_changes(basis) as
1120
# versioned-with-no-kind.
1122
for change in tree.iter_changes(tree.basis_tree()):
1123
# Find paths in the working tree that have no kind:
1124
if change[1][1] is not None and change[6][1] is None:
1125
missing.append(change[1][1])
1126
file_list = sorted(missing, reverse=True)
1127
file_deletion_strategy = 'keep'
1128
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1129
keep_files=file_deletion_strategy=='keep',
1130
force=file_deletion_strategy=='force')
1614
self.add_cleanup(tree.lock_write().unlock)
1615
# Heuristics should probably all move into tree.remove_smart or
1618
added = tree.changes_from(tree.basis_tree(),
1619
specific_files=file_list).added
1620
file_list = sorted([f[0] for f in added], reverse=True)
1621
if len(file_list) == 0:
1622
raise errors.BzrCommandError('No matching files.')
1623
elif file_list is None:
1624
# missing files show up in iter_changes(basis) as
1625
# versioned-with-no-kind.
1627
for change in tree.iter_changes(tree.basis_tree()):
1628
# Find paths in the working tree that have no kind:
1629
if change[1][1] is not None and change[6][1] is None:
1630
missing.append(change[1][1])
1631
file_list = sorted(missing, reverse=True)
1632
file_deletion_strategy = 'keep'
1633
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1634
keep_files=file_deletion_strategy=='keep',
1635
force=(file_deletion_strategy=='no-backup'))
1135
1638
class cmd_file_id(Command):
1136
"""Print file_id of a particular file or directory.
1639
__doc__ = """Print file_id of a particular file or directory.
1138
1641
The file_id is assigned when the file is first added and remains the
1139
1642
same through all revisions where the file exists, even when it is
1628
2197
raise errors.BzrCommandError(msg)
2200
def _parse_levels(s):
2204
msg = "The levels argument must be an integer."
2205
raise errors.BzrCommandError(msg)
1631
2208
class cmd_log(Command):
1632
"""Show log of a branch, file, or directory.
1634
By default show the log of the branch containing the working directory.
1636
To request a range of logs, you can use the command -r begin..end
1637
-r revision requests a specific revision, -r ..end or -r begin.. are
1641
Log the current branch::
1649
Log the last 10 revisions of a branch::
1651
bzr log -r -10.. http://server/branch
2209
__doc__ = """Show historical log for a branch or subset of a branch.
2211
log is bzr's default tool for exploring the history of a branch.
2212
The branch to use is taken from the first parameter. If no parameters
2213
are given, the branch containing the working directory is logged.
2214
Here are some simple examples::
2216
bzr log log the current branch
2217
bzr log foo.py log a file in its branch
2218
bzr log http://server/branch log a branch on a server
2220
The filtering, ordering and information shown for each revision can
2221
be controlled as explained below. By default, all revisions are
2222
shown sorted (topologically) so that newer revisions appear before
2223
older ones and descendants always appear before ancestors. If displayed,
2224
merged revisions are shown indented under the revision in which they
2229
The log format controls how information about each revision is
2230
displayed. The standard log formats are called ``long``, ``short``
2231
and ``line``. The default is long. See ``bzr help log-formats``
2232
for more details on log formats.
2234
The following options can be used to control what information is
2237
-l N display a maximum of N revisions
2238
-n N display N levels of revisions (0 for all, 1 for collapsed)
2239
-v display a status summary (delta) for each revision
2240
-p display a diff (patch) for each revision
2241
--show-ids display revision-ids (and file-ids), not just revnos
2243
Note that the default number of levels to display is a function of the
2244
log format. If the -n option is not used, the standard log formats show
2245
just the top level (mainline).
2247
Status summaries are shown using status flags like A, M, etc. To see
2248
the changes explained using words like ``added`` and ``modified``
2249
instead, use the -vv option.
2253
To display revisions from oldest to newest, use the --forward option.
2254
In most cases, using this option will have little impact on the total
2255
time taken to produce a log, though --forward does not incrementally
2256
display revisions like --reverse does when it can.
2258
:Revision filtering:
2260
The -r option can be used to specify what revision or range of revisions
2261
to filter against. The various forms are shown below::
2263
-rX display revision X
2264
-rX.. display revision X and later
2265
-r..Y display up to and including revision Y
2266
-rX..Y display from X to Y inclusive
2268
See ``bzr help revisionspec`` for details on how to specify X and Y.
2269
Some common examples are given below::
2271
-r-1 show just the tip
2272
-r-10.. show the last 10 mainline revisions
2273
-rsubmit:.. show what's new on this branch
2274
-rancestor:path.. show changes since the common ancestor of this
2275
branch and the one at location path
2276
-rdate:yesterday.. show changes since yesterday
2278
When logging a range of revisions using -rX..Y, log starts at
2279
revision Y and searches back in history through the primary
2280
("left-hand") parents until it finds X. When logging just the
2281
top level (using -n1), an error is reported if X is not found
2282
along the way. If multi-level logging is used (-n0), X may be
2283
a nested merge revision and the log will be truncated accordingly.
2287
If parameters are given and the first one is not a branch, the log
2288
will be filtered to show only those revisions that changed the
2289
nominated files or directories.
2291
Filenames are interpreted within their historical context. To log a
2292
deleted file, specify a revision range so that the file existed at
2293
the end or start of the range.
2295
Historical context is also important when interpreting pathnames of
2296
renamed files/directories. Consider the following example:
2298
* revision 1: add tutorial.txt
2299
* revision 2: modify tutorial.txt
2300
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2304
* ``bzr log guide.txt`` will log the file added in revision 1
2306
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2308
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2309
the original file in revision 2.
2311
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2312
was no file called guide.txt in revision 2.
2314
Renames are always followed by log. By design, there is no need to
2315
explicitly ask for this (and no way to stop logging a file back
2316
until it was last renamed).
2320
The --match option can be used for finding revisions that match a
2321
regular expression in a commit message, committer, author or bug.
2322
Specifying the option several times will match any of the supplied
2323
expressions. --match-author, --match-bugs, --match-committer and
2324
--match-message can be used to only match a specific field.
2328
GUI tools and IDEs are often better at exploring history than command
2329
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2330
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2331
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2332
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2334
You may find it useful to add the aliases below to ``bazaar.conf``::
2338
top = log -l10 --line
2341
``bzr tip`` will then show the latest revision while ``bzr top``
2342
will show the last 10 mainline revisions. To see the details of a
2343
particular revision X, ``bzr show -rX``.
2345
If you are interested in looking deeper into a particular merge X,
2346
use ``bzr log -n0 -rX``.
2348
``bzr log -v`` on a branch with lots of history is currently
2349
very slow. A fix for this issue is currently under development.
2350
With or without that fix, it is recommended that a revision range
2351
be given when using the -v option.
2353
bzr has a generic full-text matching plugin, bzr-search, that can be
2354
used to find revisions matching user names, commit messages, etc.
2355
Among other features, this plugin can find all revisions containing
2356
a list of words but not others.
2358
When exploring non-mainline history on large projects with deep
2359
history, the performance of log can be greatly improved by installing
2360
the historycache plugin. This plugin buffers historical information
2361
trading disk space for faster speed.
1654
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1656
takes_args = ['location?']
2363
takes_args = ['file*']
2364
_see_also = ['log-formats', 'revisionspec']
1657
2365
takes_options = [
1658
2366
Option('forward',
1659
2367
help='Show from oldest to newest.'),
1662
help='Display timezone as local, original, or utc.'),
1663
2369
custom_help('verbose',
1664
2370
help='Show files changed in each revision.'),
2374
type=bzrlib.option._parse_revision_str,
2376
help='Show just the specified revision.'
2377
' See also "help revisionspec".'),
2379
RegistryOption('authors',
2380
'What names to list as authors - first, all or committer.',
2382
lazy_registry=('bzrlib.log', 'author_list_registry'),
2386
help='Number of levels to display - 0 for all, 1 for flat.',
2388
type=_parse_levels),
1668
2389
Option('message',
1670
2390
help='Show revisions whose message matches this '
1671
2391
'regular expression.',
1673
2394
Option('limit',
1674
2395
short_name='l',
1675
2396
help='Limit the output to the first N revisions.',
1677
2398
type=_parse_limit),
2401
help='Show changes made in each revision as a patch.'),
2402
Option('include-merges',
2403
help='Show merged revisions like --levels 0 does.'),
2404
Option('exclude-common-ancestry',
2405
help='Display only the revisions that are not part'
2406
' of both ancestries (require -rX..Y)'
2408
Option('signatures',
2409
help='Show digital signature validity'),
2412
help='Show revisions whose properties match this '
2415
ListOption('match-message',
2416
help='Show revisions whose message matches this '
2419
ListOption('match-committer',
2420
help='Show revisions whose committer matches this '
2423
ListOption('match-author',
2424
help='Show revisions whose authors match this '
2427
ListOption('match-bugs',
2428
help='Show revisions whose bugs match this '
1679
2432
encoding_type = 'replace'
1681
2434
@display_command
1682
def run(self, location=None, timezone='original',
2435
def run(self, file_list=None, timezone='original',
1684
2437
show_ids=False,
1687
2441
log_format=None,
1690
from bzrlib.log import show_log
2446
include_merges=False,
2448
exclude_common_ancestry=False,
2452
match_committer=None,
2456
from bzrlib.log import (
2458
make_log_request_dict,
2459
_get_info_for_log_files,
1691
2461
direction = (forward and 'forward') or 'reverse'
1696
# find the file id to log:
1698
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1702
tree = b.basis_tree()
1703
file_id = tree.path2id(fp)
2462
if (exclude_common_ancestry
2463
and (revision is None or len(revision) != 2)):
2464
raise errors.BzrCommandError(
2465
'--exclude-common-ancestry requires -r with two revisions')
2470
raise errors.BzrCommandError(
2471
'--levels and --include-merges are mutually exclusive')
2473
if change is not None:
2475
raise errors.RangeInChangeOption()
2476
if revision is not None:
2477
raise errors.BzrCommandError(
2478
'--revision and --change are mutually exclusive')
2483
filter_by_dir = False
2485
# find the file ids to log and check for directory filtering
2486
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2487
revision, file_list, self.add_cleanup)
2488
for relpath, file_id, kind in file_info_list:
1704
2489
if file_id is None:
1705
2490
raise errors.BzrCommandError(
1706
"Path does not have any revision history: %s" %
2491
"Path unknown at end or start of revision range: %s" %
2493
# If the relpath is the top of the tree, we log everything
2498
file_ids.append(file_id)
2499
filter_by_dir = filter_by_dir or (
2500
kind in ['directory', 'tree-reference'])
1710
# FIXME ? log the current subdir only RBC 20060203
2503
# FIXME ? log the current subdir only RBC 20060203
1711
2504
if revision is not None \
1712
2505
and len(revision) > 0 and revision[0].get_branch():
1713
2506
location = revision[0].get_branch()
1716
2509
dir, relpath = bzrdir.BzrDir.open_containing(location)
1717
2510
b = dir.open_branch()
1721
if revision is None:
1724
elif len(revision) == 1:
1725
rev1 = rev2 = revision[0].in_history(b)
1726
elif len(revision) == 2:
1727
if revision[1].get_branch() != revision[0].get_branch():
1728
# b is taken from revision[0].get_branch(), and
1729
# show_log will use its revision_history. Having
1730
# different branches will lead to weird behaviors.
1731
raise errors.BzrCommandError(
1732
"Log doesn't accept two revisions in different"
1734
rev1 = revision[0].in_history(b)
1735
rev2 = revision[1].in_history(b)
1737
raise errors.BzrCommandError(
1738
'bzr log --revision takes one or two values.')
1740
if log_format is None:
1741
log_format = log.log_formatter_registry.get_default(b)
1743
lf = log_format(show_ids=show_ids, to_file=self.outf,
1744
show_timezone=timezone)
1750
direction=direction,
1751
start_revision=rev1,
2511
self.add_cleanup(b.lock_read().unlock)
2512
rev1, rev2 = _get_revision_range(revision, b, self.name())
2514
if b.get_config().validate_signatures_in_log():
2518
if not gpg.GPGStrategy.verify_signatures_available():
2519
raise errors.GpgmeNotInstalled(None)
2521
# Decide on the type of delta & diff filtering to use
2522
# TODO: add an --all-files option to make this configurable & consistent
2530
diff_type = 'partial'
2534
# Build the log formatter
2535
if log_format is None:
2536
log_format = log.log_formatter_registry.get_default(b)
2537
# Make a non-encoding output to include the diffs - bug 328007
2538
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2539
lf = log_format(show_ids=show_ids, to_file=self.outf,
2540
to_exact_file=unencoded_output,
2541
show_timezone=timezone,
2542
delta_format=get_verbosity_level(),
2544
show_advice=levels is None,
2545
author_list_handler=authors)
2547
# Choose the algorithm for doing the logging. It's annoying
2548
# having multiple code paths like this but necessary until
2549
# the underlying repository format is faster at generating
2550
# deltas or can provide everything we need from the indices.
2551
# The default algorithm - match-using-deltas - works for
2552
# multiple files and directories and is faster for small
2553
# amounts of history (200 revisions say). However, it's too
2554
# slow for logging a single file in a repository with deep
2555
# history, i.e. > 10K revisions. In the spirit of "do no
2556
# evil when adding features", we continue to use the
2557
# original algorithm - per-file-graph - for the "single
2558
# file that isn't a directory without showing a delta" case.
2559
partial_history = revision and b.repository._format.supports_chks
2560
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2561
or delta_type or partial_history)
2565
match_dict[''] = match
2567
match_dict['message'] = match_message
2569
match_dict['committer'] = match_committer
2571
match_dict['author'] = match_author
2573
match_dict['bugs'] = match_bugs
2575
# Build the LogRequest and execute it
2576
if len(file_ids) == 0:
2578
rqst = make_log_request_dict(
2579
direction=direction, specific_fileids=file_ids,
2580
start_revision=rev1, end_revision=rev2, limit=limit,
2581
message_search=message, delta_type=delta_type,
2582
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2583
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2584
signature=signatures
2586
Logger(b, rqst).show(lf)
2589
def _get_revision_range(revisionspec_list, branch, command_name):
2590
"""Take the input of a revision option and turn it into a revision range.
2592
It returns RevisionInfo objects which can be used to obtain the rev_id's
2593
of the desired revisions. It does some user input validations.
2595
if revisionspec_list is None:
2598
elif len(revisionspec_list) == 1:
2599
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2600
elif len(revisionspec_list) == 2:
2601
start_spec = revisionspec_list[0]
2602
end_spec = revisionspec_list[1]
2603
if end_spec.get_branch() != start_spec.get_branch():
2604
# b is taken from revision[0].get_branch(), and
2605
# show_log will use its revision_history. Having
2606
# different branches will lead to weird behaviors.
2607
raise errors.BzrCommandError(
2608
"bzr %s doesn't accept two revisions in different"
2609
" branches." % command_name)
2610
if start_spec.spec is None:
2611
# Avoid loading all the history.
2612
rev1 = RevisionInfo(branch, None, None)
2614
rev1 = start_spec.in_history(branch)
2615
# Avoid loading all of history when we know a missing
2616
# end of range means the last revision ...
2617
if end_spec.spec is None:
2618
last_revno, last_revision_id = branch.last_revision_info()
2619
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2621
rev2 = end_spec.in_history(branch)
2623
raise errors.BzrCommandError(
2624
'bzr %s --revision takes one or two values.' % command_name)
2628
def _revision_range_to_revid_range(revision_range):
2631
if revision_range[0] is not None:
2632
rev_id1 = revision_range[0].rev_id
2633
if revision_range[1] is not None:
2634
rev_id2 = revision_range[1].rev_id
2635
return rev_id1, rev_id2
1759
2637
def get_log_format(long=False, short=False, line=False, default='long'):
1760
2638
log_format = default
1829
2709
if path is None:
1834
2713
raise errors.BzrCommandError('cannot specify both --from-root'
1838
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2716
tree, branch, relpath = \
2717
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2719
# Calculate the prefix to use
1844
if revision is not None:
1845
tree = branch.repository.revision_tree(
1846
revision[0].as_revision_id(branch))
1848
tree = branch.basis_tree()
1852
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1853
if fp.startswith(relpath):
1854
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1855
if non_recursive and '/' in fp:
1857
if not all and not selection[fc]:
1859
if kind is not None and fkind != kind:
1862
kindch = entry.kind_character()
1863
outstring = '%-8s %s%s' % (fc, fp, kindch)
1864
if show_ids and fid is not None:
1865
outstring = "%-50s %s" % (outstring, fid)
1866
self.outf.write(outstring + '\n')
1868
self.outf.write(fp + '\0')
1871
self.outf.write(fid)
1872
self.outf.write('\0')
1880
self.outf.write('%-50s %s\n' % (fp, my_id))
1882
self.outf.write(fp + '\n')
2723
prefix = relpath + '/'
2724
elif fs_path != '.' and not fs_path.endswith('/'):
2725
prefix = fs_path + '/'
2727
if revision is not None or tree is None:
2728
tree = _get_one_revision_tree('ls', revision, branch=branch)
2731
if isinstance(tree, WorkingTree) and tree.supports_views():
2732
view_files = tree.views.lookup_view()
2735
view_str = views.view_display_str(view_files)
2736
note("Ignoring files outside view. View is %s" % view_str)
2738
self.add_cleanup(tree.lock_read().unlock)
2739
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2740
from_dir=relpath, recursive=recursive):
2741
# Apply additional masking
2742
if not all and not selection[fc]:
2744
if kind is not None and fkind != kind:
2749
fullpath = osutils.pathjoin(relpath, fp)
2752
views.check_path_in_view(tree, fullpath)
2753
except errors.FileOutsideView:
2758
fp = osutils.pathjoin(prefix, fp)
2759
kindch = entry.kind_character()
2760
outstring = fp + kindch
2761
ui.ui_factory.clear_term()
2763
outstring = '%-8s %s' % (fc, outstring)
2764
if show_ids and fid is not None:
2765
outstring = "%-50s %s" % (outstring, fid)
2766
self.outf.write(outstring + '\n')
2768
self.outf.write(fp + '\0')
2771
self.outf.write(fid)
2772
self.outf.write('\0')
2780
self.outf.write('%-50s %s\n' % (outstring, my_id))
2782
self.outf.write(outstring + '\n')
1887
2785
class cmd_unknowns(Command):
1888
"""List unknown files.
2786
__doc__ = """List unknown files.
1892
2790
_see_also = ['ls']
2791
takes_options = ['directory']
1894
2793
@display_command
1896
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2794
def run(self, directory=u'.'):
2795
for f in WorkingTree.open_containing(directory)[0].unknowns():
1897
2796
self.outf.write(osutils.quotefn(f) + '\n')
1900
2799
class cmd_ignore(Command):
1901
"""Ignore specified files or patterns.
2800
__doc__ = """Ignore specified files or patterns.
1903
2802
See ``bzr help patterns`` for details on the syntax of patterns.
2804
If a .bzrignore file does not exist, the ignore command
2805
will create one and add the specified files or patterns to the newly
2806
created file. The ignore command will also automatically add the
2807
.bzrignore file to be versioned. Creating a .bzrignore file without
2808
the use of the ignore command will require an explicit add command.
1905
2810
To remove patterns from the ignore list, edit the .bzrignore file.
1906
2811
After adding, editing or deleting that file either indirectly by
1907
2812
using this command or directly by using an editor, be sure to commit
1910
Note: ignore patterns containing shell wildcards must be quoted from
2815
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2816
the global ignore file can be found in the application data directory as
2817
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2818
Global ignores are not touched by this command. The global ignore file
2819
can be edited directly using an editor.
2821
Patterns prefixed with '!' are exceptions to ignore patterns and take
2822
precedence over regular ignores. Such exceptions are used to specify
2823
files that should be versioned which would otherwise be ignored.
2825
Patterns prefixed with '!!' act as regular ignore patterns, but have
2826
precedence over the '!' exception patterns.
2830
* Ignore patterns containing shell wildcards must be quoted from
2833
* Ignore patterns starting with "#" act as comments in the ignore file.
2834
To ignore patterns that begin with that character, use the "RE:" prefix.
1914
2837
Ignore the top level Makefile::
1916
2839
bzr ignore ./Makefile
1918
Ignore class files in all directories::
2841
Ignore .class files in all directories...::
1920
2843
bzr ignore "*.class"
2845
...but do not ignore "special.class"::
2847
bzr ignore "!special.class"
2849
Ignore files whose name begins with the "#" character::
1922
2853
Ignore .o files under the lib directory::
1924
2855
bzr ignore "lib/**/*.o"
2050
2998
================= =========================
2052
3001
takes_args = ['dest', 'branch_or_subdir?']
3002
takes_options = ['directory',
2054
3003
Option('format',
2055
3004
help="Type of file to export to.",
3007
Option('filters', help='Apply content filters to export the '
3008
'convenient form.'),
2060
3011
help="Name of the root directory inside the exported file."),
3012
Option('per-file-timestamps',
3013
help='Set modification time of files to that of the last '
3014
'revision in which it was changed.'),
2062
3016
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3017
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2064
3018
from bzrlib.export import export
2066
3020
if branch_or_subdir is None:
2067
tree = WorkingTree.open_containing(u'.')[0]
3021
tree = WorkingTree.open_containing(directory)[0]
2068
3022
b = tree.branch
2071
3025
b, subdir = Branch.open_containing(branch_or_subdir)
2073
if revision is None:
2074
# should be tree.last_revision FIXME
2075
rev_id = b.last_revision()
2077
if len(revision) != 1:
2078
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
2079
rev_id = revision[0].as_revision_id(b)
2080
t = b.repository.revision_tree(rev_id)
3028
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2082
export(t, dest, format, root, subdir)
3030
export(rev_tree, dest, format, root, subdir, filtered=filters,
3031
per_file_timestamps=per_file_timestamps)
2083
3032
except errors.NoSuchExportFormat, e:
2084
3033
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2087
3036
class cmd_cat(Command):
2088
"""Write the contents of a file as of a given revision to standard output.
3037
__doc__ = """Write the contents of a file as of a given revision to standard output.
2090
3039
If no revision is nominated, the last revision is used.
2092
3041
Note: Take care to redirect standard output when using this command on a
2096
3045
_see_also = ['ls']
3046
takes_options = ['directory',
2098
3047
Option('name-from-revision', help='The path name in the old tree.'),
3048
Option('filters', help='Apply content filters to display the '
3049
'convenience form.'),
2101
3052
takes_args = ['filename']
2102
3053
encoding_type = 'exact'
2104
3055
@display_command
2105
def run(self, filename, revision=None, name_from_revision=False):
3056
def run(self, filename, revision=None, name_from_revision=False,
3057
filters=False, directory=None):
2106
3058
if revision is not None and len(revision) != 1:
2107
3059
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2108
3060
" one revision specifier")
2109
3061
tree, branch, relpath = \
2110
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2113
return self._run(tree, branch, relpath, filename, revision,
3062
_open_directory_or_containing_tree_or_branch(filename, directory)
3063
self.add_cleanup(branch.lock_read().unlock)
3064
return self._run(tree, branch, relpath, filename, revision,
3065
name_from_revision, filters)
2118
def _run(self, tree, b, relpath, filename, revision, name_from_revision):
3067
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2119
3069
if tree is None:
2120
3070
tree = b.basis_tree()
2121
if revision is None:
2122
revision_id = b.last_revision()
2124
revision_id = revision[0].as_revision_id(b)
3071
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3072
self.add_cleanup(rev_tree.lock_read().unlock)
2126
cur_file_id = tree.path2id(relpath)
2127
rev_tree = b.repository.revision_tree(revision_id)
2128
3074
old_file_id = rev_tree.path2id(relpath)
3076
# TODO: Split out this code to something that generically finds the
3077
# best id for a path across one or more trees; it's like
3078
# find_ids_across_trees but restricted to find just one. -- mbp
2130
3080
if name_from_revision:
3081
# Try in revision if requested
2131
3082
if old_file_id is None:
2132
raise errors.BzrCommandError("%r is not present in revision %s"
2133
% (filename, revision_id))
2135
content = rev_tree.get_file_text(old_file_id)
2136
elif cur_file_id is not None:
2137
content = rev_tree.get_file_text(cur_file_id)
2138
elif old_file_id is not None:
2139
content = rev_tree.get_file_text(old_file_id)
2141
raise errors.BzrCommandError("%r is not present in revision %s" %
2142
(filename, revision_id))
3083
raise errors.BzrCommandError(
3084
"%r is not present in revision %s" % (
3085
filename, rev_tree.get_revision_id()))
3087
actual_file_id = old_file_id
3089
cur_file_id = tree.path2id(relpath)
3090
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3091
actual_file_id = cur_file_id
3092
elif old_file_id is not None:
3093
actual_file_id = old_file_id
3095
raise errors.BzrCommandError(
3096
"%r is not present in revision %s" % (
3097
filename, rev_tree.get_revision_id()))
3099
from bzrlib.filter_tree import ContentFilterTree
3100
filter_tree = ContentFilterTree(rev_tree,
3101
rev_tree._content_filter_stack)
3102
content = filter_tree.get_file_text(actual_file_id)
3104
content = rev_tree.get_file_text(actual_file_id)
2143
3106
self.outf.write(content)
2146
3109
class cmd_local_time_offset(Command):
2147
"""Show the offset in seconds from GMT to local time."""
3110
__doc__ = """Show the offset in seconds from GMT to local time."""
2149
3112
@display_command
2151
print osutils.local_time_offset()
3114
self.outf.write("%s\n" % osutils.local_time_offset())
2155
3118
class cmd_commit(Command):
2156
"""Commit changes into a new revision.
2158
If no arguments are given, the entire tree is committed.
2160
If selected files are specified, only changes to those files are
2161
committed. If a directory is specified then the directory and everything
2162
within it is committed.
2164
When excludes are given, they take precedence over selected files.
2165
For example, too commit only changes within foo, but not changes within
2168
bzr commit foo -x foo/bar
2170
If author of the change is not the same person as the committer, you can
2171
specify the author's name using the --author option. The name should be
2172
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2174
A selected-file commit may fail in some cases where the committed
2175
tree would be invalid. Consider::
2180
bzr commit foo -m "committing foo"
2181
bzr mv foo/bar foo/baz
2184
bzr commit foo/bar -m "committing bar but not baz"
2186
In the example above, the last commit will fail by design. This gives
2187
the user the opportunity to decide whether they want to commit the
2188
rename at the same time, separately first, or not at all. (As a general
2189
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2191
Note: A selected-file commit after a merge is not yet supported.
3119
__doc__ = """Commit changes into a new revision.
3121
An explanatory message needs to be given for each commit. This is
3122
often done by using the --message option (getting the message from the
3123
command line) or by using the --file option (getting the message from
3124
a file). If neither of these options is given, an editor is opened for
3125
the user to enter the message. To see the changed files in the
3126
boilerplate text loaded into the editor, use the --show-diff option.
3128
By default, the entire tree is committed and the person doing the
3129
commit is assumed to be the author. These defaults can be overridden
3134
If selected files are specified, only changes to those files are
3135
committed. If a directory is specified then the directory and
3136
everything within it is committed.
3138
When excludes are given, they take precedence over selected files.
3139
For example, to commit only changes within foo, but not changes
3142
bzr commit foo -x foo/bar
3144
A selective commit after a merge is not yet supported.
3148
If the author of the change is not the same person as the committer,
3149
you can specify the author's name using the --author option. The
3150
name should be in the same format as a committer-id, e.g.
3151
"John Doe <jdoe@example.com>". If there is more than one author of
3152
the change you can specify the option multiple times, once for each
3157
A common mistake is to forget to add a new file or directory before
3158
running the commit command. The --strict option checks for unknown
3159
files and aborts the commit if any are found. More advanced pre-commit
3160
checks can be implemented by defining hooks. See ``bzr help hooks``
3165
If you accidentially commit the wrong changes or make a spelling
3166
mistake in the commit message say, you can use the uncommit command
3167
to undo it. See ``bzr help uncommit`` for details.
3169
Hooks can also be configured to run after a commit. This allows you
3170
to trigger updates to external systems like bug trackers. The --fixes
3171
option can be used to record the association between a revision and
3172
one or more bugs. See ``bzr help bugs`` for details.
2193
# TODO: Run hooks on tree to-be-committed, and after commit.
2195
# TODO: Strict commit that fails if there are deleted files.
2196
# (what does "deleted files" mean ??)
2198
# TODO: Give better message for -s, --summary, used by tla people
2200
# XXX: verbose currently does nothing
2202
_see_also = ['bugs', 'uncommit']
3175
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2203
3176
takes_args = ['selected*']
2204
3177
takes_options = [
2205
3178
ListOption('exclude', type=str, short_name='x',
2674
3767
encoding_type = 'replace'
3770
Command.__init__(self)
3771
self.additional_selftest_args = {}
2676
3773
def run(self, testspecs_list=None, verbose=False, one=False,
2677
3774
transport=None, benchmark=None,
2678
lsprof_timed=None, cache_dir=None,
2679
3776
first=False, list_only=False,
2680
3777
randomize=None, exclude=None, strict=False,
2681
load_list=None, debugflag=None, starting_with=None):
2683
from bzrlib.tests import selftest
2684
import bzrlib.benchmarks as benchmarks
2685
from bzrlib.benchmarks import tree_creator
2687
# Make deprecation warnings visible, unless -Werror is set
2688
symbol_versioning.activate_deprecation_warnings(override=False)
2690
if cache_dir is not None:
2691
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2693
print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
2694
print ' %s (%s python%s)' % (
2696
bzrlib.version_string,
2697
bzrlib._format_version_tuple(sys.version_info),
3778
load_list=None, debugflag=None, starting_with=None, subunit=False,
3779
parallel=None, lsprof_tests=False):
3780
from bzrlib import tests
2700
3782
if testspecs_list is not None:
2701
3783
pattern = '|'.join(testspecs_list)
3788
from bzrlib.tests import SubUnitBzrRunner
3790
raise errors.BzrCommandError("subunit not available. subunit "
3791
"needs to be installed to use --subunit.")
3792
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3793
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3794
# stdout, which would corrupt the subunit stream.
3795
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3796
# following code can be deleted when it's sufficiently deployed
3797
# -- vila/mgz 20100514
3798
if (sys.platform == "win32"
3799
and getattr(sys.stdout, 'fileno', None) is not None):
3801
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3803
self.additional_selftest_args.setdefault(
3804
'suite_decorators', []).append(parallel)
2705
test_suite_factory = benchmarks.test_suite
2706
# Unless user explicitly asks for quiet, be verbose in benchmarks
2707
verbose = not is_quiet()
2708
# TODO: should possibly lock the history file...
2709
benchfile = open(".perf_history", "at", buffering=1)
3806
raise errors.BzrCommandError(
3807
"--benchmark is no longer supported from bzr 2.2; "
3808
"use bzr-usertest instead")
3809
test_suite_factory = None
3811
exclude_pattern = None
2711
test_suite_factory = None
3813
exclude_pattern = '(' + '|'.join(exclude) + ')'
3814
selftest_kwargs = {"verbose": verbose,
3816
"stop_on_failure": one,
3817
"transport": transport,
3818
"test_suite_factory": test_suite_factory,
3819
"lsprof_timed": lsprof_timed,
3820
"lsprof_tests": lsprof_tests,
3821
"matching_tests_first": first,
3822
"list_only": list_only,
3823
"random_seed": randomize,
3824
"exclude_pattern": exclude_pattern,
3826
"load_list": load_list,
3827
"debug_flags": debugflag,
3828
"starting_with": starting_with
3830
selftest_kwargs.update(self.additional_selftest_args)
3832
# Make deprecation warnings visible, unless -Werror is set
3833
cleanup = symbol_versioning.activate_deprecation_warnings(
2714
result = selftest(verbose=verbose,
2716
stop_on_failure=one,
2717
transport=transport,
2718
test_suite_factory=test_suite_factory,
2719
lsprof_timed=lsprof_timed,
2720
bench_history=benchfile,
2721
matching_tests_first=first,
2722
list_only=list_only,
2723
random_seed=randomize,
2724
exclude_pattern=exclude,
2726
load_list=load_list,
2727
debug_flags=debugflag,
2728
starting_with=starting_with,
3836
result = tests.selftest(**selftest_kwargs)
2731
if benchfile is not None:
2734
note('tests passed')
2736
note('tests failed')
2737
3839
return int(not result)
2740
3842
class cmd_version(Command):
2741
"""Show version of bzr."""
3843
__doc__ = """Show version of bzr."""
2743
3845
encoding_type = 'replace'
2744
3846
takes_options = [
2757
3859
class cmd_rocks(Command):
2758
"""Statement of optimism."""
3860
__doc__ = """Statement of optimism."""
2762
3864
@display_command
2764
print "It sure does!"
3866
self.outf.write("It sure does!\n")
2767
3869
class cmd_find_merge_base(Command):
2768
"""Find and print a base revision for merging two branches."""
3870
__doc__ = """Find and print a base revision for merging two branches."""
2769
3871
# TODO: Options to specify revisions on either side, as if
2770
3872
# merging only part of the history.
2771
3873
takes_args = ['branch', 'other']
2774
3876
@display_command
2775
3877
def run(self, branch, other):
2776
3878
from bzrlib.revision import ensure_null
2778
3880
branch1 = Branch.open_containing(branch)[0]
2779
3881
branch2 = Branch.open_containing(other)[0]
2784
last1 = ensure_null(branch1.last_revision())
2785
last2 = ensure_null(branch2.last_revision())
2787
graph = branch1.repository.get_graph(branch2.repository)
2788
base_rev_id = graph.find_unique_lca(last1, last2)
2790
print 'merge base is revision %s' % base_rev_id
3882
self.add_cleanup(branch1.lock_read().unlock)
3883
self.add_cleanup(branch2.lock_read().unlock)
3884
last1 = ensure_null(branch1.last_revision())
3885
last2 = ensure_null(branch2.last_revision())
3887
graph = branch1.repository.get_graph(branch2.repository)
3888
base_rev_id = graph.find_unique_lca(last1, last2)
3890
self.outf.write('merge base is revision %s\n' % base_rev_id)
2797
3893
class cmd_merge(Command):
2798
"""Perform a three-way merge.
3894
__doc__ = """Perform a three-way merge.
2800
3896
The source of the merge can be specified either in the form of a branch,
2801
3897
or in the form of a path to a file containing a merge directive generated
2802
3898
with bzr send. If neither is specified, the default is the upstream branch
2803
or the branch most recently merged using --remember.
2805
When merging a branch, by default the tip will be merged. To pick a different
2806
revision, pass --revision. If you specify two values, the first will be used as
2807
BASE and the second one as OTHER. Merging individual revisions, or a subset of
2808
available revisions, like this is commonly referred to as "cherrypicking".
2810
Revision numbers are always relative to the branch being merged.
2812
By default, bzr will try to merge in all new work from the other
2813
branch, automatically determining an appropriate base. If this
2814
fails, you may need to give an explicit base.
3899
or the branch most recently merged using --remember. The source of the
3900
merge may also be specified in the form of a path to a file in another
3901
branch: in this case, only the modifications to that file are merged into
3902
the current working tree.
3904
When merging from a branch, by default bzr will try to merge in all new
3905
work from the other branch, automatically determining an appropriate base
3906
revision. If this fails, you may need to give an explicit base.
3908
To pick a different ending revision, pass "--revision OTHER". bzr will
3909
try to merge in all new work up to and including revision OTHER.
3911
If you specify two values, "--revision BASE..OTHER", only revisions BASE
3912
through OTHER, excluding BASE but including OTHER, will be merged. If this
3913
causes some revisions to be skipped, i.e. if the destination branch does
3914
not already contain revision BASE, such a merge is commonly referred to as
3915
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
3916
cherrypicks. The changes look like a normal commit, and the history of the
3917
changes from the other branch is not stored in the commit.
3919
Revision numbers are always relative to the source branch.
2816
3921
Merge will do its best to combine the changes in two branches, but there
2817
3922
are some kinds of problems only a human can fix. When it encounters those,
2818
3923
it will mark a conflict. A conflict means that you need to fix something,
2893
4016
allow_pending = True
2894
4017
verified = 'inapplicable'
2895
4019
tree = WorkingTree.open_containing(directory)[0]
4020
if tree.branch.revno() == 0:
4021
raise errors.BzrCommandError('Merging into empty branches not currently supported, '
4022
'https://bugs.launchpad.net/bzr/+bug/308562')
4025
basis_tree = tree.revision_tree(tree.last_revision())
4026
except errors.NoSuchRevision:
4027
basis_tree = tree.basis_tree()
4029
# die as quickly as possible if there are uncommitted changes
4031
if tree.has_changes():
4032
raise errors.UncommittedChanges(tree)
4034
view_info = _get_view_info_for_change_reporter(tree)
2896
4035
change_reporter = delta._ChangeReporter(
2897
unversioned_filter=tree.is_ignored)
2900
pb = ui.ui_factory.nested_progress_bar()
2901
cleanups.append(pb.finished)
2903
cleanups.append(tree.unlock)
2904
if location is not None:
2906
mergeable = bundle.read_mergeable_from_url(location,
2907
possible_transports=possible_transports)
2908
except errors.NotABundle:
2912
raise errors.BzrCommandError('Cannot use --uncommitted'
2913
' with bundles or merge directives.')
2915
if revision is not None:
2916
raise errors.BzrCommandError(
2917
'Cannot use -r with merge directives or bundles')
2918
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2921
if merger is None and uncommitted:
2922
if revision is not None and len(revision) > 0:
2923
raise errors.BzrCommandError('Cannot use --uncommitted and'
2924
' --revision at the same time.')
2925
location = self._select_branch_location(tree, location)[0]
2926
other_tree, other_path = WorkingTree.open_containing(location)
2927
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2929
allow_pending = False
2930
if other_path != '':
2931
merger.interesting_files = [other_path]
2934
merger, allow_pending = self._get_merger_from_branch(tree,
2935
location, revision, remember, possible_transports, pb)
2937
merger.merge_type = merge_type
2938
merger.reprocess = reprocess
2939
merger.show_base = show_base
2940
self.sanity_check_merger(merger)
2941
if (merger.base_rev_id == merger.other_rev_id and
2942
merger.other_rev_id is not None):
2943
note('Nothing to do.')
4036
unversioned_filter=tree.is_ignored, view_info=view_info)
4037
pb = ui.ui_factory.nested_progress_bar()
4038
self.add_cleanup(pb.finished)
4039
self.add_cleanup(tree.lock_write().unlock)
4040
if location is not None:
4042
mergeable = bundle.read_mergeable_from_url(location,
4043
possible_transports=possible_transports)
4044
except errors.NotABundle:
4048
raise errors.BzrCommandError('Cannot use --uncommitted'
4049
' with bundles or merge directives.')
4051
if revision is not None:
4052
raise errors.BzrCommandError(
4053
'Cannot use -r with merge directives or bundles')
4054
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4057
if merger is None and uncommitted:
4058
if revision is not None and len(revision) > 0:
4059
raise errors.BzrCommandError('Cannot use --uncommitted and'
4060
' --revision at the same time.')
4061
merger = self.get_merger_from_uncommitted(tree, location, None)
4062
allow_pending = False
4065
merger, allow_pending = self._get_merger_from_branch(tree,
4066
location, revision, remember, possible_transports, None)
4068
merger.merge_type = merge_type
4069
merger.reprocess = reprocess
4070
merger.show_base = show_base
4071
self.sanity_check_merger(merger)
4072
if (merger.base_rev_id == merger.other_rev_id and
4073
merger.other_rev_id is not None):
4074
# check if location is a nonexistent file (and not a branch) to
4075
# disambiguate the 'Nothing to do'
4076
if merger.interesting_files:
4077
if not merger.other_tree.has_filename(
4078
merger.interesting_files[0]):
4079
note("merger: " + str(merger))
4080
raise errors.PathsDoNotExist([location])
4081
note('Nothing to do.')
4083
if pull and not preview:
4084
if merger.interesting_files is not None:
4085
raise errors.BzrCommandError('Cannot pull individual files')
4086
if (merger.base_rev_id == tree.last_revision()):
4087
result = tree.pull(merger.other_branch, False,
4088
merger.other_rev_id)
4089
result.report(self.outf)
2946
if merger.interesting_files is not None:
2947
raise errors.BzrCommandError('Cannot pull individual files')
2948
if (merger.base_rev_id == tree.last_revision()):
2949
result = tree.pull(merger.other_branch, False,
2950
merger.other_rev_id)
2951
result.report(self.outf)
2953
merger.check_basis(not force)
2955
return self._do_preview(merger)
2957
return self._do_merge(merger, change_reporter, allow_pending,
2960
for cleanup in reversed(cleanups):
4091
if merger.this_basis is None:
4092
raise errors.BzrCommandError(
4093
"This branch has no commits."
4094
" (perhaps you would prefer 'bzr pull')")
4096
return self._do_preview(merger)
4098
return self._do_interactive(merger)
4100
return self._do_merge(merger, change_reporter, allow_pending,
4103
def _get_preview(self, merger):
4104
tree_merger = merger.make_merger()
4105
tt = tree_merger.make_preview_transform()
4106
self.add_cleanup(tt.finalize)
4107
result_tree = tt.get_preview_tree()
2963
4110
def _do_preview(self, merger):
2964
4111
from bzrlib.diff import show_diff_trees
2965
tree_merger = merger.make_merger()
2966
tt = tree_merger.make_preview_transform()
2968
result_tree = tt.get_preview_tree()
2969
show_diff_trees(merger.this_tree, result_tree, self.outf,
2970
old_label='', new_label='')
4112
result_tree = self._get_preview(merger)
4113
path_encoding = osutils.get_diff_header_encoding()
4114
show_diff_trees(merger.this_tree, result_tree, self.outf,
4115
old_label='', new_label='',
4116
path_encoding=path_encoding)
2974
4118
def _do_merge(self, merger, change_reporter, allow_pending, verified):
2975
4119
merger.change_reporter = change_reporter
3122
4312
def run(self, file_list=None, merge_type=None, show_base=False,
3123
4313
reprocess=False):
4314
from bzrlib.conflicts import restore
3124
4315
if merge_type is None:
3125
4316
merge_type = _mod_merge.Merge3Merger
3126
tree, file_list = tree_files(file_list)
4317
tree, file_list = WorkingTree.open_containing_paths(file_list)
4318
self.add_cleanup(tree.lock_write().unlock)
4319
parents = tree.get_parent_ids()
4320
if len(parents) != 2:
4321
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4322
" merges. Not cherrypicking or"
4324
repository = tree.branch.repository
4325
interesting_ids = None
4327
conflicts = tree.conflicts()
4328
if file_list is not None:
4329
interesting_ids = set()
4330
for filename in file_list:
4331
file_id = tree.path2id(filename)
4333
raise errors.NotVersionedError(filename)
4334
interesting_ids.add(file_id)
4335
if tree.kind(file_id) != "directory":
4338
for name, ie in tree.inventory.iter_entries(file_id):
4339
interesting_ids.add(ie.file_id)
4340
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4342
# Remerge only supports resolving contents conflicts
4343
allowed_conflicts = ('text conflict', 'contents conflict')
4344
restore_files = [c.path for c in conflicts
4345
if c.typestring in allowed_conflicts]
4346
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4347
tree.set_conflicts(ConflictList(new_conflicts))
4348
if file_list is not None:
4349
restore_files = file_list
4350
for filename in restore_files:
4352
restore(tree.abspath(filename))
4353
except errors.NotConflicted:
4355
# Disable pending merges, because the file texts we are remerging
4356
# have not had those merges performed. If we use the wrong parents
4357
# list, we imply that the working tree text has seen and rejected
4358
# all the changes from the other tree, when in fact those changes
4359
# have not yet been seen.
4360
tree.set_parent_ids(parents[:1])
3129
parents = tree.get_parent_ids()
3130
if len(parents) != 2:
3131
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3132
" merges. Not cherrypicking or"
3134
repository = tree.branch.repository
3135
interesting_ids = None
3137
conflicts = tree.conflicts()
3138
if file_list is not None:
3139
interesting_ids = set()
3140
for filename in file_list:
3141
file_id = tree.path2id(filename)
3143
raise errors.NotVersionedError(filename)
3144
interesting_ids.add(file_id)
3145
if tree.kind(file_id) != "directory":
3148
for name, ie in tree.inventory.iter_entries(file_id):
3149
interesting_ids.add(ie.file_id)
3150
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3152
# Remerge only supports resolving contents conflicts
3153
allowed_conflicts = ('text conflict', 'contents conflict')
3154
restore_files = [c.path for c in conflicts
3155
if c.typestring in allowed_conflicts]
3156
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3157
tree.set_conflicts(ConflictList(new_conflicts))
3158
if file_list is not None:
3159
restore_files = file_list
3160
for filename in restore_files:
3162
restore(tree.abspath(filename))
3163
except errors.NotConflicted:
3165
# Disable pending merges, because the file texts we are remerging
3166
# have not had those merges performed. If we use the wrong parents
3167
# list, we imply that the working tree text has seen and rejected
3168
# all the changes from the other tree, when in fact those changes
3169
# have not yet been seen.
3170
pb = ui.ui_factory.nested_progress_bar()
3171
tree.set_parent_ids(parents[:1])
3173
merger = _mod_merge.Merger.from_revision_ids(pb,
3175
merger.interesting_ids = interesting_ids
3176
merger.merge_type = merge_type
3177
merger.show_base = show_base
3178
merger.reprocess = reprocess
3179
conflicts = merger.do_merge()
3181
tree.set_parent_ids(parents)
4362
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4363
merger.interesting_ids = interesting_ids
4364
merger.merge_type = merge_type
4365
merger.show_base = show_base
4366
merger.reprocess = reprocess
4367
conflicts = merger.do_merge()
4369
tree.set_parent_ids(parents)
3185
4370
if conflicts > 0:
3353
4586
" or specified.")
3354
4587
display_url = urlutils.unescape_for_display(parent,
3355
4588
self.outf.encoding)
3356
self.outf.write("Using saved parent location: "
4589
message("Using saved parent location: "
3357
4590
+ display_url + "\n")
3359
4592
remote_branch = Branch.open(other_branch)
3360
4593
if remote_branch.base == local_branch.base:
3361
4594
remote_branch = local_branch
3362
local_branch.lock_read()
3364
remote_branch.lock_read()
3366
local_extra, remote_extra = find_unmerged(
3367
local_branch, remote_branch, restrict,
3368
backward=not reverse,
3369
include_merges=include_merges)
3371
if log_format is None:
3372
registry = log.log_formatter_registry
3373
log_format = registry.get_default(local_branch)
3374
lf = log_format(to_file=self.outf,
3376
show_timezone='original')
3379
if local_extra and not theirs_only:
3380
self.outf.write("You have %d extra revision(s):\n" %
3382
for revision in iter_log_revisions(local_extra,
3383
local_branch.repository,
3385
lf.log_revision(revision)
3386
printed_local = True
3389
printed_local = False
3391
if remote_extra and not mine_only:
3392
if printed_local is True:
3393
self.outf.write("\n\n\n")
3394
self.outf.write("You are missing %d revision(s):\n" %
3396
for revision in iter_log_revisions(remote_extra,
3397
remote_branch.repository,
3399
lf.log_revision(revision)
3402
if mine_only and not local_extra:
3403
# We checked local, and found nothing extra
3404
self.outf.write('This branch is up to date.\n')
3405
elif theirs_only and not remote_extra:
3406
# We checked remote, and found nothing extra
3407
self.outf.write('Other branch is up to date.\n')
3408
elif not (mine_only or theirs_only or local_extra or
3410
# We checked both branches, and neither one had extra
3412
self.outf.write("Branches are up to date.\n")
3414
remote_branch.unlock()
3416
local_branch.unlock()
4596
self.add_cleanup(remote_branch.lock_read().unlock)
4598
local_revid_range = _revision_range_to_revid_range(
4599
_get_revision_range(my_revision, local_branch,
4602
remote_revid_range = _revision_range_to_revid_range(
4603
_get_revision_range(revision,
4604
remote_branch, self.name()))
4606
local_extra, remote_extra = find_unmerged(
4607
local_branch, remote_branch, restrict,
4608
backward=not reverse,
4609
include_merges=include_merges,
4610
local_revid_range=local_revid_range,
4611
remote_revid_range=remote_revid_range)
4613
if log_format is None:
4614
registry = log.log_formatter_registry
4615
log_format = registry.get_default(local_branch)
4616
lf = log_format(to_file=self.outf,
4618
show_timezone='original')
4621
if local_extra and not theirs_only:
4622
message("You have %d extra revision(s):\n" %
4624
for revision in iter_log_revisions(local_extra,
4625
local_branch.repository,
4627
lf.log_revision(revision)
4628
printed_local = True
4631
printed_local = False
4633
if remote_extra and not mine_only:
4634
if printed_local is True:
4636
message("You are missing %d revision(s):\n" %
4638
for revision in iter_log_revisions(remote_extra,
4639
remote_branch.repository,
4641
lf.log_revision(revision)
4644
if mine_only and not local_extra:
4645
# We checked local, and found nothing extra
4646
message('This branch is up to date.\n')
4647
elif theirs_only and not remote_extra:
4648
# We checked remote, and found nothing extra
4649
message('Other branch is up to date.\n')
4650
elif not (mine_only or theirs_only or local_extra or
4652
# We checked both branches, and neither one had extra
4654
message("Branches are up to date.\n")
3417
4656
if not status_code and parent is None and other_branch is not None:
3418
local_branch.lock_write()
3420
# handle race conditions - a parent might be set while we run.
3421
if local_branch.get_parent() is None:
3422
local_branch.set_parent(remote_branch.base)
3424
local_branch.unlock()
4657
self.add_cleanup(local_branch.lock_write().unlock)
4658
# handle race conditions - a parent might be set while we run.
4659
if local_branch.get_parent() is None:
4660
local_branch.set_parent(remote_branch.base)
3425
4661
return status_code
3428
4664
class cmd_pack(Command):
3429
"""Compress the data within a repository."""
4665
__doc__ = """Compress the data within a repository.
4667
This operation compresses the data within a bazaar repository. As
4668
bazaar supports automatic packing of repository, this operation is
4669
normally not required to be done manually.
4671
During the pack operation, bazaar takes a backup of existing repository
4672
data, i.e. pack files. This backup is eventually removed by bazaar
4673
automatically when it is safe to do so. To save disk space by removing
4674
the backed up pack files, the --clean-obsolete-packs option may be
4677
Warning: If you use --clean-obsolete-packs and your machine crashes
4678
during or immediately after repacking, you may be left with a state
4679
where the deletion has been written to disk but the new packs have not
4680
been. In this case the repository may be unusable.
3431
4683
_see_also = ['repositories']
3432
4684
takes_args = ['branch_or_repo?']
4686
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
3434
def run(self, branch_or_repo='.'):
4689
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
3435
4690
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3437
4692
branch = dir.open_branch()
3438
4693
repository = branch.repository
3439
4694
except errors.NotBranchError:
3440
4695
repository = dir.open_repository()
4696
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
3444
4699
class cmd_plugins(Command):
3445
"""List the installed plugins.
4700
__doc__ = """List the installed plugins.
3447
4702
This command displays the list of installed plugins including
3448
4703
version of plugin and a short description of each.
3845
5101
class cmd_serve(Command):
3846
"""Run the bzr server."""
5102
__doc__ = """Run the bzr server."""
3848
5104
aliases = ['server']
3850
5106
takes_options = [
3852
5108
help='Serve on stdin/out for use from inetd or sshd.'),
5109
RegistryOption('protocol',
5110
help="Protocol to serve.",
5111
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5112
value_switches=True),
3854
5114
help='Listen for connections on nominated port of the form '
3855
5115
'[hostname:]portnumber. Passing 0 as the port number will '
3856
'result in a dynamically allocated port. The default port is '
5116
'result in a dynamically allocated port. The default port '
5117
'depends on the protocol.',
3860
help='Serve contents of this directory.',
5119
custom_help('directory',
5120
help='Serve contents of this directory.'),
3862
5121
Option('allow-writes',
3863
5122
help='By default the server is a readonly server. Supplying '
3864
5123
'--allow-writes enables write access to the contents of '
3865
'the served directory and below.'
5124
'the served directory and below. Note that ``bzr serve`` '
5125
'does not perform authentication, so unless some form of '
5126
'external authentication is arranged supplying this '
5127
'option leads to global uncontrolled write access to your '
3869
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3870
from bzrlib import lockdir
3871
from bzrlib.smart import medium, server
3872
from bzrlib.transport import get_transport
3873
from bzrlib.transport.chroot import ChrootServer
5132
def get_host_and_port(self, port):
5133
"""Return the host and port to run the smart server on.
5135
If 'port' is None, None will be returned for the host and port.
5137
If 'port' has a colon in it, the string before the colon will be
5138
interpreted as the host.
5140
:param port: A string of the port to run the server on.
5141
:return: A tuple of (host, port), where 'host' is a host name or IP,
5142
and port is an integer TCP/IP port.
5145
if port is not None:
5147
host, port = port.split(':')
5151
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5153
from bzrlib import transport
3874
5154
if directory is None:
3875
5155
directory = os.getcwd()
5156
if protocol is None:
5157
protocol = transport.transport_server_registry.get()
5158
host, port = self.get_host_and_port(port)
3876
5159
url = urlutils.local_path_to_url(directory)
3877
5160
if not allow_writes:
3878
5161
url = 'readonly+' + url
3879
chroot_server = ChrootServer(get_transport(url))
3880
chroot_server.setUp()
3881
t = get_transport(chroot_server.get_url())
3883
smart_server = medium.SmartServerPipeStreamMedium(
3884
sys.stdin, sys.stdout, t)
3886
host = medium.BZR_DEFAULT_INTERFACE
3888
port = medium.BZR_DEFAULT_PORT
3891
host, port = port.split(':')
3893
smart_server = server.SmartTCPServer(t, host=host, port=port)
3894
print 'listening on port: ', smart_server.port
3896
# for the duration of this server, no UI output is permitted.
3897
# note that this may cause problems with blackbox tests. This should
3898
# be changed with care though, as we dont want to use bandwidth sending
3899
# progress over stderr to smart server clients!
3900
old_factory = ui.ui_factory
3901
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
3903
ui.ui_factory = ui.SilentUIFactory()
3904
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
3905
smart_server.serve()
3907
ui.ui_factory = old_factory
3908
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
5162
t = transport.get_transport(url)
5163
protocol(t, host, port, inet)
3911
5166
class cmd_join(Command):
3912
"""Combine a subtree into its containing tree.
3914
This command is for experimental use only. It requires the target tree
3915
to be in dirstate-with-subtree format, which cannot be converted into
5167
__doc__ = """Combine a tree into its containing tree.
5169
This command requires the target tree to be in a rich-root format.
3918
5171
The TREE argument should be an independent tree, inside another tree, but
3919
5172
not part of it. (Such trees can be produced by "bzr split", but also by
3920
5173
running "bzr branch" with the target inside a tree.)
3922
The result is a combined tree, with the subtree no longer an independant
5175
The result is a combined tree, with the subtree no longer an independent
3923
5176
part. This is marked as a merge of the subtree into the containing tree,
3924
5177
and all history is preserved.
3926
If --reference is specified, the subtree retains its independence. It can
3927
be branched by itself, and can be part of multiple projects at the same
3928
time. But operations performed in the containing tree, such as commit
3929
and merge, will recurse into the subtree.
3932
5180
_see_also = ['split']
3933
5181
takes_args = ['tree']
3934
5182
takes_options = [
3935
Option('reference', help='Join by reference.'),
5183
Option('reference', help='Join by reference.', hidden=True),
3939
5186
def run(self, tree, reference=False):
3940
5187
sub_tree = WorkingTree.open(tree)
4157
5431
short_name='f',
4159
5433
Option('output', short_name='o',
4160
help='Write merge directive to this file; '
5434
help='Write merge directive to this file or directory; '
4161
5435
'use - for stdout.',
5438
help='Refuse to send if there are uncommitted changes in'
5439
' the working tree, --no-strict disables the check.'),
4163
5440
Option('mail-to', help='Mail the request to this address.',
4167
RegistryOption.from_kwargs('format',
4168
'Use the specified output format.',
4169
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4170
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5444
Option('body', help='Body for the email.', type=unicode),
5445
RegistryOption('format',
5446
help='Use the specified output format.',
5447
lazy_registry=('bzrlib.send', 'format_registry')),
4173
5450
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4174
no_patch=False, revision=None, remember=False, output=None,
4175
format='4', mail_to=None, message=None, **kwargs):
4176
return self._run(submit_branch, revision, public_branch, remember,
4177
format, no_bundle, no_patch, output,
4178
kwargs.get('from', '.'), mail_to, message)
4180
def _run(self, submit_branch, revision, public_branch, remember, format,
4181
no_bundle, no_patch, output, from_, mail_to, message):
4182
from bzrlib.revision import NULL_REVISION
4183
branch = Branch.open_containing(from_)[0]
4185
outfile = StringIO()
4189
outfile = open(output, 'wb')
4190
# we may need to write data into branch's repository to calculate
4195
config = branch.get_config()
4197
mail_to = config.get_user_option('submit_to')
4198
mail_client = config.get_mail_client()
4199
if remember and submit_branch is None:
4200
raise errors.BzrCommandError(
4201
'--remember requires a branch to be specified.')
4202
stored_submit_branch = branch.get_submit_branch()
4203
remembered_submit_branch = None
4204
if submit_branch is None:
4205
submit_branch = stored_submit_branch
4206
remembered_submit_branch = "submit"
4208
if stored_submit_branch is None or remember:
4209
branch.set_submit_branch(submit_branch)
4210
if submit_branch is None:
4211
submit_branch = branch.get_parent()
4212
remembered_submit_branch = "parent"
4213
if submit_branch is None:
4214
raise errors.BzrCommandError('No submit branch known or'
4216
if remembered_submit_branch is not None:
4217
note('Using saved %s location "%s" to determine what '
4218
'changes to submit.', remembered_submit_branch,
4222
submit_config = Branch.open(submit_branch).get_config()
4223
mail_to = submit_config.get_user_option("child_submit_to")
4225
stored_public_branch = branch.get_public_branch()
4226
if public_branch is None:
4227
public_branch = stored_public_branch
4228
elif stored_public_branch is None or remember:
4229
branch.set_public_branch(public_branch)
4230
if no_bundle and public_branch is None:
4231
raise errors.BzrCommandError('No public branch specified or'
4233
base_revision_id = None
4235
if revision is not None:
4236
if len(revision) > 2:
4237
raise errors.BzrCommandError('bzr send takes '
4238
'at most two one revision identifiers')
4239
revision_id = revision[-1].as_revision_id(branch)
4240
if len(revision) == 2:
4241
base_revision_id = revision[0].as_revision_id(branch)
4242
if revision_id is None:
4243
revision_id = branch.last_revision()
4244
if revision_id == NULL_REVISION:
4245
raise errors.BzrCommandError('No revisions to submit.')
4247
directive = merge_directive.MergeDirective2.from_objects(
4248
branch.repository, revision_id, time.time(),
4249
osutils.local_time_offset(), submit_branch,
4250
public_branch=public_branch, include_patch=not no_patch,
4251
include_bundle=not no_bundle, message=message,
4252
base_revision_id=base_revision_id)
4253
elif format == '0.9':
4256
patch_type = 'bundle'
4258
raise errors.BzrCommandError('Format 0.9 does not'
4259
' permit bundle with no patch')
4265
directive = merge_directive.MergeDirective.from_objects(
4266
branch.repository, revision_id, time.time(),
4267
osutils.local_time_offset(), submit_branch,
4268
public_branch=public_branch, patch_type=patch_type,
4271
outfile.writelines(directive.to_lines())
4273
subject = '[MERGE] '
4274
if message is not None:
4277
revision = branch.repository.get_revision(revision_id)
4278
subject += revision.get_summary()
4279
basename = directive.get_disk_name(branch)
4280
mail_client.compose_merge_request(mail_to, subject,
4281
outfile.getvalue(), basename)
5451
no_patch=False, revision=None, remember=None, output=None,
5452
format=None, mail_to=None, message=None, body=None,
5453
strict=None, **kwargs):
5454
from bzrlib.send import send
5455
return send(submit_branch, revision, public_branch, remember,
5456
format, no_bundle, no_patch, output,
5457
kwargs.get('from', '.'), mail_to, message, body,
4288
5462
class cmd_bundle_revisions(cmd_send):
4290
"""Create a merge-directive for submiting changes.
5463
__doc__ = """Create a merge-directive for submitting changes.
4292
5465
A merge directive provides many things needed for requesting merges:
4365
5542
Tags are stored in the branch. Tags are copied from one branch to another
4366
5543
along when you branch, push, pull or merge.
4368
It is an error to give a tag name that already exists unless you pass
5545
It is an error to give a tag name that already exists unless you pass
4369
5546
--force, in which case the tag is moved to point to the new revision.
4371
5548
To rename a tag (change the name but keep it on the same revsion), run ``bzr
4372
5549
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5551
If no tag name is specified it will be determined through the
5552
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5553
upstream releases by reading configure.ac. See ``bzr help hooks`` for
4375
5557
_see_also = ['commit', 'tags']
4376
takes_args = ['tag_name']
5558
takes_args = ['tag_name?']
4377
5559
takes_options = [
4378
5560
Option('delete',
4379
5561
help='Delete this tag rather than placing it.',
4382
help='Branch in which to place the tag.',
5563
custom_help('directory',
5564
help='Branch in which to place the tag.'),
4386
5565
Option('force',
4387
5566
help='Replace existing tags.',
4392
def run(self, tag_name,
5571
def run(self, tag_name=None,
4398
5577
branch, relpath = Branch.open_containing(directory)
4402
branch.tags.delete_tag(tag_name)
4403
self.outf.write('Deleted tag %s.\n' % tag_name)
5578
self.add_cleanup(branch.lock_write().unlock)
5580
if tag_name is None:
5581
raise errors.BzrCommandError("No tag specified to delete.")
5582
branch.tags.delete_tag(tag_name)
5583
note('Deleted tag %s.' % tag_name)
5586
if len(revision) != 1:
5587
raise errors.BzrCommandError(
5588
"Tags can only be placed on a single revision, "
5590
revision_id = revision[0].as_revision_id(branch)
4406
if len(revision) != 1:
4407
raise errors.BzrCommandError(
4408
"Tags can only be placed on a single revision, "
4410
revision_id = revision[0].as_revision_id(branch)
4412
revision_id = branch.last_revision()
4413
if (not force) and branch.tags.has_tag(tag_name):
4414
raise errors.TagAlreadyExists(tag_name)
4415
branch.tags.set_tag(tag_name, revision_id)
4416
self.outf.write('Created tag %s.\n' % tag_name)
5592
revision_id = branch.last_revision()
5593
if tag_name is None:
5594
tag_name = branch.automatic_tag_name(revision_id)
5595
if tag_name is None:
5596
raise errors.BzrCommandError(
5597
"Please specify a tag name.")
5598
if (not force) and branch.tags.has_tag(tag_name):
5599
raise errors.TagAlreadyExists(tag_name)
5600
branch.tags.set_tag(tag_name, revision_id)
5601
note('Created tag %s.' % tag_name)
4421
5604
class cmd_tags(Command):
5605
__doc__ = """List tags.
4424
5607
This command shows a table of tag names and the revisions they reference.
4427
5610
_see_also = ['tag']
4428
5611
takes_options = [
4430
help='Branch whose tags should be displayed.',
4434
RegistryOption.from_kwargs('sort',
5612
custom_help('directory',
5613
help='Branch whose tags should be displayed.'),
5614
RegistryOption('sort',
4435
5615
'Sort tags by different criteria.', title='Sorting',
4436
alpha='Sort tags lexicographically (default).',
4437
time='Sort tags chronologically.',
5616
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
4442
5622
@display_command
5623
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5624
from bzrlib.tag import tag_sort_methods
4448
5625
branch, relpath = Branch.open_containing(directory)
4449
5627
tags = branch.tags.get_tag_dict().items()
4454
elif sort == 'time':
4456
for tag, revid in tags:
4458
revobj = branch.repository.get_revision(revid)
4459
except errors.NoSuchRevision:
4460
timestamp = sys.maxint # place them at the end
4462
timestamp = revobj.timestamp
4463
timestamps[revid] = timestamp
4464
tags.sort(key=lambda x: timestamps[x[1]])
5631
self.add_cleanup(branch.lock_read().unlock)
5633
graph = branch.repository.get_graph()
5634
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5635
revid1, revid2 = rev1.rev_id, rev2.rev_id
5636
# only show revisions between revid1 and revid2 (inclusive)
5637
tags = [(tag, revid) for tag, revid in tags if
5638
graph.is_between(revid, revid1, revid2)]
5640
sort = tag_sort_methods.get()
4465
5642
if not show_ids:
4466
5643
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
4467
revno_map = branch.get_revision_id_to_revno_map()
4468
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
4469
for tag, revid in tags ]
5644
for index, (tag, revid) in enumerate(tags):
5646
revno = branch.revision_id_to_dotted_revno(revid)
5647
if isinstance(revno, tuple):
5648
revno = '.'.join(map(str, revno))
5649
except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
5650
# Bad tag data/merges can lead to tagged revisions
5651
# which are not in this branch. Fail gracefully ...
5653
tags[index] = (tag, revno)
4470
5655
for tag, revspec in tags:
4471
5656
self.outf.write('%-20s %s\n' % (tag, revspec))
4474
5659
class cmd_reconfigure(Command):
4475
"""Reconfigure the type of a bzr directory.
5660
__doc__ = """Reconfigure the type of a bzr directory.
4477
5662
A target configuration must be specified.
4547
5764
directory of the current branch. For example, if you are currently in a
4548
5765
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4549
5766
/path/to/newbranch.
5768
Bound branches use the nickname of its master branch unless it is set
5769
locally, in which case switching will update the local nickname to be
4552
takes_args = ['to_location']
4553
takes_options = [Option('force',
4554
help='Switch even if local commits will be lost.')
5773
takes_args = ['to_location?']
5774
takes_options = ['directory',
5776
help='Switch even if local commits will be lost.'),
5778
Option('create-branch', short_name='b',
5779
help='Create the target branch from this one before'
5780
' switching to it.'),
4557
def run(self, to_location, force=False):
5783
def run(self, to_location=None, force=False, create_branch=False,
5784
revision=None, directory=u'.'):
4558
5785
from bzrlib import switch
5786
tree_location = directory
5787
revision = _get_one_revision('switch', revision)
4560
5788
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5789
if to_location is None:
5790
if revision is None:
5791
raise errors.BzrCommandError('You must supply either a'
5792
' revision or a location')
5793
to_location = tree_location
4562
to_branch = Branch.open(to_location)
5795
branch = control_dir.open_branch()
5796
had_explicit_nick = branch.get_config().has_explicit_nickname()
4563
5797
except errors.NotBranchError:
4564
to_branch = Branch.open(
4565
control_dir.open_branch().base + '../' + to_location)
4566
switch.switch(control_dir, to_branch, force)
5799
had_explicit_nick = False
5802
raise errors.BzrCommandError('cannot create branch without'
5804
to_location = directory_service.directories.dereference(
5806
if '/' not in to_location and '\\' not in to_location:
5807
# This path is meant to be relative to the existing branch
5808
this_url = self._get_branch_location(control_dir)
5809
to_location = urlutils.join(this_url, '..', to_location)
5810
to_branch = branch.bzrdir.sprout(to_location,
5811
possible_transports=[branch.bzrdir.root_transport],
5812
source_branch=branch).open_branch()
5815
to_branch = Branch.open(to_location)
5816
except errors.NotBranchError:
5817
this_url = self._get_branch_location(control_dir)
5818
to_branch = Branch.open(
5819
urlutils.join(this_url, '..', to_location))
5820
if revision is not None:
5821
revision = revision.as_revision_id(to_branch)
5822
switch.switch(control_dir, to_branch, force, revision_id=revision)
5823
if had_explicit_nick:
5824
branch = control_dir.open_branch() #get the new branch!
5825
branch.nick = to_branch.nick
4567
5826
note('Switched to branch: %s',
4568
5827
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5829
def _get_branch_location(self, control_dir):
5830
"""Return location of branch for this control dir."""
5832
this_branch = control_dir.open_branch()
5833
# This may be a heavy checkout, where we want the master branch
5834
master_location = this_branch.get_bound_location()
5835
if master_location is not None:
5836
return master_location
5837
# If not, use a local sibling
5838
return this_branch.base
5839
except errors.NotBranchError:
5840
format = control_dir.find_branch_format()
5841
if getattr(format, 'get_reference', None) is not None:
5842
return format.get_reference(control_dir)
5844
return control_dir.root_transport.base
5847
class cmd_view(Command):
5848
__doc__ = """Manage filtered views.
5850
Views provide a mask over the tree so that users can focus on
5851
a subset of a tree when doing their work. After creating a view,
5852
commands that support a list of files - status, diff, commit, etc -
5853
effectively have that list of files implicitly given each time.
5854
An explicit list of files can still be given but those files
5855
must be within the current view.
5857
In most cases, a view has a short life-span: it is created to make
5858
a selected change and is deleted once that change is committed.
5859
At other times, you may wish to create one or more named views
5860
and switch between them.
5862
To disable the current view without deleting it, you can switch to
5863
the pseudo view called ``off``. This can be useful when you need
5864
to see the whole tree for an operation or two (e.g. merge) but
5865
want to switch back to your view after that.
5868
To define the current view::
5870
bzr view file1 dir1 ...
5872
To list the current view::
5876
To delete the current view::
5880
To disable the current view without deleting it::
5882
bzr view --switch off
5884
To define a named view and switch to it::
5886
bzr view --name view-name file1 dir1 ...
5888
To list a named view::
5890
bzr view --name view-name
5892
To delete a named view::
5894
bzr view --name view-name --delete
5896
To switch to a named view::
5898
bzr view --switch view-name
5900
To list all views defined::
5904
To delete all views::
5906
bzr view --delete --all
5910
takes_args = ['file*']
5913
help='Apply list or delete action to all views.',
5916
help='Delete the view.',
5919
help='Name of the view to define, list or delete.',
5923
help='Name of the view to switch to.',
5928
def run(self, file_list,
5934
tree, file_list = WorkingTree.open_containing_paths(file_list,
5936
current_view, view_dict = tree.views.get_view_info()
5941
raise errors.BzrCommandError(
5942
"Both --delete and a file list specified")
5944
raise errors.BzrCommandError(
5945
"Both --delete and --switch specified")
5947
tree.views.set_view_info(None, {})
5948
self.outf.write("Deleted all views.\n")
5950
raise errors.BzrCommandError("No current view to delete")
5952
tree.views.delete_view(name)
5953
self.outf.write("Deleted '%s' view.\n" % name)
5956
raise errors.BzrCommandError(
5957
"Both --switch and a file list specified")
5959
raise errors.BzrCommandError(
5960
"Both --switch and --all specified")
5961
elif switch == 'off':
5962
if current_view is None:
5963
raise errors.BzrCommandError("No current view to disable")
5964
tree.views.set_view_info(None, view_dict)
5965
self.outf.write("Disabled '%s' view.\n" % (current_view))
5967
tree.views.set_view_info(switch, view_dict)
5968
view_str = views.view_display_str(tree.views.lookup_view())
5969
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5972
self.outf.write('Views defined:\n')
5973
for view in sorted(view_dict):
5974
if view == current_view:
5978
view_str = views.view_display_str(view_dict[view])
5979
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5981
self.outf.write('No views defined.\n')
5984
# No name given and no current view set
5987
raise errors.BzrCommandError(
5988
"Cannot change the 'off' pseudo view")
5989
tree.views.set_view(name, sorted(file_list))
5990
view_str = views.view_display_str(tree.views.lookup_view())
5991
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5995
# No name given and no current view set
5996
self.outf.write('No current view.\n')
5998
view_str = views.view_display_str(tree.views.lookup_view(name))
5999
self.outf.write("'%s' view is: %s\n" % (name, view_str))
4571
6002
class cmd_hooks(Command):
4572
"""Show a branch's currently registered hooks.
4576
takes_args = ['path?']
4578
def run(self, path=None):
6003
__doc__ = """Show hooks."""
6008
for hook_key in sorted(hooks.known_hooks.keys()):
6009
some_hooks = hooks.known_hooks_key_to_object(hook_key)
6010
self.outf.write("%s:\n" % type(some_hooks).__name__)
6011
for hook_name, hook_point in sorted(some_hooks.items()):
6012
self.outf.write(" %s:\n" % (hook_name,))
6013
found_hooks = list(hook_point)
6015
for hook in found_hooks:
6016
self.outf.write(" %s\n" %
6017
(some_hooks.get_hook_name(hook),))
6019
self.outf.write(" <no hooks installed>\n")
6022
class cmd_remove_branch(Command):
6023
__doc__ = """Remove a branch.
6025
This will remove the branch from the specified location but
6026
will keep any working tree or repository in place.
6030
Remove the branch at repo/trunk::
6032
bzr remove-branch repo/trunk
6036
takes_args = ["location?"]
6038
aliases = ["rmbranch"]
6040
def run(self, location=None):
6041
if location is None:
6043
branch = Branch.open_containing(location)[0]
6044
branch.bzrdir.destroy_branch()
6047
class cmd_shelve(Command):
6048
__doc__ = """Temporarily set aside some changes from the current tree.
6050
Shelve allows you to temporarily put changes you've made "on the shelf",
6051
ie. out of the way, until a later time when you can bring them back from
6052
the shelf with the 'unshelve' command. The changes are stored alongside
6053
your working tree, and so they aren't propagated along with your branch nor
6054
will they survive its deletion.
6056
If shelve --list is specified, previously-shelved changes are listed.
6058
Shelve is intended to help separate several sets of changes that have
6059
been inappropriately mingled. If you just want to get rid of all changes
6060
and you don't need to restore them later, use revert. If you want to
6061
shelve all text changes at once, use shelve --all.
6063
If filenames are specified, only the changes to those files will be
6064
shelved. Other files will be left untouched.
6066
If a revision is specified, changes since that revision will be shelved.
6068
You can put multiple items on the shelf, and by default, 'unshelve' will
6069
restore the most recently shelved changes.
6071
For complicated changes, it is possible to edit the changes in a separate
6072
editor program to decide what the file remaining in the working copy
6073
should look like. To do this, add the configuration option
6075
change_editor = PROGRAM @new_path @old_path
6077
where @new_path is replaced with the path of the new version of the
6078
file and @old_path is replaced with the path of the old version of
6079
the file. The PROGRAM should save the new file with the desired
6080
contents of the file in the working tree.
6084
takes_args = ['file*']
6089
Option('all', help='Shelve all changes.'),
6091
RegistryOption('writer', 'Method to use for writing diffs.',
6092
bzrlib.option.diff_writer_registry,
6093
value_switches=True, enum_switch=False),
6095
Option('list', help='List shelved changes.'),
6097
help='Destroy removed changes instead of shelving them.'),
6099
_see_also = ['unshelve', 'configuration']
6101
def run(self, revision=None, all=False, file_list=None, message=None,
6102
writer=None, list=False, destroy=False, directory=None):
6104
return self.run_for_list(directory=directory)
6105
from bzrlib.shelf_ui import Shelver
6107
writer = bzrlib.option.diff_writer_registry.get()
6109
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6110
file_list, message, destroy=destroy, directory=directory)
6115
except errors.UserAbort:
6118
def run_for_list(self, directory=None):
6119
if directory is None:
6121
tree = WorkingTree.open_containing(directory)[0]
6122
self.add_cleanup(tree.lock_read().unlock)
6123
manager = tree.get_shelf_manager()
6124
shelves = manager.active_shelves()
6125
if len(shelves) == 0:
6126
note('No shelved changes.')
6128
for shelf_id in reversed(shelves):
6129
message = manager.get_metadata(shelf_id).get('message')
6131
message = '<no message>'
6132
self.outf.write('%3d: %s\n' % (shelf_id, message))
6136
class cmd_unshelve(Command):
6137
__doc__ = """Restore shelved changes.
6139
By default, the most recently shelved changes are restored. However if you
6140
specify a shelf by id those changes will be restored instead. This works
6141
best when the changes don't depend on each other.
6144
takes_args = ['shelf_id?']
6147
RegistryOption.from_kwargs(
6148
'action', help="The action to perform.",
6149
enum_switch=False, value_switches=True,
6150
apply="Apply changes and remove from the shelf.",
6151
dry_run="Show changes, but do not apply or remove them.",
6152
preview="Instead of unshelving the changes, show the diff that "
6153
"would result from unshelving.",
6154
delete_only="Delete changes without applying them.",
6155
keep="Apply changes but don't delete them.",
6158
_see_also = ['shelve']
6160
def run(self, shelf_id=None, action='apply', directory=u'.'):
6161
from bzrlib.shelf_ui import Unshelver
6162
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
6166
unshelver.tree.unlock()
6169
class cmd_clean_tree(Command):
6170
__doc__ = """Remove unwanted files from working tree.
6172
By default, only unknown files, not ignored files, are deleted. Versioned
6173
files are never deleted.
6175
Another class is 'detritus', which includes files emitted by bzr during
6176
normal operations and selftests. (The value of these files decreases with
6179
If no options are specified, unknown files are deleted. Otherwise, option
6180
flags are respected, and may be combined.
6182
To check what clean-tree will do, use --dry-run.
6184
takes_options = ['directory',
6185
Option('ignored', help='Delete all ignored files.'),
6186
Option('detritus', help='Delete conflict files, merge and revert'
6187
' backups, and failed selftest dirs.'),
6189
help='Delete files unknown to bzr (default).'),
6190
Option('dry-run', help='Show files to delete instead of'
6192
Option('force', help='Do not prompt before deleting.')]
6193
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6194
force=False, directory=u'.'):
6195
from bzrlib.clean_tree import clean_tree
6196
if not (unknown or ignored or detritus):
6200
clean_tree(directory, unknown=unknown, ignored=ignored,
6201
detritus=detritus, dry_run=dry_run, no_prompt=force)
6204
class cmd_reference(Command):
6205
__doc__ = """list, view and set branch locations for nested trees.
6207
If no arguments are provided, lists the branch locations for nested trees.
6208
If one argument is provided, display the branch location for that tree.
6209
If two arguments are provided, set the branch location for that tree.
6214
takes_args = ['path?', 'location?']
6216
def run(self, path=None, location=None):
6218
if path is not None:
6220
tree, branch, relpath =(
6221
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
6222
if path is not None:
6225
tree = branch.basis_tree()
4579
6226
if path is None:
4581
branch_hooks = Branch.open(path).hooks
4582
for hook_type in branch_hooks:
4583
hooks = branch_hooks[hook_type]
4584
self.outf.write("%s:\n" % (hook_type,))
4587
self.outf.write(" %s\n" %
4588
(branch_hooks.get_hook_name(hook),))
6227
info = branch._get_all_reference_info().iteritems()
6228
self._display_reference_info(tree, branch, info)
6230
file_id = tree.path2id(path)
6232
raise errors.NotVersionedError(path)
6233
if location is None:
6234
info = [(file_id, branch.get_reference_info(file_id))]
6235
self._display_reference_info(tree, branch, info)
4590
self.outf.write(" <no hooks installed>\n")
4593
def _create_prefix(cur_transport):
4594
needed = [cur_transport]
4595
# Recurse upwards until we can create a directory successfully
4597
new_transport = cur_transport.clone('..')
4598
if new_transport.base == cur_transport.base:
4599
raise errors.BzrCommandError(
4600
"Failed to create path prefix for %s."
4601
% cur_transport.base)
4603
new_transport.mkdir('.')
4604
except errors.NoSuchFile:
4605
needed.append(new_transport)
4606
cur_transport = new_transport
4609
# Now we only need to create child directories
4611
cur_transport = needed.pop()
4612
cur_transport.ensure_base()
4615
# these get imported and then picked up by the scan for cmd_*
4616
# TODO: Some more consistent way to split command definitions across files;
4617
# we do need to load at least some information about them to know of
4618
# aliases. ideally we would avoid loading the implementation until the
4619
# details were needed.
4620
from bzrlib.cmd_version_info import cmd_version_info
4621
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
4622
from bzrlib.bundle.commands import (
4625
from bzrlib.sign_my_commits import cmd_sign_my_commits
4626
from bzrlib.weave_commands import cmd_versionedfile_list, \
4627
cmd_weave_plan_merge, cmd_weave_merge_text
6237
branch.set_reference_info(file_id, path, location)
6239
def _display_reference_info(self, tree, branch, info):
6241
for file_id, (path, location) in info:
6243
path = tree.id2path(file_id)
6244
except errors.NoSuchId:
6246
ref_list.append((path, location))
6247
for path, location in sorted(ref_list):
6248
self.outf.write('%s %s\n' % (path, location))
6251
class cmd_export_pot(Command):
6252
__doc__ = """Export command helps and error messages in po format."""
6257
from bzrlib.export_pot import export_pot
6258
export_pot(self.outf)
6261
def _register_lazy_builtins():
6262
# register lazy builtins from other modules; called at startup and should
6263
# be only called once.
6264
for (name, aliases, module_name) in [
6265
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6266
('cmd_config', [], 'bzrlib.config'),
6267
('cmd_dpush', [], 'bzrlib.foreign'),
6268
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6269
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6270
('cmd_conflicts', [], 'bzrlib.conflicts'),
6271
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6272
('cmd_verify_signatures', [],
6273
'bzrlib.commit_signature_commands'),
6274
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6276
builtin_command_registry.register_lazy(name, aliases, module_name)