78
68
_parse_revision_str,
80
70
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
86
def _get_branch_location(control_dir, possible_transports=None):
87
"""Return location of branch for this control dir."""
89
this_branch = control_dir.open_branch(
90
possible_transports=possible_transports)
91
# This may be a heavy checkout, where we want the master branch
92
master_location = this_branch.get_bound_location()
93
if master_location is not None:
94
return master_location
95
# If not, use a local sibling
96
return this_branch.base
97
except errors.NotBranchError:
98
format = control_dir.find_branch_format()
99
if getattr(format, 'get_reference', None) is not None:
100
return format.get_reference(control_dir)
102
return control_dir.root_transport.base
105
def _is_colocated(control_dir, possible_transports=None):
106
"""Check if the branch in control_dir is colocated.
108
:param control_dir: Control directory
109
:return: Boolean indicating whether
111
# This path is meant to be relative to the existing branch
112
this_url = _get_branch_location(control_dir,
113
possible_transports=possible_transports)
114
# Perhaps the target control dir supports colocated branches?
116
root = controldir.ControlDir.open(this_url,
117
possible_transports=possible_transports)
118
except errors.NotBranchError:
119
return (False, this_url)
122
wt = control_dir.open_workingtree()
123
except (errors.NoWorkingTree, errors.NotLocalUrl):
124
return (False, this_url)
127
root._format.colocated_branches and
128
control_dir.control_url == root.control_url,
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
"""Lookup the location for a new sibling branch.
135
:param control_dir: Control directory relative to which to look up
137
:param location: Name of the new branch
138
:return: Full location to the new branch
140
location = directory_service.directories.dereference(location)
141
if '/' not in location and '\\' not in location:
142
(colocated, this_url) = _is_colocated(control_dir, possible_transports)
145
return urlutils.join_segment_parameters(this_url,
146
{"branch": urlutils.escape(location)})
148
return urlutils.join(this_url, '..', urlutils.escape(location))
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
"""Lookup sibling branch.
155
:param control_dir: Control directory relative to which to lookup the
157
:param location: Location to look up
158
:return: branch to open
161
# Perhaps it's a colocated branch?
162
return control_dir.open_branch(location,
163
possible_transports=possible_transports)
164
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
166
return Branch.open(location)
167
except errors.NotBranchError:
168
this_url = _get_branch_location(control_dir)
171
this_url, '..', urlutils.escape(location)))
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
175
73
def tree_files(file_list, default_branch=u'.', canonicalize=True,
177
return internal_tree_files(file_list, default_branch, canonicalize,
76
return internal_tree_files(file_list, default_branch, canonicalize,
78
except errors.FileInWrongBranch, e:
79
raise errors.BzrCommandError("%s is not in the same branch as %s" %
80
(e.path, file_list[0]))
181
83
def tree_files_for_add(file_list):
268
167
:return: workingtree, [relative_paths]
270
return WorkingTree.open_containing_paths(
271
file_list, default_directory='.',
169
if file_list is None or len(file_list) == 0:
170
tree = WorkingTree.open_containing(default_branch)[0]
171
if tree.supports_views() and apply_view:
172
view_files = tree.views.lookup_view()
174
file_list = view_files
175
view_str = views.view_display_str(view_files)
176
note("Ignoring files outside view. View is %s" % view_str)
177
return tree, file_list
178
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
179
return tree, safe_relpath_files(tree, file_list, canonicalize,
180
apply_view=apply_view)
183
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
184
"""Convert file_list into a list of relpaths in tree.
186
:param tree: A tree to operate on.
187
:param file_list: A list of user provided paths or None.
188
:param apply_view: if True and a view is set, apply it or check that
189
specified files are within it
190
:return: A list of relative paths.
191
:raises errors.PathNotChild: When a provided path is in a different tree
194
if file_list is None:
196
if tree.supports_views() and apply_view:
197
view_files = tree.views.lookup_view()
201
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
202
# doesn't - fix that up here before we enter the loop.
204
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
207
for filename in file_list:
209
relpath = fixer(osutils.dereference_path(filename))
210
if view_files and not osutils.is_inside_any(view_files, relpath):
211
raise errors.FileOutsideView(filename, view_files)
212
new_list.append(relpath)
213
except errors.PathNotChild:
214
raise errors.FileInWrongBranch(tree.branch, filename)
276
218
def _get_view_info_for_change_reporter(tree):
413
337
takes_args = ['revision_id?']
414
takes_options = ['directory', 'revision']
338
takes_options = ['revision']
415
339
# cat-revision is more for frontends so should be exact
416
340
encoding = 'strict'
418
def print_revision(self, revisions, revid):
419
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
420
record = stream.next()
421
if record.storage_kind == 'absent':
422
raise errors.NoSuchRevision(revisions, revid)
423
revtext = record.get_bytes_as('fulltext')
424
self.outf.write(revtext.decode('utf-8'))
427
def run(self, revision_id=None, revision=None, directory=u'.'):
343
def run(self, revision_id=None, revision=None):
428
344
if revision_id is not None and revision is not None:
429
raise errors.BzrCommandError(gettext('You can only supply one of'
430
' revision_id or --revision'))
345
raise errors.BzrCommandError('You can only supply one of'
346
' revision_id or --revision')
431
347
if revision_id is None and revision is None:
432
raise errors.BzrCommandError(gettext('You must supply either'
433
' --revision or a revision_id'))
435
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
437
revisions = b.repository.revisions
438
if revisions is None:
439
raise errors.BzrCommandError(gettext('Repository %r does not support '
440
'access to raw revision texts'))
442
b.repository.lock_read()
444
# TODO: jam 20060112 should cat-revision always output utf-8?
445
if revision_id is not None:
446
revision_id = osutils.safe_revision_id(revision_id, warn=False)
448
self.print_revision(revisions, revision_id)
449
except errors.NoSuchRevision:
450
msg = gettext("The repository {0} contains no revision {1}.").format(
451
b.repository.base, revision_id)
452
raise errors.BzrCommandError(msg)
453
elif revision is not None:
456
raise errors.BzrCommandError(
457
gettext('You cannot specify a NULL revision.'))
458
rev_id = rev.as_revision_id(b)
459
self.print_revision(revisions, rev_id)
461
b.repository.unlock()
348
raise errors.BzrCommandError('You must supply either'
349
' --revision or a revision_id')
350
b = WorkingTree.open_containing(u'.')[0].branch
352
# TODO: jam 20060112 should cat-revision always output utf-8?
353
if revision_id is not None:
354
revision_id = osutils.safe_revision_id(revision_id, warn=False)
356
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
357
except errors.NoSuchRevision:
358
msg = "The repository %s contains no revision %s." % (b.repository.base,
360
raise errors.BzrCommandError(msg)
361
elif revision is not None:
364
raise errors.BzrCommandError('You cannot specify a NULL'
366
rev_id = rev.as_revision_id(b)
367
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
464
370
class cmd_dump_btree(Command):
465
__doc__ = """Dump the contents of a btree index file to stdout.
371
"""Dump the contents of a btree index file to stdout.
467
373
PATH is a btree index file, it can be any URL. This includes things like
468
374
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
554
452
To re-create the working tree, use "bzr checkout".
556
454
_see_also = ['checkout', 'working-trees']
557
takes_args = ['location*']
455
takes_args = ['location?']
558
456
takes_options = [
560
458
help='Remove the working tree even if it has '
561
'uncommitted or shelved changes.'),
459
'uncommitted changes.'),
564
def run(self, location_list, force=False):
565
if not location_list:
568
for location in location_list:
569
d = controldir.ControlDir.open(location)
572
working = d.open_workingtree()
573
except errors.NoWorkingTree:
574
raise errors.BzrCommandError(gettext("No working tree to remove"))
575
except errors.NotLocalUrl:
576
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
577
" of a remote path"))
579
if (working.has_changes()):
580
raise errors.UncommittedChanges(working)
581
if working.get_shelf_manager().last_shelf() is not None:
582
raise errors.ShelvedChanges(working)
584
if working.user_url != working.branch.user_url:
585
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
586
" from a lightweight checkout"))
588
d.destroy_workingtree()
591
class cmd_repair_workingtree(Command):
592
__doc__ = """Reset the working tree state file.
594
This is not meant to be used normally, but more as a way to recover from
595
filesystem corruption, etc. This rebuilds the working inventory back to a
596
'known good' state. Any new modifications (adding a file, renaming, etc)
597
will be lost, though modified files will still be detected as such.
599
Most users will want something more like "bzr revert" or "bzr update"
600
unless the state file has become corrupted.
602
By default this attempts to recover the current state by looking at the
603
headers of the state file. If the state file is too corrupted to even do
604
that, you can supply --revision to force the state of the tree.
607
takes_options = ['revision', 'directory',
609
help='Reset the tree even if it doesn\'t appear to be'
614
def run(self, revision=None, directory='.', force=False):
615
tree, _ = WorkingTree.open_containing(directory)
616
self.add_cleanup(tree.lock_tree_write().unlock)
462
def run(self, location='.', force=False):
463
d = bzrdir.BzrDir.open(location)
466
working = d.open_workingtree()
467
except errors.NoWorkingTree:
468
raise errors.BzrCommandError("No working tree to remove")
469
except errors.NotLocalUrl:
470
raise errors.BzrCommandError("You cannot remove the working tree"
620
except errors.BzrError:
621
pass # There seems to be a real error here, so we'll reset
624
raise errors.BzrCommandError(gettext(
625
'The tree does not appear to be corrupt. You probably'
626
' want "bzr revert" instead. Use "--force" if you are'
627
' sure you want to reset the working tree.'))
631
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
633
tree.reset_state(revision_ids)
634
except errors.BzrError, e:
635
if revision_ids is None:
636
extra = (gettext(', the header appears corrupt, try passing -r -1'
637
' to set the state to the last commit'))
640
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
473
if (working.has_changes()):
474
raise errors.UncommittedChanges(working)
476
working_path = working.bzrdir.root_transport.base
477
branch_path = working.branch.bzrdir.root_transport.base
478
if working_path != branch_path:
479
raise errors.BzrCommandError("You cannot remove the working tree"
480
" from a lightweight checkout")
482
d.destroy_workingtree()
643
485
class cmd_revno(Command):
644
__doc__ = """Show current revision number.
486
"""Show current revision number.
646
488
This is equal to the number of revisions on this branch.
649
491
_see_also = ['info']
650
492
takes_args = ['location?']
651
493
takes_options = [
652
Option('tree', help='Show revno of working tree.'),
494
Option('tree', help='Show revno of working tree'),
657
def run(self, tree=False, location=u'.', revision=None):
658
if revision is not None and tree:
659
raise errors.BzrCommandError(gettext("--tree and --revision can "
660
"not be used together"))
498
def run(self, tree=False, location=u'.'):
664
501
wt = WorkingTree.open_containing(location)[0]
665
self.add_cleanup(wt.lock_read().unlock)
666
503
except (errors.NoWorkingTree, errors.NotLocalUrl):
667
504
raise errors.NoWorkingTree(location)
505
self.add_cleanup(wt.unlock)
669
506
revid = wt.last_revision()
508
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
509
except errors.NoSuchRevision:
511
revno = ".".join(str(n) for n in revno_t)
671
513
b = Branch.open_containing(location)[0]
672
self.add_cleanup(b.lock_read().unlock)
674
if len(revision) != 1:
675
raise errors.BzrCommandError(gettext(
676
"Tags can only be placed on a single revision, "
678
revid = revision[0].as_revision_id(b)
680
revid = b.last_revision()
682
revno_t = b.revision_id_to_dotted_revno(revid)
683
except errors.NoSuchRevision:
685
revno = ".".join(str(n) for n in revno_t)
515
self.add_cleanup(b.unlock)
686
517
self.cleanup_now()
687
self.outf.write(revno + '\n')
518
self.outf.write(str(revno) + '\n')
690
521
class cmd_revision_info(Command):
691
__doc__ = """Show revision number and revision id for a given revision identifier.
522
"""Show revision number and revision id for a given revision identifier.
694
525
takes_args = ['revision_info*']
695
526
takes_options = [
697
custom_help('directory',
698
529
help='Branch to examine, '
699
'rather than the one containing the working directory.'),
700
Option('tree', help='Show revno of working tree.'),
530
'rather than the one containing the working directory.',
534
Option('tree', help='Show revno of working tree'),
833
663
for glob in sorted(ignored.keys()):
834
664
for path in ignored[glob]:
836
gettext("ignored {0} matching \"{1}\"\n").format(
665
self.outf.write("ignored %s matching \"%s\"\n"
840
669
class cmd_mkdir(Command):
841
__doc__ = """Create a new versioned directory.
670
"""Create a new versioned directory.
843
672
This is equivalent to creating the directory and then adding it.
846
675
takes_args = ['dir+']
850
help='No error if existing, make parent directories as needed.',
854
676
encoding_type = 'replace'
857
def add_file_with_parents(cls, wt, relpath):
858
if wt.path2id(relpath) is not None:
860
cls.add_file_with_parents(wt, osutils.dirname(relpath))
864
def add_file_single(cls, wt, relpath):
867
def run(self, dir_list, parents=False):
869
add_file = self.add_file_with_parents
871
add_file = self.add_file_single
873
wt, relpath = WorkingTree.open_containing(dir)
878
if e.errno != errno.EEXIST:
882
add_file(wt, relpath)
884
self.outf.write(gettext('added %s\n') % dir)
678
def run(self, dir_list):
681
wt, dd = WorkingTree.open_containing(d)
683
self.outf.write('added %s\n' % d)
887
686
class cmd_relpath(Command):
888
__doc__ = """Show path of a file relative to root"""
687
"""Show path of a file relative to root"""
890
689
takes_args = ['filename']
924
723
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
925
724
if kind and kind not in ['file', 'directory', 'symlink']:
926
raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
725
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
928
727
revision = _get_one_revision('inventory', revision)
929
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
930
self.add_cleanup(work_tree.lock_read().unlock)
728
work_tree, file_list = tree_files(file_list)
729
work_tree.lock_read()
730
self.add_cleanup(work_tree.unlock)
931
731
if revision is not None:
932
732
tree = revision.as_tree(work_tree.branch)
934
734
extra_trees = [work_tree]
935
self.add_cleanup(tree.lock_read().unlock)
736
self.add_cleanup(tree.unlock)
940
self.add_cleanup(tree.lock_read().unlock)
941
741
if file_list is not None:
942
742
file_ids = tree.paths2ids(file_list, trees=extra_trees,
943
743
require_versioned=True)
944
744
# find_ids_across_trees may include some paths that don't
945
745
# exist in 'tree'.
946
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
746
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
747
for file_id in file_ids if file_id in tree)
948
entries = tree.iter_entries_by_dir()
749
entries = tree.inventory.entries()
950
for path, entry in sorted(entries):
752
for path, entry in entries:
951
753
if kind and kind != entry.kind:
956
756
self.outf.write('%-50s %s\n' % (path, entry.file_id))
994
794
return self.run_auto(names_list, after, dry_run)
996
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
796
raise errors.BzrCommandError('--dry-run requires --auto.')
997
797
if names_list is None:
999
799
if len(names_list) < 2:
1000
raise errors.BzrCommandError(gettext("missing file argument"))
1001
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1002
for file_name in rel_names[0:-1]:
1004
raise errors.BzrCommandError(gettext("can not move root of branch"))
1005
self.add_cleanup(tree.lock_tree_write().unlock)
800
raise errors.BzrCommandError("missing file argument")
801
tree, rel_names = tree_files(names_list, canonicalize=False)
802
tree.lock_tree_write()
803
self.add_cleanup(tree.unlock)
1006
804
self._run(tree, names_list, rel_names, after)
1008
806
def run_auto(self, names_list, after, dry_run):
1009
807
if names_list is not None and len(names_list) > 1:
1010
raise errors.BzrCommandError(gettext('Only one path may be specified to'
808
raise errors.BzrCommandError('Only one path may be specified to'
1013
raise errors.BzrCommandError(gettext('--after cannot be specified with'
1015
work_tree, file_list = WorkingTree.open_containing_paths(
1016
names_list, default_directory='.')
1017
self.add_cleanup(work_tree.lock_tree_write().unlock)
811
raise errors.BzrCommandError('--after cannot be specified with'
813
work_tree, file_list = tree_files(names_list, default_branch='.')
814
work_tree.lock_tree_write()
815
self.add_cleanup(work_tree.unlock)
1018
816
rename_map.RenameMap.guess_renames(work_tree, dry_run)
1020
818
def _run(self, tree, names_list, rel_names, after):
1131
926
takes_options = ['remember', 'overwrite', 'revision',
1132
927
custom_help('verbose',
1133
928
help='Show logs of pulled revisions.'),
1134
custom_help('directory',
1135
930
help='Branch to pull into, '
1136
'rather than the one containing the working directory.'),
931
'rather than the one containing the working directory.',
1138
936
help="Perform a local pull in a bound "
1139
937
"branch. Local pulls are not applied to "
1140
938
"the master branch."
1143
help="Show base revision text in conflicts.")
1145
941
takes_args = ['location?']
1146
942
encoding_type = 'replace'
1148
def run(self, location=None, remember=None, overwrite=False,
944
def run(self, location=None, remember=False, overwrite=False,
1149
945
revision=None, verbose=False,
1150
directory=None, local=False,
946
directory=None, local=False):
1152
947
# FIXME: too much stuff is in the command class
1153
948
revision_id = None
1154
949
mergeable = None
1287
1075
Option('strict',
1288
1076
help='Refuse to push if there are uncommitted changes in'
1289
1077
' the working tree, --no-strict disables the check.'),
1291
help="Don't populate the working tree, even for protocols"
1292
" that support it."),
1294
1079
takes_args = ['location?']
1295
1080
encoding_type = 'replace'
1297
def run(self, location=None, remember=None, overwrite=False,
1082
def run(self, location=None, remember=False, overwrite=False,
1298
1083
create_prefix=False, verbose=False, revision=None,
1299
1084
use_existing_dir=False, directory=None, stacked_on=None,
1300
stacked=False, strict=None, no_tree=False):
1085
stacked=False, strict=None):
1301
1086
from bzrlib.push import _show_push_branch
1303
1088
if directory is None:
1304
1089
directory = '.'
1305
1090
# Get the source branch
1306
1091
(tree, br_from,
1307
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1092
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1308
1096
# Get the tip's revision_id
1309
1097
revision = _get_one_revision('push', revision)
1310
1098
if revision is not None:
1311
1099
revision_id = revision.in_history(br_from).rev_id
1313
1101
revision_id = None
1314
if tree is not None and revision_id is None:
1315
tree.check_changed_or_out_of_date(
1316
strict, 'push_strict',
1317
more_error='Use --no-strict to force the push.',
1318
more_warning='Uncommitted changes will not be pushed.')
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
tree, more='Use --no-strict to force the push.')
1319
1113
# Get the stacked_on branch, if any
1320
1114
if stacked_on is not None:
1321
1115
stacked_on = urlutils.normalize_url(stacked_on)
1331
1125
# error by the feedback given to them. RBC 20080227.
1332
1126
stacked_on = parent_url
1333
1127
if not stacked_on:
1334
raise errors.BzrCommandError(gettext(
1335
"Could not determine branch to refer to."))
1128
raise errors.BzrCommandError(
1129
"Could not determine branch to refer to.")
1337
1131
# Get the destination location
1338
1132
if location is None:
1339
1133
stored_loc = br_from.get_push_location()
1340
1134
if stored_loc is None:
1341
parent_loc = br_from.get_parent()
1343
raise errors.BzrCommandError(gettext(
1344
"No push location known or specified. To push to the "
1345
"parent branch (at %s), use 'bzr push :parent'." %
1346
urlutils.unescape_for_display(parent_loc,
1347
self.outf.encoding)))
1349
raise errors.BzrCommandError(gettext(
1350
"No push location known or specified."))
1135
raise errors.BzrCommandError(
1136
"No push location known or specified.")
1352
1138
display_url = urlutils.unescape_for_display(stored_loc,
1353
1139
self.outf.encoding)
1354
note(gettext("Using saved push location: %s") % display_url)
1140
self.outf.write("Using saved push location: %s\n" % display_url)
1355
1141
location = stored_loc
1357
1143
_show_push_branch(br_from, revision_id, location, self.outf,
1358
1144
verbose=verbose, overwrite=overwrite, remember=remember,
1359
1145
stacked_on=stacked_on, create_prefix=create_prefix,
1360
use_existing_dir=use_existing_dir, no_tree=no_tree)
1146
use_existing_dir=use_existing_dir)
1363
1149
class cmd_branch(Command):
1364
__doc__ = """Create a new branch that is a copy of an existing branch.
1150
"""Create a new branch that is a copy of an existing branch.
1366
1152
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1367
1153
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1406
1188
def run(self, from_location, to_location=None, revision=None,
1407
1189
hardlink=False, stacked=False, standalone=False, no_tree=False,
1408
use_existing_dir=False, switch=False, bind=False,
1190
use_existing_dir=False, switch=False, bind=False):
1410
1191
from bzrlib import switch as _mod_switch
1411
1192
from bzrlib.tag import _merge_tags_if_possible
1412
if self.invoked_as in ['get', 'clone']:
1413
ui.ui_factory.show_user_warning(
1414
'deprecated_command',
1415
deprecated_name=self.invoked_as,
1416
recommended_name='branch',
1417
deprecated_in_version='2.4')
1418
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1193
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1420
if not (hardlink or files_from):
1421
# accelerator_tree is usually slower because you have to read N
1422
# files (no readahead, lots of seeks, etc), but allow the user to
1423
# explicitly request it
1424
accelerator_tree = None
1425
if files_from is not None and files_from != from_location:
1426
accelerator_tree = WorkingTree.open(files_from)
1427
1195
revision = _get_one_revision('branch', revision)
1428
self.add_cleanup(br_from.lock_read().unlock)
1197
self.add_cleanup(br_from.unlock)
1429
1198
if revision is not None:
1430
1199
revision_id = revision.as_revision_id(br_from)
1435
1204
revision_id = br_from.last_revision()
1436
1205
if to_location is None:
1437
to_location = getattr(br_from, "name", None)
1439
to_location = urlutils.derive_to_location(from_location)
1206
to_location = urlutils.derive_to_location(from_location)
1440
1207
to_transport = transport.get_transport(to_location)
1442
1209
to_transport.mkdir('.')
1443
1210
except errors.FileExists:
1445
to_dir = controldir.ControlDir.open_from_transport(
1447
except errors.NotBranchError:
1448
if not use_existing_dir:
1449
raise errors.BzrCommandError(gettext('Target directory "%s" '
1450
'already exists.') % to_location)
1211
if not use_existing_dir:
1212
raise errors.BzrCommandError('Target directory "%s" '
1213
'already exists.' % to_location)
1455
to_dir.open_branch()
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1456
1217
except errors.NotBranchError:
1459
1220
raise errors.AlreadyBranchError(to_location)
1460
1221
except errors.NoSuchFile:
1461
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1222
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1467
# preserve whatever source format we have.
1468
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1469
possible_transports=[to_transport],
1470
accelerator_tree=accelerator_tree,
1471
hardlink=hardlink, stacked=stacked,
1472
force_new_repo=standalone,
1473
create_tree_if_local=not no_tree,
1474
source_branch=br_from)
1475
branch = to_dir.open_branch(
1476
possible_transports=[
1477
br_from.bzrdir.root_transport, to_transport])
1478
except errors.NoSuchRevision:
1479
to_transport.delete_tree('.')
1480
msg = gettext("The branch {0} has no revision {1}.").format(
1481
from_location, revision)
1482
raise errors.BzrCommandError(msg)
1485
to_repo = to_dir.open_repository()
1486
except errors.NoRepositoryPresent:
1487
to_repo = to_dir.create_repository()
1488
to_repo.fetch(br_from.repository, revision_id=revision_id)
1489
branch = br_from.sprout(to_dir, revision_id=revision_id)
1225
# preserve whatever source format we have.
1226
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1227
possible_transports=[to_transport],
1228
accelerator_tree=accelerator_tree,
1229
hardlink=hardlink, stacked=stacked,
1230
force_new_repo=standalone,
1231
create_tree_if_local=not no_tree,
1232
source_branch=br_from)
1233
branch = dir.open_branch()
1234
except errors.NoSuchRevision:
1235
to_transport.delete_tree('.')
1236
msg = "The branch %s has no revision %s." % (from_location,
1238
raise errors.BzrCommandError(msg)
1490
1239
_merge_tags_if_possible(br_from, branch)
1491
1240
# If the source branch is stacked, the new branch may
1492
1241
# be stacked whether we asked for that explicitly or not.
1493
1242
# We therefore need a try/except here and not just 'if stacked:'
1495
note(gettext('Created new stacked branch referring to %s.') %
1244
note('Created new stacked branch referring to %s.' %
1496
1245
branch.get_stacked_on_url())
1497
1246
except (errors.NotStacked, errors.UnstackableBranchFormat,
1498
1247
errors.UnstackableRepositoryFormat), e:
1499
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1248
note('Branched %d revision(s).' % branch.revno())
1501
1250
# Bind to the parent
1502
1251
parent_branch = Branch.open(from_location)
1503
1252
branch.bind(parent_branch)
1504
note(gettext('New branch bound to %s') % from_location)
1253
note('New branch bound to %s' % from_location)
1506
1255
# Switch to the new branch
1507
1256
wt, _ = WorkingTree.open_containing('.')
1508
1257
_mod_switch.switch(wt.bzrdir, branch)
1509
note(gettext('Switched to branch: %s'),
1258
note('Switched to branch: %s',
1510
1259
urlutils.unescape_for_display(branch.base, 'utf-8'))
1513
class cmd_branches(Command):
1514
__doc__ = """List the branches available at the current location.
1516
This command will print the names of all the branches at the current
1520
takes_args = ['location?']
1522
Option('recursive', short_name='R',
1523
help='Recursively scan for branches rather than '
1524
'just looking in the specified location.')]
1526
def run(self, location=".", recursive=False):
1528
t = transport.get_transport(location)
1529
if not t.listable():
1530
raise errors.BzrCommandError(
1531
"Can't scan this type of location.")
1532
for b in controldir.ControlDir.find_branches(t):
1533
self.outf.write("%s\n" % urlutils.unescape_for_display(
1534
urlutils.relative_url(t.base, b.base),
1535
self.outf.encoding).rstrip("/"))
1537
dir = controldir.ControlDir.open_containing(location)[0]
1539
active_branch = dir.open_branch(name="")
1540
except errors.NotBranchError:
1541
active_branch = None
1542
branches = dir.get_branches()
1544
for name, branch in branches.iteritems():
1547
active = (active_branch is not None and
1548
active_branch.base == branch.base)
1549
names[name] = active
1550
# Only mention the current branch explicitly if it's not
1551
# one of the colocated branches
1552
if not any(names.values()) and active_branch is not None:
1553
self.outf.write("* %s\n" % gettext("(default)"))
1554
for name in sorted(names.keys()):
1555
active = names[name]
1560
self.outf.write("%s %s\n" % (
1561
prefix, name.encode(self.outf.encoding)))
1564
1262
class cmd_checkout(Command):
1565
__doc__ = """Create a new checkout of an existing branch.
1263
"""Create a new checkout of an existing branch.
1567
1265
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1568
1266
the branch found in '.'. This is useful if you have removed the working tree
1668
1363
class cmd_update(Command):
1669
__doc__ = """Update a working tree to a new revision.
1671
This will perform a merge of the destination revision (the tip of the
1672
branch, or the specified revision) into the working tree, and then make
1673
that revision the basis revision for the working tree.
1675
You can use this to visit an older revision, or to update a working tree
1676
that is out of date from its branch.
1678
If there are any uncommitted changes in the tree, they will be carried
1679
across and remain as uncommitted changes after the update. To discard
1680
these changes, use 'bzr revert'. The uncommitted changes may conflict
1681
with the changes brought in by the change in basis revision.
1683
If the tree's branch is bound to a master branch, bzr will also update
1364
"""Update a tree to have the latest code committed to its branch.
1366
This will perform a merge into the working tree, and may generate
1367
conflicts. If you have any local changes, you will still
1368
need to commit them after the update for the update to be complete.
1370
If you want to discard your local changes, you can just do a
1371
'bzr revert' instead of 'bzr commit' after the update.
1373
If the tree's branch is bound to a master branch, it will also update
1684
1374
the branch from the master.
1686
You cannot update just a single file or directory, because each Bazaar
1687
working tree has just a single basis revision. If you want to restore a
1688
file that has been removed locally, use 'bzr revert' instead of 'bzr
1689
update'. If you want to restore a file to its state in a previous
1690
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1691
out the old content of that file to a new location.
1693
The 'dir' argument, if given, must be the location of the root of a
1694
working tree to update. By default, the working tree that contains the
1695
current working directory is used.
1698
1377
_see_also = ['pull', 'working-trees', 'status-flags']
1699
1378
takes_args = ['dir?']
1700
takes_options = ['revision',
1702
help="Show base revision text in conflicts."),
1379
takes_options = ['revision']
1704
1380
aliases = ['up']
1706
def run(self, dir=None, revision=None, show_base=None):
1382
def run(self, dir='.', revision=None):
1707
1383
if revision is not None and len(revision) != 1:
1708
raise errors.BzrCommandError(gettext(
1709
"bzr update --revision takes exactly one revision"))
1711
tree = WorkingTree.open_containing('.')[0]
1713
tree, relpath = WorkingTree.open_containing(dir)
1716
raise errors.BzrCommandError(gettext(
1717
"bzr update can only update a whole tree, "
1718
"not a file or subdirectory"))
1384
raise errors.BzrCommandError(
1385
"bzr update --revision takes exactly one revision")
1386
tree = WorkingTree.open_containing(dir)[0]
1719
1387
branch = tree.branch
1720
1388
possible_transports = []
1721
1389
master = branch.get_master_branch(
1722
1390
possible_transports=possible_transports)
1723
1391
if master is not None:
1724
1393
branch_location = master.base
1395
tree.lock_tree_write()
1727
1396
branch_location = tree.branch.base
1728
tree.lock_tree_write()
1729
1397
self.add_cleanup(tree.unlock)
1730
1398
# get rid of the final '/' and be ready for display
1731
branch_location = urlutils.unescape_for_display(
1732
branch_location.rstrip('/'),
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1734
1401
existing_pending_merges = tree.get_parent_ids()[1:]
1735
1402
if master is None:
1757
1424
change_reporter,
1758
1425
possible_transports=possible_transports,
1759
1426
revision=revision_id,
1761
show_base=show_base)
1762
1428
except errors.NoSuchRevision, e:
1763
raise errors.BzrCommandError(gettext(
1429
raise errors.BzrCommandError(
1764
1430
"branch has no revision %s\n"
1765
1431
"bzr update --revision only works"
1766
" for a revision in the branch history")
1432
" for a revision in the branch history"
1767
1433
% (e.revision))
1768
revno = tree.branch.revision_id_to_dotted_revno(
1434
revno = tree.branch.revision_id_to_revno(
1769
1435
_mod_revision.ensure_null(tree.last_revision()))
1770
note(gettext('Updated to revision {0} of branch {1}').format(
1771
'.'.join(map(str, revno)), branch_location))
1772
parent_ids = tree.get_parent_ids()
1773
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1774
note(gettext('Your local commits will now show as pending merges with '
1775
"'bzr status', and can be committed with 'bzr commit'."))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
if tree.get_parent_ids()[1:] != existing_pending_merges:
1439
note('Your local commits will now show as pending merges with '
1440
"'bzr status', and can be committed with 'bzr commit'.")
1776
1441
if conflicts != 0:
1838
1502
RegistryOption.from_kwargs('file-deletion-strategy',
1839
1503
'The file deletion mode to be used.',
1840
1504
title='Deletion Strategy', value_switches=True, enum_switch=False,
1841
safe='Backup changed files (default).',
1505
safe='Only delete files if they can be'
1506
' safely recovered (default).',
1842
1507
keep='Delete from bzr but leave the working copy.',
1843
no_backup='Don\'t backup changed files.',
1844
1508
force='Delete all the specified files, even if they can not be '
1845
'recovered and even if they are non-empty directories. '
1846
'(deprecated, use no-backup)')]
1509
'recovered and even if they are non-empty directories.')]
1847
1510
aliases = ['rm', 'del']
1848
1511
encoding_type = 'replace'
1850
1513
def run(self, file_list, verbose=False, new=False,
1851
1514
file_deletion_strategy='safe'):
1852
if file_deletion_strategy == 'force':
1853
note(gettext("(The --force option is deprecated, rather use --no-backup "
1855
file_deletion_strategy = 'no-backup'
1857
tree, file_list = WorkingTree.open_containing_paths(file_list)
1515
tree, file_list = tree_files(file_list)
1859
1517
if file_list is not None:
1860
1518
file_list = [f for f in file_list]
1862
self.add_cleanup(tree.lock_write().unlock)
1521
self.add_cleanup(tree.unlock)
1863
1522
# Heuristics should probably all move into tree.remove_smart or
2173
1809
def run(self, location, format=None, no_trees=False):
2174
1810
if format is None:
2175
format = controldir.format_registry.make_bzrdir('default')
1811
format = bzrdir.format_registry.make_bzrdir('default')
2177
1813
if location is None:
2180
1816
to_transport = transport.get_transport(location)
1817
to_transport.ensure_base()
2182
(repo, newdir, require_stacking, repository_policy) = (
2183
format.initialize_on_transport_ex(to_transport,
2184
create_prefix=True, make_working_trees=not no_trees,
2185
shared_repo=True, force_new_repo=True,
2186
use_existing_dir=True,
2187
repo_format_name=format.repository_format.get_format_string()))
1819
newdir = format.initialize_on_transport(to_transport)
1820
repo = newdir.create_repository(shared=True)
1821
repo.set_make_working_trees(not no_trees)
2188
1822
if not is_quiet():
2189
1823
from bzrlib.info import show_bzrdir_info
2190
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1824
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2193
1827
class cmd_diff(Command):
2194
__doc__ = """Show differences in the working tree, between revisions or branches.
1828
"""Show differences in the working tree, between revisions or branches.
2196
1830
If no arguments are given, all changes for the current tree are listed.
2197
1831
If files are given, only the changes in those files are listed.
2324
1936
elif ':' in prefix:
2325
1937
old_label, new_label = prefix.split(":")
2327
raise errors.BzrCommandError(gettext(
1939
raise errors.BzrCommandError(
2328
1940
'--prefix expects two values separated by a colon'
2329
' (eg "old/:new/")'))
1941
' (eg "old/:new/")')
2331
1943
if revision and len(revision) > 2:
2332
raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
2333
' one or two revision specifiers'))
2335
if using is not None and format is not None:
2336
raise errors.BzrCommandError(gettext(
2337
'{0} and {1} are mutually exclusive').format(
2338
'--using', '--format'))
1944
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1945
' one or two revision specifiers')
2340
1947
(old_tree, new_tree,
2341
1948
old_branch, new_branch,
2342
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2343
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2344
# GNU diff on Windows uses ANSI encoding for filenames
2345
path_encoding = osutils.get_diff_header_encoding()
1949
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1950
file_list, revision, old, new, apply_view=True)
2346
1951
return show_diff_trees(old_tree, new_tree, sys.stdout,
2347
1952
specific_files=specific_files,
2348
1953
external_diff_options=diff_options,
2349
1954
old_label=old_label, new_label=new_label,
2350
extra_trees=extra_trees,
2351
path_encoding=path_encoding,
1955
extra_trees=extra_trees, using=using)
2356
1958
class cmd_deleted(Command):
2357
__doc__ = """List files deleted in the working tree.
1959
"""List files deleted in the working tree.
2359
1961
# TODO: Show files deleted since a previous revision, or
2360
1962
# between two revisions.
2404
2010
class cmd_added(Command):
2405
__doc__ = """List files added in working tree.
2011
"""List files added in working tree.
2409
2015
_see_also = ['status', 'ls']
2410
takes_options = ['directory', 'null']
2018
help='Write an ascii NUL (\\0) separator '
2019
'between files rather than a newline.')
2412
2022
@display_command
2413
def run(self, null=False, directory=u'.'):
2414
wt = WorkingTree.open_containing(directory)[0]
2415
self.add_cleanup(wt.lock_read().unlock)
2023
def run(self, null=False):
2024
wt = WorkingTree.open_containing(u'.')[0]
2026
self.add_cleanup(wt.unlock)
2416
2027
basis = wt.basis_tree()
2417
self.add_cleanup(basis.lock_read().unlock)
2418
root_id = wt.get_root_id()
2419
for file_id in wt.all_file_ids():
2420
if basis.has_id(file_id):
2422
if root_id == file_id:
2424
path = wt.id2path(file_id)
2425
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2029
self.add_cleanup(basis.unlock)
2030
basis_inv = basis.inventory
2033
if file_id in basis_inv:
2035
if inv.is_root(file_id) and len(basis_inv) == 0:
2037
path = inv.id2path(file_id)
2038
if not os.access(osutils.abspath(path), os.F_OK):
2428
2041
self.outf.write(path + '\0')
2654
2259
Option('show-diff',
2655
2260
short_name='p',
2656
2261
help='Show changes made in each revision as a patch.'),
2657
Option('include-merged',
2262
Option('include-merges',
2658
2263
help='Show merged revisions like --levels 0 does.'),
2659
Option('include-merges', hidden=True,
2660
help='Historical alias for --include-merged.'),
2661
Option('omit-merges',
2662
help='Do not report commits with more than one parent.'),
2663
Option('exclude-common-ancestry',
2664
help='Display only the revisions that are not part'
2665
' of both ancestries (require -rX..Y).'
2667
Option('signatures',
2668
help='Show digital signature validity.'),
2671
help='Show revisions whose properties match this '
2674
ListOption('match-message',
2675
help='Show revisions whose message matches this '
2678
ListOption('match-committer',
2679
help='Show revisions whose committer matches this '
2682
ListOption('match-author',
2683
help='Show revisions whose authors match this '
2686
ListOption('match-bugs',
2687
help='Show revisions whose bugs match this '
2691
2265
encoding_type = 'replace'
2704
2278
show_diff=False,
2705
include_merged=None,
2707
exclude_common_ancestry=False,
2711
match_committer=None,
2715
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2279
include_merges=False):
2717
2280
from bzrlib.log import (
2719
2282
make_log_request_dict,
2720
2283
_get_info_for_log_files,
2722
2285
direction = (forward and 'forward') or 'reverse'
2723
if symbol_versioning.deprecated_passed(include_merges):
2724
ui.ui_factory.show_user_warning(
2725
'deprecated_command_option',
2726
deprecated_name='--include-merges',
2727
recommended_name='--include-merged',
2728
deprecated_in_version='2.5',
2729
command=self.invoked_as)
2730
if include_merged is None:
2731
include_merged = include_merges
2733
raise errors.BzrCommandError(gettext(
2734
'{0} and {1} are mutually exclusive').format(
2735
'--include-merges', '--include-merged'))
2736
if include_merged is None:
2737
include_merged = False
2738
if (exclude_common_ancestry
2739
and (revision is None or len(revision) != 2)):
2740
raise errors.BzrCommandError(gettext(
2741
'--exclude-common-ancestry requires -r with two revisions'))
2743
2287
if levels is None:
2746
raise errors.BzrCommandError(gettext(
2747
'{0} and {1} are mutually exclusive').format(
2748
'--levels', '--include-merged'))
2290
raise errors.BzrCommandError(
2291
'--levels and --include-merges are mutually exclusive')
2750
2293
if change is not None:
2751
2294
if len(change) > 1:
2752
2295
raise errors.RangeInChangeOption()
2753
2296
if revision is not None:
2754
raise errors.BzrCommandError(gettext(
2755
'{0} and {1} are mutually exclusive').format(
2756
'--revision', '--change'))
2297
raise errors.BzrCommandError(
2298
'--revision and --change are mutually exclusive')
2758
2300
revision = change
2956
2474
help='Recurse into subdirectories.'),
2957
2475
Option('from-root',
2958
2476
help='Print paths relative to the root of the branch.'),
2959
Option('unknown', short_name='u',
2960
help='Print unknown files.'),
2477
Option('unknown', help='Print unknown files.'),
2961
2478
Option('versioned', help='Print versioned files.',
2962
2479
short_name='V'),
2963
Option('ignored', short_name='i',
2964
help='Print ignored files.'),
2965
Option('kind', short_name='k',
2480
Option('ignored', help='Print ignored files.'),
2482
help='Write an ascii NUL (\\0) separator '
2483
'between files rather than a newline.'),
2966
2485
help='List entries of a particular kind: file, directory, symlink.',
2972
2489
@display_command
2973
2490
def run(self, revision=None, verbose=False,
2974
2491
recursive=False, from_root=False,
2975
2492
unknown=False, versioned=False, ignored=False,
2976
null=False, kind=None, show_ids=False, path=None, directory=None):
2493
null=False, kind=None, show_ids=False, path=None):
2978
2495
if kind and kind not in ('file', 'directory', 'symlink'):
2979
raise errors.BzrCommandError(gettext('invalid kind specified'))
2496
raise errors.BzrCommandError('invalid kind specified')
2981
2498
if verbose and null:
2982
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2499
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2983
2500
all = not (unknown or versioned or ignored)
2985
2502
selection = {'I':ignored, '?':unknown, 'V':versioned}
3151
2653
_see_also = ['status', 'ignored', 'patterns']
3152
2654
takes_args = ['name_pattern*']
3153
takes_options = ['directory',
3154
Option('default-rules',
3155
help='Display the default ignore rules that bzr uses.')
2656
Option('old-default-rules',
2657
help='Write out the ignore rules bzr < 0.9 always used.')
3158
def run(self, name_pattern_list=None, default_rules=None,
2660
def run(self, name_pattern_list=None, old_default_rules=None):
3160
2661
from bzrlib import ignores
3161
if default_rules is not None:
3162
# dump the default rules and exit
3163
for pattern in ignores.USER_DEFAULTS:
3164
self.outf.write("%s\n" % pattern)
2662
if old_default_rules is not None:
2663
# dump the rules and exit
2664
for pattern in ignores.OLD_DEFAULTS:
3166
2667
if not name_pattern_list:
3167
raise errors.BzrCommandError(gettext("ignore requires at least one "
3168
"NAME_PATTERN or --default-rules."))
2668
raise errors.BzrCommandError("ignore requires at least one "
2669
"NAME_PATTERN or --old-default-rules")
3169
2670
name_pattern_list = [globbing.normalize_pattern(p)
3170
2671
for p in name_pattern_list]
3172
bad_patterns_count = 0
3173
for p in name_pattern_list:
3174
if not globbing.Globster.is_pattern_valid(p):
3175
bad_patterns_count += 1
3176
bad_patterns += ('\n %s' % p)
3178
msg = (ngettext('Invalid ignore pattern found. %s',
3179
'Invalid ignore patterns found. %s',
3180
bad_patterns_count) % bad_patterns)
3181
ui.ui_factory.show_error(msg)
3182
raise errors.InvalidPattern('')
3183
2672
for name_pattern in name_pattern_list:
3184
2673
if (name_pattern[0] == '/' or
3185
2674
(len(name_pattern) > 1 and name_pattern[1] == ':')):
3186
raise errors.BzrCommandError(gettext(
3187
"NAME_PATTERN should not be an absolute path"))
3188
tree, relpath = WorkingTree.open_containing(directory)
2675
raise errors.BzrCommandError(
2676
"NAME_PATTERN should not be an absolute path")
2677
tree, relpath = WorkingTree.open_containing(u'.')
3189
2678
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3190
2679
ignored = globbing.Globster(name_pattern_list)
3192
self.add_cleanup(tree.lock_read().unlock)
3193
2682
for entry in tree.list_files():
3195
2684
if id is not None:
3196
2685
filename = entry[0]
3197
2686
if ignored.match(filename):
3198
matches.append(filename)
2687
matches.append(filename.encode('utf-8'))
3199
2689
if len(matches) > 0:
3200
self.outf.write(gettext("Warning: the following files are version "
3201
"controlled and match your ignore pattern:\n%s"
3202
"\nThese files will continue to be version controlled"
3203
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2690
print "Warning: the following files are version controlled and" \
2691
" match your ignore pattern:\n%s" \
2692
"\nThese files will continue to be version controlled" \
2693
" unless you 'bzr remove' them." % ("\n".join(matches),)
3206
2696
class cmd_ignored(Command):
3207
__doc__ = """List ignored files and the patterns that matched them.
2697
"""List ignored files and the patterns that matched them.
3209
2699
List all the ignored files and the ignore pattern that caused the file to
3293
2780
help="Name of the root directory inside the exported file."),
3294
Option('per-file-timestamps',
3295
help='Set modification time of files to that of the last '
3296
'revision in which it was changed.'),
3297
Option('uncommitted',
3298
help='Export the working tree contents rather than that of the '
3301
2782
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3302
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2783
root=None, filters=False):
3304
2784
from bzrlib.export import export
3306
2786
if branch_or_subdir is None:
3307
branch_or_subdir = directory
3309
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3311
if tree is not None:
3312
self.add_cleanup(tree.lock_read().unlock)
3316
raise errors.BzrCommandError(
3317
gettext("--uncommitted requires a working tree"))
2787
tree = WorkingTree.open_containing(u'.')[0]
3320
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2791
b, subdir = Branch.open_containing(branch_or_subdir)
2794
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3322
export(export_tree, dest, format, root, subdir, filtered=filters,
3323
per_file_timestamps=per_file_timestamps)
2796
export(rev_tree, dest, format, root, subdir, filtered=filters)
3324
2797
except errors.NoSuchExportFormat, e:
3325
raise errors.BzrCommandError(
3326
gettext('Unsupported export format: %s') % e.format)
2798
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3329
2801
class cmd_cat(Command):
3330
__doc__ = """Write the contents of a file as of a given revision to standard output.
2802
"""Write the contents of a file as of a given revision to standard output.
3332
2804
If no revision is nominated, the last revision is used.
3362
2835
if tree is None:
3363
2836
tree = b.basis_tree()
3364
2837
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3365
self.add_cleanup(rev_tree.lock_read().unlock)
2838
rev_tree.lock_read()
2839
self.add_cleanup(rev_tree.unlock)
3367
2841
old_file_id = rev_tree.path2id(relpath)
3369
# TODO: Split out this code to something that generically finds the
3370
# best id for a path across one or more trees; it's like
3371
# find_ids_across_trees but restricted to find just one. -- mbp
3373
2843
if name_from_revision:
3374
2844
# Try in revision if requested
3375
2845
if old_file_id is None:
3376
raise errors.BzrCommandError(gettext(
3377
"{0!r} is not present in revision {1}").format(
2846
raise errors.BzrCommandError(
2847
"%r is not present in revision %s" % (
3378
2848
filename, rev_tree.get_revision_id()))
3380
actual_file_id = old_file_id
2850
content = rev_tree.get_file_text(old_file_id)
3382
2852
cur_file_id = tree.path2id(relpath)
3383
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3384
actual_file_id = cur_file_id
3385
elif old_file_id is not None:
3386
actual_file_id = old_file_id
3388
raise errors.BzrCommandError(gettext(
3389
"{0!r} is not present in revision {1}").format(
2854
if cur_file_id is not None:
2855
# Then try with the actual file id
2857
content = rev_tree.get_file_text(cur_file_id)
2859
except errors.NoSuchId:
2860
# The actual file id didn't exist at that time
2862
if not found and old_file_id is not None:
2863
# Finally try with the old file id
2864
content = rev_tree.get_file_text(old_file_id)
2867
# Can't be found anywhere
2868
raise errors.BzrCommandError(
2869
"%r is not present in revision %s" % (
3390
2870
filename, rev_tree.get_revision_id()))
3392
from bzrlib.filter_tree import ContentFilterTree
3393
filter_tree = ContentFilterTree(rev_tree,
3394
rev_tree._content_filter_stack)
3395
content = filter_tree.get_file_text(actual_file_id)
2872
from bzrlib.filters import (
2873
ContentFilterContext,
2874
filtered_output_bytes,
2876
filters = rev_tree._content_filter_stack(relpath)
2877
chunks = content.splitlines(True)
2878
content = filtered_output_bytes(chunks, filters,
2879
ContentFilterContext(relpath, rev_tree))
2881
self.outf.writelines(content)
3397
content = rev_tree.get_file_text(actual_file_id)
3399
self.outf.write(content)
2884
self.outf.write(content)
3402
2887
class cmd_local_time_offset(Command):
3403
__doc__ = """Show the offset in seconds from GMT to local time."""
2888
"""Show the offset in seconds from GMT to local time."""
3405
2890
@display_command
3407
self.outf.write("%s\n" % osutils.local_time_offset())
2892
print osutils.local_time_offset()
3411
2896
class cmd_commit(Command):
3412
__doc__ = """Commit changes into a new revision.
2897
"""Commit changes into a new revision.
3414
2899
An explanatory message needs to be given for each commit. This is
3415
2900
often done by using the --message option (getting the message from the
3463
2948
to trigger updates to external systems like bug trackers. The --fixes
3464
2949
option can be used to record the association between a revision and
3465
2950
one or more bugs. See ``bzr help bugs`` for details.
2952
A selective commit may fail in some cases where the committed
2953
tree would be invalid. Consider::
2958
bzr commit foo -m "committing foo"
2959
bzr mv foo/bar foo/baz
2962
bzr commit foo/bar -m "committing bar but not baz"
2964
In the example above, the last commit will fail by design. This gives
2965
the user the opportunity to decide whether they want to commit the
2966
rename at the same time, separately first, or not at all. (As a general
2967
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2969
# TODO: Run hooks on tree to-be-committed, and after commit.
2971
# TODO: Strict commit that fails if there are deleted files.
2972
# (what does "deleted files" mean ??)
2974
# TODO: Give better message for -s, --summary, used by tla people
2976
# XXX: verbose currently does nothing
3468
2978
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
3469
2979
takes_args = ['selected*']
3498
3008
"the master branch until a normal commit "
3499
3009
"is performed."
3501
Option('show-diff', short_name='p',
3502
3012
help='When no message is supplied, show the diff along'
3503
3013
' with the status summary in the message editor.'),
3505
help='When committing to a foreign version control '
3506
'system do not push data that can not be natively '
3509
3015
aliases = ['ci', 'checkin']
3511
3017
def _iter_bug_fix_urls(self, fixes, branch):
3512
default_bugtracker = None
3513
3018
# Configure the properties for bug fixing attributes.
3514
3019
for fixed_bug in fixes:
3515
3020
tokens = fixed_bug.split(':')
3516
if len(tokens) == 1:
3517
if default_bugtracker is None:
3518
branch_config = branch.get_config()
3519
default_bugtracker = branch_config.get_user_option(
3521
if default_bugtracker is None:
3522
raise errors.BzrCommandError(gettext(
3523
"No tracker specified for bug %s. Use the form "
3524
"'tracker:id' or specify a default bug tracker "
3525
"using the `bugtracker` option.\nSee "
3526
"\"bzr help bugs\" for more information on this "
3527
"feature. Commit refused.") % fixed_bug)
3528
tag = default_bugtracker
3530
elif len(tokens) != 2:
3531
raise errors.BzrCommandError(gettext(
3021
if len(tokens) != 2:
3022
raise errors.BzrCommandError(
3532
3023
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3533
3024
"See \"bzr help bugs\" for more information on this "
3534
"feature.\nCommit refused.") % fixed_bug)
3536
tag, bug_id = tokens
3025
"feature.\nCommit refused." % fixed_bug)
3026
tag, bug_id = tokens
3538
3028
yield bugtracker.get_bug_url(tag, branch, bug_id)
3539
3029
except errors.UnknownBugTrackerAbbreviation:
3540
raise errors.BzrCommandError(gettext(
3541
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3030
raise errors.BzrCommandError(
3031
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3542
3032
except errors.MalformedBugIdentifier, e:
3543
raise errors.BzrCommandError(gettext(
3544
"%s\nCommit refused.") % (str(e),))
3033
raise errors.BzrCommandError(
3034
"%s\nCommit refused." % (str(e),))
3546
3036
def run(self, message=None, file=None, verbose=False, selected_list=None,
3547
3037
unchanged=False, strict=False, local=False, fixes=None,
3548
author=None, show_diff=False, exclude=None, commit_time=None,
3038
author=None, show_diff=False, exclude=None, commit_time=None):
3550
3039
from bzrlib.errors import (
3551
3040
PointlessCommit,
3552
3041
ConflictsInTree,
3600
3094
'(use --file "%(f)s" to take commit message from that file)'
3601
3095
% { 'f': message })
3602
3096
ui.ui_factory.show_warning(warning_msg)
3604
message = message.replace('\r\n', '\n')
3605
message = message.replace('\r', '\n')
3607
raise errors.BzrCommandError(gettext(
3608
"please specify either --message or --file"))
3610
3098
def get_message(commit_obj):
3611
3099
"""Callback to get commit message"""
3615
my_message = f.read().decode(osutils.get_user_encoding())
3618
elif message is not None:
3619
my_message = message
3621
# No message supplied: make one up.
3622
# text is the status of the tree
3623
text = make_commit_message_template_encoded(tree,
3100
my_message = message
3101
if my_message is not None and '\r' in my_message:
3102
my_message = my_message.replace('\r\n', '\n')
3103
my_message = my_message.replace('\r', '\n')
3104
if my_message is None and not file:
3105
t = make_commit_message_template_encoded(tree,
3624
3106
selected_list, diff=show_diff,
3625
3107
output_encoding=osutils.get_user_encoding())
3626
# start_message is the template generated from hooks
3627
# XXX: Warning - looks like hooks return unicode,
3628
# make_commit_message_template_encoded returns user encoding.
3629
# We probably want to be using edit_commit_message instead to
3631
my_message = set_commit_message(commit_obj)
3632
if my_message is None:
3633
start_message = generate_commit_message_template(commit_obj)
3634
my_message = edit_commit_message_encoded(text,
3635
start_message=start_message)
3636
if my_message is None:
3637
raise errors.BzrCommandError(gettext("please specify a commit"
3638
" message with either --message or --file"))
3639
if my_message == "":
3640
raise errors.BzrCommandError(gettext("Empty commit message specified."
3641
" Please specify a commit message with either"
3642
" --message or --file or leave a blank message"
3643
" with --message \"\"."))
3108
start_message = generate_commit_message_template(commit_obj)
3109
my_message = edit_commit_message_encoded(t,
3110
start_message=start_message)
3111
if my_message is None:
3112
raise errors.BzrCommandError("please specify a commit"
3113
" message with either --message or --file")
3114
elif my_message and file:
3115
raise errors.BzrCommandError(
3116
"please specify either --message or --file")
3118
my_message = codecs.open(file, 'rt',
3119
osutils.get_user_encoding()).read()
3120
if my_message == "":
3121
raise errors.BzrCommandError("empty commit message specified")
3644
3122
return my_message
3646
3124
# The API permits a commit with a filter of [] to mean 'select nothing'
3654
3132
reporter=None, verbose=verbose, revprops=properties,
3655
3133
authors=author, timestamp=commit_stamp,
3656
3134
timezone=offset,
3657
exclude=tree.safe_relpath_files(exclude),
3135
exclude=safe_relpath_files(tree, exclude))
3659
3136
except PointlessCommit:
3660
raise errors.BzrCommandError(gettext("No changes to commit."
3661
" Please 'bzr add' the files you want to commit, or use"
3662
" --unchanged to force an empty commit."))
3137
# FIXME: This should really happen before the file is read in;
3138
# perhaps prepare the commit; get the message; then actually commit
3139
raise errors.BzrCommandError("No changes to commit."
3140
" Use --unchanged to commit anyhow.")
3663
3141
except ConflictsInTree:
3664
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3142
raise errors.BzrCommandError('Conflicts detected in working '
3665
3143
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3667
3145
except StrictCommitFailed:
3668
raise errors.BzrCommandError(gettext("Commit refused because there are"
3669
" unknown files in the working tree."))
3146
raise errors.BzrCommandError("Commit refused because there are"
3147
" unknown files in the working tree.")
3670
3148
except errors.BoundBranchOutOfDate, e:
3671
e.extra_help = (gettext("\n"
3672
'To commit to master branch, run update and then commit.\n'
3673
'You can also pass --local to commit to continue working '
3149
raise errors.BzrCommandError(str(e) + "\n"
3150
'To commit to master branch, run update and then commit.\n'
3151
'You can also pass --local to commit to continue working '
3678
3155
class cmd_check(Command):
3679
__doc__ = """Validate working tree structure, branch consistency and repository history.
3156
"""Validate working tree structure, branch consistency and repository history.
3681
3158
This command checks various invariants about branch and repository storage
3682
3159
to detect data corruption or bzr bugs.
3748
3225
class cmd_upgrade(Command):
3749
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3751
When the default format has changed after a major new release of
3752
Bazaar, you may be informed during certain operations that you
3753
should upgrade. Upgrading to a newer format may improve performance
3754
or make new features available. It may however limit interoperability
3755
with older repositories or with older versions of Bazaar.
3757
If you wish to upgrade to a particular format rather than the
3758
current default, that can be specified using the --format option.
3759
As a consequence, you can use the upgrade command this way to
3760
"downgrade" to an earlier format, though some conversions are
3761
a one way process (e.g. changing from the 1.x default to the
3762
2.x default) so downgrading is not always possible.
3764
A backup.bzr.~#~ directory is created at the start of the conversion
3765
process (where # is a number). By default, this is left there on
3766
completion. If the conversion fails, delete the new .bzr directory
3767
and rename this one back in its place. Use the --clean option to ask
3768
for the backup.bzr directory to be removed on successful conversion.
3769
Alternatively, you can delete it by hand if everything looks good
3772
If the location given is a shared repository, dependent branches
3773
are also converted provided the repository converts successfully.
3774
If the conversion of a branch fails, remaining branches are still
3777
For more information on upgrades, see the Bazaar Upgrade Guide,
3778
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3226
"""Upgrade branch storage to current format.
3228
The check command or bzr developers may sometimes advise you to run
3229
this command. When the default format has changed you may also be warned
3230
during other operations to upgrade.
3781
_see_also = ['check', 'reconcile', 'formats']
3233
_see_also = ['check']
3782
3234
takes_args = ['url?']
3783
3235
takes_options = [
3784
RegistryOption('format',
3785
help='Upgrade to a specific format. See "bzr help'
3786
' formats" for details.',
3787
lazy_registry=('bzrlib.controldir', 'format_registry'),
3788
converter=lambda name: controldir.format_registry.make_bzrdir(name),
3789
value_switches=True, title='Branch format'),
3791
help='Remove the backup.bzr directory if successful.'),
3793
help="Show what would be done, but don't actually do anything."),
3236
RegistryOption('format',
3237
help='Upgrade to a specific format. See "bzr help'
3238
' formats" for details.',
3239
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3240
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3241
value_switches=True, title='Branch format'),
3796
def run(self, url='.', format=None, clean=False, dry_run=False):
3244
def run(self, url='.', format=None):
3797
3245
from bzrlib.upgrade import upgrade
3798
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3800
if len(exceptions) == 1:
3801
# Compatibility with historical behavior
3246
upgrade(url, format)
3807
3249
class cmd_whoami(Command):
3808
__doc__ = """Show or set bzr user id.
3250
"""Show or set bzr user id.
3811
3253
Show the email of the current user::
3827
3268
encoding_type = 'replace'
3829
3270
@display_command
3830
def run(self, email=False, branch=False, name=None, directory=None):
3271
def run(self, email=False, branch=False, name=None):
3831
3272
if name is None:
3832
if directory is None:
3833
# use branch if we're inside one; otherwise global config
3835
c = Branch.open_containing(u'.')[0].get_config_stack()
3836
except errors.NotBranchError:
3837
c = _mod_config.GlobalStack()
3839
c = Branch.open(directory).get_config_stack()
3840
identity = c.get('email')
3273
# use branch if we're inside one; otherwise global config
3275
c = Branch.open_containing('.')[0].get_config()
3276
except errors.NotBranchError:
3277
c = config.GlobalConfig()
3842
self.outf.write(_mod_config.extract_email_address(identity)
3279
self.outf.write(c.user_email() + '\n')
3845
self.outf.write(identity + '\n')
3281
self.outf.write(c.username() + '\n')
3849
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3852
3284
# display a warning if an email address isn't included in the given name.
3854
_mod_config.extract_email_address(name)
3286
config.extract_email_address(name)
3855
3287
except errors.NoEmailInUsername, e:
3856
3288
warning('"%s" does not seem to contain an email address. '
3857
3289
'This is allowed, but not recommended.', name)
3859
3291
# use global config unless --branch given
3861
if directory is None:
3862
c = Branch.open_containing(u'.')[0].get_config_stack()
3864
c = Branch.open(directory).get_config_stack()
3293
c = Branch.open_containing('.')[0].get_config()
3866
c = _mod_config.GlobalStack()
3867
c.set('email', name)
3295
c = config.GlobalConfig()
3296
c.set_user_option('email', name)
3870
3299
class cmd_nick(Command):
3871
__doc__ = """Print or set the branch nickname.
3300
"""Print or set the branch nickname.
3873
3302
If unset, the tree root directory name is used as the nickname.
3874
3303
To print the current nickname, execute with no argument.
4090
3514
def run(self, testspecs_list=None, verbose=False, one=False,
4091
3515
transport=None, benchmark=None,
3516
lsprof_timed=None, cache_dir=None,
4093
3517
first=False, list_only=False,
4094
3518
randomize=None, exclude=None, strict=False,
4095
3519
load_list=None, debugflag=None, starting_with=None, subunit=False,
4096
parallel=None, lsprof_tests=False,
4099
# During selftest, disallow proxying, as it can cause severe
4100
# performance penalties and is only needed for thread
4101
# safety. The selftest command is assumed to not use threads
4102
# too heavily. The call should be as early as possible, as
4103
# error reporting for past duplicate imports won't have useful
4105
lazy_import.disallow_proxying()
4107
from bzrlib import tests
3520
parallel=None, lsprof_tests=False):
3521
from bzrlib.tests import selftest
3522
import bzrlib.benchmarks as benchmarks
3523
from bzrlib.benchmarks import tree_creator
3525
# Make deprecation warnings visible, unless -Werror is set
3526
symbol_versioning.activate_deprecation_warnings(override=False)
3528
if cache_dir is not None:
3529
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
4109
3530
if testspecs_list is not None:
4110
3531
pattern = '|'.join(testspecs_list)
4115
3536
from bzrlib.tests import SubUnitBzrRunner
4116
3537
except ImportError:
4117
raise errors.BzrCommandError(gettext("subunit not available. subunit "
4118
"needs to be installed to use --subunit."))
3538
raise errors.BzrCommandError("subunit not available. subunit "
3539
"needs to be installed to use --subunit.")
4119
3540
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
4120
# On Windows, disable automatic conversion of '\n' to '\r\n' in
4121
# stdout, which would corrupt the subunit stream.
4122
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
4123
# following code can be deleted when it's sufficiently deployed
4124
# -- vila/mgz 20100514
4125
if (sys.platform == "win32"
4126
and getattr(sys.stdout, 'fileno', None) is not None):
4128
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4130
3542
self.additional_selftest_args.setdefault(
4131
3543
'suite_decorators', []).append(parallel)
4133
raise errors.BzrCommandError(gettext(
4134
"--benchmark is no longer supported from bzr 2.2; "
4135
"use bzr-usertest instead"))
4136
test_suite_factory = None
4138
exclude_pattern = None
3545
test_suite_factory = benchmarks.test_suite
3546
# Unless user explicitly asks for quiet, be verbose in benchmarks
3547
verbose = not is_quiet()
3548
# TODO: should possibly lock the history file...
3549
benchfile = open(".perf_history", "at", buffering=1)
3550
self.add_cleanup(benchfile.close)
4140
exclude_pattern = '(' + '|'.join(exclude) + ')'
4142
self._disable_fsync()
3552
test_suite_factory = None
4143
3554
selftest_kwargs = {"verbose": verbose,
4144
3555
"pattern": pattern,
4145
3556
"stop_on_failure": one,
4147
3558
"test_suite_factory": test_suite_factory,
4148
3559
"lsprof_timed": lsprof_timed,
4149
3560
"lsprof_tests": lsprof_tests,
3561
"bench_history": benchfile,
4150
3562
"matching_tests_first": first,
4151
3563
"list_only": list_only,
4152
3564
"random_seed": randomize,
4153
"exclude_pattern": exclude_pattern,
3565
"exclude_pattern": exclude,
4154
3566
"strict": strict,
4155
3567
"load_list": load_list,
4156
3568
"debug_flags": debugflag,
4157
3569
"starting_with": starting_with
4159
3571
selftest_kwargs.update(self.additional_selftest_args)
4161
# Make deprecation warnings visible, unless -Werror is set
4162
cleanup = symbol_versioning.activate_deprecation_warnings(
4165
result = tests.selftest(**selftest_kwargs)
3572
result = selftest(**selftest_kwargs)
4168
3573
return int(not result)
4170
def _disable_fsync(self):
4171
"""Change the 'os' functionality to not synchronize."""
4172
self._orig_fsync = getattr(os, 'fsync', None)
4173
if self._orig_fsync is not None:
4174
os.fsync = lambda filedes: None
4175
self._orig_fdatasync = getattr(os, 'fdatasync', None)
4176
if self._orig_fdatasync is not None:
4177
os.fdatasync = lambda filedes: None
4180
3576
class cmd_version(Command):
4181
__doc__ = """Show version of bzr."""
3577
"""Show version of bzr."""
4183
3579
encoding_type = 'replace'
4184
3580
takes_options = [
4218
3614
branch1 = Branch.open_containing(branch)[0]
4219
3615
branch2 = Branch.open_containing(other)[0]
4220
self.add_cleanup(branch1.lock_read().unlock)
4221
self.add_cleanup(branch2.lock_read().unlock)
3617
self.add_cleanup(branch1.unlock)
3619
self.add_cleanup(branch2.unlock)
4222
3620
last1 = ensure_null(branch1.last_revision())
4223
3621
last2 = ensure_null(branch2.last_revision())
4225
3623
graph = branch1.repository.get_graph(branch2.repository)
4226
3624
base_rev_id = graph.find_unique_lca(last1, last2)
4228
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3626
print 'merge base is revision %s' % base_rev_id
4231
3629
class cmd_merge(Command):
4232
__doc__ = """Perform a three-way merge.
3630
"""Perform a three-way merge.
4234
3632
The source of the merge can be specified either in the form of a branch,
4235
3633
or in the form of a path to a file containing a merge directive generated
4236
3634
with bzr send. If neither is specified, the default is the upstream branch
4237
or the branch most recently merged using --remember. The source of the
4238
merge may also be specified in the form of a path to a file in another
4239
branch: in this case, only the modifications to that file are merged into
4240
the current working tree.
4242
When merging from a branch, by default bzr will try to merge in all new
4243
work from the other branch, automatically determining an appropriate base
4244
revision. If this fails, you may need to give an explicit base.
4246
To pick a different ending revision, pass "--revision OTHER". bzr will
4247
try to merge in all new work up to and including revision OTHER.
4249
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4250
through OTHER, excluding BASE but including OTHER, will be merged. If this
4251
causes some revisions to be skipped, i.e. if the destination branch does
4252
not already contain revision BASE, such a merge is commonly referred to as
4253
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4254
cherrypicks. The changes look like a normal commit, and the history of the
4255
changes from the other branch is not stored in the commit.
4257
Revision numbers are always relative to the source branch.
3635
or the branch most recently merged using --remember.
3637
When merging a branch, by default the tip will be merged. To pick a different
3638
revision, pass --revision. If you specify two values, the first will be used as
3639
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3640
available revisions, like this is commonly referred to as "cherrypicking".
3642
Revision numbers are always relative to the branch being merged.
3644
By default, bzr will try to merge in all new work from the other
3645
branch, automatically determining an appropriate base. If this
3646
fails, you may need to give an explicit base.
4259
3648
Merge will do its best to combine the changes in two branches, but there
4260
3649
are some kinds of problems only a human can fix. When it encounters those,
4261
3650
it will mark a conflict. A conflict means that you need to fix something,
4262
before you can commit.
3651
before you should commit.
4264
3653
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
4266
If there is no default branch set, the first merge will set it (use
4267
--no-remember to avoid setting it). After that, you can omit the branch
4268
to use the default. To change the default, use --remember. The value will
4269
only be saved if the remote location can be accessed.
3655
If there is no default branch set, the first merge will set it. After
3656
that, you can omit the branch to use the default. To change the
3657
default, use --remember. The value will only be saved if the remote
3658
location can be accessed.
4271
3660
The results of the merge are placed into the destination working
4272
3661
directory, where they can be reviewed (with bzr diff), tested, and then
4273
3662
committed to record the result of the merge.
4275
3664
merge refuses to run if there are any uncommitted changes, unless
4276
--force is given. If --force is given, then the changes from the source
4277
will be merged with the current working tree, including any uncommitted
4278
changes in the tree. The --force option can also be used to create a
3665
--force is given. The --force option can also be used to create a
4279
3666
merge revision which has more than two parents.
4281
3668
If one would like to merge changes from the working tree of the other
4383
3770
mergeable = None
4385
3772
if uncommitted:
4386
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4387
' with bundles or merge directives.'))
3773
raise errors.BzrCommandError('Cannot use --uncommitted'
3774
' with bundles or merge directives.')
4389
3776
if revision is not None:
4390
raise errors.BzrCommandError(gettext(
4391
'Cannot use -r with merge directives or bundles'))
3777
raise errors.BzrCommandError(
3778
'Cannot use -r with merge directives or bundles')
4392
3779
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4395
3782
if merger is None and uncommitted:
4396
3783
if revision is not None and len(revision) > 0:
4397
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4398
' --revision at the same time.'))
4399
merger = self.get_merger_from_uncommitted(tree, location, None)
3784
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
4400
3787
allow_pending = False
4402
3789
if merger is None:
4403
3790
merger, allow_pending = self._get_merger_from_branch(tree,
4404
location, revision, remember, possible_transports, None)
3791
location, revision, remember, possible_transports, pb)
4406
3793
merger.merge_type = merge_type
4407
3794
merger.reprocess = reprocess
4409
3796
self.sanity_check_merger(merger)
4410
3797
if (merger.base_rev_id == merger.other_rev_id and
4411
3798
merger.other_rev_id is not None):
4412
# check if location is a nonexistent file (and not a branch) to
4413
# disambiguate the 'Nothing to do'
4414
if merger.interesting_files:
4415
if not merger.other_tree.has_filename(
4416
merger.interesting_files[0]):
4417
note(gettext("merger: ") + str(merger))
4418
raise errors.PathsDoNotExist([location])
4419
note(gettext('Nothing to do.'))
3799
note('Nothing to do.')
4421
if pull and not preview:
4422
3802
if merger.interesting_files is not None:
4423
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
3803
raise errors.BzrCommandError('Cannot pull individual files')
4424
3804
if (merger.base_rev_id == tree.last_revision()):
4425
3805
result = tree.pull(merger.other_branch, False,
4426
3806
merger.other_rev_id)
4427
3807
result.report(self.outf)
4429
3809
if merger.this_basis is None:
4430
raise errors.BzrCommandError(gettext(
3810
raise errors.BzrCommandError(
4431
3811
"This branch has no commits."
4432
" (perhaps you would prefer 'bzr pull')"))
3812
" (perhaps you would prefer 'bzr pull')")
4434
3814
return self._do_preview(merger)
4435
3815
elif interactive:
4533
3911
if other_revision_id is None:
4534
3912
other_revision_id = _mod_revision.ensure_null(
4535
3913
other_branch.last_revision())
4536
# Remember where we merge from. We need to remember if:
4537
# - user specify a location (and we don't merge from the parent
4539
# - user ask to remember or there is no previous location set to merge
4540
# from and user didn't ask to *not* remember
4541
if (user_location is not None
4543
or (remember is None
4544
and tree.branch.get_submit_branch() is None)))):
3914
# Remember where we merge from
3915
if ((remember or tree.branch.get_submit_branch() is None) and
3916
user_location is not None):
4545
3917
tree.branch.set_submit_branch(other_branch.base)
4546
# Merge tags (but don't set them in the master branch yet, the user
4547
# might revert this merge). Commit will propagate them.
4548
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3918
_merge_tags_if_possible(other_branch, tree.branch)
4549
3919
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4550
3920
other_revision_id, base_revision_id, other_branch, base_branch)
4551
3921
if other_path != '':
4714
4087
class cmd_revert(Command):
4715
__doc__ = """Revert files to a previous revision.
4088
"""Revert files to a previous revision.
4717
4090
Giving a list of files will revert only those files. Otherwise, all files
4718
4091
will be reverted. If the revision is not specified with '--revision', the
4719
4092
last committed revision is used.
4721
4094
To remove only some changes, without reverting to a prior version, use
4722
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4723
will remove the changes introduced by the second last commit (-2), without
4724
affecting the changes introduced by the last commit (-1). To remove
4725
certain changes on a hunk-by-hunk basis, see the shelve command.
4095
merge instead. For example, "merge . --revision -2..-3" will remove the
4096
changes introduced by -2, without affecting the changes introduced by -1.
4097
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4727
4099
By default, any files that have been manually changed will be backed up
4728
4100
first. (Files changed only by merge are not backed up.) Backup files have
4895
4269
theirs_only=False,
4896
4270
log_format=None, long=False, short=False, line=False,
4897
4271
show_ids=False, verbose=False, this=False, other=False,
4898
include_merged=None, revision=None, my_revision=None,
4900
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4272
include_merges=False, revision=None, my_revision=None):
4901
4273
from bzrlib.missing import find_unmerged, iter_log_revisions
4902
4274
def message(s):
4903
4275
if not is_quiet():
4904
4276
self.outf.write(s)
4906
if symbol_versioning.deprecated_passed(include_merges):
4907
ui.ui_factory.show_user_warning(
4908
'deprecated_command_option',
4909
deprecated_name='--include-merges',
4910
recommended_name='--include-merged',
4911
deprecated_in_version='2.5',
4912
command=self.invoked_as)
4913
if include_merged is None:
4914
include_merged = include_merges
4916
raise errors.BzrCommandError(gettext(
4917
'{0} and {1} are mutually exclusive').format(
4918
'--include-merges', '--include-merged'))
4919
if include_merged is None:
4920
include_merged = False
4922
4279
mine_only = this
4931
4288
elif theirs_only:
4932
4289
restrict = 'remote'
4934
local_branch = Branch.open_containing(directory)[0]
4935
self.add_cleanup(local_branch.lock_read().unlock)
4291
local_branch = Branch.open_containing(u".")[0]
4937
4292
parent = local_branch.get_parent()
4938
4293
if other_branch is None:
4939
4294
other_branch = parent
4940
4295
if other_branch is None:
4941
raise errors.BzrCommandError(gettext("No peer location known"
4296
raise errors.BzrCommandError("No peer location known"
4943
4298
display_url = urlutils.unescape_for_display(parent,
4944
4299
self.outf.encoding)
4945
message(gettext("Using saved parent location: {0}\n").format(
4300
message("Using saved parent location: "
4301
+ display_url + "\n")
4948
4303
remote_branch = Branch.open(other_branch)
4949
4304
if remote_branch.base == local_branch.base:
4950
4305
remote_branch = local_branch
4952
self.add_cleanup(remote_branch.lock_read().unlock)
4307
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4954
4309
local_revid_range = _revision_range_to_revid_range(
4955
4310
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4958
4315
remote_revid_range = _revision_range_to_revid_range(
4959
4316
_get_revision_range(revision,
4960
4317
remote_branch, self.name()))
5024
4378
class cmd_pack(Command):
5025
__doc__ = """Compress the data within a repository.
5027
This operation compresses the data within a bazaar repository. As
5028
bazaar supports automatic packing of repository, this operation is
5029
normally not required to be done manually.
5031
During the pack operation, bazaar takes a backup of existing repository
5032
data, i.e. pack files. This backup is eventually removed by bazaar
5033
automatically when it is safe to do so. To save disk space by removing
5034
the backed up pack files, the --clean-obsolete-packs option may be
5037
Warning: If you use --clean-obsolete-packs and your machine crashes
5038
during or immediately after repacking, you may be left with a state
5039
where the deletion has been written to disk but the new packs have not
5040
been. In this case the repository may be unusable.
4379
"""Compress the data within a repository."""
5043
4381
_see_also = ['repositories']
5044
4382
takes_args = ['branch_or_repo?']
5046
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
5049
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
5050
dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4384
def run(self, branch_or_repo='.'):
4385
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
5052
4387
branch = dir.open_branch()
5053
4388
repository = branch.repository
5054
4389
except errors.NotBranchError:
5055
4390
repository = dir.open_repository()
5056
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
5059
4394
class cmd_plugins(Command):
5060
__doc__ = """List the installed plugins.
4395
"""List the installed plugins.
5062
4397
This command displays the list of installed plugins including
5063
4398
version of plugin and a short description of each.
5134
4486
Option('long', help='Show commit date in annotations.'),
5139
4490
encoding_type = 'exact'
5141
4492
@display_command
5142
4493
def run(self, filename, all=False, long=False, revision=None,
5143
show_ids=False, directory=None):
5144
from bzrlib.annotate import (
4495
from bzrlib.annotate import annotate_file, annotate_file_tree
5147
4496
wt, branch, relpath = \
5148
_open_directory_or_containing_tree_or_branch(filename, directory)
4497
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
5149
4498
if wt is not None:
5150
self.add_cleanup(wt.lock_read().unlock)
4500
self.add_cleanup(wt.unlock)
5152
self.add_cleanup(branch.lock_read().unlock)
4503
self.add_cleanup(branch.unlock)
5153
4504
tree = _get_one_revision_tree('annotate', revision, branch=branch)
5154
self.add_cleanup(tree.lock_read().unlock)
5155
if wt is not None and revision is None:
4506
self.add_cleanup(tree.unlock)
5156
4508
file_id = wt.path2id(relpath)
5158
4510
file_id = tree.path2id(relpath)
5159
4511
if file_id is None:
5160
4512
raise errors.NotVersionedError(filename)
4513
file_version = tree.inventory[file_id].revision
5161
4514
if wt is not None and revision is None:
5162
4515
# If there is a tree and we're not annotating historical
5163
4516
# versions, annotate the working tree's content.
5164
4517
annotate_file_tree(wt, file_id, self.outf, long, all,
5165
4518
show_ids=show_ids)
5167
annotate_file_tree(tree, file_id, self.outf, long, all,
5168
show_ids=show_ids, branch=branch)
4520
annotate_file(branch, file_version, file_id, long, all, self.outf,
5171
4524
class cmd_re_sign(Command):
5172
__doc__ = """Create a digital signature for an existing revision."""
4525
"""Create a digital signature for an existing revision."""
5173
4526
# TODO be able to replace existing ones.
5175
4528
hidden = True # is this right ?
5176
4529
takes_args = ['revision_id*']
5177
takes_options = ['directory', 'revision']
4530
takes_options = ['revision']
5179
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4532
def run(self, revision_id_list=None, revision=None):
5180
4533
if revision_id_list is not None and revision is not None:
5181
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4534
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
5182
4535
if revision_id_list is None and revision is None:
5183
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
5184
b = WorkingTree.open_containing(directory)[0].branch
5185
self.add_cleanup(b.lock_write().unlock)
4536
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4537
b = WorkingTree.open_containing(u'.')[0].branch
4539
self.add_cleanup(b.unlock)
5186
4540
return self._run(b, revision_id_list, revision)
5188
4542
def _run(self, b, revision_id_list, revision):
5189
4543
import bzrlib.gpg as gpg
5190
gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4544
gpg_strategy = gpg.GPGStrategy(b.get_config())
5191
4545
if revision_id_list is not None:
5192
4546
b.repository.start_write_group()
5248
4601
_see_also = ['checkouts', 'unbind']
5249
4602
takes_args = ['location?']
5250
takes_options = ['directory']
5252
def run(self, location=None, directory=u'.'):
5253
b, relpath = Branch.open_containing(directory)
4605
def run(self, location=None):
4606
b, relpath = Branch.open_containing(u'.')
5254
4607
if location is None:
5256
4609
location = b.get_old_bound_location()
5257
4610
except errors.UpgradeRequired:
5258
raise errors.BzrCommandError(gettext('No location supplied. '
5259
'This format does not remember old locations.'))
4611
raise errors.BzrCommandError('No location supplied. '
4612
'This format does not remember old locations.')
5261
4614
if location is None:
5262
if b.get_bound_location() is not None:
5263
raise errors.BzrCommandError(gettext('Branch is already bound'))
5265
raise errors.BzrCommandError(gettext('No location supplied '
5266
'and no previous location known'))
4615
raise errors.BzrCommandError('No location supplied and no '
4616
'previous location known')
5267
4617
b_other = Branch.open(location)
5269
4619
b.bind(b_other)
5270
4620
except errors.DivergedBranches:
5271
raise errors.BzrCommandError(gettext('These branches have diverged.'
5272
' Try merging, and then bind again.'))
4621
raise errors.BzrCommandError('These branches have diverged.'
4622
' Try merging, and then bind again.')
5273
4623
if b.get_config().has_explicit_nickname():
5274
4624
b.nick = b_other.nick
5277
4627
class cmd_unbind(Command):
5278
__doc__ = """Convert the current checkout into a regular branch.
4628
"""Convert the current checkout into a regular branch.
5280
4630
After unbinding, the local branch is considered independent and subsequent
5281
4631
commits will be local only.
5339
4688
b = control.open_branch()
5341
4690
if tree is not None:
5342
self.add_cleanup(tree.lock_write().unlock)
4692
self.add_cleanup(tree.unlock)
5344
self.add_cleanup(b.lock_write().unlock)
5345
return self._run(b, tree, dry_run, verbose, revision, force,
4695
self.add_cleanup(b.unlock)
4696
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
5348
def _run(self, b, tree, dry_run, verbose, revision, force, local,
4698
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
5350
4699
from bzrlib.log import log_formatter, show_log
5351
4700
from bzrlib.uncommit import uncommit
5382
4731
end_revision=last_revno)
5385
self.outf.write(gettext('Dry-run, pretending to remove'
5386
' the above revisions.\n'))
4734
print 'Dry-run, pretending to remove the above revisions.'
4736
val = raw_input('Press <enter> to continue')
5388
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5391
if not ui.ui_factory.confirm_action(
5392
gettext(u'Uncommit these revisions'),
5393
'bzrlib.builtins.uncommit',
5395
self.outf.write(gettext('Canceled\n'))
4738
print 'The above revision(s) will be removed.'
4740
val = raw_input('Are you sure [y/N]? ')
4741
if val.lower() not in ('y', 'yes'):
5398
4745
mutter('Uncommitting from {%s} to {%s}',
5399
4746
last_rev_id, rev_id)
5400
4747
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5401
revno=revno, local=local, keep_tags=keep_tags)
5402
self.outf.write(gettext('You can restore the old tip by running:\n'
5403
' bzr pull . -r revid:%s\n') % last_rev_id)
4748
revno=revno, local=local)
4749
note('You can restore the old tip by running:\n'
4750
' bzr pull . -r revid:%s', last_rev_id)
5406
4753
class cmd_break_lock(Command):
5407
__doc__ = """Break a dead lock.
5409
This command breaks a lock on a repository, branch, working directory or
4754
"""Break a dead lock on a repository, branch or working directory.
5412
4756
CAUTION: Locks should only be broken when you are sure that the process
5413
4757
holding the lock has been stopped.
5420
4764
bzr break-lock bzr+ssh://example.com/bzr/foo
5421
bzr break-lock --conf ~/.bazaar
5424
4766
takes_args = ['location?']
5427
help='LOCATION is the directory where the config lock is.'),
5429
help='Do not ask for confirmation before breaking the lock.'),
5432
def run(self, location=None, config=False, force=False):
4768
def run(self, location=None, show=False):
5433
4769
if location is None:
5434
4770
location = u'.'
5436
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5438
{'bzrlib.lockdir.break': True})
5440
conf = _mod_config.LockableConfig(file_name=location)
5443
control, relpath = controldir.ControlDir.open_containing(location)
5445
control.break_lock()
5446
except NotImplementedError:
4771
control, relpath = bzrdir.BzrDir.open_containing(location)
4773
control.break_lock()
4774
except NotImplementedError:
5450
4778
class cmd_wait_until_signalled(Command):
5451
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4779
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5453
4781
This just prints a line to signal when it is ready, then blocks on stdin.
5514
4841
return host, port
5516
4843
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5517
protocol=None, client_timeout=None):
5518
from bzrlib import transport
4845
from bzrlib.transport import get_transport, transport_server_registry
5519
4846
if directory is None:
5520
4847
directory = os.getcwd()
5521
4848
if protocol is None:
5522
protocol = transport.transport_server_registry.get()
4849
protocol = transport_server_registry.get()
5523
4850
host, port = self.get_host_and_port(port)
5524
url = transport.location_to_url(directory)
4851
url = urlutils.local_path_to_url(directory)
5525
4852
if not allow_writes:
5526
4853
url = 'readonly+' + url
5527
t = transport.get_transport_from_url(url)
5529
protocol(t, host, port, inet, client_timeout)
5530
except TypeError, e:
5531
# We use symbol_versioning.deprecated_in just so that people
5532
# grepping can find it here.
5533
# symbol_versioning.deprecated_in((2, 5, 0))
5534
symbol_versioning.warn(
5535
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5536
'Most likely it needs to be updated to support a'
5537
' "timeout" parameter (added in bzr 2.5.0)'
5538
% (e, protocol.__module__, protocol),
5540
protocol(t, host, port, inet)
4854
transport = get_transport(url)
4855
protocol(transport, host, port, inet)
5543
4858
class cmd_join(Command):
5544
__doc__ = """Combine a tree into its containing tree.
4859
"""Combine a tree into its containing tree.
5546
4861
This command requires the target tree to be in a rich-root format.
5925
5232
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5926
5233
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5928
If no tag name is specified it will be determined through the
5929
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5930
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5934
5236
_see_also = ['commit', 'tags']
5935
takes_args = ['tag_name?']
5237
takes_args = ['tag_name']
5936
5238
takes_options = [
5937
5239
Option('delete',
5938
5240
help='Delete this tag rather than placing it.',
5940
custom_help('directory',
5941
help='Branch in which to place the tag.'),
5243
help='Branch in which to place the tag.',
5942
5247
Option('force',
5943
5248
help='Replace existing tags.',
5948
def run(self, tag_name=None,
5253
def run(self, tag_name,
5954
5259
branch, relpath = Branch.open_containing(directory)
5955
self.add_cleanup(branch.lock_write().unlock)
5261
self.add_cleanup(branch.unlock)
5957
if tag_name is None:
5958
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5959
5263
branch.tags.delete_tag(tag_name)
5960
note(gettext('Deleted tag %s.') % tag_name)
5264
self.outf.write('Deleted tag %s.\n' % tag_name)
5963
5267
if len(revision) != 1:
5964
raise errors.BzrCommandError(gettext(
5268
raise errors.BzrCommandError(
5965
5269
"Tags can only be placed on a single revision, "
5967
5271
revision_id = revision[0].as_revision_id(branch)
5969
5273
revision_id = branch.last_revision()
5970
if tag_name is None:
5971
tag_name = branch.automatic_tag_name(revision_id)
5972
if tag_name is None:
5973
raise errors.BzrCommandError(gettext(
5974
"Please specify a tag name."))
5976
existing_target = branch.tags.lookup_tag(tag_name)
5977
except errors.NoSuchTag:
5978
existing_target = None
5979
if not force and existing_target not in (None, revision_id):
5274
if (not force) and branch.tags.has_tag(tag_name):
5980
5275
raise errors.TagAlreadyExists(tag_name)
5981
if existing_target == revision_id:
5982
note(gettext('Tag %s already exists for that revision.') % tag_name)
5984
branch.tags.set_tag(tag_name, revision_id)
5985
if existing_target is None:
5986
note(gettext('Created tag %s.') % tag_name)
5988
note(gettext('Updated tag %s.') % tag_name)
5276
branch.tags.set_tag(tag_name, revision_id)
5277
self.outf.write('Created tag %s.\n' % tag_name)
5991
5280
class cmd_tags(Command):
5992
__doc__ = """List tags.
5994
5283
This command shows a table of tag names and the revisions they reference.
5997
5286
_see_also = ['tag']
5998
5287
takes_options = [
5999
custom_help('directory',
6000
help='Branch whose tags should be displayed.'),
6001
RegistryOption('sort',
5289
help='Branch whose tags should be displayed.',
5293
RegistryOption.from_kwargs('sort',
6002
5294
'Sort tags by different criteria.', title='Sorting',
6003
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5295
alpha='Sort tags lexicographically (default).',
5296
time='Sort tags chronologically.',
6009
5302
@display_command
6010
def run(self, directory='.', sort=None, show_ids=False, revision=None):
6011
from bzrlib.tag import tag_sort_methods
6012
5309
branch, relpath = Branch.open_containing(directory)
6014
5311
tags = branch.tags.get_tag_dict().items()
6018
self.add_cleanup(branch.lock_read().unlock)
5316
self.add_cleanup(branch.unlock)
6020
# Restrict to the specified range
6021
tags = self._tags_for_range(branch, revision)
6023
sort = tag_sort_methods.get()
5318
graph = branch.repository.get_graph()
5319
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5320
revid1, revid2 = rev1.rev_id, rev2.rev_id
5321
# only show revisions between revid1 and revid2 (inclusive)
5322
tags = [(tag, revid) for tag, revid in tags if
5323
graph.is_between(revid, revid1, revid2)]
5326
elif sort == 'time':
5328
for tag, revid in tags:
5330
revobj = branch.repository.get_revision(revid)
5331
except errors.NoSuchRevision:
5332
timestamp = sys.maxint # place them at the end
5334
timestamp = revobj.timestamp
5335
timestamps[revid] = timestamp
5336
tags.sort(key=lambda x: timestamps[x[1]])
6025
5337
if not show_ids:
6026
5338
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
6027
5339
for index, (tag, revid) in enumerate(tags):
6040
5350
for tag, revspec in tags:
6041
5351
self.outf.write('%-20s %s\n' % (tag, revspec))
6043
def _tags_for_range(self, branch, revision):
6045
rev1, rev2 = _get_revision_range(revision, branch, self.name())
6046
revid1, revid2 = rev1.rev_id, rev2.rev_id
6047
# _get_revision_range will always set revid2 if it's not specified.
6048
# If revid1 is None, it means we want to start from the branch
6049
# origin which is always a valid ancestor. If revid1 == revid2, the
6050
# ancestry check is useless.
6051
if revid1 and revid1 != revid2:
6052
# FIXME: We really want to use the same graph than
6053
# branch.iter_merge_sorted_revisions below, but this is not
6054
# easily available -- vila 2011-09-23
6055
if branch.repository.get_graph().is_ancestor(revid2, revid1):
6056
# We don't want to output anything in this case...
6058
# only show revisions between revid1 and revid2 (inclusive)
6059
tagged_revids = branch.tags.get_reverse_tag_dict()
6061
for r in branch.iter_merge_sorted_revisions(
6062
start_revision_id=revid2, stop_revision_id=revid1,
6063
stop_rule='include'):
6064
revid_tags = tagged_revids.get(r[0], None)
6066
found.extend([(tag, r[0]) for tag in revid_tags])
6070
5354
class cmd_reconfigure(Command):
6071
__doc__ = """Reconfigure the type of a bzr directory.
5355
"""Reconfigure the type of a bzr directory.
6073
5357
A target configuration must be specified.
6085
5369
takes_args = ['location?']
6086
5370
takes_options = [
6087
5371
RegistryOption.from_kwargs(
6090
help='The relation between branch and tree.',
5373
title='Target type',
5374
help='The type to reconfigure the directory to.',
6091
5375
value_switches=True, enum_switch=False,
6092
5376
branch='Reconfigure to be an unbound branch with no working tree.',
6093
5377
tree='Reconfigure to be an unbound branch with a working tree.',
6094
5378
checkout='Reconfigure to be a bound branch with a working tree.',
6095
5379
lightweight_checkout='Reconfigure to be a lightweight'
6096
5380
' checkout (with no local history).',
6098
RegistryOption.from_kwargs(
6100
title='Repository type',
6101
help='Location fo the repository.',
6102
value_switches=True, enum_switch=False,
6103
5381
standalone='Reconfigure to be a standalone branch '
6104
5382
'(i.e. stop using shared repository).',
6105
5383
use_shared='Reconfigure to use a shared repository.',
6107
RegistryOption.from_kwargs(
6109
title='Trees in Repository',
6110
help='Whether new branches in the repository have trees.',
6111
value_switches=True, enum_switch=False,
6112
5384
with_trees='Reconfigure repository to create '
6113
5385
'working trees on branches by default.',
6114
5386
with_no_trees='Reconfigure repository to not create '
6141
5413
# At the moment you can use --stacked-on and a different
6142
5414
# reconfiguration shape at the same time; there seems no good reason
6144
if (tree_type is None and
6145
repository_type is None and
6146
repository_trees is None):
5416
if target_type is None:
6147
5417
if stacked_on or unstacked:
6150
raise errors.BzrCommandError(gettext('No target configuration '
6152
reconfiguration = None
6153
if tree_type == 'branch':
5420
raise errors.BzrCommandError('No target configuration '
5422
elif target_type == 'branch':
6154
5423
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6155
elif tree_type == 'tree':
5424
elif target_type == 'tree':
6156
5425
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6157
elif tree_type == 'checkout':
5426
elif target_type == 'checkout':
6158
5427
reconfiguration = reconfigure.Reconfigure.to_checkout(
6159
5428
directory, bind_to)
6160
elif tree_type == 'lightweight-checkout':
5429
elif target_type == 'lightweight-checkout':
6161
5430
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6162
5431
directory, bind_to)
6164
reconfiguration.apply(force)
6165
reconfiguration = None
6166
if repository_type == 'use-shared':
5432
elif target_type == 'use-shared':
6167
5433
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6168
elif repository_type == 'standalone':
5434
elif target_type == 'standalone':
6169
5435
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6171
reconfiguration.apply(force)
6172
reconfiguration = None
6173
if repository_trees == 'with-trees':
5436
elif target_type == 'with-trees':
6174
5437
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6175
5438
directory, True)
6176
elif repository_trees == 'with-no-trees':
5439
elif target_type == 'with-no-trees':
6177
5440
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6178
5441
directory, False)
6180
reconfiguration.apply(force)
6181
reconfiguration = None
5442
reconfiguration.apply(force)
6184
5445
class cmd_switch(Command):
6185
__doc__ = """Set the branch of a checkout and update.
5446
"""Set the branch of a checkout and update.
6187
5448
For lightweight checkouts, this changes the branch being referenced.
6188
5449
For heavyweight checkouts, this checks that there are no local commits
6217
5477
def run(self, to_location=None, force=False, create_branch=False,
6218
revision=None, directory=u'.'):
6219
5479
from bzrlib import switch
6220
tree_location = directory
6221
5481
revision = _get_one_revision('switch', revision)
6222
possible_transports = []
6223
control_dir = controldir.ControlDir.open_containing(tree_location,
6224
possible_transports=possible_transports)[0]
5482
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
6225
5483
if to_location is None:
6226
5484
if revision is None:
6227
raise errors.BzrCommandError(gettext('You must supply either a'
6228
' revision or a location'))
6229
to_location = tree_location
5485
raise errors.BzrCommandError('You must supply either a'
5486
' revision or a location')
6231
branch = control_dir.open_branch(
6232
possible_transports=possible_transports)
5489
branch = control_dir.open_branch()
6233
5490
had_explicit_nick = branch.get_config().has_explicit_nickname()
6234
5491
except errors.NotBranchError:
6236
5493
had_explicit_nick = False
6237
5494
if create_branch:
6238
5495
if branch is None:
6239
raise errors.BzrCommandError(
6240
gettext('cannot create branch without source branch'))
6241
to_location = lookup_new_sibling_branch(control_dir, to_location,
6242
possible_transports=possible_transports)
5496
raise errors.BzrCommandError('cannot create branch without'
5498
to_location = directory_service.directories.dereference(
5500
if '/' not in to_location and '\\' not in to_location:
5501
# This path is meant to be relative to the existing branch
5502
this_url = self._get_branch_location(control_dir)
5503
to_location = urlutils.join(this_url, '..', to_location)
6243
5504
to_branch = branch.bzrdir.sprout(to_location,
6244
possible_transports=possible_transports,
6245
source_branch=branch).open_branch()
5505
possible_transports=[branch.bzrdir.root_transport],
5506
source_branch=branch).open_branch()
6247
to_branch = lookup_sibling_branch(control_dir, to_location)
5509
to_branch = Branch.open(to_location)
5510
except errors.NotBranchError:
5511
this_url = self._get_branch_location(control_dir)
5512
to_branch = Branch.open(
5513
urlutils.join(this_url, '..', to_location))
6248
5514
if revision is not None:
6249
5515
revision = revision.as_revision_id(to_branch)
6250
5516
switch.switch(control_dir, to_branch, force, revision_id=revision)
6251
5517
if had_explicit_nick:
6252
5518
branch = control_dir.open_branch() #get the new branch!
6253
5519
branch.nick = to_branch.nick
6254
note(gettext('Switched to branch: %s'),
5520
note('Switched to branch: %s',
6255
5521
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5523
def _get_branch_location(self, control_dir):
5524
"""Return location of branch for this control dir."""
5526
this_branch = control_dir.open_branch()
5527
# This may be a heavy checkout, where we want the master branch
5528
master_location = this_branch.get_bound_location()
5529
if master_location is not None:
5530
return master_location
5531
# If not, use a local sibling
5532
return this_branch.base
5533
except errors.NotBranchError:
5534
format = control_dir.find_branch_format()
5535
if getattr(format, 'get_reference', None) is not None:
5536
return format.get_reference(control_dir)
5538
return control_dir.root_transport.base
6259
5541
class cmd_view(Command):
6260
__doc__ = """Manage filtered views.
5542
"""Manage filtered views.
6262
5544
Views provide a mask over the tree so that users can focus on
6263
5545
a subset of a tree when doing their work. After creating a view,
6346
tree, file_list = WorkingTree.open_containing_paths(file_list,
5628
tree, file_list = tree_files(file_list, apply_view=False)
6348
5629
current_view, view_dict = tree.views.get_view_info()
6349
5630
if name is None:
6350
5631
name = current_view
6353
raise errors.BzrCommandError(gettext(
6354
"Both --delete and a file list specified"))
5634
raise errors.BzrCommandError(
5635
"Both --delete and a file list specified")
6356
raise errors.BzrCommandError(gettext(
6357
"Both --delete and --switch specified"))
5637
raise errors.BzrCommandError(
5638
"Both --delete and --switch specified")
6359
5640
tree.views.set_view_info(None, {})
6360
self.outf.write(gettext("Deleted all views.\n"))
5641
self.outf.write("Deleted all views.\n")
6361
5642
elif name is None:
6362
raise errors.BzrCommandError(gettext("No current view to delete"))
5643
raise errors.BzrCommandError("No current view to delete")
6364
5645
tree.views.delete_view(name)
6365
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5646
self.outf.write("Deleted '%s' view.\n" % name)
6368
raise errors.BzrCommandError(gettext(
6369
"Both --switch and a file list specified"))
5649
raise errors.BzrCommandError(
5650
"Both --switch and a file list specified")
6371
raise errors.BzrCommandError(gettext(
6372
"Both --switch and --all specified"))
5652
raise errors.BzrCommandError(
5653
"Both --switch and --all specified")
6373
5654
elif switch == 'off':
6374
5655
if current_view is None:
6375
raise errors.BzrCommandError(gettext("No current view to disable"))
5656
raise errors.BzrCommandError("No current view to disable")
6376
5657
tree.views.set_view_info(None, view_dict)
6377
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5658
self.outf.write("Disabled '%s' view.\n" % (current_view))
6379
5660
tree.views.set_view_info(switch, view_dict)
6380
5661
view_str = views.view_display_str(tree.views.lookup_view())
6381
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5662
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6384
self.outf.write(gettext('Views defined:\n'))
5665
self.outf.write('Views defined:\n')
6385
5666
for view in sorted(view_dict):
6386
5667
if view == current_view:
6390
5671
view_str = views.view_display_str(view_dict[view])
6391
5672
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6393
self.outf.write(gettext('No views defined.\n'))
5674
self.outf.write('No views defined.\n')
6394
5675
elif file_list:
6395
5676
if name is None:
6396
5677
# No name given and no current view set
6398
5679
elif name == 'off':
6399
raise errors.BzrCommandError(gettext(
6400
"Cannot change the 'off' pseudo view"))
5680
raise errors.BzrCommandError(
5681
"Cannot change the 'off' pseudo view")
6401
5682
tree.views.set_view(name, sorted(file_list))
6402
5683
view_str = views.view_display_str(tree.views.lookup_view())
6403
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5684
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6405
5686
# list the files
6406
5687
if name is None:
6407
5688
# No name given and no current view set
6408
self.outf.write(gettext('No current view.\n'))
5689
self.outf.write('No current view.\n')
6410
5691
view_str = views.view_display_str(tree.views.lookup_view(name))
6411
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5692
self.outf.write("'%s' view is: %s\n" % (name, view_str))
6414
5695
class cmd_hooks(Command):
6415
__doc__ = """Show hooks."""
6603
5843
' deleting them.'),
6604
5844
Option('force', help='Do not prompt before deleting.')]
6605
5845
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6606
force=False, directory=u'.'):
6607
5847
from bzrlib.clean_tree import clean_tree
6608
5848
if not (unknown or ignored or detritus):
6612
clean_tree(directory, unknown=unknown, ignored=ignored,
6613
detritus=detritus, dry_run=dry_run, no_prompt=force)
5852
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5853
dry_run=dry_run, no_prompt=force)
6616
5856
class cmd_reference(Command):
6617
__doc__ = """list, view and set branch locations for nested trees.
5857
"""list, view and set branch locations for nested trees.
6619
5859
If no arguments are provided, lists the branch locations for nested trees.
6620
5860
If one argument is provided, display the branch location for that tree.
6660
5900
self.outf.write('%s %s\n' % (path, location))
6663
class cmd_export_pot(Command):
6664
__doc__ = """Export command helps and error messages in po format."""
6667
takes_options = [Option('plugin',
6668
help='Export help text from named command '\
6669
'(defaults to all built in commands).',
6671
Option('include-duplicates',
6672
help='Output multiple copies of the same msgid '
6673
'string if it appears more than once.'),
6676
def run(self, plugin=None, include_duplicates=False):
6677
from bzrlib.export_pot import export_pot
6678
export_pot(self.outf, plugin, include_duplicates)
6681
def _register_lazy_builtins():
6682
# register lazy builtins from other modules; called at startup and should
6683
# be only called once.
6684
for (name, aliases, module_name) in [
6685
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6686
('cmd_config', [], 'bzrlib.config'),
6687
('cmd_dpush', [], 'bzrlib.foreign'),
6688
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6689
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6690
('cmd_conflicts', [], 'bzrlib.conflicts'),
6691
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6692
('cmd_verify_signatures', [],
6693
'bzrlib.commit_signature_commands'),
6694
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6696
builtin_command_registry.register_lazy(name, aliases, module_name)
5903
# these get imported and then picked up by the scan for cmd_*
5904
# TODO: Some more consistent way to split command definitions across files;
5905
# we do need to load at least some information about them to know of
5906
# aliases. ideally we would avoid loading the implementation until the
5907
# details were needed.
5908
from bzrlib.cmd_version_info import cmd_version_info
5909
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5910
from bzrlib.bundle.commands import (
5913
from bzrlib.foreign import cmd_dpush
5914
from bzrlib.sign_my_commits import cmd_sign_my_commits
5915
from bzrlib.weave_commands import cmd_versionedfile_list, \
5916
cmd_weave_plan_merge, cmd_weave_merge_text