150
274
Not versioned and not matching an ignore pattern.
276
Additionally for directories, symlinks and files with an executable
277
bit, Bazaar indicates their type using a trailing character: '/', '@'
152
280
To see ignored files use 'bzr ignored'. For details on the
153
281
changes to file texts, use 'bzr diff'.
155
--short gives a status flags for each item, similar to the SVN's status
283
Note that --short or -S gives status flags for each item, similar
284
to Subversion's status command. To get output similar to svn -q,
158
287
If no arguments are specified, the status of the entire working
159
288
directory is shown. Otherwise, only the status of the specified
160
289
files or directories is reported. If a directory is given, status
161
290
is reported for everything inside that directory.
292
Before merges are committed, the pending merge tip revisions are
293
shown. To see all pending merge revisions, use the -v option.
294
To skip the display of pending merge information altogether, use
295
the no-pending option or specify a file/directory.
163
297
If a revision argument is given, the status is calculated against
164
298
that revision, or between two revisions if two are provided.
167
301
# TODO: --no-recurse, --recurse options
169
303
takes_args = ['file*']
170
takes_options = ['show-ids', 'revision',
171
Option('short', help='Give short SVN-style status lines'),
172
Option('versioned', help='Only show versioned files')]
304
takes_options = ['show-ids', 'revision', 'change', 'verbose',
305
Option('short', help='Use short status indicators.',
307
Option('versioned', help='Only show versioned files.',
309
Option('no-pending', help='Don\'t show pending merges.',
173
312
aliases = ['st', 'stat']
175
314
encoding_type = 'replace'
176
315
_see_also = ['diff', 'revert', 'status-flags']
179
318
def run(self, show_ids=False, file_list=None, revision=None, short=False,
319
versioned=False, no_pending=False, verbose=False):
181
320
from bzrlib.status import show_tree_status
183
tree, file_list = tree_files(file_list)
322
if revision and len(revision) > 2:
323
raise errors.BzrCommandError('bzr status --revision takes exactly'
324
' one or two revision specifiers')
326
tree, relfile_list = tree_files(file_list)
327
# Avoid asking for specific files when that is not needed.
328
if relfile_list == ['']:
330
# Don't disable pending merges for full trees other than '.'.
331
if file_list == ['.']:
333
# A specific path within a tree was given.
334
elif relfile_list is not None:
185
336
show_tree_status(tree, show_ids=show_ids,
186
specific_files=file_list, revision=revision,
187
to_file=self.outf, short=short, versioned=versioned)
337
specific_files=relfile_list, revision=revision,
338
to_file=self.outf, short=short, versioned=versioned,
339
show_pending=(not no_pending), verbose=verbose)
190
342
class cmd_cat_revision(Command):
191
"""Write out metadata for a revision.
343
__doc__ = """Write out metadata for a revision.
193
345
The revision to print can either be specified by a specific
194
346
revision identifier, or you can use --revision.
198
350
takes_args = ['revision_id?']
199
takes_options = ['revision']
351
takes_options = ['directory', 'revision']
200
352
# cat-revision is more for frontends so should be exact
201
353
encoding = 'strict'
355
def print_revision(self, revisions, revid):
356
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
357
record = stream.next()
358
if record.storage_kind == 'absent':
359
raise errors.NoSuchRevision(revisions, revid)
360
revtext = record.get_bytes_as('fulltext')
361
self.outf.write(revtext.decode('utf-8'))
204
def run(self, revision_id=None, revision=None):
206
revision_id = osutils.safe_revision_id(revision_id, warn=False)
364
def run(self, revision_id=None, revision=None, directory=u'.'):
207
365
if revision_id is not None and revision is not None:
208
366
raise errors.BzrCommandError('You can only supply one of'
209
367
' revision_id or --revision')
210
368
if revision_id is None and revision is None:
211
369
raise errors.BzrCommandError('You must supply either'
212
370
' --revision or a revision_id')
213
b = WorkingTree.open_containing(u'.')[0].branch
215
# TODO: jam 20060112 should cat-revision always output utf-8?
216
if revision_id is not None:
217
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
218
elif revision is not None:
221
raise errors.BzrCommandError('You cannot specify a NULL'
223
revno, rev_id = rev.in_history(b)
224
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
371
b = WorkingTree.open_containing(directory)[0].branch
373
revisions = b.repository.revisions
374
if revisions is None:
375
raise errors.BzrCommandError('Repository %r does not support '
376
'access to raw revision texts')
378
b.repository.lock_read()
380
# TODO: jam 20060112 should cat-revision always output utf-8?
381
if revision_id is not None:
382
revision_id = osutils.safe_revision_id(revision_id, warn=False)
384
self.print_revision(revisions, revision_id)
385
except errors.NoSuchRevision:
386
msg = "The repository %s contains no revision %s." % (
387
b.repository.base, revision_id)
388
raise errors.BzrCommandError(msg)
389
elif revision is not None:
392
raise errors.BzrCommandError(
393
'You cannot specify a NULL revision.')
394
rev_id = rev.as_revision_id(b)
395
self.print_revision(revisions, rev_id)
397
b.repository.unlock()
400
class cmd_dump_btree(Command):
401
__doc__ = """Dump the contents of a btree index file to stdout.
403
PATH is a btree index file, it can be any URL. This includes things like
404
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
406
By default, the tuples stored in the index file will be displayed. With
407
--raw, we will uncompress the pages, but otherwise display the raw bytes
411
# TODO: Do we want to dump the internal nodes as well?
412
# TODO: It would be nice to be able to dump the un-parsed information,
413
# rather than only going through iter_all_entries. However, this is
414
# good enough for a start
416
encoding_type = 'exact'
417
takes_args = ['path']
418
takes_options = [Option('raw', help='Write the uncompressed bytes out,'
419
' rather than the parsed tuples.'),
422
def run(self, path, raw=False):
423
dirname, basename = osutils.split(path)
424
t = transport.get_transport(dirname)
426
self._dump_raw_bytes(t, basename)
428
self._dump_entries(t, basename)
430
def _get_index_and_bytes(self, trans, basename):
431
"""Create a BTreeGraphIndex and raw bytes."""
432
bt = btree_index.BTreeGraphIndex(trans, basename, None)
433
bytes = trans.get_bytes(basename)
434
bt._file = cStringIO.StringIO(bytes)
435
bt._size = len(bytes)
438
def _dump_raw_bytes(self, trans, basename):
441
# We need to parse at least the root node.
442
# This is because the first page of every row starts with an
443
# uncompressed header.
444
bt, bytes = self._get_index_and_bytes(trans, basename)
445
for page_idx, page_start in enumerate(xrange(0, len(bytes),
446
btree_index._PAGE_SIZE)):
447
page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
448
page_bytes = bytes[page_start:page_end]
450
self.outf.write('Root node:\n')
451
header_end, data = bt._parse_header_from_bytes(page_bytes)
452
self.outf.write(page_bytes[:header_end])
454
self.outf.write('\nPage %d\n' % (page_idx,))
455
decomp_bytes = zlib.decompress(page_bytes)
456
self.outf.write(decomp_bytes)
457
self.outf.write('\n')
459
def _dump_entries(self, trans, basename):
461
st = trans.stat(basename)
462
except errors.TransportNotPossible:
463
# We can't stat, so we'll fake it because we have to do the 'get()'
465
bt, _ = self._get_index_and_bytes(trans, basename)
467
bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
468
for node in bt.iter_all_entries():
469
# Node is made up of:
470
# (index, key, value, [references])
474
refs_as_tuples = None
476
refs_as_tuples = static_tuple.as_tuples(refs)
477
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
478
self.outf.write('%s\n' % (as_tuple,))
227
481
class cmd_remove_tree(Command):
228
"""Remove the working tree from a given branch/checkout.
482
__doc__ = """Remove the working tree from a given branch/checkout.
230
484
Since a lightweight checkout is little more than a working tree
231
485
this will refuse to run against one.
508
817
takes_args = ['names*']
509
takes_options = [Option("after", help="move only the bzr identifier"
510
" of the file (file has already been moved). Use this flag if"
511
" bzr is not able to detect this itself.")]
818
takes_options = [Option("after", help="Move only the bzr identifier"
819
" of the file, because the file has already been moved."),
820
Option('auto', help='Automatically guess renames.'),
821
Option('dry-run', help='Avoid making changes when guessing renames.'),
512
823
aliases = ['move', 'rename']
513
824
encoding_type = 'replace'
515
def run(self, names_list, after=False):
826
def run(self, names_list, after=False, auto=False, dry_run=False):
828
return self.run_auto(names_list, after, dry_run)
830
raise errors.BzrCommandError('--dry-run requires --auto.')
516
831
if names_list is None:
519
833
if len(names_list) < 2:
520
834
raise errors.BzrCommandError("missing file argument")
521
tree, rel_names = tree_files(names_list)
523
if os.path.isdir(names_list[-1]):
835
tree, rel_names = tree_files(names_list, canonicalize=False)
836
self.add_cleanup(tree.lock_tree_write().unlock)
837
self._run(tree, names_list, rel_names, after)
839
def run_auto(self, names_list, after, dry_run):
840
if names_list is not None and len(names_list) > 1:
841
raise errors.BzrCommandError('Only one path may be specified to'
844
raise errors.BzrCommandError('--after cannot be specified with'
846
work_tree, file_list = tree_files(names_list, default_branch='.')
847
self.add_cleanup(work_tree.lock_tree_write().unlock)
848
rename_map.RenameMap.guess_renames(work_tree, dry_run)
850
def _run(self, tree, names_list, rel_names, after):
851
into_existing = osutils.isdir(names_list[-1])
852
if into_existing and len(names_list) == 2:
854
# a. case-insensitive filesystem and change case of dir
855
# b. move directory after the fact (if the source used to be
856
# a directory, but now doesn't exist in the working tree
857
# and the target is an existing directory, just rename it)
858
if (not tree.case_sensitive
859
and rel_names[0].lower() == rel_names[1].lower()):
860
into_existing = False
863
# 'fix' the case of a potential 'from'
864
from_id = tree.path2id(
865
tree.get_canonical_inventory_path(rel_names[0]))
866
if (not osutils.lexists(names_list[0]) and
867
from_id and inv.get_file_kind(from_id) == "directory"):
868
into_existing = False
524
871
# move into existing directory
525
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
526
self.outf.write("%s => %s\n" % pair)
872
# All entries reference existing inventory items, so fix them up
873
# for cicp file-systems.
874
rel_names = tree.get_canonical_inventory_paths(rel_names)
875
for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
877
self.outf.write("%s => %s\n" % (src, dest))
528
879
if len(names_list) != 2:
529
880
raise errors.BzrCommandError('to mv multiple files the'
530
881
' destination must be a versioned'
532
tree.rename_one(rel_names[0], rel_names[1], after=after)
533
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
884
# for cicp file-systems: the src references an existing inventory
886
src = tree.get_canonical_inventory_path(rel_names[0])
887
# Find the canonical version of the destination: In all cases, the
888
# parent of the target must be in the inventory, so we fetch the
889
# canonical version from there (we do not always *use* the
890
# canonicalized tail portion - we may be attempting to rename the
892
canon_dest = tree.get_canonical_inventory_path(rel_names[1])
893
dest_parent = osutils.dirname(canon_dest)
894
spec_tail = osutils.basename(rel_names[1])
895
# For a CICP file-system, we need to avoid creating 2 inventory
896
# entries that differ only by case. So regardless of the case
897
# we *want* to use (ie, specified by the user or the file-system),
898
# we must always choose to use the case of any existing inventory
899
# items. The only exception to this is when we are attempting a
900
# case-only rename (ie, canonical versions of src and dest are
902
dest_id = tree.path2id(canon_dest)
903
if dest_id is None or tree.path2id(src) == dest_id:
904
# No existing item we care about, so work out what case we
905
# are actually going to use.
907
# If 'after' is specified, the tail must refer to a file on disk.
909
dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
911
# pathjoin with an empty tail adds a slash, which breaks
913
dest_parent_fq = tree.basedir
915
dest_tail = osutils.canonical_relpath(
917
osutils.pathjoin(dest_parent_fq, spec_tail))
919
# not 'after', so case as specified is used
920
dest_tail = spec_tail
922
# Use the existing item so 'mv' fails with AlreadyVersioned.
923
dest_tail = os.path.basename(canon_dest)
924
dest = osutils.pathjoin(dest_parent, dest_tail)
925
mutter("attempting to move %s => %s", src, dest)
926
tree.rename_one(src, dest, after=after)
928
self.outf.write("%s => %s\n" % (src, dest))
536
931
class cmd_pull(Command):
537
"""Turn this branch into a mirror of another branch.
932
__doc__ = """Turn this branch into a mirror of another branch.
539
This command only works on branches that have not diverged. Branches are
540
considered diverged if the destination branch's most recent commit is one
541
that has not been merged (directly or indirectly) into the parent.
934
By default, this command only works on branches that have not diverged.
935
Branches are considered diverged if the destination branch's most recent
936
commit is one that has not been merged (directly or indirectly) into the
543
939
If branches have diverged, you can use 'bzr merge' to integrate the changes
544
940
from one into the other. Once one branch has merged, the other should
545
941
be able to pull it again.
547
If you want to forget your local changes and just update your branch to
548
match the remote one, use pull --overwrite.
943
If you want to replace your local changes and just want your branch to
944
match the remote one, use pull --overwrite. This will work even if the two
945
branches have diverged.
550
947
If there is no default location set, the first pull will set it. After
551
948
that, you can omit the location to use the default. To change the
552
949
default, use --remember. The value will only be saved if the remote
553
950
location can be accessed.
952
Note: The location can be specified either in the form of a branch,
953
or in the form of a path to a file containing a merge directive generated
556
_see_also = ['push', 'update', 'status-flags']
557
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
559
help='branch to pull into, '
560
'rather than the one containing the working directory',
957
_see_also = ['push', 'update', 'status-flags', 'send']
958
takes_options = ['remember', 'overwrite', 'revision',
959
custom_help('verbose',
960
help='Show logs of pulled revisions.'),
961
custom_help('directory',
962
help='Branch to pull into, '
963
'rather than the one containing the working directory.'),
965
help="Perform a local pull in a bound "
966
"branch. Local pulls are not applied to "
565
970
takes_args = ['location?']
663
1078
_see_also = ['pull', 'update', 'working-trees']
664
takes_options = ['remember', 'overwrite', 'verbose',
1079
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
665
1080
Option('create-prefix',
666
1081
help='Create the path leading up to the branch '
667
'if it does not already exist'),
669
help='branch to push from, '
670
'rather than the one containing the working directory',
1082
'if it does not already exist.'),
1083
custom_help('directory',
1084
help='Branch to push from, '
1085
'rather than the one containing the working directory.'),
674
1086
Option('use-existing-dir',
675
1087
help='By default push will fail if the target'
676
1088
' directory exists, but does not already'
677
' have a control directory. This flag will'
1089
' have a control directory. This flag will'
678
1090
' allow push to proceed.'),
1092
help='Create a stacked branch that references the public location '
1093
'of the parent branch.'),
1094
Option('stacked-on',
1095
help='Create a stacked branch that refers to another branch '
1096
'for the commit history. Only the work not present in the '
1097
'referenced branch is included in the branch created.',
1100
help='Refuse to push if there are uncommitted changes in'
1101
' the working tree, --no-strict disables the check.'),
680
1103
takes_args = ['location?']
681
1104
encoding_type = 'replace'
683
1106
def run(self, location=None, remember=False, overwrite=False,
684
create_prefix=False, verbose=False,
685
use_existing_dir=False,
687
# FIXME: Way too big! Put this into a function called from the
1107
create_prefix=False, verbose=False, revision=None,
1108
use_existing_dir=False, directory=None, stacked_on=None,
1109
stacked=False, strict=None):
1110
from bzrlib.push import _show_push_branch
689
1112
if directory is None:
691
br_from = Branch.open_containing(directory)[0]
692
stored_loc = br_from.get_push_location()
1114
# Get the source branch
1116
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1117
# Get the tip's revision_id
1118
revision = _get_one_revision('push', revision)
1119
if revision is not None:
1120
revision_id = revision.in_history(br_from).rev_id
1123
if tree is not None and revision_id is None:
1124
tree.check_changed_or_out_of_date(
1125
strict, 'push_strict',
1126
more_error='Use --no-strict to force the push.',
1127
more_warning='Uncommitted changes will not be pushed.')
1128
# Get the stacked_on branch, if any
1129
if stacked_on is not None:
1130
stacked_on = urlutils.normalize_url(stacked_on)
1132
parent_url = br_from.get_parent()
1134
parent = Branch.open(parent_url)
1135
stacked_on = parent.get_public_branch()
1137
# I considered excluding non-http url's here, thus forcing
1138
# 'public' branches only, but that only works for some
1139
# users, so it's best to just depend on the user spotting an
1140
# error by the feedback given to them. RBC 20080227.
1141
stacked_on = parent_url
1143
raise errors.BzrCommandError(
1144
"Could not determine branch to refer to.")
1146
# Get the destination location
693
1147
if location is None:
1148
stored_loc = br_from.get_push_location()
694
1149
if stored_loc is None:
695
raise errors.BzrCommandError("No push location known or specified.")
1150
raise errors.BzrCommandError(
1151
"No push location known or specified.")
697
1153
display_url = urlutils.unescape_for_display(stored_loc,
698
1154
self.outf.encoding)
699
self.outf.write("Using saved location: %s\n" % display_url)
1155
self.outf.write("Using saved push location: %s\n" % display_url)
700
1156
location = stored_loc
702
to_transport = transport.get_transport(location)
704
br_to = repository_to = dir_to = None
706
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
707
except errors.NotBranchError:
708
pass # Didn't find anything
710
# If we can open a branch, use its direct repository, otherwise see
711
# if there is a repository without a branch.
713
br_to = dir_to.open_branch()
714
except errors.NotBranchError:
715
# Didn't find a branch, can we find a repository?
717
repository_to = dir_to.find_repository()
718
except errors.NoRepositoryPresent:
721
# Found a branch, so we must have found a repository
722
repository_to = br_to.repository
726
# The destination doesn't exist; create it.
727
# XXX: Refactor the create_prefix/no_create_prefix code into a
728
# common helper function
730
to_transport.mkdir('.')
731
except errors.FileExists:
732
if not use_existing_dir:
733
raise errors.BzrCommandError("Target directory %s"
734
" already exists, but does not have a valid .bzr"
735
" directory. Supply --use-existing-dir to push"
736
" there anyway." % location)
737
except errors.NoSuchFile:
738
if not create_prefix:
739
raise errors.BzrCommandError("Parent directory of %s"
741
"\nYou may supply --create-prefix to create all"
742
" leading parent directories."
745
_create_prefix(to_transport)
747
# Now the target directory exists, but doesn't have a .bzr
748
# directory. So we need to create it, along with any work to create
749
# all of the dependent branches, etc.
750
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
751
revision_id=br_from.last_revision())
752
br_to = dir_to.open_branch()
753
# TODO: Some more useful message about what was copied
754
note('Created new branch.')
755
# We successfully created the target, remember it
756
if br_from.get_push_location() is None or remember:
757
br_from.set_push_location(br_to.base)
758
elif repository_to is None:
759
# we have a bzrdir but no branch or repository
760
# XXX: Figure out what to do other than complain.
761
raise errors.BzrCommandError("At %s you have a valid .bzr control"
762
" directory, but not a branch or repository. This is an"
763
" unsupported configuration. Please move the target directory"
764
" out of the way and try again."
767
# We have a repository but no branch, copy the revisions, and then
769
last_revision_id = br_from.last_revision()
770
repository_to.fetch(br_from.repository,
771
revision_id=last_revision_id)
772
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
773
note('Created new branch.')
774
if br_from.get_push_location() is None or remember:
775
br_from.set_push_location(br_to.base)
776
else: # We have a valid to branch
777
# We were able to connect to the remote location, so remember it
778
# we don't need to successfully push because of possible divergence.
779
if br_from.get_push_location() is None or remember:
780
br_from.set_push_location(br_to.base)
781
old_rh = br_to.revision_history()
784
tree_to = dir_to.open_workingtree()
785
except errors.NotLocalUrl:
786
warning("This transport does not update the working "
787
"tree of: %s. See 'bzr help working-trees' for "
788
"more information." % br_to.base)
789
push_result = br_from.push(br_to, overwrite)
790
except errors.NoWorkingTree:
791
push_result = br_from.push(br_to, overwrite)
795
push_result = br_from.push(tree_to.branch, overwrite)
799
except errors.DivergedBranches:
800
raise errors.BzrCommandError('These branches have diverged.'
801
' Try using "merge" and then "push".')
802
if push_result is not None:
803
push_result.report(self.outf)
805
new_rh = br_to.revision_history()
808
from bzrlib.log import show_changed_revisions
809
show_changed_revisions(br_to, old_rh, new_rh,
812
# we probably did a clone rather than a push, so a message was
1158
_show_push_branch(br_from, revision_id, location, self.outf,
1159
verbose=verbose, overwrite=overwrite, remember=remember,
1160
stacked_on=stacked_on, create_prefix=create_prefix,
1161
use_existing_dir=use_existing_dir)
817
1164
class cmd_branch(Command):
818
"""Create a new copy of a branch.
1165
__doc__ = """Create a new branch that is a copy of an existing branch.
820
1167
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
821
1168
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
831
1178
_see_also = ['checkout']
832
1179
takes_args = ['from_location', 'to_location?']
833
takes_options = ['revision']
1180
takes_options = ['revision', Option('hardlink',
1181
help='Hard-link working tree files where possible.'),
1183
help="Create a branch without a working-tree."),
1185
help="Switch the checkout in the current directory "
1186
"to the new branch."),
1188
help='Create a stacked branch referring to the source branch. '
1189
'The new branch will depend on the availability of the source '
1190
'branch for all operations.'),
1191
Option('standalone',
1192
help='Do not use a shared repository, even if available.'),
1193
Option('use-existing-dir',
1194
help='By default branch will fail if the target'
1195
' directory exists, but does not already'
1196
' have a control directory. This flag will'
1197
' allow branch to proceed.'),
1199
help="Bind new branch to from location."),
834
1201
aliases = ['get', 'clone']
836
def run(self, from_location, to_location=None, revision=None):
1203
def run(self, from_location, to_location=None, revision=None,
1204
hardlink=False, stacked=False, standalone=False, no_tree=False,
1205
use_existing_dir=False, switch=False, bind=False):
1206
from bzrlib import switch as _mod_switch
837
1207
from bzrlib.tag import _merge_tags_if_possible
840
elif len(revision) > 1:
841
raise errors.BzrCommandError(
842
'bzr branch --revision takes exactly 1 revision value')
844
br_from = Branch.open(from_location)
847
if len(revision) == 1 and revision[0] is not None:
848
revision_id = revision[0].in_history(br_from)[1]
850
# FIXME - wt.last_revision, fallback to branch, fall back to
851
# None or perhaps NULL_REVISION to mean copy nothing
853
revision_id = br_from.last_revision()
854
if to_location is None:
855
to_location = urlutils.derive_to_location(from_location)
858
name = os.path.basename(to_location) + '\n'
860
to_transport = transport.get_transport(to_location)
862
to_transport.mkdir('.')
863
except errors.FileExists:
864
raise errors.BzrCommandError('Target directory "%s" already'
865
' exists.' % to_location)
866
except errors.NoSuchFile:
867
raise errors.BzrCommandError('Parent of "%s" does not exist.'
870
# preserve whatever source format we have.
871
dir = br_from.bzrdir.sprout(to_transport.base, revision_id)
872
branch = dir.open_branch()
873
except errors.NoSuchRevision:
874
to_transport.delete_tree('.')
875
msg = "The branch %s has no revision %s." % (from_location, revision[0])
876
raise errors.BzrCommandError(msg)
878
branch.control_files.put_utf8('branch-name', name)
879
_merge_tags_if_possible(br_from, branch)
1208
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1210
revision = _get_one_revision('branch', revision)
1211
self.add_cleanup(br_from.lock_read().unlock)
1212
if revision is not None:
1213
revision_id = revision.as_revision_id(br_from)
1215
# FIXME - wt.last_revision, fallback to branch, fall back to
1216
# None or perhaps NULL_REVISION to mean copy nothing
1218
revision_id = br_from.last_revision()
1219
if to_location is None:
1220
to_location = urlutils.derive_to_location(from_location)
1221
to_transport = transport.get_transport(to_location)
1223
to_transport.mkdir('.')
1224
except errors.FileExists:
1225
if not use_existing_dir:
1226
raise errors.BzrCommandError('Target directory "%s" '
1227
'already exists.' % to_location)
1230
bzrdir.BzrDir.open_from_transport(to_transport)
1231
except errors.NotBranchError:
1234
raise errors.AlreadyBranchError(to_location)
1235
except errors.NoSuchFile:
1236
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1239
# preserve whatever source format we have.
1240
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1241
possible_transports=[to_transport],
1242
accelerator_tree=accelerator_tree,
1243
hardlink=hardlink, stacked=stacked,
1244
force_new_repo=standalone,
1245
create_tree_if_local=not no_tree,
1246
source_branch=br_from)
1247
branch = dir.open_branch()
1248
except errors.NoSuchRevision:
1249
to_transport.delete_tree('.')
1250
msg = "The branch %s has no revision %s." % (from_location,
1252
raise errors.BzrCommandError(msg)
1253
_merge_tags_if_possible(br_from, branch)
1254
# If the source branch is stacked, the new branch may
1255
# be stacked whether we asked for that explicitly or not.
1256
# We therefore need a try/except here and not just 'if stacked:'
1258
note('Created new stacked branch referring to %s.' %
1259
branch.get_stacked_on_url())
1260
except (errors.NotStacked, errors.UnstackableBranchFormat,
1261
errors.UnstackableRepositoryFormat), e:
880
1262
note('Branched %d revision(s).' % branch.revno())
1264
# Bind to the parent
1265
parent_branch = Branch.open(from_location)
1266
branch.bind(parent_branch)
1267
note('New branch bound to %s' % from_location)
1269
# Switch to the new branch
1270
wt, _ = WorkingTree.open_containing('.')
1271
_mod_switch.switch(wt.bzrdir, branch)
1272
note('Switched to branch: %s',
1273
urlutils.unescape_for_display(branch.base, 'utf-8'))
885
1276
class cmd_checkout(Command):
886
"""Create a new checkout of an existing branch.
1277
__doc__ = """Create a new checkout of an existing branch.
888
1279
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
889
1280
the branch found in '.'. This is useful if you have removed the working tree
890
1281
or if it was never created - i.e. if you pushed the branch to its current
891
1282
location using SFTP.
893
1284
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
894
1285
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
895
1286
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
969
1354
@display_command
970
1355
def run(self, dir=u'.'):
971
1356
tree = WorkingTree.open_containing(dir)[0]
974
new_inv = tree.inventory
975
old_tree = tree.basis_tree()
978
old_inv = old_tree.inventory
979
renames = list(_mod_tree.find_renames(old_inv, new_inv))
981
for old_name, new_name in renames:
982
self.outf.write("%s => %s\n" % (old_name, new_name))
1357
self.add_cleanup(tree.lock_read().unlock)
1358
new_inv = tree.inventory
1359
old_tree = tree.basis_tree()
1360
self.add_cleanup(old_tree.lock_read().unlock)
1361
old_inv = old_tree.inventory
1363
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1364
for f, paths, c, v, p, n, k, e in iterator:
1365
if paths[0] == paths[1]:
1369
renames.append(paths)
1371
for old_name, new_name in renames:
1372
self.outf.write("%s => %s\n" % (old_name, new_name))
989
1375
class cmd_update(Command):
990
"""Update a tree to have the latest code committed to its branch.
1376
__doc__ = """Update a tree to have the latest code committed to its branch.
992
1378
This will perform a merge into the working tree, and may generate
993
conflicts. If you have any local changes, you will still
1379
conflicts. If you have any local changes, you will still
994
1380
need to commit them after the update for the update to be complete.
996
If you want to discard your local changes, you can just do a
1382
If you want to discard your local changes, you can just do a
997
1383
'bzr revert' instead of 'bzr commit' after the update.
1385
If the tree's branch is bound to a master branch, it will also update
1386
the branch from the master.
1000
_see_also = ['pull', 'working-trees']
1389
_see_also = ['pull', 'working-trees', 'status-flags']
1001
1390
takes_args = ['dir?']
1391
takes_options = ['revision']
1002
1392
aliases = ['up']
1004
def run(self, dir='.'):
1394
def run(self, dir='.', revision=None):
1395
if revision is not None and len(revision) != 1:
1396
raise errors.BzrCommandError(
1397
"bzr update --revision takes exactly one revision")
1005
1398
tree = WorkingTree.open_containing(dir)[0]
1006
master = tree.branch.get_master_branch()
1399
branch = tree.branch
1400
possible_transports = []
1401
master = branch.get_master_branch(
1402
possible_transports=possible_transports)
1007
1403
if master is not None:
1404
branch_location = master.base
1008
1405
tree.lock_write()
1407
branch_location = tree.branch.base
1010
1408
tree.lock_tree_write()
1409
self.add_cleanup(tree.unlock)
1410
# get rid of the final '/' and be ready for display
1411
branch_location = urlutils.unescape_for_display(
1412
branch_location.rstrip('/'),
1414
existing_pending_merges = tree.get_parent_ids()[1:]
1418
# may need to fetch data into a heavyweight checkout
1419
# XXX: this may take some time, maybe we should display a
1421
old_tip = branch.update(possible_transports)
1422
if revision is not None:
1423
revision_id = revision[0].as_revision_id(branch)
1425
revision_id = branch.last_revision()
1426
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1427
revno = branch.revision_id_to_dotted_revno(revision_id)
1428
note("Tree is up to date at revision %s of branch %s" %
1429
('.'.join(map(str, revno)), branch_location))
1431
view_info = _get_view_info_for_change_reporter(tree)
1432
change_reporter = delta._ChangeReporter(
1433
unversioned_filter=tree.is_ignored,
1434
view_info=view_info)
1012
existing_pending_merges = tree.get_parent_ids()[1:]
1013
last_rev = tree.last_revision()
1014
if last_rev == tree.branch.last_revision():
1015
# may be up to date, check master too.
1016
master = tree.branch.get_master_branch()
1017
if master is None or last_rev == master.last_revision():
1018
revno = tree.branch.revision_id_to_revno(last_rev)
1019
note("Tree is up to date at revision %d." % (revno,))
1021
conflicts = tree.update(delta._ChangeReporter(
1022
unversioned_filter=tree.is_ignored))
1023
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1024
note('Updated to revision %d.' % (revno,))
1025
if tree.get_parent_ids()[1:] != existing_pending_merges:
1026
note('Your local commits will now show as pending merges with '
1027
"'bzr status', and can be committed with 'bzr commit'.")
1436
conflicts = tree.update(
1438
possible_transports=possible_transports,
1439
revision=revision_id,
1441
except errors.NoSuchRevision, e:
1442
raise errors.BzrCommandError(
1443
"branch has no revision %s\n"
1444
"bzr update --revision only works"
1445
" for a revision in the branch history"
1447
revno = tree.branch.revision_id_to_dotted_revno(
1448
_mod_revision.ensure_null(tree.last_revision()))
1449
note('Updated to revision %s of branch %s' %
1450
('.'.join(map(str, revno)), branch_location))
1451
parent_ids = tree.get_parent_ids()
1452
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1453
note('Your local commits will now show as pending merges with '
1454
"'bzr status', and can be committed with 'bzr commit'.")
1036
1461
class cmd_info(Command):
1037
"""Show information about a working tree, branch or repository.
1462
__doc__ = """Show information about a working tree, branch or repository.
1039
1464
This command will show all known locations and formats associated to the
1040
tree, branch or repository. Statistical information is included with
1465
tree, branch or repository.
1467
In verbose mode, statistical information is included with each report.
1468
To see extended statistic information, use a verbosity level of 2 or
1469
higher by specifying the verbose option multiple times, e.g. -vv.
1043
1471
Branches and working trees will also report any missing revisions.
1475
Display information on the format and related locations:
1479
Display the above together with extended format information and
1480
basic statistics (like the number of files in the working tree and
1481
number of revisions in the branch and repository):
1485
Display the above together with number of committers to the branch:
1045
1489
_see_also = ['revno', 'working-trees', 'repositories']
1046
1490
takes_args = ['location?']
1047
1491
takes_options = ['verbose']
1492
encoding_type = 'replace'
1049
1494
@display_command
1050
def run(self, location=None, verbose=0):
1495
def run(self, location=None, verbose=False):
1497
noise_level = get_verbosity_level()
1051
1500
from bzrlib.info import show_bzrdir_info
1052
1501
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1502
verbose=noise_level, outfile=self.outf)
1056
1505
class cmd_remove(Command):
1057
"""Remove files or directories.
1059
This makes bzr stop tracking changes to the specified files and
1060
delete them if they can easily be recovered using revert.
1062
You can specify one or more files, and/or --new. If you specify --new,
1063
only 'added' files will be removed. If you specify both, then new files
1064
in the specified directories will be removed. If the directories are
1065
also new, they will also be removed.
1506
__doc__ = """Remove files or directories.
1508
This makes bzr stop tracking changes to the specified files. bzr will delete
1509
them if they can easily be recovered using revert. If no options or
1510
parameters are given bzr will scan for files that are being tracked by bzr
1511
but missing in your tree and stop tracking them for you.
1067
1513
takes_args = ['file*']
1068
1514
takes_options = ['verbose',
1069
Option('new', help='remove newly-added files'),
1515
Option('new', help='Only remove files that have never been committed.'),
1070
1516
RegistryOption.from_kwargs('file-deletion-strategy',
1071
'The file deletion mode to be used',
1517
'The file deletion mode to be used.',
1072
1518
title='Deletion Strategy', value_switches=True, enum_switch=False,
1073
1519
safe='Only delete files if they can be'
1074
1520
' safely recovered (default).',
1075
keep="Don't delete any files.",
1521
keep='Delete from bzr but leave the working copy.',
1076
1522
force='Delete all the specified files, even if they can not be '
1077
1523
'recovered and even if they are non-empty directories.')]
1524
aliases = ['rm', 'del']
1079
1525
encoding_type = 'replace'
1081
1527
def run(self, file_list, verbose=False, new=False,
1563
2080
raise errors.BzrCommandError(msg)
2083
def _parse_levels(s):
2087
msg = "The levels argument must be an integer."
2088
raise errors.BzrCommandError(msg)
1566
2091
class cmd_log(Command):
1567
"""Show log of a branch, file, or directory.
1569
By default show the log of the branch containing the working directory.
1571
To request a range of logs, you can use the command -r begin..end
1572
-r revision requests a specific revision, -r ..end or -r begin.. are
1578
bzr log -r -10.. http://server/branch
2092
__doc__ = """Show historical log for a branch or subset of a branch.
2094
log is bzr's default tool for exploring the history of a branch.
2095
The branch to use is taken from the first parameter. If no parameters
2096
are given, the branch containing the working directory is logged.
2097
Here are some simple examples::
2099
bzr log log the current branch
2100
bzr log foo.py log a file in its branch
2101
bzr log http://server/branch log a branch on a server
2103
The filtering, ordering and information shown for each revision can
2104
be controlled as explained below. By default, all revisions are
2105
shown sorted (topologically) so that newer revisions appear before
2106
older ones and descendants always appear before ancestors. If displayed,
2107
merged revisions are shown indented under the revision in which they
2112
The log format controls how information about each revision is
2113
displayed. The standard log formats are called ``long``, ``short``
2114
and ``line``. The default is long. See ``bzr help log-formats``
2115
for more details on log formats.
2117
The following options can be used to control what information is
2120
-l N display a maximum of N revisions
2121
-n N display N levels of revisions (0 for all, 1 for collapsed)
2122
-v display a status summary (delta) for each revision
2123
-p display a diff (patch) for each revision
2124
--show-ids display revision-ids (and file-ids), not just revnos
2126
Note that the default number of levels to display is a function of the
2127
log format. If the -n option is not used, the standard log formats show
2128
just the top level (mainline).
2130
Status summaries are shown using status flags like A, M, etc. To see
2131
the changes explained using words like ``added`` and ``modified``
2132
instead, use the -vv option.
2136
To display revisions from oldest to newest, use the --forward option.
2137
In most cases, using this option will have little impact on the total
2138
time taken to produce a log, though --forward does not incrementally
2139
display revisions like --reverse does when it can.
2141
:Revision filtering:
2143
The -r option can be used to specify what revision or range of revisions
2144
to filter against. The various forms are shown below::
2146
-rX display revision X
2147
-rX.. display revision X and later
2148
-r..Y display up to and including revision Y
2149
-rX..Y display from X to Y inclusive
2151
See ``bzr help revisionspec`` for details on how to specify X and Y.
2152
Some common examples are given below::
2154
-r-1 show just the tip
2155
-r-10.. show the last 10 mainline revisions
2156
-rsubmit:.. show what's new on this branch
2157
-rancestor:path.. show changes since the common ancestor of this
2158
branch and the one at location path
2159
-rdate:yesterday.. show changes since yesterday
2161
When logging a range of revisions using -rX..Y, log starts at
2162
revision Y and searches back in history through the primary
2163
("left-hand") parents until it finds X. When logging just the
2164
top level (using -n1), an error is reported if X is not found
2165
along the way. If multi-level logging is used (-n0), X may be
2166
a nested merge revision and the log will be truncated accordingly.
2170
If parameters are given and the first one is not a branch, the log
2171
will be filtered to show only those revisions that changed the
2172
nominated files or directories.
2174
Filenames are interpreted within their historical context. To log a
2175
deleted file, specify a revision range so that the file existed at
2176
the end or start of the range.
2178
Historical context is also important when interpreting pathnames of
2179
renamed files/directories. Consider the following example:
2181
* revision 1: add tutorial.txt
2182
* revision 2: modify tutorial.txt
2183
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2187
* ``bzr log guide.txt`` will log the file added in revision 1
2189
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2191
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2192
the original file in revision 2.
2194
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2195
was no file called guide.txt in revision 2.
2197
Renames are always followed by log. By design, there is no need to
2198
explicitly ask for this (and no way to stop logging a file back
2199
until it was last renamed).
2203
The --message option can be used for finding revisions that match a
2204
regular expression in a commit message.
2208
GUI tools and IDEs are often better at exploring history than command
2209
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2210
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2211
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2212
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2214
You may find it useful to add the aliases below to ``bazaar.conf``::
2218
top = log -l10 --line
2221
``bzr tip`` will then show the latest revision while ``bzr top``
2222
will show the last 10 mainline revisions. To see the details of a
2223
particular revision X, ``bzr show -rX``.
2225
If you are interested in looking deeper into a particular merge X,
2226
use ``bzr log -n0 -rX``.
2228
``bzr log -v`` on a branch with lots of history is currently
2229
very slow. A fix for this issue is currently under development.
2230
With or without that fix, it is recommended that a revision range
2231
be given when using the -v option.
2233
bzr has a generic full-text matching plugin, bzr-search, that can be
2234
used to find revisions matching user names, commit messages, etc.
2235
Among other features, this plugin can find all revisions containing
2236
a list of words but not others.
2238
When exploring non-mainline history on large projects with deep
2239
history, the performance of log can be greatly improved by installing
2240
the historycache plugin. This plugin buffers historical information
2241
trading disk space for faster speed.
1581
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1583
takes_args = ['location?']
1584
takes_options = [Option('forward',
1585
help='show from oldest to newest'),
1589
help='show files changed in each revision'),
1590
'show-ids', 'revision',
1594
help='show revisions whose message matches this regexp',
1597
help='limit the output to the first N revisions',
2243
takes_args = ['file*']
2244
_see_also = ['log-formats', 'revisionspec']
2247
help='Show from oldest to newest.'),
2249
custom_help('verbose',
2250
help='Show files changed in each revision.'),
2254
type=bzrlib.option._parse_revision_str,
2256
help='Show just the specified revision.'
2257
' See also "help revisionspec".'),
2259
RegistryOption('authors',
2260
'What names to list as authors - first, all or committer.',
2262
lazy_registry=('bzrlib.log', 'author_list_registry'),
2266
help='Number of levels to display - 0 for all, 1 for flat.',
2268
type=_parse_levels),
2271
help='Show revisions whose message matches this '
2272
'regular expression.',
2276
help='Limit the output to the first N revisions.',
2281
help='Show changes made in each revision as a patch.'),
2282
Option('include-merges',
2283
help='Show merged revisions like --levels 0 does.'),
2284
Option('exclude-common-ancestry',
2285
help='Display only the revisions that are not part'
2286
' of both ancestries (require -rX..Y)'
1600
2289
encoding_type = 'replace'
1602
2291
@display_command
1603
def run(self, location=None, timezone='original',
2292
def run(self, file_list=None, timezone='original',
1605
2294
show_ids=False,
1608
2298
log_format=None,
1611
from bzrlib.log import show_log
1612
assert message is None or isinstance(message, basestring), \
1613
"invalid message argument %r" % message
2303
include_merges=False,
2305
exclude_common_ancestry=False,
2307
from bzrlib.log import (
2309
make_log_request_dict,
2310
_get_info_for_log_files,
1614
2312
direction = (forward and 'forward') or 'reverse'
1619
# find the file id to log:
1621
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1625
tree = b.basis_tree()
1626
file_id = tree.path2id(fp)
2313
if (exclude_common_ancestry
2314
and (revision is None or len(revision) != 2)):
2315
raise errors.BzrCommandError(
2316
'--exclude-common-ancestry requires -r with two revisions')
2321
raise errors.BzrCommandError(
2322
'--levels and --include-merges are mutually exclusive')
2324
if change is not None:
2326
raise errors.RangeInChangeOption()
2327
if revision is not None:
2328
raise errors.BzrCommandError(
2329
'--revision and --change are mutually exclusive')
2334
filter_by_dir = False
2336
# find the file ids to log and check for directory filtering
2337
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2338
revision, file_list, self.add_cleanup)
2339
for relpath, file_id, kind in file_info_list:
1627
2340
if file_id is None:
1628
2341
raise errors.BzrCommandError(
1629
"Path does not have any revision history: %s" %
2342
"Path unknown at end or start of revision range: %s" %
2344
# If the relpath is the top of the tree, we log everything
2349
file_ids.append(file_id)
2350
filter_by_dir = filter_by_dir or (
2351
kind in ['directory', 'tree-reference'])
1633
# FIXME ? log the current subdir only RBC 20060203
2354
# FIXME ? log the current subdir only RBC 20060203
1634
2355
if revision is not None \
1635
2356
and len(revision) > 0 and revision[0].get_branch():
1636
2357
location = revision[0].get_branch()
1745
2540
if path is None:
1750
2544
raise errors.BzrCommandError('cannot specify both --from-root'
1754
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2547
tree, branch, relpath = \
2548
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2550
# Calculate the prefix to use
1760
if revision is not None:
1761
tree = branch.repository.revision_tree(
1762
revision[0].in_history(branch).rev_id)
1764
tree = branch.basis_tree()
1768
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1769
if fp.startswith(relpath):
1770
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1771
if non_recursive and '/' in fp:
1773
if not all and not selection[fc]:
1775
if kind is not None and fkind != kind:
1778
kindch = entry.kind_character()
1779
outstring = '%-8s %s%s' % (fc, fp, kindch)
1780
if show_ids and fid is not None:
1781
outstring = "%-50s %s" % (outstring, fid)
1782
self.outf.write(outstring + '\n')
1784
self.outf.write(fp + '\0')
1787
self.outf.write(fid)
1788
self.outf.write('\0')
1796
self.outf.write('%-50s %s\n' % (fp, my_id))
1798
self.outf.write(fp + '\n')
2554
prefix = relpath + '/'
2555
elif fs_path != '.' and not fs_path.endswith('/'):
2556
prefix = fs_path + '/'
2558
if revision is not None or tree is None:
2559
tree = _get_one_revision_tree('ls', revision, branch=branch)
2562
if isinstance(tree, WorkingTree) and tree.supports_views():
2563
view_files = tree.views.lookup_view()
2566
view_str = views.view_display_str(view_files)
2567
note("Ignoring files outside view. View is %s" % view_str)
2569
self.add_cleanup(tree.lock_read().unlock)
2570
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2571
from_dir=relpath, recursive=recursive):
2572
# Apply additional masking
2573
if not all and not selection[fc]:
2575
if kind is not None and fkind != kind:
2580
fullpath = osutils.pathjoin(relpath, fp)
2583
views.check_path_in_view(tree, fullpath)
2584
except errors.FileOutsideView:
2589
fp = osutils.pathjoin(prefix, fp)
2590
kindch = entry.kind_character()
2591
outstring = fp + kindch
2592
ui.ui_factory.clear_term()
2594
outstring = '%-8s %s' % (fc, outstring)
2595
if show_ids and fid is not None:
2596
outstring = "%-50s %s" % (outstring, fid)
2597
self.outf.write(outstring + '\n')
2599
self.outf.write(fp + '\0')
2602
self.outf.write(fid)
2603
self.outf.write('\0')
2611
self.outf.write('%-50s %s\n' % (outstring, my_id))
2613
self.outf.write(outstring + '\n')
1803
2616
class cmd_unknowns(Command):
1804
"""List unknown files.
2617
__doc__ = """List unknown files.
1808
2621
_see_also = ['ls']
2622
takes_options = ['directory']
1810
2624
@display_command
1812
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2625
def run(self, directory=u'.'):
2626
for f in WorkingTree.open_containing(directory)[0].unknowns():
1813
2627
self.outf.write(osutils.quotefn(f) + '\n')
1816
2630
class cmd_ignore(Command):
1817
"""Ignore specified files or patterns.
2631
__doc__ = """Ignore specified files or patterns.
2633
See ``bzr help patterns`` for details on the syntax of patterns.
2635
If a .bzrignore file does not exist, the ignore command
2636
will create one and add the specified files or patterns to the newly
2637
created file. The ignore command will also automatically add the
2638
.bzrignore file to be versioned. Creating a .bzrignore file without
2639
the use of the ignore command will require an explicit add command.
1819
2641
To remove patterns from the ignore list, edit the .bzrignore file.
1821
Trailing slashes on patterns are ignored.
1822
If the pattern contains a slash or is a regular expression, it is compared
1823
to the whole path from the branch root. Otherwise, it is compared to only
1824
the last component of the path. To match a file only in the root
1825
directory, prepend './'.
1827
Ignore patterns specifying absolute paths are not allowed.
1829
Ignore patterns may include globbing wildcards such as:
1830
? - Matches any single character except '/'
1831
* - Matches 0 or more characters except '/'
1832
/**/ - Matches 0 or more directories in a path
1833
[a-z] - Matches a single character from within a group of characters
1835
Ignore patterns may also be Python regular expressions.
1836
Regular expression ignore patterns are identified by a 'RE:' prefix
1837
followed by the regular expression. Regular expression ignore patterns
1838
may not include named or numbered groups.
1840
Note: ignore patterns containing shell wildcards must be quoted from
2642
After adding, editing or deleting that file either indirectly by
2643
using this command or directly by using an editor, be sure to commit
2646
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2647
the global ignore file can be found in the application data directory as
2648
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2649
Global ignores are not touched by this command. The global ignore file
2650
can be edited directly using an editor.
2652
Patterns prefixed with '!' are exceptions to ignore patterns and take
2653
precedence over regular ignores. Such exceptions are used to specify
2654
files that should be versioned which would otherwise be ignored.
2656
Patterns prefixed with '!!' act as regular ignore patterns, but have
2657
precedence over the '!' exception patterns.
2659
Note: ignore patterns containing shell wildcards must be quoted from
1841
2660
the shell on Unix.
1844
bzr ignore ./Makefile
1845
bzr ignore '*.class'
1846
bzr ignore 'lib/**/*.o'
1847
bzr ignore 'RE:lib/.*\.o'
2663
Ignore the top level Makefile::
2665
bzr ignore ./Makefile
2667
Ignore .class files in all directories...::
2669
bzr ignore "*.class"
2671
...but do not ignore "special.class"::
2673
bzr ignore "!special.class"
2675
Ignore .o files under the lib directory::
2677
bzr ignore "lib/**/*.o"
2679
Ignore .o files under the lib directory::
2681
bzr ignore "RE:lib/.*\.o"
2683
Ignore everything but the "debian" toplevel directory::
2685
bzr ignore "RE:(?!debian/).*"
2687
Ignore everything except the "local" toplevel directory,
2688
but always ignore "*~" autosave files, even under local/::
2691
bzr ignore "!./local"
1850
_see_also = ['status', 'ignored']
2695
_see_also = ['status', 'ignored', 'patterns']
1851
2696
takes_args = ['name_pattern*']
1853
Option('old-default-rules',
1854
help='Out the ignore rules bzr < 0.9 always used.')
1857
def run(self, name_pattern_list=None, old_default_rules=None):
1858
from bzrlib.atomicfile import AtomicFile
1859
if old_default_rules is not None:
1860
# dump the rules and exit
1861
for pattern in ignores.OLD_DEFAULTS:
2697
takes_options = ['directory',
2698
Option('default-rules',
2699
help='Display the default ignore rules that bzr uses.')
2702
def run(self, name_pattern_list=None, default_rules=None,
2704
from bzrlib import ignores
2705
if default_rules is not None:
2706
# dump the default rules and exit
2707
for pattern in ignores.USER_DEFAULTS:
2708
self.outf.write("%s\n" % pattern)
1864
2710
if not name_pattern_list:
1865
2711
raise errors.BzrCommandError("ignore requires at least one "
1866
"NAME_PATTERN or --old-default-rules")
1867
name_pattern_list = [globbing.normalize_pattern(p)
2712
"NAME_PATTERN or --default-rules.")
2713
name_pattern_list = [globbing.normalize_pattern(p)
1868
2714
for p in name_pattern_list]
1869
2715
for name_pattern in name_pattern_list:
1870
if (name_pattern[0] == '/' or
2716
if (name_pattern[0] == '/' or
1871
2717
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1872
2718
raise errors.BzrCommandError(
1873
2719
"NAME_PATTERN should not be an absolute path")
1874
tree, relpath = WorkingTree.open_containing(u'.')
1875
ifn = tree.abspath('.bzrignore')
1876
if os.path.exists(ifn):
1879
igns = f.read().decode('utf-8')
1885
# TODO: If the file already uses crlf-style termination, maybe
1886
# we should use that for the newly added lines?
1888
if igns and igns[-1] != '\n':
1890
for name_pattern in name_pattern_list:
1891
igns += name_pattern + '\n'
1893
f = AtomicFile(ifn, 'wb')
1895
f.write(igns.encode('utf-8'))
1900
if not tree.path2id('.bzrignore'):
1901
tree.add(['.bzrignore'])
2720
tree, relpath = WorkingTree.open_containing(directory)
2721
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2722
ignored = globbing.Globster(name_pattern_list)
2724
self.add_cleanup(tree.lock_read().unlock)
2725
for entry in tree.list_files():
2729
if ignored.match(filename):
2730
matches.append(filename)
2731
if len(matches) > 0:
2732
self.outf.write("Warning: the following files are version controlled and"
2733
" match your ignore pattern:\n%s"
2734
"\nThese files will continue to be version controlled"
2735
" unless you 'bzr remove' them.\n" % ("\n".join(matches),))
1904
2738
class cmd_ignored(Command):
1905
"""List ignored files and the patterns that matched them.
2739
__doc__ = """List ignored files and the patterns that matched them.
2741
List all the ignored files and the ignore pattern that caused the file to
2744
Alternatively, to list just the files::
1908
_see_also = ['ignore']
2749
encoding_type = 'replace'
2750
_see_also = ['ignore', 'ls']
2751
takes_options = ['directory']
1909
2753
@display_command
1911
tree = WorkingTree.open_containing(u'.')[0]
1914
for path, file_class, kind, file_id, entry in tree.list_files():
1915
if file_class != 'I':
1917
## XXX: Slightly inefficient since this was already calculated
1918
pat = tree.is_ignored(path)
1919
print '%-50s %s' % (path, pat)
2754
def run(self, directory=u'.'):
2755
tree = WorkingTree.open_containing(directory)[0]
2756
self.add_cleanup(tree.lock_read().unlock)
2757
for path, file_class, kind, file_id, entry in tree.list_files():
2758
if file_class != 'I':
2760
## XXX: Slightly inefficient since this was already calculated
2761
pat = tree.is_ignored(path)
2762
self.outf.write('%-50s %s\n' % (path, pat))
1924
2765
class cmd_lookup_revision(Command):
1925
"""Lookup the revision-id from a revision-number
2766
__doc__ = """Lookup the revision-id from a revision-number
1928
2769
bzr lookup-revision 33
1931
2772
takes_args = ['revno']
2773
takes_options = ['directory']
1933
2775
@display_command
1934
def run(self, revno):
2776
def run(self, revno, directory=u'.'):
1936
2778
revno = int(revno)
1937
2779
except ValueError:
1938
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
1940
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2780
raise errors.BzrCommandError("not a valid revision-number: %r"
2782
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2783
self.outf.write("%s\n" % revid)
1943
2786
class cmd_export(Command):
1944
"""Export current or past revision to a destination directory or archive.
2787
__doc__ = """Export current or past revision to a destination directory or archive.
1946
2789
If no revision is specified this exports the last committed revision.
1959
2802
Note: Export of tree with non-ASCII filenames to zip is not supported.
1961
Supported formats Autodetected by extension
1962
----------------- -------------------------
2804
================= =========================
2805
Supported formats Autodetected by extension
2806
================= =========================
1965
2809
tbz2 .tar.bz2, .tbz2
1966
2810
tgz .tar.gz, .tgz
2812
================= =========================
1969
takes_args = ['dest', 'branch?']
1970
takes_options = ['revision', 'format', 'root']
1971
def run(self, dest, branch=None, revision=None, format=None, root=None):
2814
takes_args = ['dest', 'branch_or_subdir?']
2815
takes_options = ['directory',
2817
help="Type of file to export to.",
2820
Option('filters', help='Apply content filters to export the '
2821
'convenient form.'),
2824
help="Name of the root directory inside the exported file."),
2825
Option('per-file-timestamps',
2826
help='Set modification time of files to that of the last '
2827
'revision in which it was changed.'),
2829
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2830
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
1972
2831
from bzrlib.export import export
1975
tree = WorkingTree.open_containing(u'.')[0]
2833
if branch_or_subdir is None:
2834
tree = WorkingTree.open_containing(directory)[0]
1976
2835
b = tree.branch
1978
b = Branch.open(branch)
1980
if revision is None:
1981
# should be tree.last_revision FIXME
1982
rev_id = b.last_revision()
1984
if len(revision) != 1:
1985
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1986
rev_id = revision[0].in_history(b).rev_id
1987
t = b.repository.revision_tree(rev_id)
2838
b, subdir = Branch.open_containing(branch_or_subdir)
2841
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
1989
export(t, dest, format, root)
2843
export(rev_tree, dest, format, root, subdir, filtered=filters,
2844
per_file_timestamps=per_file_timestamps)
1990
2845
except errors.NoSuchExportFormat, e:
1991
2846
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1994
2849
class cmd_cat(Command):
1995
"""Write the contents of a file as of a given revision to standard output.
2850
__doc__ = """Write the contents of a file as of a given revision to standard output.
1997
2852
If no revision is nominated, the last revision is used.
1999
2854
Note: Take care to redirect standard output when using this command on a
2003
2858
_see_also = ['ls']
2004
takes_options = ['revision', 'name-from-revision']
2859
takes_options = ['directory',
2860
Option('name-from-revision', help='The path name in the old tree.'),
2861
Option('filters', help='Apply content filters to display the '
2862
'convenience form.'),
2005
2865
takes_args = ['filename']
2006
2866
encoding_type = 'exact'
2008
2868
@display_command
2009
def run(self, filename, revision=None, name_from_revision=False):
2869
def run(self, filename, revision=None, name_from_revision=False,
2870
filters=False, directory=None):
2010
2871
if revision is not None and len(revision) != 1:
2011
2872
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2016
tree, b, relpath = \
2017
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2018
except errors.NotBranchError:
2021
if revision is not None and revision[0].get_branch() is not None:
2022
b = Branch.open(revision[0].get_branch())
2873
" one revision specifier")
2874
tree, branch, relpath = \
2875
_open_directory_or_containing_tree_or_branch(filename, directory)
2876
self.add_cleanup(branch.lock_read().unlock)
2877
return self._run(tree, branch, relpath, filename, revision,
2878
name_from_revision, filters)
2880
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2023
2882
if tree is None:
2024
2883
tree = b.basis_tree()
2025
if revision is None:
2026
revision_id = b.last_revision()
2028
revision_id = revision[0].in_history(b).rev_id
2884
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2885
self.add_cleanup(rev_tree.lock_read().unlock)
2030
cur_file_id = tree.path2id(relpath)
2031
rev_tree = b.repository.revision_tree(revision_id)
2032
2887
old_file_id = rev_tree.path2id(relpath)
2034
2889
if name_from_revision:
2890
# Try in revision if requested
2035
2891
if old_file_id is None:
2036
raise errors.BzrCommandError("%r is not present in revision %s"
2037
% (filename, revision_id))
2892
raise errors.BzrCommandError(
2893
"%r is not present in revision %s" % (
2894
filename, rev_tree.get_revision_id()))
2039
rev_tree.print_file(old_file_id)
2040
elif cur_file_id is not None:
2041
rev_tree.print_file(cur_file_id)
2042
elif old_file_id is not None:
2043
rev_tree.print_file(old_file_id)
2045
raise errors.BzrCommandError("%r is not present in revision %s" %
2046
(filename, revision_id))
2896
content = rev_tree.get_file_text(old_file_id)
2898
cur_file_id = tree.path2id(relpath)
2900
if cur_file_id is not None:
2901
# Then try with the actual file id
2903
content = rev_tree.get_file_text(cur_file_id)
2905
except errors.NoSuchId:
2906
# The actual file id didn't exist at that time
2908
if not found and old_file_id is not None:
2909
# Finally try with the old file id
2910
content = rev_tree.get_file_text(old_file_id)
2913
# Can't be found anywhere
2914
raise errors.BzrCommandError(
2915
"%r is not present in revision %s" % (
2916
filename, rev_tree.get_revision_id()))
2918
from bzrlib.filters import (
2919
ContentFilterContext,
2920
filtered_output_bytes,
2922
filters = rev_tree._content_filter_stack(relpath)
2923
chunks = content.splitlines(True)
2924
content = filtered_output_bytes(chunks, filters,
2925
ContentFilterContext(relpath, rev_tree))
2927
self.outf.writelines(content)
2930
self.outf.write(content)
2049
2933
class cmd_local_time_offset(Command):
2050
"""Show the offset in seconds from GMT to local time."""
2934
__doc__ = """Show the offset in seconds from GMT to local time."""
2052
2936
@display_command
2054
print osutils.local_time_offset()
2938
self.outf.write("%s\n" % osutils.local_time_offset())
2058
2942
class cmd_commit(Command):
2059
"""Commit changes into a new revision.
2061
If no arguments are given, the entire tree is committed.
2063
If selected files are specified, only changes to those files are
2064
committed. If a directory is specified then the directory and everything
2065
within it is committed.
2067
A selected-file commit may fail in some cases where the committed
2068
tree would be invalid. Consider::
2073
bzr commit foo -m "committing foo"
2074
bzr mv foo/bar foo/baz
2077
bzr commit foo/bar -m "committing bar but not baz"
2079
In the example above, the last commit will fail by design. This gives
2080
the user the opportunity to decide whether they want to commit the
2081
rename at the same time, separately first, or not at all. (As a general
2082
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2084
Note: A selected-file commit after a merge is not yet supported.
2943
__doc__ = """Commit changes into a new revision.
2945
An explanatory message needs to be given for each commit. This is
2946
often done by using the --message option (getting the message from the
2947
command line) or by using the --file option (getting the message from
2948
a file). If neither of these options is given, an editor is opened for
2949
the user to enter the message. To see the changed files in the
2950
boilerplate text loaded into the editor, use the --show-diff option.
2952
By default, the entire tree is committed and the person doing the
2953
commit is assumed to be the author. These defaults can be overridden
2958
If selected files are specified, only changes to those files are
2959
committed. If a directory is specified then the directory and
2960
everything within it is committed.
2962
When excludes are given, they take precedence over selected files.
2963
For example, to commit only changes within foo, but not changes
2966
bzr commit foo -x foo/bar
2968
A selective commit after a merge is not yet supported.
2972
If the author of the change is not the same person as the committer,
2973
you can specify the author's name using the --author option. The
2974
name should be in the same format as a committer-id, e.g.
2975
"John Doe <jdoe@example.com>". If there is more than one author of
2976
the change you can specify the option multiple times, once for each
2981
A common mistake is to forget to add a new file or directory before
2982
running the commit command. The --strict option checks for unknown
2983
files and aborts the commit if any are found. More advanced pre-commit
2984
checks can be implemented by defining hooks. See ``bzr help hooks``
2989
If you accidentially commit the wrong changes or make a spelling
2990
mistake in the commit message say, you can use the uncommit command
2991
to undo it. See ``bzr help uncommit`` for details.
2993
Hooks can also be configured to run after a commit. This allows you
2994
to trigger updates to external systems like bug trackers. The --fixes
2995
option can be used to record the association between a revision and
2996
one or more bugs. See ``bzr help bugs`` for details.
2998
A selective commit may fail in some cases where the committed
2999
tree would be invalid. Consider::
3004
bzr commit foo -m "committing foo"
3005
bzr mv foo/bar foo/baz
3008
bzr commit foo/bar -m "committing bar but not baz"
3010
In the example above, the last commit will fail by design. This gives
3011
the user the opportunity to decide whether they want to commit the
3012
rename at the same time, separately first, or not at all. (As a general
3013
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2086
3015
# TODO: Run hooks on tree to-be-committed, and after commit.
2394
3521
takes_args = ['testspecs*']
2395
3522
takes_options = ['verbose',
2397
help='stop when one test fails',
3524
help='Stop when one test fails.',
2398
3525
short_name='1',
2400
Option('keep-output',
2401
help='keep output directories when tests fail'),
2402
3527
Option('transport',
2403
3528
help='Use a different transport by default '
2404
3529
'throughout the test suite.',
2405
3530
type=get_transport_type),
2406
Option('benchmark', help='run the bzr benchmarks.'),
3532
help='Run the benchmarks rather than selftests.'),
2407
3533
Option('lsprof-timed',
2408
help='generate lsprof output for benchmarked'
3534
help='Generate lsprof output for benchmarked'
2409
3535
' sections of code.'),
3536
Option('lsprof-tests',
3537
help='Generate lsprof output for each test.'),
2410
3538
Option('cache-dir', type=str,
2411
help='a directory to cache intermediate'
2412
' benchmark steps'),
2413
Option('clean-output',
2414
help='clean temporary tests directories'
2415
' without running tests'),
3539
help='Cache intermediate benchmark output in this '
2416
3541
Option('first',
2417
help='run all tests, but run specified tests first',
3542
help='Run all tests, but run specified tests first.',
2418
3543
short_name='f',
2420
Option('numbered-dirs',
2421
help='use numbered dirs for TestCaseInTempDir'),
2422
3545
Option('list-only',
2423
help='list the tests instead of running them'),
3546
help='List the tests instead of running them.'),
3547
RegistryOption('parallel',
3548
help="Run the test suite in parallel.",
3549
lazy_registry=('bzrlib.tests', 'parallel_registry'),
3550
value_switches=False,
2424
3552
Option('randomize', type=str, argname="SEED",
2425
help='randomize the order of tests using the given'
2426
' seed or "now" for the current time'),
3553
help='Randomize the order of tests using the given'
3554
' seed or "now" for the current time.'),
2427
3555
Option('exclude', type=str, argname="PATTERN",
2428
3556
short_name='x',
2429
help='exclude tests that match this regular'
3557
help='Exclude tests that match this regular'
3560
help='Output test progress via subunit.'),
3561
Option('strict', help='Fail on missing dependencies or '
3563
Option('load-list', type=str, argname='TESTLISTFILE',
3564
help='Load a test id list from a text file.'),
3565
ListOption('debugflag', type=str, short_name='E',
3566
help='Turn on a selftest debug flag.'),
3567
ListOption('starting-with', type=str, argname='TESTID',
3568
param_name='starting_with', short_name='s',
3570
'Load only the tests starting with TESTID.'),
2432
3572
encoding_type = 'replace'
2434
def run(self, testspecs_list=None, verbose=None, one=False,
2435
keep_output=False, transport=None, benchmark=None,
2436
lsprof_timed=None, cache_dir=None, clean_output=False,
2437
first=False, numbered_dirs=None, list_only=False,
2438
randomize=None, exclude=None):
3575
Command.__init__(self)
3576
self.additional_selftest_args = {}
3578
def run(self, testspecs_list=None, verbose=False, one=False,
3579
transport=None, benchmark=None,
3580
lsprof_timed=None, cache_dir=None,
3581
first=False, list_only=False,
3582
randomize=None, exclude=None, strict=False,
3583
load_list=None, debugflag=None, starting_with=None, subunit=False,
3584
parallel=None, lsprof_tests=False):
2440
3585
from bzrlib.tests import selftest
2441
3586
import bzrlib.benchmarks as benchmarks
2442
3587
from bzrlib.benchmarks import tree_creator
2445
from bzrlib.tests import clean_selftest_output
2446
clean_selftest_output()
2449
warning("notice: selftest --keep-output "
2450
"is no longer supported; "
2451
"test output is always removed")
2453
if numbered_dirs is None and sys.platform == 'win32':
2454
numbered_dirs = True
3589
# Make deprecation warnings visible, unless -Werror is set
3590
symbol_versioning.activate_deprecation_warnings(override=False)
2456
3592
if cache_dir is not None:
2457
3593
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2458
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2459
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2461
3594
if testspecs_list is not None:
2462
3595
pattern = '|'.join(testspecs_list)
3600
from bzrlib.tests import SubUnitBzrRunner
3602
raise errors.BzrCommandError("subunit not available. subunit "
3603
"needs to be installed to use --subunit.")
3604
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3605
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3606
# stdout, which would corrupt the subunit stream.
3607
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3608
# following code can be deleted when it's sufficiently deployed
3609
# -- vila/mgz 20100514
3610
if (sys.platform == "win32"
3611
and getattr(sys.stdout, 'fileno', None) is not None):
3613
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3615
self.additional_selftest_args.setdefault(
3616
'suite_decorators', []).append(parallel)
2466
3618
test_suite_factory = benchmarks.test_suite
3619
# Unless user explicitly asks for quiet, be verbose in benchmarks
3620
verbose = not is_quiet()
2469
3621
# TODO: should possibly lock the history file...
2470
3622
benchfile = open(".perf_history", "at", buffering=1)
3623
self.add_cleanup(benchfile.close)
2472
3625
test_suite_factory = None
2475
3626
benchfile = None
2477
result = selftest(verbose=verbose,
2479
stop_on_failure=one,
2480
transport=transport,
2481
test_suite_factory=test_suite_factory,
2482
lsprof_timed=lsprof_timed,
2483
bench_history=benchfile,
2484
matching_tests_first=first,
2485
numbered_dirs=numbered_dirs,
2486
list_only=list_only,
2487
random_seed=randomize,
2488
exclude_pattern=exclude
2491
if benchfile is not None:
2494
info('tests passed')
2496
info('tests failed')
3627
selftest_kwargs = {"verbose": verbose,
3629
"stop_on_failure": one,
3630
"transport": transport,
3631
"test_suite_factory": test_suite_factory,
3632
"lsprof_timed": lsprof_timed,
3633
"lsprof_tests": lsprof_tests,
3634
"bench_history": benchfile,
3635
"matching_tests_first": first,
3636
"list_only": list_only,
3637
"random_seed": randomize,
3638
"exclude_pattern": exclude,
3640
"load_list": load_list,
3641
"debug_flags": debugflag,
3642
"starting_with": starting_with
3644
selftest_kwargs.update(self.additional_selftest_args)
3645
result = selftest(**selftest_kwargs)
2497
3646
return int(not result)
2500
3649
class cmd_version(Command):
2501
"""Show version of bzr."""
3650
__doc__ = """Show version of bzr."""
3652
encoding_type = 'replace'
3654
Option("short", help="Print just the version number."),
2503
3657
@display_command
3658
def run(self, short=False):
2505
3659
from bzrlib.version import show_version
3661
self.outf.write(bzrlib.version_string + '\n')
3663
show_version(to_file=self.outf)
2509
3666
class cmd_rocks(Command):
2510
"""Statement of optimism."""
3667
__doc__ = """Statement of optimism."""
2514
3671
@display_command
2516
print "It sure does!"
3673
self.outf.write("It sure does!\n")
2519
3676
class cmd_find_merge_base(Command):
2520
"""Find and print a base revision for merging two branches."""
3677
__doc__ = """Find and print a base revision for merging two branches."""
2521
3678
# TODO: Options to specify revisions on either side, as if
2522
3679
# merging only part of the history.
2523
3680
takes_args = ['branch', 'other']
2526
3683
@display_command
2527
3684
def run(self, branch, other):
2528
from bzrlib.revision import ensure_null, MultipleRevisionSources
3685
from bzrlib.revision import ensure_null
2530
3687
branch1 = Branch.open_containing(branch)[0]
2531
3688
branch2 = Branch.open_containing(other)[0]
3689
self.add_cleanup(branch1.lock_read().unlock)
3690
self.add_cleanup(branch2.lock_read().unlock)
2533
3691
last1 = ensure_null(branch1.last_revision())
2534
3692
last2 = ensure_null(branch2.last_revision())
2536
3694
graph = branch1.repository.get_graph(branch2.repository)
2537
3695
base_rev_id = graph.find_unique_lca(last1, last2)
2539
print 'merge base is revision %s' % base_rev_id
3697
self.outf.write('merge base is revision %s\n' % base_rev_id)
2542
3700
class cmd_merge(Command):
2543
"""Perform a three-way merge.
2545
The branch is the branch you will merge from. By default, it will merge
2546
the latest revision. If you specify a revision, that revision will be
2547
merged. If you specify two revisions, the first will be used as a BASE,
2548
and the second one as OTHER. Revision numbers are always relative to the
3701
__doc__ = """Perform a three-way merge.
3703
The source of the merge can be specified either in the form of a branch,
3704
or in the form of a path to a file containing a merge directive generated
3705
with bzr send. If neither is specified, the default is the upstream branch
3706
or the branch most recently merged using --remember.
3708
When merging a branch, by default the tip will be merged. To pick a different
3709
revision, pass --revision. If you specify two values, the first will be used as
3710
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3711
available revisions, like this is commonly referred to as "cherrypicking".
3713
Revision numbers are always relative to the branch being merged.
2551
3715
By default, bzr will try to merge in all new work from the other
2552
3716
branch, automatically determining an appropriate base. If this
2553
3717
fails, you may need to give an explicit base.
2555
3719
Merge will do its best to combine the changes in two branches, but there
2556
3720
are some kinds of problems only a human can fix. When it encounters those,
2557
3721
it will mark a conflict. A conflict means that you need to fix something,
2568
3732
directory, where they can be reviewed (with bzr diff), tested, and then
2569
3733
committed to record the result of the merge.
2573
To merge the latest revision from bzr.dev:
2574
bzr merge ../bzr.dev
2576
To merge changes up to and including revision 82 from bzr.dev:
2577
bzr merge -r 82 ../bzr.dev
2579
To merge the changes introduced by 82, without previous changes:
2580
bzr merge -r 81..82 ../bzr.dev
2582
3735
merge refuses to run if there are any uncommitted changes, unless
3736
--force is given. The --force option can also be used to create a
3737
merge revision which has more than two parents.
3739
If one would like to merge changes from the working tree of the other
3740
branch without merging any committed revisions, the --uncommitted option
3743
To select only some changes to merge, use "merge -i", which will prompt
3744
you to apply each diff hunk and file change, similar to "shelve".
3747
To merge the latest revision from bzr.dev::
3749
bzr merge ../bzr.dev
3751
To merge changes up to and including revision 82 from bzr.dev::
3753
bzr merge -r 82 ../bzr.dev
3755
To merge the changes introduced by 82, without previous changes::
3757
bzr merge -r 81..82 ../bzr.dev
3759
To apply a merge directive contained in /tmp/merge::
3761
bzr merge /tmp/merge
3763
To create a merge revision with three parents from two branches
3764
feature1a and feature1b:
3766
bzr merge ../feature1a
3767
bzr merge ../feature1b --force
3768
bzr commit -m 'revision with three parents'
2586
_see_also = ['update', 'remerge', 'status-flags']
2587
takes_args = ['branch?']
2588
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
3771
encoding_type = 'exact'
3772
_see_also = ['update', 'remerge', 'status-flags', 'send']
3773
takes_args = ['location?']
3778
help='Merge even if the destination tree has uncommitted changes.'),
2589
3782
Option('show-base', help="Show base revision text in "
2591
3784
Option('uncommitted', help='Apply uncommitted changes'
2592
' from a working copy, instead of branch changes'),
3785
' from a working copy, instead of branch changes.'),
2593
3786
Option('pull', help='If the destination is already'
2594
3787
' completely merged into the source, pull from the'
2595
' source rather than merging. When this happens,'
3788
' source rather than merging. When this happens,'
2596
3789
' you do not need to commit the result.'),
2598
help='Branch to merge into, '
2599
'rather than the one containing the working directory',
3790
custom_help('directory',
3791
help='Branch to merge into, '
3792
'rather than the one containing the working directory.'),
3793
Option('preview', help='Instead of merging, show a diff of the'
3795
Option('interactive', help='Select changes interactively.',
2605
def run(self, branch=None, revision=None, force=False, merge_type=None,
2606
show_base=False, reprocess=False, remember=False,
3799
def run(self, location=None, revision=None, force=False,
3800
merge_type=None, show_base=False, reprocess=None, remember=False,
2607
3801
uncommitted=False, pull=False,
2608
3802
directory=None,
2610
from bzrlib.tag import _merge_tags_if_possible
2611
other_revision_id = None
2612
3806
if merge_type is None:
2613
3807
merge_type = _mod_merge.Merge3Merger
2615
3809
if directory is None: directory = u'.'
2616
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2617
# inventory. Because merge is a mutating operation, it really
2618
# should be a lock_write() for the whole cmd_merge operation.
2619
# However, cmd_merge open's its own tree in _merge_helper, which
2620
# means if we lock here, the later lock_write() will always block.
2621
# Either the merge helper code should be updated to take a tree,
2622
# (What about tree.merge_from_branch?)
3810
possible_transports = []
3812
allow_pending = True
3813
verified = 'inapplicable'
2623
3814
tree = WorkingTree.open_containing(directory)[0]
3817
basis_tree = tree.revision_tree(tree.last_revision())
3818
except errors.NoSuchRevision:
3819
basis_tree = tree.basis_tree()
3821
# die as quickly as possible if there are uncommitted changes
3823
if tree.has_changes():
3824
raise errors.UncommittedChanges(tree)
3826
view_info = _get_view_info_for_change_reporter(tree)
2624
3827
change_reporter = delta._ChangeReporter(
2625
unversioned_filter=tree.is_ignored)
2627
if branch is not None:
3828
unversioned_filter=tree.is_ignored, view_info=view_info)
3829
pb = ui.ui_factory.nested_progress_bar()
3830
self.add_cleanup(pb.finished)
3831
self.add_cleanup(tree.lock_write().unlock)
3832
if location is not None:
2629
mergeable = bundle.read_mergeable_from_url(
3834
mergeable = bundle.read_mergeable_from_url(location,
3835
possible_transports=possible_transports)
2631
3836
except errors.NotABundle:
2632
pass # Continue on considering this url a Branch
3840
raise errors.BzrCommandError('Cannot use --uncommitted'
3841
' with bundles or merge directives.')
2634
3843
if revision is not None:
2635
3844
raise errors.BzrCommandError(
2636
3845
'Cannot use -r with merge directives or bundles')
2637
other_revision_id = mergeable.install_revisions(
2638
tree.branch.repository)
2639
revision = [RevisionSpec.from_string(
2640
'revid:' + other_revision_id)]
2642
if revision is None \
2643
or len(revision) < 1 or revision[0].needs_branch():
2644
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2646
if revision is None or len(revision) < 1:
2649
other = [branch, None]
2652
other = [branch, -1]
2653
other_branch, path = Branch.open_containing(branch)
3846
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3849
if merger is None and uncommitted:
3850
if revision is not None and len(revision) > 0:
2656
3851
raise errors.BzrCommandError('Cannot use --uncommitted and'
2657
' --revision at the same time.')
2658
branch = revision[0].get_branch() or branch
2659
if len(revision) == 1:
2661
if other_revision_id is not None:
2666
other_branch, path = Branch.open_containing(branch)
2667
revno = revision[0].in_history(other_branch).revno
2668
other = [branch, revno]
2670
assert len(revision) == 2
2671
if None in revision:
2672
raise errors.BzrCommandError(
2673
"Merge doesn't permit empty revision specifier.")
2674
base_branch, path = Branch.open_containing(branch)
2675
branch1 = revision[1].get_branch() or branch
2676
other_branch, path1 = Branch.open_containing(branch1)
2677
if revision[0].get_branch() is not None:
2678
# then path was obtained from it, and is None.
2681
base = [branch, revision[0].in_history(base_branch).revno]
2682
other = [branch1, revision[1].in_history(other_branch).revno]
2684
if ((tree.branch.get_parent() is None or remember) and
2685
other_branch is not None):
2686
tree.branch.set_parent(other_branch.base)
2688
# pull tags now... it's a bit inconsistent to do it ahead of copying
2689
# the history but that's done inside the merge code
2690
if other_branch is not None:
2691
_merge_tags_if_possible(other_branch, tree.branch)
2694
interesting_files = [path]
2696
interesting_files = None
2697
pb = ui.ui_factory.nested_progress_bar()
3852
' --revision at the same time.')
3853
merger = self.get_merger_from_uncommitted(tree, location, None)
3854
allow_pending = False
3857
merger, allow_pending = self._get_merger_from_branch(tree,
3858
location, revision, remember, possible_transports, None)
3860
merger.merge_type = merge_type
3861
merger.reprocess = reprocess
3862
merger.show_base = show_base
3863
self.sanity_check_merger(merger)
3864
if (merger.base_rev_id == merger.other_rev_id and
3865
merger.other_rev_id is not None):
3866
note('Nothing to do.')
3869
if merger.interesting_files is not None:
3870
raise errors.BzrCommandError('Cannot pull individual files')
3871
if (merger.base_rev_id == tree.last_revision()):
3872
result = tree.pull(merger.other_branch, False,
3873
merger.other_rev_id)
3874
result.report(self.outf)
3876
if merger.this_basis is None:
3877
raise errors.BzrCommandError(
3878
"This branch has no commits."
3879
" (perhaps you would prefer 'bzr pull')")
3881
return self._do_preview(merger)
3883
return self._do_interactive(merger)
3885
return self._do_merge(merger, change_reporter, allow_pending,
3888
def _get_preview(self, merger):
3889
tree_merger = merger.make_merger()
3890
tt = tree_merger.make_preview_transform()
3891
self.add_cleanup(tt.finalize)
3892
result_tree = tt.get_preview_tree()
3895
def _do_preview(self, merger):
3896
from bzrlib.diff import show_diff_trees
3897
result_tree = self._get_preview(merger)
3898
path_encoding = osutils.get_diff_header_encoding()
3899
show_diff_trees(merger.this_tree, result_tree, self.outf,
3900
old_label='', new_label='',
3901
path_encoding=path_encoding)
3903
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3904
merger.change_reporter = change_reporter
3905
conflict_count = merger.do_merge()
3907
merger.set_pending()
3908
if verified == 'failed':
3909
warning('Preview patch does not match changes')
3910
if conflict_count != 0:
3915
def _do_interactive(self, merger):
3916
"""Perform an interactive merge.
3918
This works by generating a preview tree of the merge, then using
3919
Shelver to selectively remove the differences between the working tree
3920
and the preview tree.
3922
from bzrlib import shelf_ui
3923
result_tree = self._get_preview(merger)
3924
writer = bzrlib.option.diff_writer_registry.get()
3925
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3926
reporter=shelf_ui.ApplyReporter(),
3927
diff_writer=writer(sys.stdout))
2700
conflict_count = _merge_helper(
2701
other, base, other_rev_id=other_revision_id,
2702
check_clean=(not force),
2703
merge_type=merge_type,
2704
reprocess=reprocess,
2705
show_base=show_base,
2708
pb=pb, file_list=interesting_files,
2709
change_reporter=change_reporter)
2712
if conflict_count != 0:
3933
def sanity_check_merger(self, merger):
3934
if (merger.show_base and
3935
not merger.merge_type is _mod_merge.Merge3Merger):
3936
raise errors.BzrCommandError("Show-base is not supported for this"
3937
" merge type. %s" % merger.merge_type)
3938
if merger.reprocess is None:
3939
if merger.show_base:
3940
merger.reprocess = False
2716
except errors.AmbiguousBase, e:
2717
m = ("sorry, bzr can't determine the right merge base yet\n"
2718
"candidates are:\n "
2719
+ "\n ".join(e.bases)
2721
"please specify an explicit base with -r,\n"
2722
"and (if you want) report this to the bzr developers\n")
2725
# TODO: move up to common parent; this isn't merge-specific anymore.
2726
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3942
# Use reprocess if the merger supports it
3943
merger.reprocess = merger.merge_type.supports_reprocess
3944
if merger.reprocess and not merger.merge_type.supports_reprocess:
3945
raise errors.BzrCommandError("Conflict reduction is not supported"
3946
" for merge type %s." %
3948
if merger.reprocess and merger.show_base:
3949
raise errors.BzrCommandError("Cannot do conflict reduction and"
3952
def _get_merger_from_branch(self, tree, location, revision, remember,
3953
possible_transports, pb):
3954
"""Produce a merger from a location, assuming it refers to a branch."""
3955
from bzrlib.tag import _merge_tags_if_possible
3956
# find the branch locations
3957
other_loc, user_location = self._select_branch_location(tree, location,
3959
if revision is not None and len(revision) == 2:
3960
base_loc, _unused = self._select_branch_location(tree,
3961
location, revision, 0)
3963
base_loc = other_loc
3965
other_branch, other_path = Branch.open_containing(other_loc,
3966
possible_transports)
3967
if base_loc == other_loc:
3968
base_branch = other_branch
3970
base_branch, base_path = Branch.open_containing(base_loc,
3971
possible_transports)
3972
# Find the revision ids
3973
other_revision_id = None
3974
base_revision_id = None
3975
if revision is not None:
3976
if len(revision) >= 1:
3977
other_revision_id = revision[-1].as_revision_id(other_branch)
3978
if len(revision) == 2:
3979
base_revision_id = revision[0].as_revision_id(base_branch)
3980
if other_revision_id is None:
3981
other_revision_id = _mod_revision.ensure_null(
3982
other_branch.last_revision())
3983
# Remember where we merge from
3984
if ((remember or tree.branch.get_submit_branch() is None) and
3985
user_location is not None):
3986
tree.branch.set_submit_branch(other_branch.base)
3987
_merge_tags_if_possible(other_branch, tree.branch)
3988
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3989
other_revision_id, base_revision_id, other_branch, base_branch)
3990
if other_path != '':
3991
allow_pending = False
3992
merger.interesting_files = [other_path]
3994
allow_pending = True
3995
return merger, allow_pending
3997
def get_merger_from_uncommitted(self, tree, location, pb):
3998
"""Get a merger for uncommitted changes.
4000
:param tree: The tree the merger should apply to.
4001
:param location: The location containing uncommitted changes.
4002
:param pb: The progress bar to use for showing progress.
4004
location = self._select_branch_location(tree, location)[0]
4005
other_tree, other_path = WorkingTree.open_containing(location)
4006
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
4007
if other_path != '':
4008
merger.interesting_files = [other_path]
4011
def _select_branch_location(self, tree, user_location, revision=None,
4013
"""Select a branch location, according to possible inputs.
4015
If provided, branches from ``revision`` are preferred. (Both
4016
``revision`` and ``index`` must be supplied.)
4018
Otherwise, the ``location`` parameter is used. If it is None, then the
4019
``submit`` or ``parent`` location is used, and a note is printed.
4021
:param tree: The working tree to select a branch for merging into
4022
:param location: The location entered by the user
4023
:param revision: The revision parameter to the command
4024
:param index: The index to use for the revision parameter. Negative
4025
indices are permitted.
4026
:return: (selected_location, user_location). The default location
4027
will be the user-entered location.
4029
if (revision is not None and index is not None
4030
and revision[index] is not None):
4031
branch = revision[index].get_branch()
4032
if branch is not None:
4033
return branch, branch
4034
if user_location is None:
4035
location = self._get_remembered(tree, 'Merging from')
4037
location = user_location
4038
return location, user_location
4040
def _get_remembered(self, tree, verb_string):
2727
4041
"""Use tree.branch's parent if none was supplied.
2729
4043
Report if the remembered location was used.
2731
if supplied_location is not None:
2732
return supplied_location
2733
stored_location = tree.branch.get_parent()
4045
stored_location = tree.branch.get_submit_branch()
4046
stored_location_type = "submit"
4047
if stored_location is None:
4048
stored_location = tree.branch.get_parent()
4049
stored_location_type = "parent"
2734
4050
mutter("%s", stored_location)
2735
4051
if stored_location is None:
2736
4052
raise errors.BzrCommandError("No location specified or remembered")
2737
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2738
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
4053
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4054
note(u"%s remembered %s location %s", verb_string,
4055
stored_location_type, display_url)
2739
4056
return stored_location
2742
4059
class cmd_remerge(Command):
4060
__doc__ = """Redo a merge.
2745
4062
Use this if you want to try a different merge technique while resolving
2746
conflicts. Some merge techniques are better than others, and remerge
4063
conflicts. Some merge techniques are better than others, and remerge
2747
4064
lets you try different ones on different files.
2749
4066
The options for remerge have the same meaning and defaults as the ones for
2750
4067
merge. The difference is that remerge can (only) be run when there is a
2751
4068
pending merge, and it lets you specify particular files.
2755
$ bzr remerge --show-base
2756
4071
Re-do the merge of all conflicted files, and show the base text in
2757
conflict regions, in addition to the usual THIS and OTHER texts.
2759
$ bzr remerge --merge-type weave --reprocess foobar
4072
conflict regions, in addition to the usual THIS and OTHER texts::
4074
bzr remerge --show-base
2760
4076
Re-do the merge of "foobar", using the weave merge algorithm, with
2761
additional processing to reduce the size of conflict regions.
4077
additional processing to reduce the size of conflict regions::
4079
bzr remerge --merge-type weave --reprocess foobar
2763
4081
takes_args = ['file*']
2764
takes_options = ['merge-type', 'reprocess',
2765
Option('show-base', help="Show base revision text in "
4086
help="Show base revision text in conflicts."),
2768
4089
def run(self, file_list=None, merge_type=None, show_base=False,
2769
4090
reprocess=False):
4091
from bzrlib.conflicts import restore
2770
4092
if merge_type is None:
2771
4093
merge_type = _mod_merge.Merge3Merger
2772
4094
tree, file_list = tree_files(file_list)
4095
self.add_cleanup(tree.lock_write().unlock)
4096
parents = tree.get_parent_ids()
4097
if len(parents) != 2:
4098
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4099
" merges. Not cherrypicking or"
4101
repository = tree.branch.repository
4102
interesting_ids = None
4104
conflicts = tree.conflicts()
4105
if file_list is not None:
4106
interesting_ids = set()
4107
for filename in file_list:
4108
file_id = tree.path2id(filename)
4110
raise errors.NotVersionedError(filename)
4111
interesting_ids.add(file_id)
4112
if tree.kind(file_id) != "directory":
4115
for name, ie in tree.inventory.iter_entries(file_id):
4116
interesting_ids.add(ie.file_id)
4117
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4119
# Remerge only supports resolving contents conflicts
4120
allowed_conflicts = ('text conflict', 'contents conflict')
4121
restore_files = [c.path for c in conflicts
4122
if c.typestring in allowed_conflicts]
4123
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4124
tree.set_conflicts(ConflictList(new_conflicts))
4125
if file_list is not None:
4126
restore_files = file_list
4127
for filename in restore_files:
4129
restore(tree.abspath(filename))
4130
except errors.NotConflicted:
4132
# Disable pending merges, because the file texts we are remerging
4133
# have not had those merges performed. If we use the wrong parents
4134
# list, we imply that the working tree text has seen and rejected
4135
# all the changes from the other tree, when in fact those changes
4136
# have not yet been seen.
4137
tree.set_parent_ids(parents[:1])
2775
parents = tree.get_parent_ids()
2776
if len(parents) != 2:
2777
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2778
" merges. Not cherrypicking or"
2780
repository = tree.branch.repository
2781
graph = repository.get_graph()
2782
base_revision = graph.find_unique_lca(parents[0], parents[1])
2783
base_tree = repository.revision_tree(base_revision)
2784
other_tree = repository.revision_tree(parents[1])
2785
interesting_ids = None
2787
conflicts = tree.conflicts()
2788
if file_list is not None:
2789
interesting_ids = set()
2790
for filename in file_list:
2791
file_id = tree.path2id(filename)
2793
raise errors.NotVersionedError(filename)
2794
interesting_ids.add(file_id)
2795
if tree.kind(file_id) != "directory":
2798
for name, ie in tree.inventory.iter_entries(file_id):
2799
interesting_ids.add(ie.file_id)
2800
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2802
# Remerge only supports resolving contents conflicts
2803
allowed_conflicts = ('text conflict', 'contents conflict')
2804
restore_files = [c.path for c in conflicts
2805
if c.typestring in allowed_conflicts]
2806
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2807
tree.set_conflicts(ConflictList(new_conflicts))
2808
if file_list is not None:
2809
restore_files = file_list
2810
for filename in restore_files:
2812
restore(tree.abspath(filename))
2813
except errors.NotConflicted:
2815
conflicts = _mod_merge.merge_inner(
2816
tree.branch, other_tree, base_tree,
2818
interesting_ids=interesting_ids,
2819
other_rev_id=parents[1],
2820
merge_type=merge_type,
2821
show_base=show_base,
2822
reprocess=reprocess)
4139
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4140
merger.interesting_ids = interesting_ids
4141
merger.merge_type = merge_type
4142
merger.show_base = show_base
4143
merger.reprocess = reprocess
4144
conflicts = merger.do_merge()
4146
tree.set_parent_ids(parents)
2825
4147
if conflicts > 0:
2908
4253
class cmd_shell_complete(Command):
2909
"""Show appropriate completions for context.
4254
__doc__ = """Show appropriate completions for context.
2911
4256
For a list of all available commands, say 'bzr shell-complete'.
2913
4258
takes_args = ['context?']
2914
4259
aliases = ['s-c']
2917
4262
@display_command
2918
4263
def run(self, context=None):
2919
4264
import shellcomplete
2920
4265
shellcomplete.shellcomplete(context)
2923
class cmd_fetch(Command):
2924
"""Copy in history from another branch but don't merge it.
2926
This is an internal method used for pull and merge.
2929
takes_args = ['from_branch', 'to_branch']
2930
def run(self, from_branch, to_branch):
2931
from bzrlib.fetch import Fetcher
2932
from_b = Branch.open(from_branch)
2933
to_b = Branch.open(to_branch)
2934
Fetcher(to_b, from_b)
2937
4268
class cmd_missing(Command):
2938
"""Show unmerged/unpulled revisions between two branches.
4269
__doc__ = """Show unmerged/unpulled revisions between two branches.
2940
4271
OTHER_BRANCH may be local or remote.
4273
To filter on a range of revisions, you can use the command -r begin..end
4274
-r revision requests a specific revision, -r ..end or -r begin.. are
4278
1 - some missing revisions
4279
0 - no missing revisions
4283
Determine the missing revisions between this and the branch at the
4284
remembered pull location::
4288
Determine the missing revisions between this and another branch::
4290
bzr missing http://server/branch
4292
Determine the missing revisions up to a specific revision on the other
4295
bzr missing -r ..-10
4297
Determine the missing revisions up to a specific revision on this
4300
bzr missing --my-revision ..-10
2943
4303
_see_also = ['merge', 'pull']
2944
4304
takes_args = ['other_branch?']
2945
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2947
'Display changes in the local branch only'),
2948
Option('this' , 'same as --mine-only'),
2949
Option('theirs-only',
2950
'Display changes in the remote branch only'),
2951
Option('other', 'same as --theirs-only'),
4307
Option('reverse', 'Reverse the order of revisions.'),
4309
'Display changes in the local branch only.'),
4310
Option('this' , 'Same as --mine-only.'),
4311
Option('theirs-only',
4312
'Display changes in the remote branch only.'),
4313
Option('other', 'Same as --theirs-only.'),
4317
custom_help('revision',
4318
help='Filter on other branch revisions (inclusive). '
4319
'See "help revisionspec" for details.'),
4320
Option('my-revision',
4321
type=_parse_revision_str,
4322
help='Filter on local branch revisions (inclusive). '
4323
'See "help revisionspec" for details.'),
4324
Option('include-merges',
4325
'Show all revisions in addition to the mainline ones.'),
2956
4327
encoding_type = 'replace'
2958
4329
@display_command
2959
4330
def run(self, other_branch=None, reverse=False, mine_only=False,
2960
theirs_only=False, log_format=None, long=False, short=False, line=False,
2961
show_ids=False, verbose=False, this=False, other=False):
4332
log_format=None, long=False, short=False, line=False,
4333
show_ids=False, verbose=False, this=False, other=False,
4334
include_merges=False, revision=None, my_revision=None,
2962
4336
from bzrlib.missing import find_unmerged, iter_log_revisions
2963
from bzrlib.log import log_formatter
2970
local_branch = Branch.open_containing(u".")[0]
4345
# TODO: We should probably check that we don't have mine-only and
4346
# theirs-only set, but it gets complicated because we also have
4347
# this and other which could be used.
4354
local_branch = Branch.open_containing(directory)[0]
4355
self.add_cleanup(local_branch.lock_read().unlock)
2971
4357
parent = local_branch.get_parent()
2972
4358
if other_branch is None:
2973
4359
other_branch = parent
2974
4360
if other_branch is None:
2975
raise errors.BzrCommandError("No peer location known or specified.")
4361
raise errors.BzrCommandError("No peer location known"
2976
4363
display_url = urlutils.unescape_for_display(parent,
2977
4364
self.outf.encoding)
2978
print "Using last location: " + display_url
4365
message("Using saved parent location: "
4366
+ display_url + "\n")
2980
4368
remote_branch = Branch.open(other_branch)
2981
4369
if remote_branch.base == local_branch.base:
2982
4370
remote_branch = local_branch
2983
local_branch.lock_read()
2985
remote_branch.lock_read()
2987
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2988
if (log_format is None):
2989
log_format = log.log_formatter_registry.get_default(
2991
lf = log_format(to_file=self.outf,
2993
show_timezone='original')
2994
if reverse is False:
2995
local_extra.reverse()
2996
remote_extra.reverse()
2997
if local_extra and not theirs_only:
2998
print "You have %d extra revision(s):" % len(local_extra)
2999
for revision in iter_log_revisions(local_extra,
3000
local_branch.repository,
3002
lf.log_revision(revision)
3003
printed_local = True
3005
printed_local = False
3006
if remote_extra and not mine_only:
3007
if printed_local is True:
3009
print "You are missing %d revision(s):" % len(remote_extra)
3010
for revision in iter_log_revisions(remote_extra,
3011
remote_branch.repository,
3013
lf.log_revision(revision)
3014
if not remote_extra and not local_extra:
3016
print "Branches are up to date."
3020
remote_branch.unlock()
3022
local_branch.unlock()
4372
self.add_cleanup(remote_branch.lock_read().unlock)
4374
local_revid_range = _revision_range_to_revid_range(
4375
_get_revision_range(my_revision, local_branch,
4378
remote_revid_range = _revision_range_to_revid_range(
4379
_get_revision_range(revision,
4380
remote_branch, self.name()))
4382
local_extra, remote_extra = find_unmerged(
4383
local_branch, remote_branch, restrict,
4384
backward=not reverse,
4385
include_merges=include_merges,
4386
local_revid_range=local_revid_range,
4387
remote_revid_range=remote_revid_range)
4389
if log_format is None:
4390
registry = log.log_formatter_registry
4391
log_format = registry.get_default(local_branch)
4392
lf = log_format(to_file=self.outf,
4394
show_timezone='original')
4397
if local_extra and not theirs_only:
4398
message("You have %d extra revision(s):\n" %
4400
for revision in iter_log_revisions(local_extra,
4401
local_branch.repository,
4403
lf.log_revision(revision)
4404
printed_local = True
4407
printed_local = False
4409
if remote_extra and not mine_only:
4410
if printed_local is True:
4412
message("You are missing %d revision(s):\n" %
4414
for revision in iter_log_revisions(remote_extra,
4415
remote_branch.repository,
4417
lf.log_revision(revision)
4420
if mine_only and not local_extra:
4421
# We checked local, and found nothing extra
4422
message('This branch is up to date.\n')
4423
elif theirs_only and not remote_extra:
4424
# We checked remote, and found nothing extra
4425
message('Other branch is up to date.\n')
4426
elif not (mine_only or theirs_only or local_extra or
4428
# We checked both branches, and neither one had extra
4430
message("Branches are up to date.\n")
3023
4432
if not status_code and parent is None and other_branch is not None:
3024
local_branch.lock_write()
3026
# handle race conditions - a parent might be set while we run.
3027
if local_branch.get_parent() is None:
3028
local_branch.set_parent(remote_branch.base)
3030
local_branch.unlock()
4433
self.add_cleanup(local_branch.lock_write().unlock)
4434
# handle race conditions - a parent might be set while we run.
4435
if local_branch.get_parent() is None:
4436
local_branch.set_parent(remote_branch.base)
3031
4437
return status_code
4440
class cmd_pack(Command):
4441
__doc__ = """Compress the data within a repository.
4443
This operation compresses the data within a bazaar repository. As
4444
bazaar supports automatic packing of repository, this operation is
4445
normally not required to be done manually.
4447
During the pack operation, bazaar takes a backup of existing repository
4448
data, i.e. pack files. This backup is eventually removed by bazaar
4449
automatically when it is safe to do so. To save disk space by removing
4450
the backed up pack files, the --clean-obsolete-packs option may be
4453
Warning: If you use --clean-obsolete-packs and your machine crashes
4454
during or immediately after repacking, you may be left with a state
4455
where the deletion has been written to disk but the new packs have not
4456
been. In this case the repository may be unusable.
4459
_see_also = ['repositories']
4460
takes_args = ['branch_or_repo?']
4462
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4465
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4466
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4468
branch = dir.open_branch()
4469
repository = branch.repository
4470
except errors.NotBranchError:
4471
repository = dir.open_repository()
4472
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
3034
4475
class cmd_plugins(Command):
4476
__doc__ = """List the installed plugins.
4478
This command displays the list of installed plugins including
4479
version of plugin and a short description of each.
4481
--verbose shows the path where each plugin is located.
4483
A plugin is an external component for Bazaar that extends the
4484
revision control system, by adding or replacing code in Bazaar.
4485
Plugins can do a variety of things, including overriding commands,
4486
adding new commands, providing additional network transports and
4487
customizing log output.
4489
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4490
for further information on plugins including where to find them and how to
4491
install them. Instructions are also provided there on how to write new
4492
plugins using the Python programming language.
4494
takes_options = ['verbose']
3037
4496
@display_command
4497
def run(self, verbose=False):
3039
4498
import bzrlib.plugin
3040
4499
from inspect import getdoc
3041
for name, plugin in bzrlib.plugin.all_plugins().items():
3042
if getattr(plugin, '__path__', None) is not None:
3043
print plugin.__path__[0]
3044
elif getattr(plugin, '__file__', None) is not None:
3045
print plugin.__file__
4501
for name, plugin in bzrlib.plugin.plugins().items():
4502
version = plugin.__version__
4503
if version == 'unknown':
4505
name_ver = '%s %s' % (name, version)
4506
d = getdoc(plugin.module)
3051
print '\t', d.split('\n')[0]
4508
doc = d.split('\n')[0]
4510
doc = '(no description)'
4511
result.append((name_ver, doc, plugin.path()))
4512
for name_ver, doc, path in sorted(result):
4513
self.outf.write("%s\n" % name_ver)
4514
self.outf.write(" %s\n" % doc)
4516
self.outf.write(" %s\n" % path)
4517
self.outf.write("\n")
3054
4520
class cmd_testament(Command):
3055
"""Show testament (signing-form) of a revision."""
3056
takes_options = ['revision',
3057
Option('long', help='Produce long-format testament'),
3058
Option('strict', help='Produce a strict-format'
4521
__doc__ = """Show testament (signing-form) of a revision."""
4524
Option('long', help='Produce long-format testament.'),
4526
help='Produce a strict-format testament.')]
3060
4527
takes_args = ['branch?']
3061
4528
@display_command
3062
4529
def run(self, branch=u'.', revision=None, long=False, strict=False):
3065
4532
testament_class = StrictTestament
3067
4534
testament_class = Testament
3068
b = WorkingTree.open_containing(branch)[0].branch
3071
if revision is None:
3072
rev_id = b.last_revision()
3074
rev_id = revision[0].in_history(b).rev_id
3075
t = testament_class.from_revision(b.repository, rev_id)
3077
sys.stdout.writelines(t.as_text_lines())
3079
sys.stdout.write(t.as_short_text())
4536
b = Branch.open_containing(branch)[0]
4538
b = Branch.open(branch)
4539
self.add_cleanup(b.lock_read().unlock)
4540
if revision is None:
4541
rev_id = b.last_revision()
4543
rev_id = revision[0].as_revision_id(b)
4544
t = testament_class.from_revision(b.repository, rev_id)
4546
sys.stdout.writelines(t.as_text_lines())
4548
sys.stdout.write(t.as_short_text())
3084
4551
class cmd_annotate(Command):
3085
"""Show the origin of each line in a file.
4552
__doc__ = """Show the origin of each line in a file.
3087
4554
This prints out the given file with an annotation on the left side
3088
4555
indicating which revision, author and date introduced the change.
3090
If the origin is the same for a run of consecutive lines, it is
4557
If the origin is the same for a run of consecutive lines, it is
3091
4558
shown only at the top, unless the --all option is given.
3093
4560
# TODO: annotate directories; showing when each file was last changed
3094
# TODO: if the working copy is modified, show annotations on that
4561
# TODO: if the working copy is modified, show annotations on that
3095
4562
# with new uncommitted lines marked
3096
4563
aliases = ['ann', 'blame', 'praise']
3097
4564
takes_args = ['filename']
3098
takes_options = [Option('all', help='show annotations on all lines'),
3099
Option('long', help='show date in annotations'),
4565
takes_options = [Option('all', help='Show annotations on all lines.'),
4566
Option('long', help='Show commit date in annotations.'),
3103
4571
encoding_type = 'exact'
3105
4573
@display_command
3106
4574
def run(self, filename, all=False, long=False, revision=None,
3108
from bzrlib.annotate import annotate_file
3109
tree, relpath = WorkingTree.open_containing(filename)
3110
branch = tree.branch
3113
if revision is None:
3114
revision_id = branch.last_revision()
3115
elif len(revision) != 1:
3116
raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
3118
revision_id = revision[0].in_history(branch).rev_id
4575
show_ids=False, directory=None):
4576
from bzrlib.annotate import annotate_file, annotate_file_tree
4577
wt, branch, relpath = \
4578
_open_directory_or_containing_tree_or_branch(filename, directory)
4580
self.add_cleanup(wt.lock_read().unlock)
4582
self.add_cleanup(branch.lock_read().unlock)
4583
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4584
self.add_cleanup(tree.lock_read().unlock)
4586
file_id = wt.path2id(relpath)
3119
4588
file_id = tree.path2id(relpath)
3121
raise errors.NotVersionedError(filename)
3122
tree = branch.repository.revision_tree(revision_id)
3123
file_version = tree.inventory[file_id].revision
4590
raise errors.NotVersionedError(filename)
4591
file_version = tree.inventory[file_id].revision
4592
if wt is not None and revision is None:
4593
# If there is a tree and we're not annotating historical
4594
# versions, annotate the working tree's content.
4595
annotate_file_tree(wt, file_id, self.outf, long, all,
3124
4598
annotate_file(branch, file_version, file_id, long, all, self.outf,
3125
4599
show_ids=show_ids)
3130
4602
class cmd_re_sign(Command):
3131
"""Create a digital signature for an existing revision."""
4603
__doc__ = """Create a digital signature for an existing revision."""
3132
4604
# TODO be able to replace existing ones.
3134
4606
hidden = True # is this right ?
3135
4607
takes_args = ['revision_id*']
3136
takes_options = ['revision']
3138
def run(self, revision_id_list=None, revision=None):
3139
import bzrlib.gpg as gpg
4608
takes_options = ['directory', 'revision']
4610
def run(self, revision_id_list=None, revision=None, directory=u'.'):
3140
4611
if revision_id_list is not None and revision is not None:
3141
4612
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
3142
4613
if revision_id_list is None and revision is None:
3143
4614
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
3144
b = WorkingTree.open_containing(u'.')[0].branch
4615
b = WorkingTree.open_containing(directory)[0].branch
4616
self.add_cleanup(b.lock_write().unlock)
4617
return self._run(b, revision_id_list, revision)
4619
def _run(self, b, revision_id_list, revision):
4620
import bzrlib.gpg as gpg
3145
4621
gpg_strategy = gpg.GPGStrategy(b.get_config())
3146
4622
if revision_id_list is not None:
3147
for revision_id in revision_id_list:
3148
b.repository.sign_revision(revision_id, gpg_strategy)
4623
b.repository.start_write_group()
4625
for revision_id in revision_id_list:
4626
b.repository.sign_revision(revision_id, gpg_strategy)
4628
b.repository.abort_write_group()
4631
b.repository.commit_write_group()
3149
4632
elif revision is not None:
3150
4633
if len(revision) == 1:
3151
4634
revno, rev_id = revision[0].in_history(b)
3152
b.repository.sign_revision(rev_id, gpg_strategy)
4635
b.repository.start_write_group()
4637
b.repository.sign_revision(rev_id, gpg_strategy)
4639
b.repository.abort_write_group()
4642
b.repository.commit_write_group()
3153
4643
elif len(revision) == 2:
3154
4644
# are they both on rh- if so we can walk between them
3155
4645
# might be nice to have a range helper for arbitrary
3567
5105
s.send_email(message)
5108
class cmd_send(Command):
5109
__doc__ = """Mail or create a merge-directive for submitting changes.
5111
A merge directive provides many things needed for requesting merges:
5113
* A machine-readable description of the merge to perform
5115
* An optional patch that is a preview of the changes requested
5117
* An optional bundle of revision data, so that the changes can be applied
5118
directly from the merge directive, without retrieving data from a
5121
`bzr send` creates a compact data set that, when applied using bzr
5122
merge, has the same effect as merging from the source branch.
5124
By default the merge directive is self-contained and can be applied to any
5125
branch containing submit_branch in its ancestory without needing access to
5128
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5129
revisions, but only a structured request to merge from the
5130
public_location. In that case the public_branch is needed and it must be
5131
up-to-date and accessible to the recipient. The public_branch is always
5132
included if known, so that people can check it later.
5134
The submit branch defaults to the parent of the source branch, but can be
5135
overridden. Both submit branch and public branch will be remembered in
5136
branch.conf the first time they are used for a particular branch. The
5137
source branch defaults to that containing the working directory, but can
5138
be changed using --from.
5140
In order to calculate those changes, bzr must analyse the submit branch.
5141
Therefore it is most efficient for the submit branch to be a local mirror.
5142
If a public location is known for the submit_branch, that location is used
5143
in the merge directive.
5145
The default behaviour is to send the merge directive by mail, unless -o is
5146
given, in which case it is sent to a file.
5148
Mail is sent using your preferred mail program. This should be transparent
5149
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5150
If the preferred client can't be found (or used), your editor will be used.
5152
To use a specific mail program, set the mail_client configuration option.
5153
(For Thunderbird 1.5, this works around some bugs.) Supported values for
5154
specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5155
Mail.app), "mutt", and "thunderbird"; generic options are "default",
5156
"editor", "emacsclient", "mapi", and "xdg-email". Plugins may also add
5159
If mail is being sent, a to address is required. This can be supplied
5160
either on the commandline, by setting the submit_to configuration
5161
option in the branch itself or the child_submit_to configuration option
5162
in the submit branch.
5164
Two formats are currently supported: "4" uses revision bundle format 4 and
5165
merge directive format 2. It is significantly faster and smaller than
5166
older formats. It is compatible with Bazaar 0.19 and later. It is the
5167
default. "0.9" uses revision bundle format 0.9 and merge directive
5168
format 1. It is compatible with Bazaar 0.12 - 0.18.
5170
The merge directives created by bzr send may be applied using bzr merge or
5171
bzr pull by specifying a file containing a merge directive as the location.
5173
bzr send makes extensive use of public locations to map local locations into
5174
URLs that can be used by other people. See `bzr help configuration` to
5175
set them, and use `bzr info` to display them.
5178
encoding_type = 'exact'
5180
_see_also = ['merge', 'pull']
5182
takes_args = ['submit_branch?', 'public_branch?']
5186
help='Do not include a bundle in the merge directive.'),
5187
Option('no-patch', help='Do not include a preview patch in the merge'
5190
help='Remember submit and public branch.'),
5192
help='Branch to generate the submission from, '
5193
'rather than the one containing the working directory.',
5196
Option('output', short_name='o',
5197
help='Write merge directive to this file or directory; '
5198
'use - for stdout.',
5201
help='Refuse to send if there are uncommitted changes in'
5202
' the working tree, --no-strict disables the check.'),
5203
Option('mail-to', help='Mail the request to this address.',
5207
Option('body', help='Body for the email.', type=unicode),
5208
RegistryOption('format',
5209
help='Use the specified output format.',
5210
lazy_registry=('bzrlib.send', 'format_registry')),
5213
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5214
no_patch=False, revision=None, remember=False, output=None,
5215
format=None, mail_to=None, message=None, body=None,
5216
strict=None, **kwargs):
5217
from bzrlib.send import send
5218
return send(submit_branch, revision, public_branch, remember,
5219
format, no_bundle, no_patch, output,
5220
kwargs.get('from', '.'), mail_to, message, body,
5225
class cmd_bundle_revisions(cmd_send):
5226
__doc__ = """Create a merge-directive for submitting changes.
5228
A merge directive provides many things needed for requesting merges:
5230
* A machine-readable description of the merge to perform
5232
* An optional patch that is a preview of the changes requested
5234
* An optional bundle of revision data, so that the changes can be applied
5235
directly from the merge directive, without retrieving data from a
5238
If --no-bundle is specified, then public_branch is needed (and must be
5239
up-to-date), so that the receiver can perform the merge using the
5240
public_branch. The public_branch is always included if known, so that
5241
people can check it later.
5243
The submit branch defaults to the parent, but can be overridden. Both
5244
submit branch and public branch will be remembered if supplied.
5246
If a public_branch is known for the submit_branch, that public submit
5247
branch is used in the merge instructions. This means that a local mirror
5248
can be used as your actual submit branch, once you have set public_branch
5251
Two formats are currently supported: "4" uses revision bundle format 4 and
5252
merge directive format 2. It is significantly faster and smaller than
5253
older formats. It is compatible with Bazaar 0.19 and later. It is the
5254
default. "0.9" uses revision bundle format 0.9 and merge directive
5255
format 1. It is compatible with Bazaar 0.12 - 0.18.
5260
help='Do not include a bundle in the merge directive.'),
5261
Option('no-patch', help='Do not include a preview patch in the merge'
5264
help='Remember submit and public branch.'),
5266
help='Branch to generate the submission from, '
5267
'rather than the one containing the working directory.',
5270
Option('output', short_name='o', help='Write directive to this file.',
5273
help='Refuse to bundle revisions if there are uncommitted'
5274
' changes in the working tree, --no-strict disables the check.'),
5276
RegistryOption('format',
5277
help='Use the specified output format.',
5278
lazy_registry=('bzrlib.send', 'format_registry')),
5280
aliases = ['bundle']
5282
_see_also = ['send', 'merge']
5286
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5287
no_patch=False, revision=None, remember=False, output=None,
5288
format=None, strict=None, **kwargs):
5291
from bzrlib.send import send
5292
return send(submit_branch, revision, public_branch, remember,
5293
format, no_bundle, no_patch, output,
5294
kwargs.get('from', '.'), None, None, None,
5295
self.outf, strict=strict)
3570
5298
class cmd_tag(Command):
3571
"""Create a tag naming a revision.
5299
__doc__ = """Create, remove or modify a tag naming a revision.
3573
5301
Tags give human-meaningful names to revisions. Commands that take a -r
3574
5302
(--revision) option can be given -rtag:X, where X is any previously
3577
5305
Tags are stored in the branch. Tags are copied from one branch to another
3578
5306
along when you branch, push, pull or merge.
3580
It is an error to give a tag name that already exists unless you pass
5308
It is an error to give a tag name that already exists unless you pass
3581
5309
--force, in which case the tag is moved to point to the new revision.
5311
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5312
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5314
If no tag name is specified it will be determined through the
5315
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5316
upstream releases by reading configure.ac. See ``bzr help hooks`` for
3584
5320
_see_also = ['commit', 'tags']
3585
takes_args = ['tag_name']
5321
takes_args = ['tag_name?']
3586
5322
takes_options = [
3587
5323
Option('delete',
3588
5324
help='Delete this tag rather than placing it.',
3591
help='Branch in which to place the tag.',
5326
custom_help('directory',
5327
help='Branch in which to place the tag.'),
3595
5328
Option('force',
3596
help='Replace existing tags',
5329
help='Replace existing tags.',
3601
def run(self, tag_name,
5334
def run(self, tag_name=None,
3607
5340
branch, relpath = Branch.open_containing(directory)
3611
branch.tags.delete_tag(tag_name)
3612
self.outf.write('Deleted tag %s.\n' % tag_name)
5341
self.add_cleanup(branch.lock_write().unlock)
5343
if tag_name is None:
5344
raise errors.BzrCommandError("No tag specified to delete.")
5345
branch.tags.delete_tag(tag_name)
5346
self.outf.write('Deleted tag %s.\n' % tag_name)
5349
if len(revision) != 1:
5350
raise errors.BzrCommandError(
5351
"Tags can only be placed on a single revision, "
5353
revision_id = revision[0].as_revision_id(branch)
3615
if len(revision) != 1:
3616
raise errors.BzrCommandError(
3617
"Tags can only be placed on a single revision, "
3619
revision_id = revision[0].in_history(branch).rev_id
3621
revision_id = branch.last_revision()
3622
if (not force) and branch.tags.has_tag(tag_name):
3623
raise errors.TagAlreadyExists(tag_name)
3624
branch.tags.set_tag(tag_name, revision_id)
3625
self.outf.write('Created tag %s.\n' % tag_name)
5355
revision_id = branch.last_revision()
5356
if tag_name is None:
5357
tag_name = branch.automatic_tag_name(revision_id)
5358
if tag_name is None:
5359
raise errors.BzrCommandError(
5360
"Please specify a tag name.")
5361
if (not force) and branch.tags.has_tag(tag_name):
5362
raise errors.TagAlreadyExists(tag_name)
5363
branch.tags.set_tag(tag_name, revision_id)
5364
self.outf.write('Created tag %s.\n' % tag_name)
3630
5367
class cmd_tags(Command):
5368
__doc__ = """List tags.
3633
This tag shows a table of tag names and the revisions they reference.
5370
This command shows a table of tag names and the revisions they reference.
3636
5373
_see_also = ['tag']
3637
5374
takes_options = [
3639
help='Branch whose tags should be displayed',
5375
custom_help('directory',
5376
help='Branch whose tags should be displayed.'),
5377
RegistryOption.from_kwargs('sort',
5378
'Sort tags by different criteria.', title='Sorting',
5379
alpha='Sort tags lexicographically (default).',
5380
time='Sort tags chronologically.',
3645
5386
@display_command
3649
5393
branch, relpath = Branch.open_containing(directory)
3650
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3651
self.outf.write('%-20s %s\n' % (tag_name, target))
3654
# command-line interpretation helper for merge-related commands
3655
def _merge_helper(other_revision, base_revision,
3656
check_clean=True, ignore_zero=False,
3657
this_dir=None, backup_files=False,
3659
file_list=None, show_base=False, reprocess=False,
3662
change_reporter=None,
3664
"""Merge changes into a tree.
3667
list(path, revno) Base for three-way merge.
3668
If [None, None] then a base will be automatically determined.
3670
list(path, revno) Other revision for three-way merge.
3672
Directory to merge changes into; '.' by default.
3674
If true, this_dir must have no uncommitted changes before the
3676
ignore_zero - If true, suppress the "zero conflicts" message when
3677
there are no conflicts; should be set when doing something we expect
3678
to complete perfectly.
3679
file_list - If supplied, merge only changes to selected files.
3681
All available ancestors of other_revision and base_revision are
3682
automatically pulled into the branch.
3684
The revno may be -1 to indicate the last revision on the branch, which is
3687
This function is intended for use from the command line; programmatic
3688
clients might prefer to call merge.merge_inner(), which has less magic
3691
# Loading it late, so that we don't always have to import bzrlib.merge
3692
if merge_type is None:
3693
merge_type = _mod_merge.Merge3Merger
3694
if this_dir is None:
3696
this_tree = WorkingTree.open_containing(this_dir)[0]
3697
if show_base and not merge_type is _mod_merge.Merge3Merger:
3698
raise errors.BzrCommandError("Show-base is not supported for this merge"
3699
" type. %s" % merge_type)
3700
if reprocess and not merge_type.supports_reprocess:
3701
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3702
" type %s." % merge_type)
3703
if reprocess and show_base:
3704
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3705
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3706
# only want to take out a lock_tree_write() if we don't have to pull
3707
# any ancestry. But merge might fetch ancestry in the middle, in
3708
# which case we would need a lock_write().
3709
# Because we cannot upgrade locks, for now we live with the fact that
3710
# the tree will be locked multiple times during a merge. (Maybe
3711
# read-only some of the time, but it means things will get read
3714
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3715
pb=pb, change_reporter=change_reporter)
3716
merger.pp = ProgressPhase("Merge phase", 5, pb)
3717
merger.pp.next_phase()
3718
merger.check_basis(check_clean)
3719
if other_rev_id is not None:
3720
merger.set_other_revision(other_rev_id, this_tree.branch)
3722
merger.set_other(other_revision)
3723
merger.pp.next_phase()
3724
merger.set_base(base_revision)
3725
if merger.base_rev_id == merger.other_rev_id:
3726
note('Nothing to do.')
3728
if file_list is None:
3729
if pull and merger.base_rev_id == merger.this_rev_id:
3730
# FIXME: deduplicate with pull
3731
result = merger.this_tree.pull(merger.this_branch,
3732
False, merger.other_rev_id)
3733
if result.old_revid == result.new_revid:
3734
note('No revisions to pull.')
3736
note('Now on revision %d.' % result.new_revno)
3738
merger.backup_files = backup_files
3739
merger.merge_type = merge_type
3740
merger.set_interesting_files(file_list)
3741
merger.show_base = show_base
3742
merger.reprocess = reprocess
3743
conflicts = merger.do_merge()
3744
if file_list is None:
3745
merger.set_pending()
3751
def _create_prefix(cur_transport):
3752
needed = [cur_transport]
3753
# Recurse upwards until we can create a directory successfully
3755
new_transport = cur_transport.clone('..')
3756
if new_transport.base == cur_transport.base:
3757
raise errors.BzrCommandError("Failed to create path"
3761
new_transport.mkdir('.')
3762
except errors.NoSuchFile:
3763
needed.append(new_transport)
3764
cur_transport = new_transport
3768
# Now we only need to create child directories
3770
cur_transport = needed.pop()
3771
cur_transport.ensure_base()
3774
merge = _merge_helper
3777
# these get imported and then picked up by the scan for cmd_*
3778
# TODO: Some more consistent way to split command definitions across files;
3779
# we do need to load at least some information about them to know of
3780
# aliases. ideally we would avoid loading the implementation until the
3781
# details were needed.
3782
from bzrlib.cmd_version_info import cmd_version_info
3783
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
3784
from bzrlib.bundle.commands import cmd_bundle_revisions
3785
from bzrlib.sign_my_commits import cmd_sign_my_commits
3786
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
3787
cmd_weave_plan_merge, cmd_weave_merge_text
5395
tags = branch.tags.get_tag_dict().items()
5399
self.add_cleanup(branch.lock_read().unlock)
5401
graph = branch.repository.get_graph()
5402
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5403
revid1, revid2 = rev1.rev_id, rev2.rev_id
5404
# only show revisions between revid1 and revid2 (inclusive)
5405
tags = [(tag, revid) for tag, revid in tags if
5406
graph.is_between(revid, revid1, revid2)]
5409
elif sort == 'time':
5411
for tag, revid in tags:
5413
revobj = branch.repository.get_revision(revid)
5414
except errors.NoSuchRevision:
5415
timestamp = sys.maxint # place them at the end
5417
timestamp = revobj.timestamp
5418
timestamps[revid] = timestamp
5419
tags.sort(key=lambda x: timestamps[x[1]])
5421
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5422
for index, (tag, revid) in enumerate(tags):
5424
revno = branch.revision_id_to_dotted_revno(revid)
5425
if isinstance(revno, tuple):
5426
revno = '.'.join(map(str, revno))
5427
except errors.NoSuchRevision:
5428
# Bad tag data/merges can lead to tagged revisions
5429
# which are not in this branch. Fail gracefully ...
5431
tags[index] = (tag, revno)
5433
for tag, revspec in tags:
5434
self.outf.write('%-20s %s\n' % (tag, revspec))
5437
class cmd_reconfigure(Command):
5438
__doc__ = """Reconfigure the type of a bzr directory.
5440
A target configuration must be specified.
5442
For checkouts, the bind-to location will be auto-detected if not specified.
5443
The order of preference is
5444
1. For a lightweight checkout, the current bound location.
5445
2. For branches that used to be checkouts, the previously-bound location.
5446
3. The push location.
5447
4. The parent location.
5448
If none of these is available, --bind-to must be specified.
5451
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5452
takes_args = ['location?']
5454
RegistryOption.from_kwargs(
5456
title='Target type',
5457
help='The type to reconfigure the directory to.',
5458
value_switches=True, enum_switch=False,
5459
branch='Reconfigure to be an unbound branch with no working tree.',
5460
tree='Reconfigure to be an unbound branch with a working tree.',
5461
checkout='Reconfigure to be a bound branch with a working tree.',
5462
lightweight_checkout='Reconfigure to be a lightweight'
5463
' checkout (with no local history).',
5464
standalone='Reconfigure to be a standalone branch '
5465
'(i.e. stop using shared repository).',
5466
use_shared='Reconfigure to use a shared repository.',
5467
with_trees='Reconfigure repository to create '
5468
'working trees on branches by default.',
5469
with_no_trees='Reconfigure repository to not create '
5470
'working trees on branches by default.'
5472
Option('bind-to', help='Branch to bind checkout to.', type=str),
5474
help='Perform reconfiguration even if local changes'
5476
Option('stacked-on',
5477
help='Reconfigure a branch to be stacked on another branch.',
5481
help='Reconfigure a branch to be unstacked. This '
5482
'may require copying substantial data into it.',
5486
def run(self, location=None, target_type=None, bind_to=None, force=False,
5489
directory = bzrdir.BzrDir.open(location)
5490
if stacked_on and unstacked:
5491
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5492
elif stacked_on is not None:
5493
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5495
reconfigure.ReconfigureUnstacked().apply(directory)
5496
# At the moment you can use --stacked-on and a different
5497
# reconfiguration shape at the same time; there seems no good reason
5499
if target_type is None:
5500
if stacked_on or unstacked:
5503
raise errors.BzrCommandError('No target configuration '
5505
elif target_type == 'branch':
5506
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5507
elif target_type == 'tree':
5508
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5509
elif target_type == 'checkout':
5510
reconfiguration = reconfigure.Reconfigure.to_checkout(
5512
elif target_type == 'lightweight-checkout':
5513
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5515
elif target_type == 'use-shared':
5516
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5517
elif target_type == 'standalone':
5518
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5519
elif target_type == 'with-trees':
5520
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5522
elif target_type == 'with-no-trees':
5523
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5525
reconfiguration.apply(force)
5528
class cmd_switch(Command):
5529
__doc__ = """Set the branch of a checkout and update.
5531
For lightweight checkouts, this changes the branch being referenced.
5532
For heavyweight checkouts, this checks that there are no local commits
5533
versus the current bound branch, then it makes the local branch a mirror
5534
of the new location and binds to it.
5536
In both cases, the working tree is updated and uncommitted changes
5537
are merged. The user can commit or revert these as they desire.
5539
Pending merges need to be committed or reverted before using switch.
5541
The path to the branch to switch to can be specified relative to the parent
5542
directory of the current branch. For example, if you are currently in a
5543
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5546
Bound branches use the nickname of its master branch unless it is set
5547
locally, in which case switching will update the local nickname to be
5551
takes_args = ['to_location?']
5552
takes_options = ['directory',
5554
help='Switch even if local commits will be lost.'),
5556
Option('create-branch', short_name='b',
5557
help='Create the target branch from this one before'
5558
' switching to it.'),
5561
def run(self, to_location=None, force=False, create_branch=False,
5562
revision=None, directory=u'.'):
5563
from bzrlib import switch
5564
tree_location = directory
5565
revision = _get_one_revision('switch', revision)
5566
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5567
if to_location is None:
5568
if revision is None:
5569
raise errors.BzrCommandError('You must supply either a'
5570
' revision or a location')
5571
to_location = tree_location
5573
branch = control_dir.open_branch()
5574
had_explicit_nick = branch.get_config().has_explicit_nickname()
5575
except errors.NotBranchError:
5577
had_explicit_nick = False
5580
raise errors.BzrCommandError('cannot create branch without'
5582
to_location = directory_service.directories.dereference(
5584
if '/' not in to_location and '\\' not in to_location:
5585
# This path is meant to be relative to the existing branch
5586
this_url = self._get_branch_location(control_dir)
5587
to_location = urlutils.join(this_url, '..', to_location)
5588
to_branch = branch.bzrdir.sprout(to_location,
5589
possible_transports=[branch.bzrdir.root_transport],
5590
source_branch=branch).open_branch()
5593
to_branch = Branch.open(to_location)
5594
except errors.NotBranchError:
5595
this_url = self._get_branch_location(control_dir)
5596
to_branch = Branch.open(
5597
urlutils.join(this_url, '..', to_location))
5598
if revision is not None:
5599
revision = revision.as_revision_id(to_branch)
5600
switch.switch(control_dir, to_branch, force, revision_id=revision)
5601
if had_explicit_nick:
5602
branch = control_dir.open_branch() #get the new branch!
5603
branch.nick = to_branch.nick
5604
note('Switched to branch: %s',
5605
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5607
def _get_branch_location(self, control_dir):
5608
"""Return location of branch for this control dir."""
5610
this_branch = control_dir.open_branch()
5611
# This may be a heavy checkout, where we want the master branch
5612
master_location = this_branch.get_bound_location()
5613
if master_location is not None:
5614
return master_location
5615
# If not, use a local sibling
5616
return this_branch.base
5617
except errors.NotBranchError:
5618
format = control_dir.find_branch_format()
5619
if getattr(format, 'get_reference', None) is not None:
5620
return format.get_reference(control_dir)
5622
return control_dir.root_transport.base
5625
class cmd_view(Command):
5626
__doc__ = """Manage filtered views.
5628
Views provide a mask over the tree so that users can focus on
5629
a subset of a tree when doing their work. After creating a view,
5630
commands that support a list of files - status, diff, commit, etc -
5631
effectively have that list of files implicitly given each time.
5632
An explicit list of files can still be given but those files
5633
must be within the current view.
5635
In most cases, a view has a short life-span: it is created to make
5636
a selected change and is deleted once that change is committed.
5637
At other times, you may wish to create one or more named views
5638
and switch between them.
5640
To disable the current view without deleting it, you can switch to
5641
the pseudo view called ``off``. This can be useful when you need
5642
to see the whole tree for an operation or two (e.g. merge) but
5643
want to switch back to your view after that.
5646
To define the current view::
5648
bzr view file1 dir1 ...
5650
To list the current view::
5654
To delete the current view::
5658
To disable the current view without deleting it::
5660
bzr view --switch off
5662
To define a named view and switch to it::
5664
bzr view --name view-name file1 dir1 ...
5666
To list a named view::
5668
bzr view --name view-name
5670
To delete a named view::
5672
bzr view --name view-name --delete
5674
To switch to a named view::
5676
bzr view --switch view-name
5678
To list all views defined::
5682
To delete all views::
5684
bzr view --delete --all
5688
takes_args = ['file*']
5691
help='Apply list or delete action to all views.',
5694
help='Delete the view.',
5697
help='Name of the view to define, list or delete.',
5701
help='Name of the view to switch to.',
5706
def run(self, file_list,
5712
tree, file_list = tree_files(file_list, apply_view=False)
5713
current_view, view_dict = tree.views.get_view_info()
5718
raise errors.BzrCommandError(
5719
"Both --delete and a file list specified")
5721
raise errors.BzrCommandError(
5722
"Both --delete and --switch specified")
5724
tree.views.set_view_info(None, {})
5725
self.outf.write("Deleted all views.\n")
5727
raise errors.BzrCommandError("No current view to delete")
5729
tree.views.delete_view(name)
5730
self.outf.write("Deleted '%s' view.\n" % name)
5733
raise errors.BzrCommandError(
5734
"Both --switch and a file list specified")
5736
raise errors.BzrCommandError(
5737
"Both --switch and --all specified")
5738
elif switch == 'off':
5739
if current_view is None:
5740
raise errors.BzrCommandError("No current view to disable")
5741
tree.views.set_view_info(None, view_dict)
5742
self.outf.write("Disabled '%s' view.\n" % (current_view))
5744
tree.views.set_view_info(switch, view_dict)
5745
view_str = views.view_display_str(tree.views.lookup_view())
5746
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5749
self.outf.write('Views defined:\n')
5750
for view in sorted(view_dict):
5751
if view == current_view:
5755
view_str = views.view_display_str(view_dict[view])
5756
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5758
self.outf.write('No views defined.\n')
5761
# No name given and no current view set
5764
raise errors.BzrCommandError(
5765
"Cannot change the 'off' pseudo view")
5766
tree.views.set_view(name, sorted(file_list))
5767
view_str = views.view_display_str(tree.views.lookup_view())
5768
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5772
# No name given and no current view set
5773
self.outf.write('No current view.\n')
5775
view_str = views.view_display_str(tree.views.lookup_view(name))
5776
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5779
class cmd_hooks(Command):
5780
__doc__ = """Show hooks."""
5785
for hook_key in sorted(hooks.known_hooks.keys()):
5786
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5787
self.outf.write("%s:\n" % type(some_hooks).__name__)
5788
for hook_name, hook_point in sorted(some_hooks.items()):
5789
self.outf.write(" %s:\n" % (hook_name,))
5790
found_hooks = list(hook_point)
5792
for hook in found_hooks:
5793
self.outf.write(" %s\n" %
5794
(some_hooks.get_hook_name(hook),))
5796
self.outf.write(" <no hooks installed>\n")
5799
class cmd_remove_branch(Command):
5800
__doc__ = """Remove a branch.
5802
This will remove the branch from the specified location but
5803
will keep any working tree or repository in place.
5807
Remove the branch at repo/trunk::
5809
bzr remove-branch repo/trunk
5813
takes_args = ["location?"]
5815
aliases = ["rmbranch"]
5817
def run(self, location=None):
5818
if location is None:
5820
branch = Branch.open_containing(location)[0]
5821
branch.bzrdir.destroy_branch()
5824
class cmd_shelve(Command):
5825
__doc__ = """Temporarily set aside some changes from the current tree.
5827
Shelve allows you to temporarily put changes you've made "on the shelf",
5828
ie. out of the way, until a later time when you can bring them back from
5829
the shelf with the 'unshelve' command. The changes are stored alongside
5830
your working tree, and so they aren't propagated along with your branch nor
5831
will they survive its deletion.
5833
If shelve --list is specified, previously-shelved changes are listed.
5835
Shelve is intended to help separate several sets of changes that have
5836
been inappropriately mingled. If you just want to get rid of all changes
5837
and you don't need to restore them later, use revert. If you want to
5838
shelve all text changes at once, use shelve --all.
5840
If filenames are specified, only the changes to those files will be
5841
shelved. Other files will be left untouched.
5843
If a revision is specified, changes since that revision will be shelved.
5845
You can put multiple items on the shelf, and by default, 'unshelve' will
5846
restore the most recently shelved changes.
5849
takes_args = ['file*']
5854
Option('all', help='Shelve all changes.'),
5856
RegistryOption('writer', 'Method to use for writing diffs.',
5857
bzrlib.option.diff_writer_registry,
5858
value_switches=True, enum_switch=False),
5860
Option('list', help='List shelved changes.'),
5862
help='Destroy removed changes instead of shelving them.'),
5864
_see_also = ['unshelve']
5866
def run(self, revision=None, all=False, file_list=None, message=None,
5867
writer=None, list=False, destroy=False, directory=u'.'):
5869
return self.run_for_list()
5870
from bzrlib.shelf_ui import Shelver
5872
writer = bzrlib.option.diff_writer_registry.get()
5874
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5875
file_list, message, destroy=destroy, directory=directory)
5880
except errors.UserAbort:
5883
def run_for_list(self):
5884
tree = WorkingTree.open_containing('.')[0]
5885
self.add_cleanup(tree.lock_read().unlock)
5886
manager = tree.get_shelf_manager()
5887
shelves = manager.active_shelves()
5888
if len(shelves) == 0:
5889
note('No shelved changes.')
5891
for shelf_id in reversed(shelves):
5892
message = manager.get_metadata(shelf_id).get('message')
5894
message = '<no message>'
5895
self.outf.write('%3d: %s\n' % (shelf_id, message))
5899
class cmd_unshelve(Command):
5900
__doc__ = """Restore shelved changes.
5902
By default, the most recently shelved changes are restored. However if you
5903
specify a shelf by id those changes will be restored instead. This works
5904
best when the changes don't depend on each other.
5907
takes_args = ['shelf_id?']
5910
RegistryOption.from_kwargs(
5911
'action', help="The action to perform.",
5912
enum_switch=False, value_switches=True,
5913
apply="Apply changes and remove from the shelf.",
5914
dry_run="Show changes, but do not apply or remove them.",
5915
preview="Instead of unshelving the changes, show the diff that "
5916
"would result from unshelving.",
5917
delete_only="Delete changes without applying them.",
5918
keep="Apply changes but don't delete them.",
5921
_see_also = ['shelve']
5923
def run(self, shelf_id=None, action='apply', directory=u'.'):
5924
from bzrlib.shelf_ui import Unshelver
5925
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5929
unshelver.tree.unlock()
5932
class cmd_clean_tree(Command):
5933
__doc__ = """Remove unwanted files from working tree.
5935
By default, only unknown files, not ignored files, are deleted. Versioned
5936
files are never deleted.
5938
Another class is 'detritus', which includes files emitted by bzr during
5939
normal operations and selftests. (The value of these files decreases with
5942
If no options are specified, unknown files are deleted. Otherwise, option
5943
flags are respected, and may be combined.
5945
To check what clean-tree will do, use --dry-run.
5947
takes_options = ['directory',
5948
Option('ignored', help='Delete all ignored files.'),
5949
Option('detritus', help='Delete conflict files, merge'
5950
' backups, and failed selftest dirs.'),
5952
help='Delete files unknown to bzr (default).'),
5953
Option('dry-run', help='Show files to delete instead of'
5955
Option('force', help='Do not prompt before deleting.')]
5956
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5957
force=False, directory=u'.'):
5958
from bzrlib.clean_tree import clean_tree
5959
if not (unknown or ignored or detritus):
5963
clean_tree(directory, unknown=unknown, ignored=ignored,
5964
detritus=detritus, dry_run=dry_run, no_prompt=force)
5967
class cmd_reference(Command):
5968
__doc__ = """list, view and set branch locations for nested trees.
5970
If no arguments are provided, lists the branch locations for nested trees.
5971
If one argument is provided, display the branch location for that tree.
5972
If two arguments are provided, set the branch location for that tree.
5977
takes_args = ['path?', 'location?']
5979
def run(self, path=None, location=None):
5981
if path is not None:
5983
tree, branch, relpath =(
5984
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5985
if path is not None:
5988
tree = branch.basis_tree()
5990
info = branch._get_all_reference_info().iteritems()
5991
self._display_reference_info(tree, branch, info)
5993
file_id = tree.path2id(path)
5995
raise errors.NotVersionedError(path)
5996
if location is None:
5997
info = [(file_id, branch.get_reference_info(file_id))]
5998
self._display_reference_info(tree, branch, info)
6000
branch.set_reference_info(file_id, path, location)
6002
def _display_reference_info(self, tree, branch, info):
6004
for file_id, (path, location) in info:
6006
path = tree.id2path(file_id)
6007
except errors.NoSuchId:
6009
ref_list.append((path, location))
6010
for path, location in sorted(ref_list):
6011
self.outf.write('%s %s\n' % (path, location))
6014
def _register_lazy_builtins():
6015
# register lazy builtins from other modules; called at startup and should
6016
# be only called once.
6017
for (name, aliases, module_name) in [
6018
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6019
('cmd_dpush', [], 'bzrlib.foreign'),
6020
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6021
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6022
('cmd_conflicts', [], 'bzrlib.conflicts'),
6023
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6025
builtin_command_registry.register_lazy(name, aliases, module_name)