78
65
_parse_revision_str,
80
67
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
target = control_dir.get_branch_reference()
90
except errors.NotBranchError:
91
return control_dir.root_transport.base
92
if target is not None:
94
this_branch = control_dir.open_branch(
95
possible_transports=possible_transports)
96
# This may be a heavy checkout, where we want the master branch
97
master_location = this_branch.get_bound_location()
98
if master_location is not None:
99
return master_location
100
# If not, use a local sibling
101
return this_branch.base
104
def _is_colocated(control_dir, possible_transports=None):
105
"""Check if the branch in control_dir is colocated.
107
:param control_dir: Control directory
108
:return: Tuple with boolean indicating whether the branch is colocated
109
and the full URL to the actual branch
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 to find sibling branches from
136
:param location: Name of the new branch
137
:return: Full location to the new branch
139
location = directory_service.directories.dereference(location)
140
if '/' not in location and '\\' not in location:
141
(colocated, this_url) = _is_colocated(control_dir, possible_transports)
144
return urlutils.join_segment_parameters(this_url,
145
{"branch": urlutils.escape(location)})
147
return urlutils.join(this_url, '..', urlutils.escape(location))
151
def open_sibling_branch(control_dir, location, possible_transports=None):
152
"""Open a branch, possibly a sibling of another.
154
:param control_dir: Control directory relative to which to lookup the
156
:param location: Location to look up
157
:return: branch to open
160
# Perhaps it's a colocated branch?
161
return control_dir.open_branch(location,
162
possible_transports=possible_transports)
163
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
164
this_url = _get_branch_location(control_dir)
167
this_url, '..', urlutils.escape(location)))
170
def open_nearby_branch(near=None, location=None, possible_transports=None):
171
"""Open a nearby branch.
173
:param near: Optional location of container from which to open branch
174
:param location: Location of the branch
175
:return: Branch instance
181
return Branch.open(location,
182
possible_transports=possible_transports)
183
except errors.NotBranchError:
185
cdir = controldir.ControlDir.open(near,
186
possible_transports=possible_transports)
187
return open_sibling_branch(cdir, location,
188
possible_transports=possible_transports)
191
def iter_sibling_branches(control_dir, possible_transports=None):
192
"""Iterate over the siblings of a branch.
194
:param control_dir: Control directory for which to look up the siblings
195
:return: Iterator over tuples with branch name and branch object
199
reference = control_dir.get_branch_reference()
200
except errors.NotBranchError:
201
# There is no active branch, just return the colocated branches.
202
for name, branch in control_dir.get_branches().iteritems():
205
if reference is not None:
206
ref_branch = Branch.open(reference,
207
possible_transports=possible_transports)
210
if ref_branch is None or ref_branch.name:
211
if ref_branch is not None:
212
control_dir = ref_branch.bzrdir
213
for name, branch in control_dir.get_branches().iteritems():
216
repo = ref_branch.bzrdir.find_repository()
217
for branch in repo.find_branches(using=True):
218
name = urlutils.relative_url(repo.user_url,
219
branch.user_url).rstrip("/")
70
def tree_files(file_list, default_branch=u'.', canonicalize=True,
73
return internal_tree_files(file_list, default_branch, canonicalize,
75
except errors.FileInWrongBranch, e:
76
raise errors.BzrCommandError("%s is not in the same branch as %s" %
77
(e.path, file_list[0]))
223
80
def tree_files_for_add(file_list):
145
# XXX: Bad function name; should possibly also be a class method of
146
# WorkingTree rather than a function.
147
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
149
"""Convert command-line paths to a WorkingTree and relative paths.
151
This is typically used for command-line processors that take one or
152
more filenames, and infer the workingtree that contains them.
154
The filenames given are not required to exist.
156
:param file_list: Filenames to convert.
158
:param default_branch: Fallback tree path to use if file_list is empty or
161
:param apply_view: if True and a view is set, apply it or check that
162
specified files are within it
164
:return: workingtree, [relative_paths]
166
if file_list is None or len(file_list) == 0:
167
tree = WorkingTree.open_containing(default_branch)[0]
168
if tree.supports_views() and apply_view:
169
view_files = tree.views.lookup_view()
171
file_list = view_files
172
view_str = views.view_display_str(view_files)
173
note("Ignoring files outside view. View is %s" % view_str)
174
return tree, file_list
175
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
176
return tree, safe_relpath_files(tree, file_list, canonicalize,
177
apply_view=apply_view)
180
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
181
"""Convert file_list into a list of relpaths in tree.
183
:param tree: A tree to operate on.
184
:param file_list: A list of user provided paths or None.
185
:param apply_view: if True and a view is set, apply it or check that
186
specified files are within it
187
:return: A list of relative paths.
188
:raises errors.PathNotChild: When a provided path is in a different tree
191
if file_list is None:
193
if tree.supports_views() and apply_view:
194
view_files = tree.views.lookup_view()
198
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
199
# doesn't - fix that up here before we enter the loop.
201
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
204
for filename in file_list:
206
relpath = fixer(osutils.dereference_path(filename))
207
if view_files and not osutils.is_inside_any(view_files, relpath):
208
raise errors.FileOutsideView(filename, view_files)
209
new_list.append(relpath)
210
except errors.PathNotChild:
211
raise errors.FileInWrongBranch(tree.branch, filename)
288
215
def _get_view_info_for_change_reporter(tree):
289
216
"""Get the view information from a tree for change reporting."""
425
330
takes_args = ['revision_id?']
426
takes_options = ['directory', 'revision']
331
takes_options = ['revision']
427
332
# cat-revision is more for frontends so should be exact
428
333
encoding = 'strict'
430
def print_revision(self, revisions, revid):
431
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
432
record = stream.next()
433
if record.storage_kind == 'absent':
434
raise errors.NoSuchRevision(revisions, revid)
435
revtext = record.get_bytes_as('fulltext')
436
self.outf.write(revtext.decode('utf-8'))
439
def run(self, revision_id=None, revision=None, directory=u'.'):
336
def run(self, revision_id=None, revision=None):
440
337
if revision_id is not None and revision is not None:
441
raise errors.BzrCommandError(gettext('You can only supply one of'
442
' revision_id or --revision'))
338
raise errors.BzrCommandError('You can only supply one of'
339
' revision_id or --revision')
443
340
if revision_id is None and revision is None:
444
raise errors.BzrCommandError(gettext('You must supply either'
445
' --revision or a revision_id'))
447
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
449
revisions = b.repository.revisions
450
if revisions is None:
451
raise errors.BzrCommandError(gettext('Repository %r does not support '
452
'access to raw revision texts'))
454
b.repository.lock_read()
456
# TODO: jam 20060112 should cat-revision always output utf-8?
457
if revision_id is not None:
458
revision_id = osutils.safe_revision_id(revision_id, warn=False)
460
self.print_revision(revisions, revision_id)
461
except errors.NoSuchRevision:
462
msg = gettext("The repository {0} contains no revision {1}.").format(
463
b.repository.base, revision_id)
464
raise errors.BzrCommandError(msg)
465
elif revision is not None:
468
raise errors.BzrCommandError(
469
gettext('You cannot specify a NULL revision.'))
470
rev_id = rev.as_revision_id(b)
471
self.print_revision(revisions, rev_id)
473
b.repository.unlock()
341
raise errors.BzrCommandError('You must supply either'
342
' --revision or a revision_id')
343
b = WorkingTree.open_containing(u'.')[0].branch
345
# TODO: jam 20060112 should cat-revision always output utf-8?
346
if revision_id is not None:
347
revision_id = osutils.safe_revision_id(revision_id, warn=False)
349
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
350
except errors.NoSuchRevision:
351
msg = "The repository %s contains no revision %s." % (b.repository.base,
353
raise errors.BzrCommandError(msg)
354
elif revision is not None:
357
raise errors.BzrCommandError('You cannot specify a NULL'
359
rev_id = rev.as_revision_id(b)
360
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
476
363
class cmd_dump_btree(Command):
477
__doc__ = """Dump the contents of a btree index file to stdout.
364
"""Dump the contents of a btree index file to stdout.
479
366
PATH is a btree index file, it can be any URL. This includes things like
480
367
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
566
443
To re-create the working tree, use "bzr checkout".
568
445
_see_also = ['checkout', 'working-trees']
569
takes_args = ['location*']
446
takes_args = ['location?']
570
447
takes_options = [
572
449
help='Remove the working tree even if it has '
573
'uncommitted or shelved changes.'),
450
'uncommitted changes.'),
576
def run(self, location_list, force=False):
577
if not location_list:
580
for location in location_list:
581
d = controldir.ControlDir.open(location)
584
working = d.open_workingtree()
585
except errors.NoWorkingTree:
586
raise errors.BzrCommandError(gettext("No working tree to remove"))
587
except errors.NotLocalUrl:
588
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
589
" of a remote path"))
591
if (working.has_changes()):
592
raise errors.UncommittedChanges(working)
593
if working.get_shelf_manager().last_shelf() is not None:
594
raise errors.ShelvedChanges(working)
596
if working.user_url != working.branch.user_url:
597
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
598
" from a lightweight checkout"))
600
d.destroy_workingtree()
603
class cmd_repair_workingtree(Command):
604
__doc__ = """Reset the working tree state file.
606
This is not meant to be used normally, but more as a way to recover from
607
filesystem corruption, etc. This rebuilds the working inventory back to a
608
'known good' state. Any new modifications (adding a file, renaming, etc)
609
will be lost, though modified files will still be detected as such.
611
Most users will want something more like "bzr revert" or "bzr update"
612
unless the state file has become corrupted.
614
By default this attempts to recover the current state by looking at the
615
headers of the state file. If the state file is too corrupted to even do
616
that, you can supply --revision to force the state of the tree.
619
takes_options = ['revision', 'directory',
621
help='Reset the tree even if it doesn\'t appear to be'
626
def run(self, revision=None, directory='.', force=False):
627
tree, _ = WorkingTree.open_containing(directory)
628
self.add_cleanup(tree.lock_tree_write().unlock)
453
def run(self, location='.', force=False):
454
d = bzrdir.BzrDir.open(location)
457
working = d.open_workingtree()
458
except errors.NoWorkingTree:
459
raise errors.BzrCommandError("No working tree to remove")
460
except errors.NotLocalUrl:
461
raise errors.BzrCommandError("You cannot remove the working tree"
632
except errors.BzrError:
633
pass # There seems to be a real error here, so we'll reset
636
raise errors.BzrCommandError(gettext(
637
'The tree does not appear to be corrupt. You probably'
638
' want "bzr revert" instead. Use "--force" if you are'
639
' sure you want to reset the working tree.'))
643
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
645
tree.reset_state(revision_ids)
646
except errors.BzrError, e:
647
if revision_ids is None:
648
extra = (gettext(', the header appears corrupt, try passing -r -1'
649
' to set the state to the last commit'))
652
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
464
# XXX: What about pending merges ? -- vila 20090629
465
if working.has_changes(working.basis_tree()):
466
raise errors.UncommittedChanges(working)
468
working_path = working.bzrdir.root_transport.base
469
branch_path = working.branch.bzrdir.root_transport.base
470
if working_path != branch_path:
471
raise errors.BzrCommandError("You cannot remove the working tree"
472
" from a lightweight checkout")
474
d.destroy_workingtree()
655
477
class cmd_revno(Command):
656
__doc__ = """Show current revision number.
478
"""Show current revision number.
658
480
This is equal to the number of revisions on this branch.
661
483
_see_also = ['info']
662
484
takes_args = ['location?']
663
485
takes_options = [
664
Option('tree', help='Show revno of working tree.'),
486
Option('tree', help='Show revno of working tree'),
669
def run(self, tree=False, location=u'.', revision=None):
670
if revision is not None and tree:
671
raise errors.BzrCommandError(gettext("--tree and --revision can "
672
"not be used together"))
490
def run(self, tree=False, location=u'.'):
676
493
wt = WorkingTree.open_containing(location)[0]
677
self.add_cleanup(wt.lock_read().unlock)
678
495
except (errors.NoWorkingTree, errors.NotLocalUrl):
679
496
raise errors.NoWorkingTree(location)
681
revid = wt.last_revision()
498
revid = wt.last_revision()
500
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
501
except errors.NoSuchRevision:
503
revno = ".".join(str(n) for n in revno_t)
683
507
b = Branch.open_containing(location)[0]
684
self.add_cleanup(b.lock_read().unlock)
686
if len(revision) != 1:
687
raise errors.BzrCommandError(gettext(
688
"Revision numbers only make sense for single "
689
"revisions, not ranges"))
690
revid = revision[0].as_revision_id(b)
692
revid = b.last_revision()
694
revno_t = b.revision_id_to_dotted_revno(revid)
695
except errors.NoSuchRevision:
697
revno = ".".join(str(n) for n in revno_t)
699
self.outf.write(revno + '\n')
514
self.outf.write(str(revno) + '\n')
702
517
class cmd_revision_info(Command):
703
__doc__ = """Show revision number and revision id for a given revision identifier.
518
"""Show revision number and revision id for a given revision identifier.
706
521
takes_args = ['revision_info*']
707
522
takes_options = [
709
custom_help('directory',
710
525
help='Branch to examine, '
711
'rather than the one containing the working directory.'),
712
Option('tree', help='Show revno of working tree.'),
526
'rather than the one containing the working directory.',
530
Option('tree', help='Show revno of working tree'),
720
538
wt = WorkingTree.open_containing(directory)[0]
722
self.add_cleanup(wt.lock_read().unlock)
723
541
except (errors.NoWorkingTree, errors.NotLocalUrl):
725
543
b = Branch.open_containing(directory)[0]
726
self.add_cleanup(b.lock_read().unlock)
728
if revision is not None:
729
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
730
if revision_info_list is not None:
731
for rev_str in revision_info_list:
732
rev_spec = RevisionSpec.from_string(rev_str)
733
revision_ids.append(rev_spec.as_revision_id(b))
734
# No arguments supplied, default to the last revision
735
if len(revision_ids) == 0:
738
raise errors.NoWorkingTree(directory)
739
revision_ids.append(wt.last_revision())
547
if revision is not None:
548
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
549
if revision_info_list is not None:
550
for rev_str in revision_info_list:
551
rev_spec = RevisionSpec.from_string(rev_str)
552
revision_ids.append(rev_spec.as_revision_id(b))
553
# No arguments supplied, default to the last revision
554
if len(revision_ids) == 0:
557
raise errors.NoWorkingTree(directory)
558
revision_ids.append(wt.last_revision())
560
revision_ids.append(b.last_revision())
564
for revision_id in revision_ids:
566
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
567
revno = '.'.join(str(i) for i in dotted_revno)
568
except errors.NoSuchRevision:
570
maxlen = max(maxlen, len(revno))
571
revinfos.append([revno, revision_id])
741
revision_ids.append(b.last_revision())
745
for revision_id in revision_ids:
747
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
748
revno = '.'.join(str(i) for i in dotted_revno)
749
except errors.NoSuchRevision:
751
maxlen = max(maxlen, len(revno))
752
revinfos.append([revno, revision_id])
755
578
for ri in revinfos:
756
579
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
759
582
class cmd_add(Command):
760
__doc__ = """Add specified files or directories.
583
"""Add specified files or directories.
762
585
In non-recursive mode, all the named items are added, regardless
763
586
of whether they were previously ignored. A warning is given if
832
647
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
833
648
to_file=self.outf, should_print=(not is_quiet()))
835
action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
650
action = bzrlib.add.AddAction(to_file=self.outf,
836
651
should_print=(not is_quiet()))
839
self.add_cleanup(base_tree.lock_read().unlock)
840
tree, file_list = tree_files_for_add(file_list)
841
added, ignored = tree.smart_add(file_list, not
842
no_recurse, action=action, save=not dry_run)
654
base_tree.lock_read()
656
file_list = self._maybe_expand_globs(file_list)
657
tree, file_list = tree_files_for_add(file_list)
658
added, ignored = tree.smart_add(file_list, not
659
no_recurse, action=action, save=not dry_run)
661
if base_tree is not None:
844
663
if len(ignored) > 0:
846
665
for glob in sorted(ignored.keys()):
847
666
for path in ignored[glob]:
849
gettext("ignored {0} matching \"{1}\"\n").format(
667
self.outf.write("ignored %s matching \"%s\"\n"
853
671
class cmd_mkdir(Command):
854
__doc__ = """Create a new versioned directory.
672
"""Create a new versioned directory.
856
674
This is equivalent to creating the directory and then adding it.
859
677
takes_args = ['dir+']
863
help='No error if existing, make parent directories as needed.',
867
678
encoding_type = 'replace'
870
def add_file_with_parents(cls, wt, relpath):
871
if wt.path2id(relpath) is not None:
873
cls.add_file_with_parents(wt, osutils.dirname(relpath))
877
def add_file_single(cls, wt, relpath):
880
def run(self, dir_list, parents=False):
882
add_file = self.add_file_with_parents
884
add_file = self.add_file_single
886
wt, relpath = WorkingTree.open_containing(dir)
891
if e.errno != errno.EEXIST:
895
add_file(wt, relpath)
897
self.outf.write(gettext('added %s\n') % dir)
680
def run(self, dir_list):
683
wt, dd = WorkingTree.open_containing(d)
685
self.outf.write('added %s\n' % d)
900
688
class cmd_relpath(Command):
901
__doc__ = """Show path of a file relative to root"""
689
"""Show path of a file relative to root"""
903
691
takes_args = ['filename']
937
725
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
938
726
if kind and kind not in ['file', 'directory', 'symlink']:
939
raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
727
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
941
729
revision = _get_one_revision('inventory', revision)
942
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
943
self.add_cleanup(work_tree.lock_read().unlock)
944
if revision is not None:
945
tree = revision.as_tree(work_tree.branch)
947
extra_trees = [work_tree]
948
self.add_cleanup(tree.lock_read().unlock)
953
self.add_cleanup(tree.lock_read().unlock)
954
if file_list is not None:
955
file_ids = tree.paths2ids(file_list, trees=extra_trees,
956
require_versioned=True)
957
# find_ids_across_trees may include some paths that don't
959
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
961
entries = tree.iter_entries_by_dir()
963
for path, entry in sorted(entries):
730
work_tree, file_list = tree_files(file_list)
731
work_tree.lock_read()
733
if revision is not None:
734
tree = revision.as_tree(work_tree.branch)
736
extra_trees = [work_tree]
742
if file_list is not None:
743
file_ids = tree.paths2ids(file_list, trees=extra_trees,
744
require_versioned=True)
745
# find_ids_across_trees may include some paths that don't
747
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
748
for file_id in file_ids if file_id in tree)
750
entries = tree.inventory.entries()
753
if tree is not work_tree:
756
for path, entry in entries:
964
757
if kind and kind != entry.kind:
969
760
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1007
798
return self.run_auto(names_list, after, dry_run)
1009
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
800
raise errors.BzrCommandError('--dry-run requires --auto.')
1010
801
if names_list is None:
1012
803
if len(names_list) < 2:
1013
raise errors.BzrCommandError(gettext("missing file argument"))
1014
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1015
for file_name in rel_names[0:-1]:
1017
raise errors.BzrCommandError(gettext("can not move root of branch"))
1018
self.add_cleanup(tree.lock_tree_write().unlock)
1019
self._run(tree, names_list, rel_names, after)
804
raise errors.BzrCommandError("missing file argument")
805
tree, rel_names = tree_files(names_list, canonicalize=False)
806
tree.lock_tree_write()
808
self._run(tree, names_list, rel_names, after)
1021
812
def run_auto(self, names_list, after, dry_run):
1022
813
if names_list is not None and len(names_list) > 1:
1023
raise errors.BzrCommandError(gettext('Only one path may be specified to'
814
raise errors.BzrCommandError('Only one path may be specified to'
1026
raise errors.BzrCommandError(gettext('--after cannot be specified with'
1028
work_tree, file_list = WorkingTree.open_containing_paths(
1029
names_list, default_directory='.')
1030
self.add_cleanup(work_tree.lock_tree_write().unlock)
1031
rename_map.RenameMap.guess_renames(work_tree, dry_run)
817
raise errors.BzrCommandError('--after cannot be specified with'
819
work_tree, file_list = tree_files(names_list, default_branch='.')
820
work_tree.lock_tree_write()
822
rename_map.RenameMap.guess_renames(work_tree, dry_run)
1033
826
def _run(self, tree, names_list, rel_names, after):
1034
827
into_existing = osutils.isdir(names_list[-1])
1106
899
dest = osutils.pathjoin(dest_parent, dest_tail)
1107
900
mutter("attempting to move %s => %s", src, dest)
1108
901
tree.rename_one(src, dest, after=after)
1110
self.outf.write("%s => %s\n" % (src, dest))
902
self.outf.write("%s => %s\n" % (src, dest))
1113
905
class cmd_pull(Command):
1114
__doc__ = """Turn this branch into a mirror of another branch.
906
"""Turn this branch into a mirror of another branch.
1116
By default, this command only works on branches that have not diverged.
1117
Branches are considered diverged if the destination branch's most recent
1118
commit is one that has not been merged (directly or indirectly) into the
908
This command only works on branches that have not diverged. Branches are
909
considered diverged if the destination branch's most recent commit is one
910
that has not been merged (directly or indirectly) into the parent.
1121
912
If branches have diverged, you can use 'bzr merge' to integrate the changes
1122
913
from one into the other. Once one branch has merged, the other should
1123
914
be able to pull it again.
1125
If you want to replace your local changes and just want your branch to
1126
match the remote one, use pull --overwrite. This will work even if the two
1127
branches have diverged.
1129
If there is no default location set, the first pull will set it (use
1130
--no-remember to avoid setting it). After that, you can omit the
1131
location to use the default. To change the default, use --remember. The
1132
value will only be saved if the remote location can be accessed.
1134
The --verbose option will display the revisions pulled using the log_format
1135
configuration option. You can use a different format by overriding it with
1136
-Olog_format=<other_format>.
916
If you want to forget your local changes and just update your branch to
917
match the remote one, use pull --overwrite.
919
If there is no default location set, the first pull will set it. After
920
that, you can omit the location to use the default. To change the
921
default, use --remember. The value will only be saved if the remote
922
location can be accessed.
1138
924
Note: The location can be specified either in the form of a branch,
1139
925
or in the form of a path to a file containing a merge directive generated
1223
996
branch_from = Branch.open(location,
1224
997
possible_transports=possible_transports)
1225
self.add_cleanup(branch_from.lock_read().unlock)
1226
# Remembers if asked explicitly or no previous location is set
1228
or (remember is None and branch_to.get_parent() is None)):
1229
# FIXME: This shouldn't be done before the pull
1230
# succeeds... -- vila 2012-01-02
999
if branch_to.get_parent() is None or remember:
1231
1000
branch_to.set_parent(branch_from.base)
1233
if revision is not None:
1234
revision_id = revision.as_revision_id(branch_from)
1236
if tree_to is not None:
1237
view_info = _get_view_info_for_change_reporter(tree_to)
1238
change_reporter = delta._ChangeReporter(
1239
unversioned_filter=tree_to.is_ignored,
1240
view_info=view_info)
1241
result = tree_to.pull(
1242
branch_from, overwrite, revision_id, change_reporter,
1243
local=local, show_base=show_base)
1245
result = branch_to.pull(
1246
branch_from, overwrite, revision_id, local=local)
1248
result.report(self.outf)
1249
if verbose and result.old_revid != result.new_revid:
1250
log.show_branch_change(
1251
branch_to, self.outf, result.old_revno,
1253
if getattr(result, 'tag_conflicts', None):
1002
if branch_from is not branch_to:
1003
branch_from.lock_read()
1005
if revision is not None:
1006
revision_id = revision.as_revision_id(branch_from)
1008
branch_to.lock_write()
1010
if tree_to is not None:
1011
view_info = _get_view_info_for_change_reporter(tree_to)
1012
change_reporter = delta._ChangeReporter(
1013
unversioned_filter=tree_to.is_ignored,
1014
view_info=view_info)
1015
result = tree_to.pull(
1016
branch_from, overwrite, revision_id, change_reporter,
1017
possible_transports=possible_transports, local=local)
1019
result = branch_to.pull(
1020
branch_from, overwrite, revision_id, local=local)
1022
result.report(self.outf)
1023
if verbose and result.old_revid != result.new_revid:
1024
log.show_branch_change(
1025
branch_to, self.outf, result.old_revno,
1030
if branch_from is not branch_to:
1031
branch_from.unlock()
1259
1034
class cmd_push(Command):
1260
__doc__ = """Update a mirror of this branch.
1035
"""Update a mirror of this branch.
1262
1037
The target branch will not have its working tree populated because this
1263
1038
is both expensive, and is not supported on remote file systems.
1310
1084
Option('strict',
1311
1085
help='Refuse to push if there are uncommitted changes in'
1312
1086
' the working tree, --no-strict disables the check.'),
1314
help="Don't populate the working tree, even for protocols"
1315
" that support it."),
1316
Option('overwrite-tags',
1317
help="Overwrite tags only."),
1319
1088
takes_args = ['location?']
1320
1089
encoding_type = 'replace'
1322
def run(self, location=None, remember=None, overwrite=False,
1091
def run(self, location=None, remember=False, overwrite=False,
1323
1092
create_prefix=False, verbose=False, revision=None,
1324
1093
use_existing_dir=False, directory=None, stacked_on=None,
1325
stacked=False, strict=None, no_tree=False,
1326
overwrite_tags=False):
1094
stacked=False, strict=None):
1327
1095
from bzrlib.push import _show_push_branch
1330
overwrite = ["history", "tags"]
1331
elif overwrite_tags:
1332
overwrite = ["tags"]
1336
1097
if directory is None:
1337
1098
directory = '.'
1338
1099
# Get the source branch
1339
1100
(tree, br_from,
1340
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1101
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1103
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1104
if strict is None: strict = True # default value
1341
1105
# Get the tip's revision_id
1342
1106
revision = _get_one_revision('push', revision)
1343
1107
if revision is not None:
1344
1108
revision_id = revision.in_history(br_from).rev_id
1346
1110
revision_id = None
1347
if tree is not None and revision_id is None:
1348
tree.check_changed_or_out_of_date(
1349
strict, 'push_strict',
1350
more_error='Use --no-strict to force the push.',
1351
more_warning='Uncommitted changes will not be pushed.')
1111
if strict and tree is not None and revision_id is None:
1112
if (tree.has_changes(tree.basis_tree())
1113
or len(tree.get_parent_ids()) > 1):
1114
raise errors.UncommittedChanges(
1115
tree, more='Use --no-strict to force the push.')
1116
if tree.last_revision() != tree.branch.last_revision():
1117
# The tree has lost sync with its branch, there is little
1118
# chance that the user is aware of it but he can still force
1119
# the push with --no-strict
1120
raise errors.OutOfDateTree(
1121
tree, more='Use --no-strict to force the push.')
1352
1123
# Get the stacked_on branch, if any
1353
1124
if stacked_on is not None:
1354
1125
stacked_on = urlutils.normalize_url(stacked_on)
1364
1135
# error by the feedback given to them. RBC 20080227.
1365
1136
stacked_on = parent_url
1366
1137
if not stacked_on:
1367
raise errors.BzrCommandError(gettext(
1368
"Could not determine branch to refer to."))
1138
raise errors.BzrCommandError(
1139
"Could not determine branch to refer to.")
1370
1141
# Get the destination location
1371
1142
if location is None:
1372
1143
stored_loc = br_from.get_push_location()
1373
1144
if stored_loc is None:
1374
parent_loc = br_from.get_parent()
1376
raise errors.BzrCommandError(gettext(
1377
"No push location known or specified. To push to the "
1378
"parent branch (at %s), use 'bzr push :parent'." %
1379
urlutils.unescape_for_display(parent_loc,
1380
self.outf.encoding)))
1382
raise errors.BzrCommandError(gettext(
1383
"No push location known or specified."))
1145
raise errors.BzrCommandError(
1146
"No push location known or specified.")
1385
1148
display_url = urlutils.unescape_for_display(stored_loc,
1386
1149
self.outf.encoding)
1387
note(gettext("Using saved push location: %s") % display_url)
1150
self.outf.write("Using saved push location: %s\n" % display_url)
1388
1151
location = stored_loc
1390
1153
_show_push_branch(br_from, revision_id, location, self.outf,
1391
1154
verbose=verbose, overwrite=overwrite, remember=remember,
1392
1155
stacked_on=stacked_on, create_prefix=create_prefix,
1393
use_existing_dir=use_existing_dir, no_tree=no_tree)
1156
use_existing_dir=use_existing_dir)
1396
1159
class cmd_branch(Command):
1397
__doc__ = """Create a new branch that is a copy of an existing branch.
1160
"""Create a new branch that is a copy of an existing branch.
1399
1162
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1400
1163
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1431
1190
' directory exists, but does not already'
1432
1191
' have a control directory. This flag will'
1433
1192
' allow branch to proceed.'),
1435
help="Bind new branch to from location."),
1437
1194
aliases = ['get', 'clone']
1439
1196
def run(self, from_location, to_location=None, revision=None,
1440
1197
hardlink=False, stacked=False, standalone=False, no_tree=False,
1441
use_existing_dir=False, switch=False, bind=False,
1198
use_existing_dir=False, switch=False):
1443
1199
from bzrlib import switch as _mod_switch
1444
1200
from bzrlib.tag import _merge_tags_if_possible
1445
if self.invoked_as in ['get', 'clone']:
1446
ui.ui_factory.show_user_warning(
1447
'deprecated_command',
1448
deprecated_name=self.invoked_as,
1449
recommended_name='branch',
1450
deprecated_in_version='2.4')
1451
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1201
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1453
if not (hardlink or files_from):
1454
# accelerator_tree is usually slower because you have to read N
1455
# files (no readahead, lots of seeks, etc), but allow the user to
1456
# explicitly request it
1203
if (accelerator_tree is not None and
1204
accelerator_tree.supports_content_filtering()):
1457
1205
accelerator_tree = None
1458
if files_from is not None and files_from != from_location:
1459
accelerator_tree = WorkingTree.open(files_from)
1460
1206
revision = _get_one_revision('branch', revision)
1461
self.add_cleanup(br_from.lock_read().unlock)
1462
if revision is not None:
1463
revision_id = revision.as_revision_id(br_from)
1465
# FIXME - wt.last_revision, fallback to branch, fall back to
1466
# None or perhaps NULL_REVISION to mean copy nothing
1468
revision_id = br_from.last_revision()
1469
if to_location is None:
1470
to_location = getattr(br_from, "name", None)
1209
if revision is not None:
1210
revision_id = revision.as_revision_id(br_from)
1212
# FIXME - wt.last_revision, fallback to branch, fall back to
1213
# None or perhaps NULL_REVISION to mean copy nothing
1215
revision_id = br_from.last_revision()
1216
if to_location is None:
1472
1217
to_location = urlutils.derive_to_location(from_location)
1473
to_transport = transport.get_transport(to_location)
1475
to_transport.mkdir('.')
1476
except errors.FileExists:
1218
to_transport = transport.get_transport(to_location)
1478
to_dir = controldir.ControlDir.open_from_transport(
1480
except errors.NotBranchError:
1220
to_transport.mkdir('.')
1221
except errors.FileExists:
1481
1222
if not use_existing_dir:
1482
raise errors.BzrCommandError(gettext('Target directory "%s" '
1483
'already exists.') % to_location)
1488
to_dir.open_branch()
1489
except errors.NotBranchError:
1492
raise errors.AlreadyBranchError(to_location)
1493
except errors.NoSuchFile:
1494
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1223
raise errors.BzrCommandError('Target directory "%s" '
1224
'already exists.' % to_location)
1227
bzrdir.BzrDir.open_from_transport(to_transport)
1228
except errors.NotBranchError:
1231
raise errors.AlreadyBranchError(to_location)
1232
except errors.NoSuchFile:
1233
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1500
1236
# preserve whatever source format we have.
1501
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1237
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1502
1238
possible_transports=[to_transport],
1503
1239
accelerator_tree=accelerator_tree,
1504
1240
hardlink=hardlink, stacked=stacked,
1505
1241
force_new_repo=standalone,
1506
1242
create_tree_if_local=not no_tree,
1507
1243
source_branch=br_from)
1508
branch = to_dir.open_branch(
1509
possible_transports=[
1510
br_from.bzrdir.root_transport, to_transport])
1244
branch = dir.open_branch()
1511
1245
except errors.NoSuchRevision:
1512
1246
to_transport.delete_tree('.')
1513
msg = gettext("The branch {0} has no revision {1}.").format(
1514
from_location, revision)
1247
msg = "The branch %s has no revision %s." % (from_location,
1515
1249
raise errors.BzrCommandError(msg)
1518
to_repo = to_dir.open_repository()
1519
except errors.NoRepositoryPresent:
1520
to_repo = to_dir.create_repository()
1521
to_repo.fetch(br_from.repository, revision_id=revision_id)
1522
branch = br_from.sprout(to_dir, revision_id=revision_id)
1523
_merge_tags_if_possible(br_from, branch)
1524
# If the source branch is stacked, the new branch may
1525
# be stacked whether we asked for that explicitly or not.
1526
# We therefore need a try/except here and not just 'if stacked:'
1528
note(gettext('Created new stacked branch referring to %s.') %
1529
branch.get_stacked_on_url())
1530
except (errors.NotStacked, errors.UnstackableBranchFormat,
1531
errors.UnstackableRepositoryFormat), e:
1532
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1534
# Bind to the parent
1535
parent_branch = Branch.open(from_location)
1536
branch.bind(parent_branch)
1537
note(gettext('New branch bound to %s') % from_location)
1539
# Switch to the new branch
1540
wt, _ = WorkingTree.open_containing('.')
1541
_mod_switch.switch(wt.bzrdir, branch)
1542
note(gettext('Switched to branch: %s'),
1543
urlutils.unescape_for_display(branch.base, 'utf-8'))
1546
class cmd_branches(Command):
1547
__doc__ = """List the branches available at the current location.
1549
This command will print the names of all the branches at the current
1553
takes_args = ['location?']
1555
Option('recursive', short_name='R',
1556
help='Recursively scan for branches rather than '
1557
'just looking in the specified location.')]
1559
def run(self, location=".", recursive=False):
1561
t = transport.get_transport(location)
1562
if not t.listable():
1563
raise errors.BzrCommandError(
1564
"Can't scan this type of location.")
1565
for b in controldir.ControlDir.find_branches(t):
1566
self.outf.write("%s\n" % urlutils.unescape_for_display(
1567
urlutils.relative_url(t.base, b.base),
1568
self.outf.encoding).rstrip("/"))
1570
dir = controldir.ControlDir.open_containing(location)[0]
1572
active_branch = dir.open_branch(name="")
1573
except errors.NotBranchError:
1574
active_branch = None
1576
for name, branch in iter_sibling_branches(dir):
1579
active = (active_branch is not None and
1580
active_branch.base == branch.base)
1581
names[name] = active
1582
# Only mention the current branch explicitly if it's not
1583
# one of the colocated branches
1584
if not any(names.values()) and active_branch is not None:
1585
self.outf.write("* %s\n" % gettext("(default)"))
1586
for name in sorted(names.keys()):
1587
active = names[name]
1592
self.outf.write("%s %s\n" % (
1593
prefix, name.encode(self.outf.encoding)))
1250
_merge_tags_if_possible(br_from, branch)
1251
# If the source branch is stacked, the new branch may
1252
# be stacked whether we asked for that explicitly or not.
1253
# We therefore need a try/except here and not just 'if stacked:'
1255
note('Created new stacked branch referring to %s.' %
1256
branch.get_stacked_on_url())
1257
except (errors.NotStacked, errors.UnstackableBranchFormat,
1258
errors.UnstackableRepositoryFormat), e:
1259
note('Branched %d revision(s).' % branch.revno())
1261
# Switch to the new branch
1262
wt, _ = WorkingTree.open_containing('.')
1263
_mod_switch.switch(wt.bzrdir, branch)
1264
note('Switched to branch: %s',
1265
urlutils.unescape_for_display(branch.base, 'utf-8'))
1596
1270
class cmd_checkout(Command):
1597
__doc__ = """Create a new checkout of an existing branch.
1271
"""Create a new checkout of an existing branch.
1599
1273
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1600
1274
the branch found in '.'. This is useful if you have removed the working tree
1679
1348
@display_command
1680
1349
def run(self, dir=u'.'):
1681
1350
tree = WorkingTree.open_containing(dir)[0]
1682
self.add_cleanup(tree.lock_read().unlock)
1683
old_tree = tree.basis_tree()
1684
self.add_cleanup(old_tree.lock_read().unlock)
1686
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1687
for f, paths, c, v, p, n, k, e in iterator:
1688
if paths[0] == paths[1]:
1692
renames.append(paths)
1694
for old_name, new_name in renames:
1695
self.outf.write("%s => %s\n" % (old_name, new_name))
1353
new_inv = tree.inventory
1354
old_tree = tree.basis_tree()
1355
old_tree.lock_read()
1357
old_inv = old_tree.inventory
1359
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1360
for f, paths, c, v, p, n, k, e in iterator:
1361
if paths[0] == paths[1]:
1365
renames.append(paths)
1367
for old_name, new_name in renames:
1368
self.outf.write("%s => %s\n" % (old_name, new_name))
1698
1375
class cmd_update(Command):
1699
__doc__ = """Update a working tree to a new revision.
1701
This will perform a merge of the destination revision (the tip of the
1702
branch, or the specified revision) into the working tree, and then make
1703
that revision the basis revision for the working tree.
1705
You can use this to visit an older revision, or to update a working tree
1706
that is out of date from its branch.
1708
If there are any uncommitted changes in the tree, they will be carried
1709
across and remain as uncommitted changes after the update. To discard
1710
these changes, use 'bzr revert'. The uncommitted changes may conflict
1711
with the changes brought in by the change in basis revision.
1713
If the tree's branch is bound to a master branch, bzr will also update
1714
the branch from the master.
1716
You cannot update just a single file or directory, because each Bazaar
1717
working tree has just a single basis revision. If you want to restore a
1718
file that has been removed locally, use 'bzr revert' instead of 'bzr
1719
update'. If you want to restore a file to its state in a previous
1720
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1721
out the old content of that file to a new location.
1723
The 'dir' argument, if given, must be the location of the root of a
1724
working tree to update. By default, the working tree that contains the
1725
current working directory is used.
1376
"""Update a tree to have the latest code committed to its branch.
1378
This will perform a merge into the working tree, and may generate
1379
conflicts. If you have any local changes, you will still
1380
need to commit them after the update for the update to be complete.
1382
If you want to discard your local changes, you can just do a
1383
'bzr revert' instead of 'bzr commit' after the update.
1728
1386
_see_also = ['pull', 'working-trees', 'status-flags']
1729
1387
takes_args = ['dir?']
1730
takes_options = ['revision',
1732
help="Show base revision text in conflicts."),
1734
1388
aliases = ['up']
1736
def run(self, dir=None, revision=None, show_base=None):
1737
if revision is not None and len(revision) != 1:
1738
raise errors.BzrCommandError(gettext(
1739
"bzr update --revision takes exactly one revision"))
1741
tree = WorkingTree.open_containing('.')[0]
1743
tree, relpath = WorkingTree.open_containing(dir)
1746
raise errors.BzrCommandError(gettext(
1747
"bzr update can only update a whole tree, "
1748
"not a file or subdirectory"))
1749
branch = tree.branch
1390
def run(self, dir='.'):
1391
tree = WorkingTree.open_containing(dir)[0]
1750
1392
possible_transports = []
1751
master = branch.get_master_branch(
1393
master = tree.branch.get_master_branch(
1752
1394
possible_transports=possible_transports)
1753
1395
if master is not None:
1754
branch_location = master.base
1755
1396
tree.lock_write()
1757
branch_location = tree.branch.base
1758
1398
tree.lock_tree_write()
1759
self.add_cleanup(tree.unlock)
1760
# get rid of the final '/' and be ready for display
1761
branch_location = urlutils.unescape_for_display(
1762
branch_location.rstrip('/'),
1764
existing_pending_merges = tree.get_parent_ids()[1:]
1768
# may need to fetch data into a heavyweight checkout
1769
# XXX: this may take some time, maybe we should display a
1771
old_tip = branch.update(possible_transports)
1772
if revision is not None:
1773
revision_id = revision[0].as_revision_id(branch)
1775
revision_id = branch.last_revision()
1776
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1777
revno = branch.revision_id_to_dotted_revno(revision_id)
1778
note(gettext("Tree is up to date at revision {0} of branch {1}"
1779
).format('.'.join(map(str, revno)), branch_location))
1781
view_info = _get_view_info_for_change_reporter(tree)
1782
change_reporter = delta._ChangeReporter(
1783
unversioned_filter=tree.is_ignored,
1784
view_info=view_info)
1400
existing_pending_merges = tree.get_parent_ids()[1:]
1401
last_rev = _mod_revision.ensure_null(tree.last_revision())
1402
if last_rev == _mod_revision.ensure_null(
1403
tree.branch.last_revision()):
1404
# may be up to date, check master too.
1405
if master is None or last_rev == _mod_revision.ensure_null(
1406
master.last_revision()):
1407
revno = tree.branch.revision_id_to_revno(last_rev)
1408
note("Tree is up to date at revision %d." % (revno,))
1410
view_info = _get_view_info_for_change_reporter(tree)
1786
1411
conflicts = tree.update(
1788
possible_transports=possible_transports,
1789
revision=revision_id,
1791
show_base=show_base)
1792
except errors.NoSuchRevision, e:
1793
raise errors.BzrCommandError(gettext(
1794
"branch has no revision %s\n"
1795
"bzr update --revision only works"
1796
" for a revision in the branch history")
1798
revno = tree.branch.revision_id_to_dotted_revno(
1799
_mod_revision.ensure_null(tree.last_revision()))
1800
note(gettext('Updated to revision {0} of branch {1}').format(
1801
'.'.join(map(str, revno)), branch_location))
1802
parent_ids = tree.get_parent_ids()
1803
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1804
note(gettext('Your local commits will now show as pending merges with '
1805
"'bzr status', and can be committed with 'bzr commit'."))
1412
delta._ChangeReporter(unversioned_filter=tree.is_ignored,
1413
view_info=view_info), possible_transports=possible_transports)
1414
revno = tree.branch.revision_id_to_revno(
1415
_mod_revision.ensure_null(tree.last_revision()))
1416
note('Updated to revision %d.' % (revno,))
1417
if tree.get_parent_ids()[1:] != existing_pending_merges:
1418
note('Your local commits will now show as pending merges with '
1419
"'bzr status', and can be committed with 'bzr commit'.")
1812
1428
class cmd_info(Command):
1813
__doc__ = """Show information about a working tree, branch or repository.
1429
"""Show information about a working tree, branch or repository.
1815
1431
This command will show all known locations and formats associated to the
1816
1432
tree, branch or repository.
1868
1483
RegistryOption.from_kwargs('file-deletion-strategy',
1869
1484
'The file deletion mode to be used.',
1870
1485
title='Deletion Strategy', value_switches=True, enum_switch=False,
1871
safe='Backup changed files (default).',
1486
safe='Only delete files if they can be'
1487
' safely recovered (default).',
1872
1488
keep='Delete from bzr but leave the working copy.',
1873
no_backup='Don\'t backup changed files.'),
1489
force='Delete all the specified files, even if they can not be '
1490
'recovered and even if they are non-empty directories.')]
1875
1491
aliases = ['rm', 'del']
1876
1492
encoding_type = 'replace'
1878
1494
def run(self, file_list, verbose=False, new=False,
1879
1495
file_deletion_strategy='safe'):
1881
tree, file_list = WorkingTree.open_containing_paths(file_list)
1496
tree, file_list = tree_files(file_list)
1883
1498
if file_list is not None:
1884
1499
file_list = [f for f in file_list]
1886
self.add_cleanup(tree.lock_write().unlock)
1887
# Heuristics should probably all move into tree.remove_smart or
1890
added = tree.changes_from(tree.basis_tree(),
1891
specific_files=file_list).added
1892
file_list = sorted([f[0] for f in added], reverse=True)
1893
if len(file_list) == 0:
1894
raise errors.BzrCommandError(gettext('No matching files.'))
1895
elif file_list is None:
1896
# missing files show up in iter_changes(basis) as
1897
# versioned-with-no-kind.
1899
for change in tree.iter_changes(tree.basis_tree()):
1900
# Find paths in the working tree that have no kind:
1901
if change[1][1] is not None and change[6][1] is None:
1902
missing.append(change[1][1])
1903
file_list = sorted(missing, reverse=True)
1904
file_deletion_strategy = 'keep'
1905
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1906
keep_files=file_deletion_strategy=='keep',
1907
force=(file_deletion_strategy=='no-backup'))
1503
# Heuristics should probably all move into tree.remove_smart or
1506
added = tree.changes_from(tree.basis_tree(),
1507
specific_files=file_list).added
1508
file_list = sorted([f[0] for f in added], reverse=True)
1509
if len(file_list) == 0:
1510
raise errors.BzrCommandError('No matching files.')
1511
elif file_list is None:
1512
# missing files show up in iter_changes(basis) as
1513
# versioned-with-no-kind.
1515
for change in tree.iter_changes(tree.basis_tree()):
1516
# Find paths in the working tree that have no kind:
1517
if change[1][1] is not None and change[6][1] is None:
1518
missing.append(change[1][1])
1519
file_list = sorted(missing, reverse=True)
1520
file_deletion_strategy = 'keep'
1521
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1522
keep_files=file_deletion_strategy=='keep',
1523
force=file_deletion_strategy=='force')
1910
1528
class cmd_file_id(Command):
1911
__doc__ = """Print file_id of a particular file or directory.
1529
"""Print file_id of a particular file or directory.
1913
1531
The file_id is assigned when the file is first added and remains the
1914
1532
same through all revisions where the file exists, even when it is
2353
1899
elif ':' in prefix:
2354
1900
old_label, new_label = prefix.split(":")
2356
raise errors.BzrCommandError(gettext(
1902
raise errors.BzrCommandError(
2357
1903
'--prefix expects two values separated by a colon'
2358
' (eg "old/:new/")'))
1904
' (eg "old/:new/")')
2360
1906
if revision and len(revision) > 2:
2361
raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
2362
' one or two revision specifiers'))
2364
if using is not None and format is not None:
2365
raise errors.BzrCommandError(gettext(
2366
'{0} and {1} are mutually exclusive').format(
2367
'--using', '--format'))
2369
(old_tree, new_tree,
2370
old_branch, new_branch,
2371
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2372
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2373
# GNU diff on Windows uses ANSI encoding for filenames
2374
path_encoding = osutils.get_diff_header_encoding()
1907
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1908
' one or two revision specifiers')
1910
old_tree, new_tree, specific_files, extra_trees = \
1911
_get_trees_to_diff(file_list, revision, old, new,
2375
1913
return show_diff_trees(old_tree, new_tree, sys.stdout,
2376
1914
specific_files=specific_files,
2377
1915
external_diff_options=diff_options,
2378
1916
old_label=old_label, new_label=new_label,
2379
extra_trees=extra_trees,
2380
path_encoding=path_encoding,
2381
using=using, context=context,
1917
extra_trees=extra_trees, using=using)
2385
1920
class cmd_deleted(Command):
2386
__doc__ = """List files deleted in the working tree.
1921
"""List files deleted in the working tree.
2388
1923
# TODO: Show files deleted since a previous revision, or
2389
1924
# between two revisions.
2392
1927
# level of effort but possibly much less IO. (Or possibly not,
2393
1928
# if the directories are very large...)
2394
1929
_see_also = ['status', 'ls']
2395
takes_options = ['directory', 'show-ids']
1930
takes_options = ['show-ids']
2397
1932
@display_command
2398
def run(self, show_ids=False, directory=u'.'):
2399
tree = WorkingTree.open_containing(directory)[0]
2400
self.add_cleanup(tree.lock_read().unlock)
2401
old = tree.basis_tree()
2402
self.add_cleanup(old.lock_read().unlock)
2403
for path, ie in old.iter_entries_by_dir():
2404
if not tree.has_id(ie.file_id):
2405
self.outf.write(path)
2407
self.outf.write(' ')
2408
self.outf.write(ie.file_id)
2409
self.outf.write('\n')
1933
def run(self, show_ids=False):
1934
tree = WorkingTree.open_containing(u'.')[0]
1937
old = tree.basis_tree()
1940
for path, ie in old.inventory.iter_entries():
1941
if not tree.has_id(ie.file_id):
1942
self.outf.write(path)
1944
self.outf.write(' ')
1945
self.outf.write(ie.file_id)
1946
self.outf.write('\n')
2412
1953
class cmd_modified(Command):
2413
__doc__ = """List files modified in working tree.
1954
"""List files modified in working tree.
2417
1958
_see_also = ['status', 'ls']
2418
takes_options = ['directory', 'null']
1961
help='Write an ascii NUL (\\0) separator '
1962
'between files rather than a newline.')
2420
1965
@display_command
2421
def run(self, null=False, directory=u'.'):
2422
tree = WorkingTree.open_containing(directory)[0]
2423
self.add_cleanup(tree.lock_read().unlock)
1966
def run(self, null=False):
1967
tree = WorkingTree.open_containing(u'.')[0]
2424
1968
td = tree.changes_from(tree.basis_tree())
2426
1969
for path, id, kind, text_modified, meta_modified in td.modified:
2428
1971
self.outf.write(path + '\0')
2433
1976
class cmd_added(Command):
2434
__doc__ = """List files added in working tree.
1977
"""List files added in working tree.
2438
1981
_see_also = ['status', 'ls']
2439
takes_options = ['directory', 'null']
1984
help='Write an ascii NUL (\\0) separator '
1985
'between files rather than a newline.')
2441
1988
@display_command
2442
def run(self, null=False, directory=u'.'):
2443
wt = WorkingTree.open_containing(directory)[0]
2444
self.add_cleanup(wt.lock_read().unlock)
2445
basis = wt.basis_tree()
2446
self.add_cleanup(basis.lock_read().unlock)
2447
root_id = wt.get_root_id()
2448
for file_id in wt.all_file_ids():
2449
if basis.has_id(file_id):
2451
if root_id == file_id:
2453
path = wt.id2path(file_id)
2454
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2457
self.outf.write(path + '\0')
2459
self.outf.write(osutils.quotefn(path) + '\n')
1989
def run(self, null=False):
1990
wt = WorkingTree.open_containing(u'.')[0]
1993
basis = wt.basis_tree()
1996
basis_inv = basis.inventory
1999
if file_id in basis_inv:
2001
if inv.is_root(file_id) and len(basis_inv) == 0:
2003
path = inv.id2path(file_id)
2004
if not os.access(osutils.abspath(path), os.F_OK):
2007
self.outf.write(path + '\0')
2009
self.outf.write(osutils.quotefn(path) + '\n')
2462
2016
class cmd_root(Command):
2463
__doc__ = """Show the tree root directory.
2017
"""Show the tree root directory.
2465
2019
The root is the nearest enclosing directory with a .bzr control
2733
2251
show_diff=False,
2734
include_merged=None,
2736
exclude_common_ancestry=False,
2740
match_committer=None,
2744
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2252
include_merges=False):
2746
2253
from bzrlib.log import (
2748
2255
make_log_request_dict,
2749
2256
_get_info_for_log_files,
2751
2258
direction = (forward and 'forward') or 'reverse'
2752
if symbol_versioning.deprecated_passed(include_merges):
2753
ui.ui_factory.show_user_warning(
2754
'deprecated_command_option',
2755
deprecated_name='--include-merges',
2756
recommended_name='--include-merged',
2757
deprecated_in_version='2.5',
2758
command=self.invoked_as)
2759
if include_merged is None:
2760
include_merged = include_merges
2762
raise errors.BzrCommandError(gettext(
2763
'{0} and {1} are mutually exclusive').format(
2764
'--include-merges', '--include-merged'))
2765
if include_merged is None:
2766
include_merged = False
2767
if (exclude_common_ancestry
2768
and (revision is None or len(revision) != 2)):
2769
raise errors.BzrCommandError(gettext(
2770
'--exclude-common-ancestry requires -r with two revisions'))
2772
2260
if levels is None:
2775
raise errors.BzrCommandError(gettext(
2776
'{0} and {1} are mutually exclusive').format(
2777
'--levels', '--include-merged'))
2263
raise errors.BzrCommandError(
2264
'--levels and --include-merges are mutually exclusive')
2779
2266
if change is not None:
2780
2267
if len(change) > 1:
2781
2268
raise errors.RangeInChangeOption()
2782
2269
if revision is not None:
2783
raise errors.BzrCommandError(gettext(
2784
'{0} and {1} are mutually exclusive').format(
2785
'--revision', '--change'))
2270
raise errors.BzrCommandError(
2271
'--revision and --change are mutually exclusive')
2787
2273
revision = change
2790
2276
filter_by_dir = False
2792
# find the file ids to log and check for directory filtering
2793
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2794
revision, file_list, self.add_cleanup)
2795
for relpath, file_id, kind in file_info_list:
2797
raise errors.BzrCommandError(gettext(
2798
"Path unknown at end or start of revision range: %s") %
2800
# If the relpath is the top of the tree, we log everything
2280
# find the file ids to log and check for directory filtering
2281
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2282
revision, file_list)
2283
for relpath, file_id, kind in file_info_list:
2285
raise errors.BzrCommandError(
2286
"Path unknown at end or start of revision range: %s" %
2288
# If the relpath is the top of the tree, we log everything
2293
file_ids.append(file_id)
2294
filter_by_dir = filter_by_dir or (
2295
kind in ['directory', 'tree-reference'])
2298
# FIXME ? log the current subdir only RBC 20060203
2299
if revision is not None \
2300
and len(revision) > 0 and revision[0].get_branch():
2301
location = revision[0].get_branch()
2805
file_ids.append(file_id)
2806
filter_by_dir = filter_by_dir or (
2807
kind in ['directory', 'tree-reference'])
2810
# FIXME ? log the current subdir only RBC 20060203
2811
if revision is not None \
2812
and len(revision) > 0 and revision[0].get_branch():
2813
location = revision[0].get_branch()
2816
dir, relpath = controldir.ControlDir.open_containing(location)
2817
b = dir.open_branch()
2818
self.add_cleanup(b.lock_read().unlock)
2819
rev1, rev2 = _get_revision_range(revision, b, self.name())
2821
if b.get_config_stack().get('validate_signatures_in_log'):
2825
if not gpg.GPGStrategy.verify_signatures_available():
2826
raise errors.GpgmeNotInstalled(None)
2828
# Decide on the type of delta & diff filtering to use
2829
# TODO: add an --all-files option to make this configurable & consistent
2837
diff_type = 'partial'
2841
# Build the log formatter
2842
if log_format is None:
2843
log_format = log.log_formatter_registry.get_default(b)
2844
# Make a non-encoding output to include the diffs - bug 328007
2845
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2846
lf = log_format(show_ids=show_ids, to_file=self.outf,
2847
to_exact_file=unencoded_output,
2848
show_timezone=timezone,
2849
delta_format=get_verbosity_level(),
2851
show_advice=levels is None,
2852
author_list_handler=authors)
2854
# Choose the algorithm for doing the logging. It's annoying
2855
# having multiple code paths like this but necessary until
2856
# the underlying repository format is faster at generating
2857
# deltas or can provide everything we need from the indices.
2858
# The default algorithm - match-using-deltas - works for
2859
# multiple files and directories and is faster for small
2860
# amounts of history (200 revisions say). However, it's too
2861
# slow for logging a single file in a repository with deep
2862
# history, i.e. > 10K revisions. In the spirit of "do no
2863
# evil when adding features", we continue to use the
2864
# original algorithm - per-file-graph - for the "single
2865
# file that isn't a directory without showing a delta" case.
2866
partial_history = revision and b.repository._format.supports_chks
2867
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2868
or delta_type or partial_history)
2872
match_dict[''] = match
2874
match_dict['message'] = match_message
2876
match_dict['committer'] = match_committer
2878
match_dict['author'] = match_author
2880
match_dict['bugs'] = match_bugs
2882
# Build the LogRequest and execute it
2883
if len(file_ids) == 0:
2885
rqst = make_log_request_dict(
2886
direction=direction, specific_fileids=file_ids,
2887
start_revision=rev1, end_revision=rev2, limit=limit,
2888
message_search=message, delta_type=delta_type,
2889
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2890
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2891
signature=signatures, omit_merges=omit_merges,
2893
Logger(b, rqst).show(lf)
2304
dir, relpath = bzrdir.BzrDir.open_containing(location)
2305
b = dir.open_branch()
2307
rev1, rev2 = _get_revision_range(revision, b, self.name())
2309
# Decide on the type of delta & diff filtering to use
2310
# TODO: add an --all-files option to make this configurable & consistent
2318
diff_type = 'partial'
2322
# Build the log formatter
2323
if log_format is None:
2324
log_format = log.log_formatter_registry.get_default(b)
2325
lf = log_format(show_ids=show_ids, to_file=self.outf,
2326
show_timezone=timezone,
2327
delta_format=get_verbosity_level(),
2329
show_advice=levels is None)
2331
# Choose the algorithm for doing the logging. It's annoying
2332
# having multiple code paths like this but necessary until
2333
# the underlying repository format is faster at generating
2334
# deltas or can provide everything we need from the indices.
2335
# The default algorithm - match-using-deltas - works for
2336
# multiple files and directories and is faster for small
2337
# amounts of history (200 revisions say). However, it's too
2338
# slow for logging a single file in a repository with deep
2339
# history, i.e. > 10K revisions. In the spirit of "do no
2340
# evil when adding features", we continue to use the
2341
# original algorithm - per-file-graph - for the "single
2342
# file that isn't a directory without showing a delta" case.
2343
partial_history = revision and b.repository._format.supports_chks
2344
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2345
or delta_type or partial_history)
2347
# Build the LogRequest and execute it
2348
if len(file_ids) == 0:
2350
rqst = make_log_request_dict(
2351
direction=direction, specific_fileids=file_ids,
2352
start_revision=rev1, end_revision=rev2, limit=limit,
2353
message_search=message, delta_type=delta_type,
2354
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2355
Logger(b, rqst).show(lf)
2896
2361
def _get_revision_range(revisionspec_list, branch, command_name):
2985
2449
help='Recurse into subdirectories.'),
2986
2450
Option('from-root',
2987
2451
help='Print paths relative to the root of the branch.'),
2988
Option('unknown', short_name='u',
2989
help='Print unknown files.'),
2452
Option('unknown', help='Print unknown files.'),
2990
2453
Option('versioned', help='Print versioned files.',
2991
2454
short_name='V'),
2992
Option('ignored', short_name='i',
2993
help='Print ignored files.'),
2994
Option('kind', short_name='k',
2455
Option('ignored', help='Print ignored files.'),
2457
help='Write an ascii NUL (\\0) separator '
2458
'between files rather than a newline.'),
2995
2460
help='List entries of a particular kind: file, directory, symlink.',
3001
2464
@display_command
3002
2465
def run(self, revision=None, verbose=False,
3003
2466
recursive=False, from_root=False,
3004
2467
unknown=False, versioned=False, ignored=False,
3005
null=False, kind=None, show_ids=False, path=None, directory=None):
2468
null=False, kind=None, show_ids=False, path=None):
3007
2470
if kind and kind not in ('file', 'directory', 'symlink'):
3008
raise errors.BzrCommandError(gettext('invalid kind specified'))
2471
raise errors.BzrCommandError('invalid kind specified')
3010
2473
if verbose and null:
3011
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2474
raise errors.BzrCommandError('Cannot set both --verbose and --null')
3012
2475
all = not (unknown or versioned or ignored)
3014
2477
selection = {'I':ignored, '?':unknown, 'V':versioned}
3041
2504
apply_view = True
3042
2505
view_str = views.view_display_str(view_files)
3043
note(gettext("Ignoring files outside view. View is %s") % view_str)
3045
self.add_cleanup(tree.lock_read().unlock)
3046
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
3047
from_dir=relpath, recursive=recursive):
3048
# Apply additional masking
3049
if not all and not selection[fc]:
3051
if kind is not None and fkind != kind:
3056
fullpath = osutils.pathjoin(relpath, fp)
3059
views.check_path_in_view(tree, fullpath)
3060
except errors.FileOutsideView:
3065
fp = osutils.pathjoin(prefix, fp)
3066
kindch = entry.kind_character()
3067
outstring = fp + kindch
3068
ui.ui_factory.clear_term()
3070
outstring = '%-8s %s' % (fc, outstring)
3071
if show_ids and fid is not None:
3072
outstring = "%-50s %s" % (outstring, fid)
3073
self.outf.write(outstring + '\n')
3075
self.outf.write(fp + '\0')
3078
self.outf.write(fid)
3079
self.outf.write('\0')
3087
self.outf.write('%-50s %s\n' % (outstring, my_id))
2506
note("Ignoring files outside view. View is %s" % view_str)
2510
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2511
from_dir=relpath, recursive=recursive):
2512
# Apply additional masking
2513
if not all and not selection[fc]:
2515
if kind is not None and fkind != kind:
2520
fullpath = osutils.pathjoin(relpath, fp)
2523
views.check_path_in_view(tree, fullpath)
2524
except errors.FileOutsideView:
2529
fp = osutils.pathjoin(prefix, fp)
2530
kindch = entry.kind_character()
2531
outstring = fp + kindch
2532
ui.ui_factory.clear_term()
2534
outstring = '%-8s %s' % (fc, outstring)
2535
if show_ids and fid is not None:
2536
outstring = "%-50s %s" % (outstring, fid)
3089
2537
self.outf.write(outstring + '\n')
2539
self.outf.write(fp + '\0')
2542
self.outf.write(fid)
2543
self.outf.write('\0')
2551
self.outf.write('%-50s %s\n' % (outstring, my_id))
2553
self.outf.write(outstring + '\n')
3092
2558
class cmd_unknowns(Command):
3093
__doc__ = """List unknown files.
2559
"""List unknown files.
3097
2563
_see_also = ['ls']
3098
takes_options = ['directory']
3100
2565
@display_command
3101
def run(self, directory=u'.'):
3102
for f in WorkingTree.open_containing(directory)[0].unknowns():
2567
for f in WorkingTree.open_containing(u'.')[0].unknowns():
3103
2568
self.outf.write(osutils.quotefn(f) + '\n')
3106
2571
class cmd_ignore(Command):
3107
__doc__ = """Ignore specified files or patterns.
2572
"""Ignore specified files or patterns.
3109
2574
See ``bzr help patterns`` for details on the syntax of patterns.
3111
If a .bzrignore file does not exist, the ignore command
3112
will create one and add the specified files or patterns to the newly
3113
created file. The ignore command will also automatically add the
3114
.bzrignore file to be versioned. Creating a .bzrignore file without
3115
the use of the ignore command will require an explicit add command.
3117
2576
To remove patterns from the ignore list, edit the .bzrignore file.
3118
2577
After adding, editing or deleting that file either indirectly by
3119
2578
using this command or directly by using an editor, be sure to commit
3122
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
3123
the global ignore file can be found in the application data directory as
3124
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
3125
Global ignores are not touched by this command. The global ignore file
3126
can be edited directly using an editor.
3128
Patterns prefixed with '!' are exceptions to ignore patterns and take
3129
precedence over regular ignores. Such exceptions are used to specify
3130
files that should be versioned which would otherwise be ignored.
3132
Patterns prefixed with '!!' act as regular ignore patterns, but have
3133
precedence over the '!' exception patterns.
3137
* Ignore patterns containing shell wildcards must be quoted from
3140
* Ignore patterns starting with "#" act as comments in the ignore file.
3141
To ignore patterns that begin with that character, use the "RE:" prefix.
2581
Note: ignore patterns containing shell wildcards must be quoted from
3144
2585
Ignore the top level Makefile::
3146
2587
bzr ignore ./Makefile
3148
Ignore .class files in all directories...::
2589
Ignore class files in all directories::
3150
2591
bzr ignore "*.class"
3152
...but do not ignore "special.class"::
3154
bzr ignore "!special.class"
3156
Ignore files whose name begins with the "#" character::
3160
2593
Ignore .o files under the lib directory::
3162
2595
bzr ignore "lib/**/*.o"
3168
2601
Ignore everything but the "debian" toplevel directory::
3170
2603
bzr ignore "RE:(?!debian/).*"
3172
Ignore everything except the "local" toplevel directory,
3173
but always ignore autosave files ending in ~, even under local/::
3176
bzr ignore "!./local"
3180
2606
_see_also = ['status', 'ignored', 'patterns']
3181
2607
takes_args = ['name_pattern*']
3182
takes_options = ['directory',
3183
Option('default-rules',
3184
help='Display the default ignore rules that bzr uses.')
2609
Option('old-default-rules',
2610
help='Write out the ignore rules bzr < 0.9 always used.')
3187
def run(self, name_pattern_list=None, default_rules=None,
2613
def run(self, name_pattern_list=None, old_default_rules=None):
3189
2614
from bzrlib import ignores
3190
if default_rules is not None:
3191
# dump the default rules and exit
3192
for pattern in ignores.USER_DEFAULTS:
3193
self.outf.write("%s\n" % pattern)
2615
if old_default_rules is not None:
2616
# dump the rules and exit
2617
for pattern in ignores.OLD_DEFAULTS:
3195
2620
if not name_pattern_list:
3196
raise errors.BzrCommandError(gettext("ignore requires at least one "
3197
"NAME_PATTERN or --default-rules."))
2621
raise errors.BzrCommandError("ignore requires at least one "
2622
"NAME_PATTERN or --old-default-rules")
3198
2623
name_pattern_list = [globbing.normalize_pattern(p)
3199
2624
for p in name_pattern_list]
3201
bad_patterns_count = 0
3202
for p in name_pattern_list:
3203
if not globbing.Globster.is_pattern_valid(p):
3204
bad_patterns_count += 1
3205
bad_patterns += ('\n %s' % p)
3207
msg = (ngettext('Invalid ignore pattern found. %s',
3208
'Invalid ignore patterns found. %s',
3209
bad_patterns_count) % bad_patterns)
3210
ui.ui_factory.show_error(msg)
3211
raise errors.InvalidPattern('')
3212
2625
for name_pattern in name_pattern_list:
3213
2626
if (name_pattern[0] == '/' or
3214
2627
(len(name_pattern) > 1 and name_pattern[1] == ':')):
3215
raise errors.BzrCommandError(gettext(
3216
"NAME_PATTERN should not be an absolute path"))
3217
tree, relpath = WorkingTree.open_containing(directory)
2628
raise errors.BzrCommandError(
2629
"NAME_PATTERN should not be an absolute path")
2630
tree, relpath = WorkingTree.open_containing(u'.')
3218
2631
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3219
2632
ignored = globbing.Globster(name_pattern_list)
3221
self.add_cleanup(tree.lock_read().unlock)
3222
2635
for entry in tree.list_files():
3224
2637
if id is not None:
3225
2638
filename = entry[0]
3226
2639
if ignored.match(filename):
3227
matches.append(filename)
2640
matches.append(filename.encode('utf-8'))
3228
2642
if len(matches) > 0:
3229
self.outf.write(gettext("Warning: the following files are version "
3230
"controlled and match your ignore pattern:\n%s"
3231
"\nThese files will continue to be version controlled"
3232
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2643
print "Warning: the following files are version controlled and" \
2644
" match your ignore pattern:\n%s" \
2645
"\nThese files will continue to be version controlled" \
2646
" unless you 'bzr remove' them." % ("\n".join(matches),)
3235
2649
class cmd_ignored(Command):
3236
__doc__ = """List ignored files and the patterns that matched them.
2650
"""List ignored files and the patterns that matched them.
3238
2652
List all the ignored files and the ignore pattern that caused the file to
3246
2660
encoding_type = 'replace'
3247
2661
_see_also = ['ignore', 'ls']
3248
takes_options = ['directory']
3250
2663
@display_command
3251
def run(self, directory=u'.'):
3252
tree = WorkingTree.open_containing(directory)[0]
3253
self.add_cleanup(tree.lock_read().unlock)
3254
for path, file_class, kind, file_id, entry in tree.list_files():
3255
if file_class != 'I':
3257
## XXX: Slightly inefficient since this was already calculated
3258
pat = tree.is_ignored(path)
3259
self.outf.write('%-50s %s\n' % (path, pat))
2665
tree = WorkingTree.open_containing(u'.')[0]
2668
for path, file_class, kind, file_id, entry in tree.list_files():
2669
if file_class != 'I':
2671
## XXX: Slightly inefficient since this was already calculated
2672
pat = tree.is_ignored(path)
2673
self.outf.write('%-50s %s\n' % (path, pat))
3262
2678
class cmd_lookup_revision(Command):
3263
__doc__ = """Lookup the revision-id from a revision-number
2679
"""Lookup the revision-id from a revision-number
3266
2682
bzr lookup-revision 33
3269
2685
takes_args = ['revno']
3270
takes_options = ['directory']
3272
2687
@display_command
3273
def run(self, revno, directory=u'.'):
2688
def run(self, revno):
3275
2690
revno = int(revno)
3276
2691
except ValueError:
3277
raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3279
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3280
self.outf.write("%s\n" % revid)
2692
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2694
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
3283
2697
class cmd_export(Command):
3284
__doc__ = """Export current or past revision to a destination directory or archive.
2698
"""Export current or past revision to a destination directory or archive.
3286
2700
If no revision is specified this exports the last committed revision.
3322
2735
help="Name of the root directory inside the exported file."),
3323
Option('per-file-timestamps',
3324
help='Set modification time of files to that of the last '
3325
'revision in which it was changed.'),
3326
Option('uncommitted',
3327
help='Export the working tree contents rather than that of the '
3330
2737
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3331
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2738
root=None, filters=False):
3333
2739
from bzrlib.export import export
3335
2741
if branch_or_subdir is None:
3336
branch_or_subdir = directory
3338
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3340
if tree is not None:
3341
self.add_cleanup(tree.lock_read().unlock)
3345
raise errors.BzrCommandError(
3346
gettext("--uncommitted requires a working tree"))
2742
tree = WorkingTree.open_containing(u'.')[0]
3349
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2746
b, subdir = Branch.open_containing(branch_or_subdir)
2749
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3351
export(export_tree, dest, format, root, subdir, filtered=filters,
3352
per_file_timestamps=per_file_timestamps)
2751
export(rev_tree, dest, format, root, subdir, filtered=filters)
3353
2752
except errors.NoSuchExportFormat, e:
3354
raise errors.BzrCommandError(
3355
gettext('Unsupported export format: %s') % e.format)
2753
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3358
2756
class cmd_cat(Command):
3359
__doc__ = """Write the contents of a file as of a given revision to standard output.
2757
"""Write the contents of a file as of a given revision to standard output.
3361
2759
If no revision is nominated, the last revision is used.
3377
2775
@display_command
3378
2776
def run(self, filename, revision=None, name_from_revision=False,
3379
filters=False, directory=None):
3380
2778
if revision is not None and len(revision) != 1:
3381
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3382
" one revision specifier"))
2779
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2780
" one revision specifier")
3383
2781
tree, branch, relpath = \
3384
_open_directory_or_containing_tree_or_branch(filename, directory)
3385
self.add_cleanup(branch.lock_read().unlock)
3386
return self._run(tree, branch, relpath, filename, revision,
3387
name_from_revision, filters)
2782
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2785
return self._run(tree, branch, relpath, filename, revision,
2786
name_from_revision, filters)
3389
2790
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
3391
2792
if tree is None:
3392
2793
tree = b.basis_tree()
3393
2794
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3394
self.add_cleanup(rev_tree.lock_read().unlock)
3396
2796
old_file_id = rev_tree.path2id(relpath)
3398
# TODO: Split out this code to something that generically finds the
3399
# best id for a path across one or more trees; it's like
3400
# find_ids_across_trees but restricted to find just one. -- mbp
3402
2798
if name_from_revision:
3403
2799
# Try in revision if requested
3404
2800
if old_file_id is None:
3405
raise errors.BzrCommandError(gettext(
3406
"{0!r} is not present in revision {1}").format(
2801
raise errors.BzrCommandError(
2802
"%r is not present in revision %s" % (
3407
2803
filename, rev_tree.get_revision_id()))
3409
actual_file_id = old_file_id
2805
content = rev_tree.get_file_text(old_file_id)
3411
2807
cur_file_id = tree.path2id(relpath)
3412
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3413
actual_file_id = cur_file_id
3414
elif old_file_id is not None:
3415
actual_file_id = old_file_id
3417
raise errors.BzrCommandError(gettext(
3418
"{0!r} is not present in revision {1}").format(
2809
if cur_file_id is not None:
2810
# Then try with the actual file id
2812
content = rev_tree.get_file_text(cur_file_id)
2814
except errors.NoSuchId:
2815
# The actual file id didn't exist at that time
2817
if not found and old_file_id is not None:
2818
# Finally try with the old file id
2819
content = rev_tree.get_file_text(old_file_id)
2822
# Can't be found anywhere
2823
raise errors.BzrCommandError(
2824
"%r is not present in revision %s" % (
3419
2825
filename, rev_tree.get_revision_id()))
3421
from bzrlib.filter_tree import ContentFilterTree
3422
filter_tree = ContentFilterTree(rev_tree,
3423
rev_tree._content_filter_stack)
3424
content = filter_tree.get_file_text(actual_file_id)
2827
from bzrlib.filters import (
2828
ContentFilterContext,
2829
filtered_output_bytes,
2831
filters = rev_tree._content_filter_stack(relpath)
2832
chunks = content.splitlines(True)
2833
content = filtered_output_bytes(chunks, filters,
2834
ContentFilterContext(relpath, rev_tree))
2835
self.outf.writelines(content)
3426
content = rev_tree.get_file_text(actual_file_id)
3428
self.outf.write(content)
2837
self.outf.write(content)
3431
2840
class cmd_local_time_offset(Command):
3432
__doc__ = """Show the offset in seconds from GMT to local time."""
2841
"""Show the offset in seconds from GMT to local time."""
3434
2843
@display_command
3436
self.outf.write("%s\n" % osutils.local_time_offset())
2845
print osutils.local_time_offset()
3440
2849
class cmd_commit(Command):
3441
__doc__ = """Commit changes into a new revision.
2850
"""Commit changes into a new revision.
3443
2852
An explanatory message needs to be given for each commit. This is
3444
2853
often done by using the --message option (getting the message from the
3527
2958
"the master branch until a normal commit "
3528
2959
"is performed."
3530
Option('show-diff', short_name='p',
3531
help='When no message is supplied, show the diff along'
3532
' with the status summary in the message editor.'),
3534
help='When committing to a foreign version control '
3535
'system do not push data that can not be natively '
2962
help='When no message is supplied, show the diff along'
2963
' with the status summary in the message editor.'),
3538
2965
aliases = ['ci', 'checkin']
3540
2967
def _iter_bug_fix_urls(self, fixes, branch):
3541
default_bugtracker = None
3542
2968
# Configure the properties for bug fixing attributes.
3543
2969
for fixed_bug in fixes:
3544
2970
tokens = fixed_bug.split(':')
3545
if len(tokens) == 1:
3546
if default_bugtracker is None:
3547
branch_config = branch.get_config_stack()
3548
default_bugtracker = branch_config.get(
3550
if default_bugtracker is None:
3551
raise errors.BzrCommandError(gettext(
3552
"No tracker specified for bug %s. Use the form "
3553
"'tracker:id' or specify a default bug tracker "
3554
"using the `bugtracker` option.\nSee "
3555
"\"bzr help bugs\" for more information on this "
3556
"feature. Commit refused.") % fixed_bug)
3557
tag = default_bugtracker
3559
elif len(tokens) != 2:
3560
raise errors.BzrCommandError(gettext(
2971
if len(tokens) != 2:
2972
raise errors.BzrCommandError(
3561
2973
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3562
2974
"See \"bzr help bugs\" for more information on this "
3563
"feature.\nCommit refused.") % fixed_bug)
3565
tag, bug_id = tokens
2975
"feature.\nCommit refused." % fixed_bug)
2976
tag, bug_id = tokens
3567
2978
yield bugtracker.get_bug_url(tag, branch, bug_id)
3568
2979
except errors.UnknownBugTrackerAbbreviation:
3569
raise errors.BzrCommandError(gettext(
3570
'Unrecognized bug %s. Commit refused.') % fixed_bug)
2980
raise errors.BzrCommandError(
2981
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3571
2982
except errors.MalformedBugIdentifier, e:
3572
raise errors.BzrCommandError(gettext(
3573
"%s\nCommit refused.") % (str(e),))
2983
raise errors.BzrCommandError(
2984
"%s\nCommit refused." % (str(e),))
3575
2986
def run(self, message=None, file=None, verbose=False, selected_list=None,
3576
2987
unchanged=False, strict=False, local=False, fixes=None,
3577
author=None, show_diff=False, exclude=None, commit_time=None,
2988
author=None, show_diff=False, exclude=None):
3579
2989
from bzrlib.errors import (
3580
2990
PointlessCommit,
3581
2991
ConflictsInTree,
3615
3022
if local and not tree.branch.get_bound_location():
3616
3023
raise errors.LocalRequiresBoundBranch()
3618
if message is not None:
3620
file_exists = osutils.lexists(message)
3621
except UnicodeError:
3622
# The commit message contains unicode characters that can't be
3623
# represented in the filesystem encoding, so that can't be a
3628
'The commit message is a file name: "%(f)s".\n'
3629
'(use --file "%(f)s" to take commit message from that file)'
3631
ui.ui_factory.show_warning(warning_msg)
3633
message = message.replace('\r\n', '\n')
3634
message = message.replace('\r', '\n')
3636
raise errors.BzrCommandError(gettext(
3637
"please specify either --message or --file"))
3639
3025
def get_message(commit_obj):
3640
3026
"""Callback to get commit message"""
3644
my_message = f.read().decode(osutils.get_user_encoding())
3647
elif message is not None:
3648
my_message = message
3650
# No message supplied: make one up.
3651
# text is the status of the tree
3652
text = make_commit_message_template_encoded(tree,
3027
my_message = message
3028
if my_message is None and not file:
3029
t = make_commit_message_template_encoded(tree,
3653
3030
selected_list, diff=show_diff,
3654
3031
output_encoding=osutils.get_user_encoding())
3655
# start_message is the template generated from hooks
3656
# XXX: Warning - looks like hooks return unicode,
3657
# make_commit_message_template_encoded returns user encoding.
3658
# We probably want to be using edit_commit_message instead to
3660
my_message = set_commit_message(commit_obj)
3661
if my_message is None:
3662
start_message = generate_commit_message_template(commit_obj)
3663
my_message = edit_commit_message_encoded(text,
3664
start_message=start_message)
3665
if my_message is None:
3666
raise errors.BzrCommandError(gettext("please specify a commit"
3667
" message with either --message or --file"))
3668
if my_message == "":
3669
raise errors.BzrCommandError(gettext("Empty commit message specified."
3670
" Please specify a commit message with either"
3671
" --message or --file or leave a blank message"
3672
" with --message \"\"."))
3032
start_message = generate_commit_message_template(commit_obj)
3033
my_message = edit_commit_message_encoded(t,
3034
start_message=start_message)
3035
if my_message is None:
3036
raise errors.BzrCommandError("please specify a commit"
3037
" message with either --message or --file")
3038
elif my_message and file:
3039
raise errors.BzrCommandError(
3040
"please specify either --message or --file")
3042
my_message = codecs.open(file, 'rt',
3043
osutils.get_user_encoding()).read()
3044
if my_message == "":
3045
raise errors.BzrCommandError("empty commit message specified")
3673
3046
return my_message
3675
3048
# The API permits a commit with a filter of [] to mean 'select nothing'
3681
3054
specific_files=selected_list,
3682
3055
allow_pointless=unchanged, strict=strict, local=local,
3683
3056
reporter=None, verbose=verbose, revprops=properties,
3684
authors=author, timestamp=commit_stamp,
3686
exclude=tree.safe_relpath_files(exclude),
3058
exclude=safe_relpath_files(tree, exclude))
3688
3059
except PointlessCommit:
3689
raise errors.BzrCommandError(gettext("No changes to commit."
3690
" Please 'bzr add' the files you want to commit, or use"
3691
" --unchanged to force an empty commit."))
3060
# FIXME: This should really happen before the file is read in;
3061
# perhaps prepare the commit; get the message; then actually commit
3062
raise errors.BzrCommandError("No changes to commit."
3063
" Use --unchanged to commit anyhow.")
3692
3064
except ConflictsInTree:
3693
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3065
raise errors.BzrCommandError('Conflicts detected in working '
3694
3066
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3696
3068
except StrictCommitFailed:
3697
raise errors.BzrCommandError(gettext("Commit refused because there are"
3698
" unknown files in the working tree."))
3069
raise errors.BzrCommandError("Commit refused because there are"
3070
" unknown files in the working tree.")
3699
3071
except errors.BoundBranchOutOfDate, e:
3700
e.extra_help = (gettext("\n"
3701
'To commit to master branch, run update and then commit.\n'
3702
'You can also pass --local to commit to continue working '
3072
raise errors.BzrCommandError(str(e) + "\n"
3073
'To commit to master branch, run update and then commit.\n'
3074
'You can also pass --local to commit to continue working '
3707
3078
class cmd_check(Command):
3708
__doc__ = """Validate working tree structure, branch consistency and repository history.
3079
"""Validate working tree structure, branch consistency and repository history.
3710
3081
This command checks various invariants about branch and repository storage
3711
3082
to detect data corruption or bzr bugs.
3777
3148
class cmd_upgrade(Command):
3778
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3780
When the default format has changed after a major new release of
3781
Bazaar, you may be informed during certain operations that you
3782
should upgrade. Upgrading to a newer format may improve performance
3783
or make new features available. It may however limit interoperability
3784
with older repositories or with older versions of Bazaar.
3786
If you wish to upgrade to a particular format rather than the
3787
current default, that can be specified using the --format option.
3788
As a consequence, you can use the upgrade command this way to
3789
"downgrade" to an earlier format, though some conversions are
3790
a one way process (e.g. changing from the 1.x default to the
3791
2.x default) so downgrading is not always possible.
3793
A backup.bzr.~#~ directory is created at the start of the conversion
3794
process (where # is a number). By default, this is left there on
3795
completion. If the conversion fails, delete the new .bzr directory
3796
and rename this one back in its place. Use the --clean option to ask
3797
for the backup.bzr directory to be removed on successful conversion.
3798
Alternatively, you can delete it by hand if everything looks good
3801
If the location given is a shared repository, dependent branches
3802
are also converted provided the repository converts successfully.
3803
If the conversion of a branch fails, remaining branches are still
3806
For more information on upgrades, see the Bazaar Upgrade Guide,
3807
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3149
"""Upgrade branch storage to current format.
3151
The check command or bzr developers may sometimes advise you to run
3152
this command. When the default format has changed you may also be warned
3153
during other operations to upgrade.
3810
_see_also = ['check', 'reconcile', 'formats']
3156
_see_also = ['check']
3811
3157
takes_args = ['url?']
3812
3158
takes_options = [
3813
RegistryOption('format',
3814
help='Upgrade to a specific format. See "bzr help'
3815
' formats" for details.',
3816
lazy_registry=('bzrlib.controldir', 'format_registry'),
3817
converter=lambda name: controldir.format_registry.make_bzrdir(name),
3818
value_switches=True, title='Branch format'),
3820
help='Remove the backup.bzr directory if successful.'),
3822
help="Show what would be done, but don't actually do anything."),
3159
RegistryOption('format',
3160
help='Upgrade to a specific format. See "bzr help'
3161
' formats" for details.',
3162
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3163
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3164
value_switches=True, title='Branch format'),
3825
def run(self, url='.', format=None, clean=False, dry_run=False):
3167
def run(self, url='.', format=None):
3826
3168
from bzrlib.upgrade import upgrade
3827
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3829
if len(exceptions) == 1:
3830
# Compatibility with historical behavior
3169
upgrade(url, format)
3836
3172
class cmd_whoami(Command):
3837
__doc__ = """Show or set bzr user id.
3173
"""Show or set bzr user id.
3840
3176
Show the email of the current user::
3856
3191
encoding_type = 'replace'
3858
3193
@display_command
3859
def run(self, email=False, branch=False, name=None, directory=None):
3194
def run(self, email=False, branch=False, name=None):
3860
3195
if name is None:
3861
if directory is None:
3862
# use branch if we're inside one; otherwise global config
3864
c = Branch.open_containing(u'.')[0].get_config_stack()
3865
except errors.NotBranchError:
3866
c = _mod_config.GlobalStack()
3868
c = Branch.open(directory).get_config_stack()
3869
identity = c.get('email')
3196
# use branch if we're inside one; otherwise global config
3198
c = Branch.open_containing('.')[0].get_config()
3199
except errors.NotBranchError:
3200
c = config.GlobalConfig()
3871
self.outf.write(_mod_config.extract_email_address(identity)
3202
self.outf.write(c.user_email() + '\n')
3874
self.outf.write(identity + '\n')
3204
self.outf.write(c.username() + '\n')
3878
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3881
3207
# display a warning if an email address isn't included in the given name.
3883
_mod_config.extract_email_address(name)
3209
config.extract_email_address(name)
3884
3210
except errors.NoEmailInUsername, e:
3885
3211
warning('"%s" does not seem to contain an email address. '
3886
3212
'This is allowed, but not recommended.', name)
3888
3214
# use global config unless --branch given
3890
if directory is None:
3891
c = Branch.open_containing(u'.')[0].get_config_stack()
3893
b = Branch.open(directory)
3894
self.add_cleanup(b.lock_write().unlock)
3895
c = b.get_config_stack()
3216
c = Branch.open_containing('.')[0].get_config()
3897
c = _mod_config.GlobalStack()
3898
c.set('email', name)
3218
c = config.GlobalConfig()
3219
c.set_user_option('email', name)
3901
3222
class cmd_nick(Command):
3902
__doc__ = """Print or set the branch nickname.
3223
"""Print or set the branch nickname.
3904
If unset, the colocated branch name is used for colocated branches, and
3905
the branch directory name is used for other branches. To print the
3906
current nickname, execute with no argument.
3225
If unset, the tree root directory name is used as the nickname.
3226
To print the current nickname, execute with no argument.
3908
3228
Bound branches use the nickname of its master branch unless it is set
4122
3432
def run(self, testspecs_list=None, verbose=False, one=False,
4123
3433
transport=None, benchmark=None,
3434
lsprof_timed=None, cache_dir=None,
4125
3435
first=False, list_only=False,
4126
3436
randomize=None, exclude=None, strict=False,
4127
3437
load_list=None, debugflag=None, starting_with=None, subunit=False,
4128
parallel=None, lsprof_tests=False,
4131
# During selftest, disallow proxying, as it can cause severe
4132
# performance penalties and is only needed for thread
4133
# safety. The selftest command is assumed to not use threads
4134
# too heavily. The call should be as early as possible, as
4135
# error reporting for past duplicate imports won't have useful
4137
lazy_import.disallow_proxying()
4139
from bzrlib import tests
3439
from bzrlib.tests import selftest
3440
import bzrlib.benchmarks as benchmarks
3441
from bzrlib.benchmarks import tree_creator
3443
# Make deprecation warnings visible, unless -Werror is set
3444
symbol_versioning.activate_deprecation_warnings(override=False)
3446
if cache_dir is not None:
3447
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
4141
3448
if testspecs_list is not None:
4142
3449
pattern = '|'.join(testspecs_list)
4147
3454
from bzrlib.tests import SubUnitBzrRunner
4148
3455
except ImportError:
4149
raise errors.BzrCommandError(gettext("subunit not available. subunit "
4150
"needs to be installed to use --subunit."))
3456
raise errors.BzrCommandError("subunit not available. subunit "
3457
"needs to be installed to use --subunit.")
4151
3458
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
4152
# On Windows, disable automatic conversion of '\n' to '\r\n' in
4153
# stdout, which would corrupt the subunit stream.
4154
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
4155
# following code can be deleted when it's sufficiently deployed
4156
# -- vila/mgz 20100514
4157
if (sys.platform == "win32"
4158
and getattr(sys.stdout, 'fileno', None) is not None):
4160
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4162
3460
self.additional_selftest_args.setdefault(
4163
3461
'suite_decorators', []).append(parallel)
4165
raise errors.BzrCommandError(gettext(
4166
"--benchmark is no longer supported from bzr 2.2; "
4167
"use bzr-usertest instead"))
4168
test_suite_factory = None
4170
exclude_pattern = None
3463
test_suite_factory = benchmarks.test_suite
3464
# Unless user explicitly asks for quiet, be verbose in benchmarks
3465
verbose = not is_quiet()
3466
# TODO: should possibly lock the history file...
3467
benchfile = open(".perf_history", "at", buffering=1)
4172
exclude_pattern = '(' + '|'.join(exclude) + ')'
4174
self._disable_fsync()
4175
selftest_kwargs = {"verbose": verbose,
4177
"stop_on_failure": one,
4178
"transport": transport,
4179
"test_suite_factory": test_suite_factory,
4180
"lsprof_timed": lsprof_timed,
4181
"lsprof_tests": lsprof_tests,
4182
"matching_tests_first": first,
4183
"list_only": list_only,
4184
"random_seed": randomize,
4185
"exclude_pattern": exclude_pattern,
4187
"load_list": load_list,
4188
"debug_flags": debugflag,
4189
"starting_with": starting_with
4191
selftest_kwargs.update(self.additional_selftest_args)
4193
# Make deprecation warnings visible, unless -Werror is set
4194
cleanup = symbol_versioning.activate_deprecation_warnings(
3469
test_suite_factory = None
4197
result = tests.selftest(**selftest_kwargs)
3472
selftest_kwargs = {"verbose": verbose,
3474
"stop_on_failure": one,
3475
"transport": transport,
3476
"test_suite_factory": test_suite_factory,
3477
"lsprof_timed": lsprof_timed,
3478
"bench_history": benchfile,
3479
"matching_tests_first": first,
3480
"list_only": list_only,
3481
"random_seed": randomize,
3482
"exclude_pattern": exclude,
3484
"load_list": load_list,
3485
"debug_flags": debugflag,
3486
"starting_with": starting_with
3488
selftest_kwargs.update(self.additional_selftest_args)
3489
result = selftest(**selftest_kwargs)
3491
if benchfile is not None:
4200
3493
return int(not result)
4202
def _disable_fsync(self):
4203
"""Change the 'os' functionality to not synchronize."""
4204
self._orig_fsync = getattr(os, 'fsync', None)
4205
if self._orig_fsync is not None:
4206
os.fsync = lambda filedes: None
4207
self._orig_fdatasync = getattr(os, 'fdatasync', None)
4208
if self._orig_fdatasync is not None:
4209
os.fdatasync = lambda filedes: None
4212
3496
class cmd_version(Command):
4213
__doc__ = """Show version of bzr."""
3497
"""Show version of bzr."""
4215
3499
encoding_type = 'replace'
4216
3500
takes_options = [
4250
3534
branch1 = Branch.open_containing(branch)[0]
4251
3535
branch2 = Branch.open_containing(other)[0]
4252
self.add_cleanup(branch1.lock_read().unlock)
4253
self.add_cleanup(branch2.lock_read().unlock)
4254
last1 = ensure_null(branch1.last_revision())
4255
last2 = ensure_null(branch2.last_revision())
4257
graph = branch1.repository.get_graph(branch2.repository)
4258
base_rev_id = graph.find_unique_lca(last1, last2)
4260
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3540
last1 = ensure_null(branch1.last_revision())
3541
last2 = ensure_null(branch2.last_revision())
3543
graph = branch1.repository.get_graph(branch2.repository)
3544
base_rev_id = graph.find_unique_lca(last1, last2)
3546
print 'merge base is revision %s' % base_rev_id
4263
3553
class cmd_merge(Command):
4264
__doc__ = """Perform a three-way merge.
3554
"""Perform a three-way merge.
4266
3556
The source of the merge can be specified either in the form of a branch,
4267
3557
or in the form of a path to a file containing a merge directive generated
4268
3558
with bzr send. If neither is specified, the default is the upstream branch
4269
or the branch most recently merged using --remember. The source of the
4270
merge may also be specified in the form of a path to a file in another
4271
branch: in this case, only the modifications to that file are merged into
4272
the current working tree.
4274
When merging from a branch, by default bzr will try to merge in all new
4275
work from the other branch, automatically determining an appropriate base
4276
revision. If this fails, you may need to give an explicit base.
4278
To pick a different ending revision, pass "--revision OTHER". bzr will
4279
try to merge in all new work up to and including revision OTHER.
4281
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4282
through OTHER, excluding BASE but including OTHER, will be merged. If this
4283
causes some revisions to be skipped, i.e. if the destination branch does
4284
not already contain revision BASE, such a merge is commonly referred to as
4285
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4286
cherrypicks. The changes look like a normal commit, and the history of the
4287
changes from the other branch is not stored in the commit.
4289
Revision numbers are always relative to the source branch.
3559
or the branch most recently merged using --remember.
3561
When merging a branch, by default the tip will be merged. To pick a different
3562
revision, pass --revision. If you specify two values, the first will be used as
3563
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3564
available revisions, like this is commonly referred to as "cherrypicking".
3566
Revision numbers are always relative to the branch being merged.
3568
By default, bzr will try to merge in all new work from the other
3569
branch, automatically determining an appropriate base. If this
3570
fails, you may need to give an explicit base.
4291
3572
Merge will do its best to combine the changes in two branches, but there
4292
3573
are some kinds of problems only a human can fix. When it encounters those,
4293
3574
it will mark a conflict. A conflict means that you need to fix something,
4294
before you can commit.
3575
before you should commit.
4296
3577
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
4298
If there is no default branch set, the first merge will set it (use
4299
--no-remember to avoid setting it). After that, you can omit the branch
4300
to use the default. To change the default, use --remember. The value will
4301
only be saved if the remote location can be accessed.
3579
If there is no default branch set, the first merge will set it. After
3580
that, you can omit the branch to use the default. To change the
3581
default, use --remember. The value will only be saved if the remote
3582
location can be accessed.
4303
3584
The results of the merge are placed into the destination working
4304
3585
directory, where they can be reviewed (with bzr diff), tested, and then
4305
3586
committed to record the result of the merge.
4307
3588
merge refuses to run if there are any uncommitted changes, unless
4308
--force is given. If --force is given, then the changes from the source
4309
will be merged with the current working tree, including any uncommitted
4310
changes in the tree. The --force option can also be used to create a
4311
merge revision which has more than two parents.
4313
If one would like to merge changes from the working tree of the other
4314
branch without merging any committed revisions, the --uncommitted option
4317
3591
To select only some changes to merge, use "merge -i", which will prompt
4318
3592
you to apply each diff hunk and file change, similar to "shelve".
4321
To merge all new revisions from bzr.dev::
3595
To merge the latest revision from bzr.dev::
4323
3597
bzr merge ../bzr.dev
4386
3656
allow_pending = True
4387
3657
verified = 'inapplicable'
4389
3658
tree = WorkingTree.open_containing(directory)[0]
4390
if tree.branch.revno() == 0:
4391
raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4392
'https://bugs.launchpad.net/bzr/+bug/308562'))
3660
# die as quickly as possible if there are uncommitted changes
4395
3662
basis_tree = tree.revision_tree(tree.last_revision())
4396
3663
except errors.NoSuchRevision:
4397
3664
basis_tree = tree.basis_tree()
4399
# die as quickly as possible if there are uncommitted changes
4401
if tree.has_changes():
3666
if tree.has_changes(basis_tree):
4402
3667
raise errors.UncommittedChanges(tree)
4404
3669
view_info = _get_view_info_for_change_reporter(tree)
4405
3670
change_reporter = delta._ChangeReporter(
4406
3671
unversioned_filter=tree.is_ignored, view_info=view_info)
4407
pb = ui.ui_factory.nested_progress_bar()
4408
self.add_cleanup(pb.finished)
4409
self.add_cleanup(tree.lock_write().unlock)
4410
if location is not None:
4412
mergeable = bundle.read_mergeable_from_url(location,
4413
possible_transports=possible_transports)
4414
except errors.NotABundle:
3674
pb = ui.ui_factory.nested_progress_bar()
3675
cleanups.append(pb.finished)
3677
cleanups.append(tree.unlock)
3678
if location is not None:
3680
mergeable = bundle.read_mergeable_from_url(location,
3681
possible_transports=possible_transports)
3682
except errors.NotABundle:
3686
raise errors.BzrCommandError('Cannot use --uncommitted'
3687
' with bundles or merge directives.')
3689
if revision is not None:
3690
raise errors.BzrCommandError(
3691
'Cannot use -r with merge directives or bundles')
3692
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3695
if merger is None and uncommitted:
3696
if revision is not None and len(revision) > 0:
3697
raise errors.BzrCommandError('Cannot use --uncommitted and'
3698
' --revision at the same time.')
3699
merger = self.get_merger_from_uncommitted(tree, location, pb,
3701
allow_pending = False
3704
merger, allow_pending = self._get_merger_from_branch(tree,
3705
location, revision, remember, possible_transports, pb)
3707
merger.merge_type = merge_type
3708
merger.reprocess = reprocess
3709
merger.show_base = show_base
3710
self.sanity_check_merger(merger)
3711
if (merger.base_rev_id == merger.other_rev_id and
3712
merger.other_rev_id is not None):
3713
note('Nothing to do.')
3716
if merger.interesting_files is not None:
3717
raise errors.BzrCommandError('Cannot pull individual files')
3718
if (merger.base_rev_id == tree.last_revision()):
3719
result = tree.pull(merger.other_branch, False,
3720
merger.other_rev_id)
3721
result.report(self.outf)
3723
merger.check_basis(False)
3725
return self._do_preview(merger, cleanups)
3727
return self._do_interactive(merger, cleanups)
4418
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4419
' with bundles or merge directives.'))
4421
if revision is not None:
4422
raise errors.BzrCommandError(gettext(
4423
'Cannot use -r with merge directives or bundles'))
4424
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4427
if merger is None and uncommitted:
4428
if revision is not None and len(revision) > 0:
4429
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4430
' --revision at the same time.'))
4431
merger = self.get_merger_from_uncommitted(tree, location, None)
4432
allow_pending = False
4435
merger, allow_pending = self._get_merger_from_branch(tree,
4436
location, revision, remember, possible_transports, None)
4438
merger.merge_type = merge_type
4439
merger.reprocess = reprocess
4440
merger.show_base = show_base
4441
self.sanity_check_merger(merger)
4442
if (merger.base_rev_id == merger.other_rev_id and
4443
merger.other_rev_id is not None):
4444
# check if location is a nonexistent file (and not a branch) to
4445
# disambiguate the 'Nothing to do'
4446
if merger.interesting_files:
4447
if not merger.other_tree.has_filename(
4448
merger.interesting_files[0]):
4449
note(gettext("merger: ") + str(merger))
4450
raise errors.PathsDoNotExist([location])
4451
note(gettext('Nothing to do.'))
4453
if pull and not preview:
4454
if merger.interesting_files is not None:
4455
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4456
if (merger.base_rev_id == tree.last_revision()):
4457
result = tree.pull(merger.other_branch, False,
4458
merger.other_rev_id)
4459
result.report(self.outf)
4461
if merger.this_basis is None:
4462
raise errors.BzrCommandError(gettext(
4463
"This branch has no commits."
4464
" (perhaps you would prefer 'bzr pull')"))
4466
return self._do_preview(merger)
4468
return self._do_interactive(merger)
4470
return self._do_merge(merger, change_reporter, allow_pending,
4473
def _get_preview(self, merger):
3729
return self._do_merge(merger, change_reporter, allow_pending,
3732
for cleanup in reversed(cleanups):
3735
def _get_preview(self, merger, cleanups):
4474
3736
tree_merger = merger.make_merger()
4475
3737
tt = tree_merger.make_preview_transform()
4476
self.add_cleanup(tt.finalize)
3738
cleanups.append(tt.finalize)
4477
3739
result_tree = tt.get_preview_tree()
4478
3740
return result_tree
4480
def _do_preview(self, merger):
3742
def _do_preview(self, merger, cleanups):
4481
3743
from bzrlib.diff import show_diff_trees
4482
result_tree = self._get_preview(merger)
4483
path_encoding = osutils.get_diff_header_encoding()
3744
result_tree = self._get_preview(merger, cleanups)
4484
3745
show_diff_trees(merger.this_tree, result_tree, self.outf,
4485
old_label='', new_label='',
4486
path_encoding=path_encoding)
3746
old_label='', new_label='')
4488
3748
def _do_merge(self, merger, change_reporter, allow_pending, verified):
4489
3749
merger.change_reporter = change_reporter
4682
3933
def run(self, file_list=None, merge_type=None, show_base=False,
4683
3934
reprocess=False):
4684
from bzrlib.conflicts import restore
4685
3935
if merge_type is None:
4686
3936
merge_type = _mod_merge.Merge3Merger
4687
tree, file_list = WorkingTree.open_containing_paths(file_list)
4688
self.add_cleanup(tree.lock_write().unlock)
4689
parents = tree.get_parent_ids()
4690
if len(parents) != 2:
4691
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4692
" merges. Not cherrypicking or"
4694
repository = tree.branch.repository
4695
interesting_ids = None
4697
conflicts = tree.conflicts()
4698
if file_list is not None:
4699
interesting_ids = set()
4700
for filename in file_list:
4701
file_id = tree.path2id(filename)
4703
raise errors.NotVersionedError(filename)
4704
interesting_ids.add(file_id)
4705
if tree.kind(file_id) != "directory":
3937
tree, file_list = tree_files(file_list)
3940
parents = tree.get_parent_ids()
3941
if len(parents) != 2:
3942
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3943
" merges. Not cherrypicking or"
3945
repository = tree.branch.repository
3946
interesting_ids = None
3948
conflicts = tree.conflicts()
3949
if file_list is not None:
3950
interesting_ids = set()
3951
for filename in file_list:
3952
file_id = tree.path2id(filename)
3954
raise errors.NotVersionedError(filename)
3955
interesting_ids.add(file_id)
3956
if tree.kind(file_id) != "directory":
4708
# FIXME: Support nested trees
4709
for name, ie in tree.root_inventory.iter_entries(file_id):
4710
interesting_ids.add(ie.file_id)
4711
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4713
# Remerge only supports resolving contents conflicts
4714
allowed_conflicts = ('text conflict', 'contents conflict')
4715
restore_files = [c.path for c in conflicts
4716
if c.typestring in allowed_conflicts]
4717
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4718
tree.set_conflicts(ConflictList(new_conflicts))
4719
if file_list is not None:
4720
restore_files = file_list
4721
for filename in restore_files:
3959
for name, ie in tree.inventory.iter_entries(file_id):
3960
interesting_ids.add(ie.file_id)
3961
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3963
# Remerge only supports resolving contents conflicts
3964
allowed_conflicts = ('text conflict', 'contents conflict')
3965
restore_files = [c.path for c in conflicts
3966
if c.typestring in allowed_conflicts]
3967
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3968
tree.set_conflicts(ConflictList(new_conflicts))
3969
if file_list is not None:
3970
restore_files = file_list
3971
for filename in restore_files:
3973
restore(tree.abspath(filename))
3974
except errors.NotConflicted:
3976
# Disable pending merges, because the file texts we are remerging
3977
# have not had those merges performed. If we use the wrong parents
3978
# list, we imply that the working tree text has seen and rejected
3979
# all the changes from the other tree, when in fact those changes
3980
# have not yet been seen.
3981
pb = ui.ui_factory.nested_progress_bar()
3982
tree.set_parent_ids(parents[:1])
4723
restore(tree.abspath(filename))
4724
except errors.NotConflicted:
4726
# Disable pending merges, because the file texts we are remerging
4727
# have not had those merges performed. If we use the wrong parents
4728
# list, we imply that the working tree text has seen and rejected
4729
# all the changes from the other tree, when in fact those changes
4730
# have not yet been seen.
4731
tree.set_parent_ids(parents[:1])
4733
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4734
merger.interesting_ids = interesting_ids
4735
merger.merge_type = merge_type
4736
merger.show_base = show_base
4737
merger.reprocess = reprocess
4738
conflicts = merger.do_merge()
3984
merger = _mod_merge.Merger.from_revision_ids(pb,
3986
merger.interesting_ids = interesting_ids
3987
merger.merge_type = merge_type
3988
merger.show_base = show_base
3989
merger.reprocess = reprocess
3990
conflicts = merger.do_merge()
3992
tree.set_parent_ids(parents)
4740
tree.set_parent_ids(parents)
4741
3996
if conflicts > 0:
4747
4002
class cmd_revert(Command):
4749
Set files in the working tree back to the contents of a previous revision.
4003
"""Revert files to a previous revision.
4751
4005
Giving a list of files will revert only those files. Otherwise, all files
4752
4006
will be reverted. If the revision is not specified with '--revision', the
4753
working tree basis revision is used. A revert operation affects only the
4754
working tree, not any revision history like the branch and repository or
4755
the working tree basis revision.
4007
last committed revision is used.
4757
4009
To remove only some changes, without reverting to a prior version, use
4758
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4759
will remove the changes introduced by the second last commit (-2), without
4760
affecting the changes introduced by the last commit (-1). To remove
4761
certain changes on a hunk-by-hunk basis, see the shelve command.
4762
To update the branch to a specific revision or the latest revision and
4763
update the working tree accordingly while preserving local changes, see the
4010
merge instead. For example, "merge . --revision -2..-3" will remove the
4011
changes introduced by -2, without affecting the changes introduced by -1.
4012
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4766
Uncommitted changes to files that are reverted will be discarded.
4767
Howver, by default, any files that have been manually changed will be
4768
backed up first. (Files changed only by merge are not backed up.) Backup
4769
files have '.~#~' appended to their name, where # is a number.
4014
By default, any files that have been manually changed will be backed up
4015
first. (Files changed only by merge are not backed up.) Backup files have
4016
'.~#~' appended to their name, where # is a number.
4771
4018
When you provide files, you can use their current pathname or the pathname
4772
4019
from the target revision. So you can use revert to "undelete" a file by
4773
4020
name. If you name a directory, all the contents of that directory will be
4776
If you have newly added files since the target revision, they will be
4777
removed. If the files to be removed have been changed, backups will be
4778
created as above. Directories containing unknown files will not be
4023
Any files that have been newly added since that revision will be deleted,
4024
with a backup kept if appropriate. Directories containing unknown files
4025
will not be deleted.
4781
The working tree contains a list of revisions that have been merged but
4782
not yet committed. These revisions will be included as additional parents
4783
of the next commit. Normally, using revert clears that list as well as
4784
reverting the files. If any files are specified, revert leaves the list
4785
of uncommitted merges alone and reverts only the files. Use ``bzr revert
4786
.`` in the tree root to revert all files but keep the recorded merges,
4787
and ``bzr revert --forget-merges`` to clear the pending merge list without
4027
The working tree contains a list of pending merged revisions, which will
4028
be included as parents in the next commit. Normally, revert clears that
4029
list as well as reverting the files. If any files are specified, revert
4030
leaves the pending merge list alone and reverts only the files. Use "bzr
4031
revert ." in the tree root to revert all files but keep the merge record,
4032
and "bzr revert --forget-merges" to clear the pending merge list without
4788
4033
reverting any files.
4790
Using "bzr revert --forget-merges", it is possible to apply all of the
4791
changes from a branch in a single revision. To do this, perform the merge
4792
as desired. Then doing revert with the "--forget-merges" option will keep
4793
the content of the tree as it was, but it will clear the list of pending
4794
merges. The next commit will then contain all of the changes that are
4795
present in the other branch, but without any other parent revisions.
4796
Because this technique forgets where these changes originated, it may
4797
cause additional conflicts on later merges involving the same source and
4801
_see_also = ['cat', 'export', 'merge', 'shelve']
4036
_see_also = ['cat', 'export']
4802
4037
takes_options = [
4804
4039
Option('no-backup', "Do not save backups of reverted files."),
4999
4213
_get_revision_range(revision,
5000
4214
remote_branch, self.name()))
5002
local_extra, remote_extra = find_unmerged(
5003
local_branch, remote_branch, restrict,
5004
backward=not reverse,
5005
include_merged=include_merged,
5006
local_revid_range=local_revid_range,
5007
remote_revid_range=remote_revid_range)
5009
if log_format is None:
5010
registry = log.log_formatter_registry
5011
log_format = registry.get_default(local_branch)
5012
lf = log_format(to_file=self.outf,
5014
show_timezone='original')
5017
if local_extra and not theirs_only:
5018
message(ngettext("You have %d extra revision:\n",
5019
"You have %d extra revisions:\n",
5023
if local_branch.supports_tags():
5024
rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5025
for revision in iter_log_revisions(local_extra,
5026
local_branch.repository,
5029
lf.log_revision(revision)
5030
printed_local = True
5033
printed_local = False
5035
if remote_extra and not mine_only:
5036
if printed_local is True:
5038
message(ngettext("You are missing %d revision:\n",
5039
"You are missing %d revisions:\n",
5040
len(remote_extra)) %
5042
if remote_branch.supports_tags():
5043
rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5044
for revision in iter_log_revisions(remote_extra,
5045
remote_branch.repository,
5048
lf.log_revision(revision)
5051
if mine_only and not local_extra:
5052
# We checked local, and found nothing extra
5053
message(gettext('This branch has no new revisions.\n'))
5054
elif theirs_only and not remote_extra:
5055
# We checked remote, and found nothing extra
5056
message(gettext('Other branch has no new revisions.\n'))
5057
elif not (mine_only or theirs_only or local_extra or
5059
# We checked both branches, and neither one had extra
5061
message(gettext("Branches are up to date.\n"))
4216
local_branch.lock_read()
4218
remote_branch.lock_read()
4220
local_extra, remote_extra = find_unmerged(
4221
local_branch, remote_branch, restrict,
4222
backward=not reverse,
4223
include_merges=include_merges,
4224
local_revid_range=local_revid_range,
4225
remote_revid_range=remote_revid_range)
4227
if log_format is None:
4228
registry = log.log_formatter_registry
4229
log_format = registry.get_default(local_branch)
4230
lf = log_format(to_file=self.outf,
4232
show_timezone='original')
4235
if local_extra and not theirs_only:
4236
message("You have %d extra revision(s):\n" %
4238
for revision in iter_log_revisions(local_extra,
4239
local_branch.repository,
4241
lf.log_revision(revision)
4242
printed_local = True
4245
printed_local = False
4247
if remote_extra and not mine_only:
4248
if printed_local is True:
4250
message("You are missing %d revision(s):\n" %
4252
for revision in iter_log_revisions(remote_extra,
4253
remote_branch.repository,
4255
lf.log_revision(revision)
4258
if mine_only and not local_extra:
4259
# We checked local, and found nothing extra
4260
message('This branch is up to date.\n')
4261
elif theirs_only and not remote_extra:
4262
# We checked remote, and found nothing extra
4263
message('Other branch is up to date.\n')
4264
elif not (mine_only or theirs_only or local_extra or
4266
# We checked both branches, and neither one had extra
4268
message("Branches are up to date.\n")
4270
remote_branch.unlock()
4272
local_branch.unlock()
5063
4273
if not status_code and parent is None and other_branch is not None:
5064
self.add_cleanup(local_branch.lock_write().unlock)
5065
# handle race conditions - a parent might be set while we run.
5066
if local_branch.get_parent() is None:
5067
local_branch.set_parent(remote_branch.base)
4274
local_branch.lock_write()
4276
# handle race conditions - a parent might be set while we run.
4277
if local_branch.get_parent() is None:
4278
local_branch.set_parent(remote_branch.base)
4280
local_branch.unlock()
5068
4281
return status_code
5071
4284
class cmd_pack(Command):
5072
__doc__ = """Compress the data within a repository.
5074
This operation compresses the data within a bazaar repository. As
5075
bazaar supports automatic packing of repository, this operation is
5076
normally not required to be done manually.
5078
During the pack operation, bazaar takes a backup of existing repository
5079
data, i.e. pack files. This backup is eventually removed by bazaar
5080
automatically when it is safe to do so. To save disk space by removing
5081
the backed up pack files, the --clean-obsolete-packs option may be
5084
Warning: If you use --clean-obsolete-packs and your machine crashes
5085
during or immediately after repacking, you may be left with a state
5086
where the deletion has been written to disk but the new packs have not
5087
been. In this case the repository may be unusable.
4285
"""Compress the data within a repository."""
5090
4287
_see_also = ['repositories']
5091
4288
takes_args = ['branch_or_repo?']
5093
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
5096
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
5097
dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4290
def run(self, branch_or_repo='.'):
4291
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
5099
4293
branch = dir.open_branch()
5100
4294
repository = branch.repository
5101
4295
except errors.NotBranchError:
5102
4296
repository = dir.open_repository()
5103
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
5106
4300
class cmd_plugins(Command):
5107
__doc__ = """List the installed plugins.
4301
"""List the installed plugins.
5109
4303
This command displays the list of installed plugins including
5110
4304
version of plugin and a short description of each.
5117
4311
adding new commands, providing additional network transports and
5118
4312
customizing log output.
5120
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
5121
for further information on plugins including where to find them and how to
5122
install them. Instructions are also provided there on how to write new
5123
plugins using the Python programming language.
4314
See the Bazaar web site, http://bazaar-vcs.org, for further
4315
information on plugins including where to find them and how to
4316
install them. Instructions are also provided there on how to
4317
write new plugins using the Python programming language.
5125
4319
takes_options = ['verbose']
5127
4321
@display_command
5128
4322
def run(self, verbose=False):
5129
from bzrlib import plugin
5130
# Don't give writelines a generator as some codecs don't like that
5131
self.outf.writelines(
5132
list(plugin.describe_plugins(show_paths=verbose)))
4323
import bzrlib.plugin
4324
from inspect import getdoc
4326
for name, plugin in bzrlib.plugin.plugins().items():
4327
version = plugin.__version__
4328
if version == 'unknown':
4330
name_ver = '%s %s' % (name, version)
4331
d = getdoc(plugin.module)
4333
doc = d.split('\n')[0]
4335
doc = '(no description)'
4336
result.append((name_ver, doc, plugin.path()))
4337
for name_ver, doc, path in sorted(result):
5135
4345
class cmd_testament(Command):
5136
__doc__ = """Show testament (signing-form) of a revision."""
4346
"""Show testament (signing-form) of a revision."""
5137
4347
takes_options = [
5139
4349
Option('long', help='Produce long-format testament.'),
5140
4350
Option('strict',
5141
4351
help='Produce a strict-format testament.')]
5142
4352
takes_args = ['branch?']
5143
encoding_type = 'exact'
5144
4353
@display_command
5145
4354
def run(self, branch=u'.', revision=None, long=False, strict=False):
5146
4355
from bzrlib.testament import Testament, StrictTestament
5182
4394
Option('long', help='Show commit date in annotations.'),
5187
4398
encoding_type = 'exact'
5189
4400
@display_command
5190
4401
def run(self, filename, all=False, long=False, revision=None,
5191
show_ids=False, directory=None):
5192
from bzrlib.annotate import (
4403
from bzrlib.annotate import annotate_file, annotate_file_tree
5195
4404
wt, branch, relpath = \
5196
_open_directory_or_containing_tree_or_branch(filename, directory)
4405
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
5197
4406
if wt is not None:
5198
self.add_cleanup(wt.lock_read().unlock)
5200
self.add_cleanup(branch.lock_read().unlock)
5201
tree = _get_one_revision_tree('annotate', revision, branch=branch)
5202
self.add_cleanup(tree.lock_read().unlock)
5203
if wt is not None and revision is None:
5204
file_id = wt.path2id(relpath)
5206
file_id = tree.path2id(relpath)
5208
raise errors.NotVersionedError(filename)
5209
if wt is not None and revision is None:
5210
# If there is a tree and we're not annotating historical
5211
# versions, annotate the working tree's content.
5212
annotate_file_tree(wt, file_id, self.outf, long, all,
5215
annotate_file_tree(tree, file_id, self.outf, long, all,
5216
show_ids=show_ids, branch=branch)
4411
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4415
file_id = wt.path2id(relpath)
4417
file_id = tree.path2id(relpath)
4419
raise errors.NotVersionedError(filename)
4420
file_version = tree.inventory[file_id].revision
4421
if wt is not None and revision is None:
4422
# If there is a tree and we're not annotating historical
4423
# versions, annotate the working tree's content.
4424
annotate_file_tree(wt, file_id, self.outf, long, all,
4427
annotate_file(branch, file_version, file_id, long, all,
4428
self.outf, show_ids=show_ids)
5219
4438
class cmd_re_sign(Command):
5220
__doc__ = """Create a digital signature for an existing revision."""
4439
"""Create a digital signature for an existing revision."""
5221
4440
# TODO be able to replace existing ones.
5223
4442
hidden = True # is this right ?
5224
4443
takes_args = ['revision_id*']
5225
takes_options = ['directory', 'revision']
4444
takes_options = ['revision']
5227
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4446
def run(self, revision_id_list=None, revision=None):
5228
4447
if revision_id_list is not None and revision is not None:
5229
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4448
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
5230
4449
if revision_id_list is None and revision is None:
5231
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
5232
b = WorkingTree.open_containing(directory)[0].branch
5233
self.add_cleanup(b.lock_write().unlock)
5234
return self._run(b, revision_id_list, revision)
4450
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4451
b = WorkingTree.open_containing(u'.')[0].branch
4454
return self._run(b, revision_id_list, revision)
5236
4458
def _run(self, b, revision_id_list, revision):
5237
4459
import bzrlib.gpg as gpg
5238
gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4460
gpg_strategy = gpg.GPGStrategy(b.get_config())
5239
4461
if revision_id_list is not None:
5240
4462
b.repository.start_write_group()
5279
4501
b.repository.commit_write_group()
5281
raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4503
raise errors.BzrCommandError('Please supply either one revision, or a range.')
5284
4506
class cmd_bind(Command):
5285
__doc__ = """Convert the current branch into a checkout of the supplied branch.
5286
If no branch is supplied, rebind to the last bound location.
4507
"""Convert the current branch into a checkout of the supplied branch.
5288
4509
Once converted into a checkout, commits must succeed on the master branch
5289
4510
before they will be applied to the local branch.
5291
4512
Bound branches use the nickname of its master branch unless it is set
5292
locally, in which case binding will update the local nickname to be
4513
locally, in which case binding will update the the local nickname to be
5293
4514
that of the master.
5296
4517
_see_also = ['checkouts', 'unbind']
5297
4518
takes_args = ['location?']
5298
takes_options = ['directory']
5300
def run(self, location=None, directory=u'.'):
5301
b, relpath = Branch.open_containing(directory)
4521
def run(self, location=None):
4522
b, relpath = Branch.open_containing(u'.')
5302
4523
if location is None:
5304
4525
location = b.get_old_bound_location()
5305
4526
except errors.UpgradeRequired:
5306
raise errors.BzrCommandError(gettext('No location supplied. '
5307
'This format does not remember old locations.'))
4527
raise errors.BzrCommandError('No location supplied. '
4528
'This format does not remember old locations.')
5309
4530
if location is None:
5310
if b.get_bound_location() is not None:
5311
raise errors.BzrCommandError(
5312
gettext('Branch is already bound'))
5314
raise errors.BzrCommandError(
5315
gettext('No location supplied'
5316
' and no previous location known'))
4531
raise errors.BzrCommandError('No location supplied and no '
4532
'previous location known')
5317
4533
b_other = Branch.open(location)
5319
4535
b.bind(b_other)
5320
4536
except errors.DivergedBranches:
5321
raise errors.BzrCommandError(gettext('These branches have diverged.'
5322
' Try merging, and then bind again.'))
4537
raise errors.BzrCommandError('These branches have diverged.'
4538
' Try merging, and then bind again.')
5323
4539
if b.get_config().has_explicit_nickname():
5324
4540
b.nick = b_other.nick
5327
4543
class cmd_unbind(Command):
5328
__doc__ = """Convert the current checkout into a regular branch.
4544
"""Convert the current checkout into a regular branch.
5330
4546
After unbinding, the local branch is considered independent and subsequent
5331
4547
commits will be local only.
5432
4652
end_revision=last_revno)
5435
self.outf.write(gettext('Dry-run, pretending to remove'
5436
' the above revisions.\n'))
4655
print 'Dry-run, pretending to remove the above revisions.'
4657
val = raw_input('Press <enter> to continue')
5438
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5441
if not ui.ui_factory.confirm_action(
5442
gettext(u'Uncommit these revisions'),
5443
'bzrlib.builtins.uncommit',
5445
self.outf.write(gettext('Canceled\n'))
4659
print 'The above revision(s) will be removed.'
4661
val = raw_input('Are you sure [y/N]? ')
4662
if val.lower() not in ('y', 'yes'):
5448
4666
mutter('Uncommitting from {%s} to {%s}',
5449
4667
last_rev_id, rev_id)
5450
4668
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5451
revno=revno, local=local, keep_tags=keep_tags)
5452
self.outf.write(gettext('You can restore the old tip by running:\n'
5453
' bzr pull . -r revid:%s\n') % last_rev_id)
4669
revno=revno, local=local)
4670
note('You can restore the old tip by running:\n'
4671
' bzr pull . -r revid:%s', last_rev_id)
5456
4674
class cmd_break_lock(Command):
5457
__doc__ = """Break a dead lock.
5459
This command breaks a lock on a repository, branch, working directory or
4675
"""Break a dead lock on a repository, branch or working directory.
5462
4677
CAUTION: Locks should only be broken when you are sure that the process
5463
4678
holding the lock has been stopped.
5465
You can get information on what locks are open via the 'bzr info
5466
[location]' command.
4680
You can get information on what locks are open via the 'bzr info' command.
5470
bzr break-lock bzr+ssh://example.com/bzr/foo
5471
bzr break-lock --conf ~/.bazaar
5474
4685
takes_args = ['location?']
5477
help='LOCATION is the directory where the config lock is.'),
5479
help='Do not ask for confirmation before breaking the lock.'),
5482
def run(self, location=None, config=False, force=False):
4687
def run(self, location=None, show=False):
5483
4688
if location is None:
5484
4689
location = u'.'
5486
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5488
{'bzrlib.lockdir.break': True})
5490
conf = _mod_config.LockableConfig(file_name=location)
5493
control, relpath = controldir.ControlDir.open_containing(location)
5495
control.break_lock()
5496
except NotImplementedError:
4690
control, relpath = bzrdir.BzrDir.open_containing(location)
4692
control.break_lock()
4693
except NotImplementedError:
5500
4697
class cmd_wait_until_signalled(Command):
5501
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4698
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5503
4700
This just prints a line to signal when it is ready, then blocks on stdin.
5514
4711
class cmd_serve(Command):
5515
__doc__ = """Run the bzr server."""
4712
"""Run the bzr server."""
5517
4714
aliases = ['server']
5519
4716
takes_options = [
5521
4718
help='Serve on stdin/out for use from inetd or sshd.'),
5522
RegistryOption('protocol',
5523
help="Protocol to serve.",
4719
RegistryOption('protocol',
4720
help="Protocol to serve.",
5524
4721
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5525
4722
value_switches=True),
5527
help='Listen for connections on nominated address.', type=str),
5529
help='Listen for connections on nominated port. Passing 0 as '
5530
'the port number will result in a dynamically allocated '
5531
'port. The default port depends on the protocol.',
5533
custom_help('directory',
5534
help='Serve contents of this directory.'),
4724
help='Listen for connections on nominated port of the form '
4725
'[hostname:]portnumber. Passing 0 as the port number will '
4726
'result in a dynamically allocated port. The default port '
4727
'depends on the protocol.',
4730
help='Serve contents of this directory.',
5535
4732
Option('allow-writes',
5536
4733
help='By default the server is a readonly server. Supplying '
5537
4734
'--allow-writes enables write access to the contents of '
5538
'the served directory and below. Note that ``bzr serve`` '
5539
'does not perform authentication, so unless some form of '
5540
'external authentication is arranged supplying this '
5541
'option leads to global uncontrolled write access to your '
4735
'the served directory and below.'
5544
Option('client-timeout', type=float,
5545
help='Override the default idle client timeout (5min).'),
5548
def run(self, listen=None, port=None, inet=False, directory=None,
5549
allow_writes=False, protocol=None, client_timeout=None):
5550
from bzrlib import transport
4739
def get_host_and_port(self, port):
4740
"""Return the host and port to run the smart server on.
4742
If 'port' is None, None will be returned for the host and port.
4744
If 'port' has a colon in it, the string before the colon will be
4745
interpreted as the host.
4747
:param port: A string of the port to run the server on.
4748
:return: A tuple of (host, port), where 'host' is a host name or IP,
4749
and port is an integer TCP/IP port.
4752
if port is not None:
4754
host, port = port.split(':')
4758
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4760
from bzrlib.transport import get_transport, transport_server_registry
5551
4761
if directory is None:
5552
4762
directory = os.getcwd()
5553
4763
if protocol is None:
5554
protocol = transport.transport_server_registry.get()
5555
url = transport.location_to_url(directory)
4764
protocol = transport_server_registry.get()
4765
host, port = self.get_host_and_port(port)
4766
url = urlutils.local_path_to_url(directory)
5556
4767
if not allow_writes:
5557
4768
url = 'readonly+' + url
5558
t = transport.get_transport_from_url(url)
5559
protocol(t, listen, port, inet, client_timeout)
4769
transport = get_transport(url)
4770
protocol(transport, host, port, inet)
5562
4773
class cmd_join(Command):
5563
__doc__ = """Combine a tree into its containing tree.
4774
"""Combine a tree into its containing tree.
5565
4776
This command requires the target tree to be in a rich-root format.
5746
4954
directly from the merge directive, without retrieving data from a
5749
`bzr send` creates a compact data set that, when applied using bzr
5750
merge, has the same effect as merging from the source branch.
5752
By default the merge directive is self-contained and can be applied to any
5753
branch containing submit_branch in its ancestory without needing access to
5756
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5757
revisions, but only a structured request to merge from the
5758
public_location. In that case the public_branch is needed and it must be
5759
up-to-date and accessible to the recipient. The public_branch is always
5760
included if known, so that people can check it later.
5762
The submit branch defaults to the parent of the source branch, but can be
5763
overridden. Both submit branch and public branch will be remembered in
5764
branch.conf the first time they are used for a particular branch. The
5765
source branch defaults to that containing the working directory, but can
5766
be changed using --from.
5768
Both the submit branch and the public branch follow the usual behavior with
5769
respect to --remember: If there is no default location set, the first send
5770
will set it (use --no-remember to avoid setting it). After that, you can
5771
omit the location to use the default. To change the default, use
5772
--remember. The value will only be saved if the location can be accessed.
5774
In order to calculate those changes, bzr must analyse the submit branch.
5775
Therefore it is most efficient for the submit branch to be a local mirror.
5776
If a public location is known for the submit_branch, that location is used
5777
in the merge directive.
5779
The default behaviour is to send the merge directive by mail, unless -o is
5780
given, in which case it is sent to a file.
4957
If --no-bundle is specified, then public_branch is needed (and must be
4958
up-to-date), so that the receiver can perform the merge using the
4959
public_branch. The public_branch is always included if known, so that
4960
people can check it later.
4962
The submit branch defaults to the parent, but can be overridden. Both
4963
submit branch and public branch will be remembered if supplied.
4965
If a public_branch is known for the submit_branch, that public submit
4966
branch is used in the merge instructions. This means that a local mirror
4967
can be used as your actual submit branch, once you have set public_branch
5782
4970
Mail is sent using your preferred mail program. This should be transparent
5783
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
4971
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5784
4972
If the preferred client can't be found (or used), your editor will be used.
5786
4974
To use a specific mail program, set the mail_client configuration option.
5787
4975
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5788
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5789
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5790
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
4976
specific clients are "claws", "evolution", "kmail", "mutt", and
4977
"thunderbird"; generic options are "default", "editor", "emacsclient",
4978
"mapi", and "xdg-email". Plugins may also add supported clients.
5793
4980
If mail is being sent, a to address is required. This can be supplied
5794
4981
either on the commandline, by setting the submit_to configuration
5945
5128
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5946
5129
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5948
If no tag name is specified it will be determined through the
5949
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5950
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5954
5132
_see_also = ['commit', 'tags']
5955
takes_args = ['tag_name?']
5133
takes_args = ['tag_name']
5956
5134
takes_options = [
5957
5135
Option('delete',
5958
5136
help='Delete this tag rather than placing it.',
5960
custom_help('directory',
5961
help='Branch in which to place the tag.'),
5139
help='Branch in which to place the tag.',
5962
5143
Option('force',
5963
5144
help='Replace existing tags.',
5968
def run(self, tag_name=None,
5149
def run(self, tag_name,
5974
5155
branch, relpath = Branch.open_containing(directory)
5975
self.add_cleanup(branch.lock_write().unlock)
5977
if tag_name is None:
5978
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5979
branch.tags.delete_tag(tag_name)
5980
note(gettext('Deleted tag %s.') % tag_name)
5983
if len(revision) != 1:
5984
raise errors.BzrCommandError(gettext(
5985
"Tags can only be placed on a single revision, "
5987
revision_id = revision[0].as_revision_id(branch)
5989
revision_id = branch.last_revision()
5990
if tag_name is None:
5991
tag_name = branch.automatic_tag_name(revision_id)
5992
if tag_name is None:
5993
raise errors.BzrCommandError(gettext(
5994
"Please specify a tag name."))
5996
existing_target = branch.tags.lookup_tag(tag_name)
5997
except errors.NoSuchTag:
5998
existing_target = None
5999
if not force and existing_target not in (None, revision_id):
6000
raise errors.TagAlreadyExists(tag_name)
6001
if existing_target == revision_id:
6002
note(gettext('Tag %s already exists for that revision.') % tag_name)
5159
branch.tags.delete_tag(tag_name)
5160
self.outf.write('Deleted tag %s.\n' % tag_name)
5163
if len(revision) != 1:
5164
raise errors.BzrCommandError(
5165
"Tags can only be placed on a single revision, "
5167
revision_id = revision[0].as_revision_id(branch)
5169
revision_id = branch.last_revision()
5170
if (not force) and branch.tags.has_tag(tag_name):
5171
raise errors.TagAlreadyExists(tag_name)
6004
5172
branch.tags.set_tag(tag_name, revision_id)
6005
if existing_target is None:
6006
note(gettext('Created tag %s.') % tag_name)
6008
note(gettext('Updated tag %s.') % tag_name)
5173
self.outf.write('Created tag %s.\n' % tag_name)
6011
5178
class cmd_tags(Command):
6012
__doc__ = """List tags.
6014
5181
This command shows a table of tag names and the revisions they reference.
6017
5184
_see_also = ['tag']
6018
5185
takes_options = [
6019
custom_help('directory',
6020
help='Branch whose tags should be displayed.'),
6021
RegistryOption('sort',
5187
help='Branch whose tags should be displayed.',
5191
RegistryOption.from_kwargs('sort',
6022
5192
'Sort tags by different criteria.', title='Sorting',
6023
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5193
alpha='Sort tags lexicographically (default).',
5194
time='Sort tags chronologically.',
6029
5200
@display_command
6030
def run(self, directory='.', sort=None, show_ids=False, revision=None):
6031
from bzrlib.tag import tag_sort_methods
6032
5207
branch, relpath = Branch.open_containing(directory)
6034
5209
tags = branch.tags.get_tag_dict().items()
6038
self.add_cleanup(branch.lock_read().unlock)
6040
# Restrict to the specified range
6041
tags = self._tags_for_range(branch, revision)
6043
sort = tag_sort_methods.get()
6046
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
6047
for index, (tag, revid) in enumerate(tags):
6049
revno = branch.revision_id_to_dotted_revno(revid)
6050
if isinstance(revno, tuple):
6051
revno = '.'.join(map(str, revno))
6052
except (errors.NoSuchRevision,
6053
errors.GhostRevisionsHaveNoRevno,
6054
errors.UnsupportedOperation):
6055
# Bad tag data/merges can lead to tagged revisions
6056
# which are not in this branch. Fail gracefully ...
6058
tags[index] = (tag, revno)
5216
graph = branch.repository.get_graph()
5217
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5218
revid1, revid2 = rev1.rev_id, rev2.rev_id
5219
# only show revisions between revid1 and revid2 (inclusive)
5220
tags = [(tag, revid) for tag, revid in tags if
5221
graph.is_between(revid, revid1, revid2)]
5224
elif sort == 'time':
5226
for tag, revid in tags:
5228
revobj = branch.repository.get_revision(revid)
5229
except errors.NoSuchRevision:
5230
timestamp = sys.maxint # place them at the end
5232
timestamp = revobj.timestamp
5233
timestamps[revid] = timestamp
5234
tags.sort(key=lambda x: timestamps[x[1]])
5236
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5237
for index, (tag, revid) in enumerate(tags):
5239
revno = branch.revision_id_to_dotted_revno(revid)
5240
if isinstance(revno, tuple):
5241
revno = '.'.join(map(str, revno))
5242
except errors.NoSuchRevision:
5243
# Bad tag data/merges can lead to tagged revisions
5244
# which are not in this branch. Fail gracefully ...
5246
tags[index] = (tag, revno)
6060
5249
for tag, revspec in tags:
6061
5250
self.outf.write('%-20s %s\n' % (tag, revspec))
6063
def _tags_for_range(self, branch, revision):
6065
rev1, rev2 = _get_revision_range(revision, branch, self.name())
6066
revid1, revid2 = rev1.rev_id, rev2.rev_id
6067
# _get_revision_range will always set revid2 if it's not specified.
6068
# If revid1 is None, it means we want to start from the branch
6069
# origin which is always a valid ancestor. If revid1 == revid2, the
6070
# ancestry check is useless.
6071
if revid1 and revid1 != revid2:
6072
# FIXME: We really want to use the same graph than
6073
# branch.iter_merge_sorted_revisions below, but this is not
6074
# easily available -- vila 2011-09-23
6075
if branch.repository.get_graph().is_ancestor(revid2, revid1):
6076
# We don't want to output anything in this case...
6078
# only show revisions between revid1 and revid2 (inclusive)
6079
tagged_revids = branch.tags.get_reverse_tag_dict()
6081
for r in branch.iter_merge_sorted_revisions(
6082
start_revision_id=revid2, stop_revision_id=revid1,
6083
stop_rule='include'):
6084
revid_tags = tagged_revids.get(r[0], None)
6086
found.extend([(tag, r[0]) for tag in revid_tags])
6090
5253
class cmd_reconfigure(Command):
6091
__doc__ = """Reconfigure the type of a bzr directory.
5254
"""Reconfigure the type of a bzr directory.
6093
5256
A target configuration must be specified.
6161
5312
# At the moment you can use --stacked-on and a different
6162
5313
# reconfiguration shape at the same time; there seems no good reason
6164
if (tree_type is None and
6165
repository_type is None and
6166
repository_trees is None):
5315
if target_type is None:
6167
5316
if stacked_on or unstacked:
6170
raise errors.BzrCommandError(gettext('No target configuration '
6172
reconfiguration = None
6173
if tree_type == 'branch':
5319
raise errors.BzrCommandError('No target configuration '
5321
elif target_type == 'branch':
6174
5322
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6175
elif tree_type == 'tree':
5323
elif target_type == 'tree':
6176
5324
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6177
elif tree_type == 'checkout':
5325
elif target_type == 'checkout':
6178
5326
reconfiguration = reconfigure.Reconfigure.to_checkout(
6179
5327
directory, bind_to)
6180
elif tree_type == 'lightweight-checkout':
5328
elif target_type == 'lightweight-checkout':
6181
5329
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6182
5330
directory, bind_to)
6184
reconfiguration.apply(force)
6185
reconfiguration = None
6186
if repository_type == 'use-shared':
5331
elif target_type == 'use-shared':
6187
5332
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6188
elif repository_type == 'standalone':
5333
elif target_type == 'standalone':
6189
5334
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6191
reconfiguration.apply(force)
6192
reconfiguration = None
6193
if repository_trees == 'with-trees':
5335
elif target_type == 'with-trees':
6194
5336
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6195
5337
directory, True)
6196
elif repository_trees == 'with-no-trees':
5338
elif target_type == 'with-no-trees':
6197
5339
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6198
5340
directory, False)
6200
reconfiguration.apply(force)
6201
reconfiguration = None
5341
reconfiguration.apply(force)
6204
5344
class cmd_switch(Command):
6205
__doc__ = """Set the branch of a checkout and update.
5345
"""Set the branch of a checkout and update.
6207
5347
For lightweight checkouts, this changes the branch being referenced.
6208
5348
For heavyweight checkouts, this checks that there are no local commits
6220
5360
/path/to/newbranch.
6222
5362
Bound branches use the nickname of its master branch unless it is set
6223
locally, in which case switching will update the local nickname to be
5363
locally, in which case switching will update the the local nickname to be
6224
5364
that of the master.
6227
takes_args = ['to_location?']
6228
takes_options = ['directory',
5367
takes_args = ['to_location']
5368
takes_options = [Option('force',
6230
5369
help='Switch even if local commits will be lost.'),
6232
5370
Option('create-branch', short_name='b',
6233
5371
help='Create the target branch from this one before'
6234
5372
' switching to it.'),
6236
help='Store and restore uncommitted changes in the'
6240
def run(self, to_location=None, force=False, create_branch=False,
6241
revision=None, directory=u'.', store=False):
5375
def run(self, to_location, force=False, create_branch=False):
6242
5376
from bzrlib import switch
6243
tree_location = directory
6244
revision = _get_one_revision('switch', revision)
6245
possible_transports = []
6246
control_dir = controldir.ControlDir.open_containing(tree_location,
6247
possible_transports=possible_transports)[0]
6248
if to_location is None:
6249
if revision is None:
6250
raise errors.BzrCommandError(gettext('You must supply either a'
6251
' revision or a location'))
6252
to_location = tree_location
5378
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
6254
branch = control_dir.open_branch(
6255
possible_transports=possible_transports)
5380
branch = control_dir.open_branch()
6256
5381
had_explicit_nick = branch.get_config().has_explicit_nickname()
6257
5382
except errors.NotBranchError:
6259
5384
had_explicit_nick = False
6260
5385
if create_branch:
6261
5386
if branch is None:
6262
raise errors.BzrCommandError(
6263
gettext('cannot create branch without source branch'))
6264
to_location = lookup_new_sibling_branch(control_dir, to_location,
6265
possible_transports=possible_transports)
5387
raise errors.BzrCommandError('cannot create branch without'
5389
if '/' not in to_location and '\\' not in to_location:
5390
# This path is meant to be relative to the existing branch
5391
this_url = self._get_branch_location(control_dir)
5392
to_location = urlutils.join(this_url, '..', to_location)
6266
5393
to_branch = branch.bzrdir.sprout(to_location,
6267
possible_transports=possible_transports,
6268
source_branch=branch).open_branch()
5394
possible_transports=[branch.bzrdir.root_transport],
5395
source_branch=branch).open_branch()
5397
# from_branch = control_dir.open_branch()
5398
# except errors.NotBranchError:
5399
# raise BzrCommandError('Cannot create a branch from this'
5400
# ' location when we cannot open this branch')
5401
# from_branch.bzrdir.sprout(
6271
to_branch = Branch.open(to_location,
6272
possible_transports=possible_transports)
5405
to_branch = Branch.open(to_location)
6273
5406
except errors.NotBranchError:
6274
to_branch = open_sibling_branch(control_dir, to_location,
6275
possible_transports=possible_transports)
6276
if revision is not None:
6277
revision = revision.as_revision_id(to_branch)
6278
switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
store_uncommitted=store)
5407
this_url = self._get_branch_location(control_dir)
5408
to_branch = Branch.open(
5409
urlutils.join(this_url, '..', to_location))
5410
switch.switch(control_dir, to_branch, force)
6280
5411
if had_explicit_nick:
6281
5412
branch = control_dir.open_branch() #get the new branch!
6282
5413
branch.nick = to_branch.nick
6283
note(gettext('Switched to branch: %s'),
5414
note('Switched to branch: %s',
6284
5415
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5417
def _get_branch_location(self, control_dir):
5418
"""Return location of branch for this control dir."""
5420
this_branch = control_dir.open_branch()
5421
# This may be a heavy checkout, where we want the master branch
5422
master_location = this_branch.get_bound_location()
5423
if master_location is not None:
5424
return master_location
5425
# If not, use a local sibling
5426
return this_branch.base
5427
except errors.NotBranchError:
5428
format = control_dir.find_branch_format()
5429
if getattr(format, 'get_reference', None) is not None:
5430
return format.get_reference(control_dir)
5432
return control_dir.root_transport.base
6288
5435
class cmd_view(Command):
6289
__doc__ = """Manage filtered views.
5436
"""Manage filtered views.
6291
5438
Views provide a mask over the tree so that users can focus on
6292
5439
a subset of a tree when doing their work. After creating a view,
6375
tree, file_list = WorkingTree.open_containing_paths(file_list,
5522
tree, file_list = tree_files(file_list, apply_view=False)
6377
5523
current_view, view_dict = tree.views.get_view_info()
6378
5524
if name is None:
6379
5525
name = current_view
6382
raise errors.BzrCommandError(gettext(
6383
"Both --delete and a file list specified"))
5528
raise errors.BzrCommandError(
5529
"Both --delete and a file list specified")
6385
raise errors.BzrCommandError(gettext(
6386
"Both --delete and --switch specified"))
5531
raise errors.BzrCommandError(
5532
"Both --delete and --switch specified")
6388
5534
tree.views.set_view_info(None, {})
6389
self.outf.write(gettext("Deleted all views.\n"))
5535
self.outf.write("Deleted all views.\n")
6390
5536
elif name is None:
6391
raise errors.BzrCommandError(gettext("No current view to delete"))
5537
raise errors.BzrCommandError("No current view to delete")
6393
5539
tree.views.delete_view(name)
6394
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5540
self.outf.write("Deleted '%s' view.\n" % name)
6397
raise errors.BzrCommandError(gettext(
6398
"Both --switch and a file list specified"))
5543
raise errors.BzrCommandError(
5544
"Both --switch and a file list specified")
6400
raise errors.BzrCommandError(gettext(
6401
"Both --switch and --all specified"))
5546
raise errors.BzrCommandError(
5547
"Both --switch and --all specified")
6402
5548
elif switch == 'off':
6403
5549
if current_view is None:
6404
raise errors.BzrCommandError(gettext("No current view to disable"))
5550
raise errors.BzrCommandError("No current view to disable")
6405
5551
tree.views.set_view_info(None, view_dict)
6406
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5552
self.outf.write("Disabled '%s' view.\n" % (current_view))
6408
5554
tree.views.set_view_info(switch, view_dict)
6409
5555
view_str = views.view_display_str(tree.views.lookup_view())
6410
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5556
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6413
self.outf.write(gettext('Views defined:\n'))
5559
self.outf.write('Views defined:\n')
6414
5560
for view in sorted(view_dict):
6415
5561
if view == current_view:
6457
5603
self.outf.write(" %s\n" %
6458
5604
(some_hooks.get_hook_name(hook),))
6460
self.outf.write(gettext(" <no hooks installed>\n"))
6463
class cmd_remove_branch(Command):
6464
__doc__ = """Remove a branch.
6466
This will remove the branch from the specified location but
6467
will keep any working tree or repository in place.
6471
Remove the branch at repo/trunk::
6473
bzr remove-branch repo/trunk
6477
takes_args = ["location?"]
6479
takes_options = ['directory',
6480
Option('force', help='Remove branch even if it is the active branch.')]
6482
aliases = ["rmbranch"]
6484
def run(self, directory=None, location=None, force=False):
6485
br = open_nearby_branch(near=directory, location=location)
6486
if not force and br.bzrdir.has_workingtree():
6488
active_branch = br.bzrdir.open_branch(name="")
6489
except errors.NotBranchError:
6490
active_branch = None
6491
if (active_branch is not None and
6492
br.control_url == active_branch.control_url):
6493
raise errors.BzrCommandError(
6494
gettext("Branch is active. Use --force to remove it."))
6495
br.bzrdir.destroy_branch(br.name)
5606
self.outf.write(" <no hooks installed>\n")
6498
5609
class cmd_shelve(Command):
6499
__doc__ = """Temporarily set aside some changes from the current tree.
5610
"""Temporarily set aside some changes from the current tree.
6501
5612
Shelve allows you to temporarily put changes you've made "on the shelf",
6502
5613
ie. out of the way, until a later time when you can bring them back from
6547
5645
Option('destroy',
6548
5646
help='Destroy removed changes instead of shelving them.'),
6550
_see_also = ['unshelve', 'configuration']
5648
_see_also = ['unshelve']
6552
5650
def run(self, revision=None, all=False, file_list=None, message=None,
6553
writer=None, list=False, destroy=False, directory=None):
5651
writer=None, list=False, destroy=False):
6555
return self.run_for_list(directory=directory)
5653
return self.run_for_list()
6556
5654
from bzrlib.shelf_ui import Shelver
6557
5655
if writer is None:
6558
5656
writer = bzrlib.option.diff_writer_registry.get()
6560
5658
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6561
file_list, message, destroy=destroy, directory=directory)
5659
file_list, message, destroy=destroy)
5663
shelver.work_tree.unlock()
6566
5664
except errors.UserAbort:
6569
def run_for_list(self, directory=None):
6570
if directory is None:
6572
tree = WorkingTree.open_containing(directory)[0]
6573
self.add_cleanup(tree.lock_read().unlock)
6574
manager = tree.get_shelf_manager()
6575
shelves = manager.active_shelves()
6576
if len(shelves) == 0:
6577
note(gettext('No shelved changes.'))
6579
for shelf_id in reversed(shelves):
6580
message = manager.get_metadata(shelf_id).get('message')
6582
message = '<no message>'
6583
self.outf.write('%3d: %s\n' % (shelf_id, message))
5667
def run_for_list(self):
5668
tree = WorkingTree.open_containing('.')[0]
5671
manager = tree.get_shelf_manager()
5672
shelves = manager.active_shelves()
5673
if len(shelves) == 0:
5674
note('No shelved changes.')
5676
for shelf_id in reversed(shelves):
5677
message = manager.get_metadata(shelf_id).get('message')
5679
message = '<no message>'
5680
self.outf.write('%3d: %s\n' % (shelf_id, message))
6587
5686
class cmd_unshelve(Command):
6588
__doc__ = """Restore shelved changes.
5687
"""Restore shelved changes.
6590
5689
By default, the most recently shelved changes are restored. However if you
6591
5690
specify a shelf by id those changes will be restored instead. This works
6699
5793
self.outf.write('%s %s\n' % (path, location))
6702
class cmd_export_pot(Command):
6703
__doc__ = """Export command helps and error messages in po format."""
6706
takes_options = [Option('plugin',
6707
help='Export help text from named command '\
6708
'(defaults to all built in commands).',
6710
Option('include-duplicates',
6711
help='Output multiple copies of the same msgid '
6712
'string if it appears more than once.'),
6715
def run(self, plugin=None, include_duplicates=False):
6716
from bzrlib.export_pot import export_pot
6717
export_pot(self.outf, plugin, include_duplicates)
6720
def _register_lazy_builtins():
6721
# register lazy builtins from other modules; called at startup and should
6722
# be only called once.
6723
for (name, aliases, module_name) in [
6724
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6725
('cmd_config', [], 'bzrlib.config'),
6726
('cmd_dpush', [], 'bzrlib.foreign'),
6727
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6728
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6729
('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
('cmd_ping', [], 'bzrlib.smart.ping'),
6731
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6732
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6733
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6735
builtin_command_registry.register_lazy(name, aliases, module_name)
5796
# these get imported and then picked up by the scan for cmd_*
5797
# TODO: Some more consistent way to split command definitions across files;
5798
# we do need to load at least some information about them to know of
5799
# aliases. ideally we would avoid loading the implementation until the
5800
# details were needed.
5801
from bzrlib.cmd_version_info import cmd_version_info
5802
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5803
from bzrlib.bundle.commands import (
5806
from bzrlib.foreign import cmd_dpush
5807
from bzrlib.sign_my_commits import cmd_sign_my_commits
5808
from bzrlib.weave_commands import cmd_versionedfile_list, \
5809
cmd_weave_plan_merge, cmd_weave_merge_text