17
17
"""builtin bzr commands"""
19
# DO NOT change this to cStringIO - it results in control files
21
# FIXIT! (Only deal with byte streams OR unicode at any one layer.)
24
from StringIO import StringIO
23
from shutil import rmtree
29
from bzrlib import BZRDIR
28
from bzrlib.branch import Branch
29
import bzrlib.bzrdir as bzrdir
30
from bzrlib.bundle import read_bundle_from_url
31
from bzrlib.bundle.read_bundle import BundleReader
32
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
30
33
from bzrlib.commands import Command, display_command
31
from bzrlib.branch import Branch
32
from bzrlib.revision import common_ancestor
33
34
import bzrlib.errors as errors
34
35
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
35
36
NotBranchError, DivergedBranches, NotConflicted,
36
NoSuchFile, NoWorkingTree, FileInWrongBranch)
37
NoSuchFile, NoWorkingTree, FileInWrongBranch,
38
NotVersionedError, NotABundle)
39
from bzrlib.log import show_one_log
40
from bzrlib.merge import Merge3Merger
37
41
from bzrlib.option import Option
43
from bzrlib.progress import DummyProgress, ProgressPhase
44
from bzrlib.revision import common_ancestor
38
45
from bzrlib.revisionspec import RevisionSpec
39
46
import bzrlib.trace
40
47
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
48
from bzrlib.transport.local import LocalTransport
50
import bzrlib.urlutils as urlutils
41
51
from bzrlib.workingtree import WorkingTree
42
from bzrlib.log import show_one_log
45
54
def tree_files(file_list, default_branch=u'.'):
224
272
takes_args = ['file*']
225
273
takes_options = ['no-recurse', 'dry-run', 'verbose']
274
encoding_type = 'replace'
227
276
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
228
277
import bzrlib.add
232
# This is pointless, but I'd rather not raise an error
233
action = bzrlib.add.add_action_null
235
action = bzrlib.add.add_action_print
237
action = bzrlib.add.add_action_add
239
action = bzrlib.add.add_action_add_and_print
279
action = bzrlib.add.AddAction(to_file=self.outf,
280
should_print=(not is_quiet()))
241
282
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
283
action=action, save=not dry_run)
243
284
if len(ignored) > 0:
244
for glob in sorted(ignored.keys()):
245
match_len = len(ignored[glob])
286
for glob in sorted(ignored.keys()):
247
287
for path in ignored[glob]:
248
print "ignored %s matching \"%s\"" % (path, glob)
250
print "ignored %d file(s) matching \"%s\"" % (match_len,
252
print "If you wish to add some of these files, please add them"\
288
self.outf.write("ignored %s matching \"%s\"\n"
292
for glob, paths in ignored.items():
293
match_len += len(paths)
294
self.outf.write("ignored %d file(s).\n" % match_len)
295
self.outf.write("If you wish to add some of these files,"
296
" please add them by name.\n")
256
299
class cmd_mkdir(Command):
298
348
if len(revision) > 1:
299
349
raise BzrCommandError('bzr inventory --revision takes'
300
350
' exactly one revision identifier')
301
inv = tree.branch.get_revision_inventory(
351
inv = tree.branch.repository.get_revision_inventory(
302
352
revision[0].in_history(tree.branch).rev_id)
304
354
for path, entry in inv.entries():
305
355
if kind and kind != entry.kind:
308
print '%-50s %s' % (path, entry.file_id)
358
self.outf.write('%-50s %s\n' % (path, entry.file_id))
313
class cmd_move(Command):
314
"""Move files to a different directory.
319
The destination must be a versioned directory in the same branch.
321
takes_args = ['source$', 'dest']
322
def run(self, source_list, dest):
323
tree, source_list = tree_files(source_list)
324
# TODO: glob expansion on windows?
325
tree.move(source_list, tree.relpath(dest))
328
class cmd_rename(Command):
329
"""Change the name of an entry.
332
bzr rename frob.c frobber.c
333
bzr rename src/frob.c lib/frob.c
335
It is an error if the destination name exists.
337
See also the 'move' command, which moves files into a different
338
directory without changing their name.
340
# TODO: Some way to rename multiple files without invoking
341
# bzr for each one?"""
342
takes_args = ['from_name', 'to_name']
344
def run(self, from_name, to_name):
345
tree, (from_name, to_name) = tree_files((from_name, to_name))
346
tree.rename_one(from_name, to_name)
360
self.outf.write(path)
361
self.outf.write('\n')
349
364
class cmd_mv(Command):
368
387
if os.path.isdir(names_list[-1]):
369
388
# move into existing directory
370
389
for pair in tree.move(rel_names[:-1], rel_names[-1]):
371
print "%s => %s" % pair
390
self.outf.write("%s => %s\n" % pair)
373
392
if len(names_list) != 2:
374
393
raise BzrCommandError('to mv multiple files the destination '
375
394
'must be a versioned directory')
376
395
tree.rename_one(rel_names[0], rel_names[1])
377
print "%s => %s" % (rel_names[0], rel_names[1])
396
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
380
399
class cmd_pull(Command):
381
"""Pull any changes from another branch into the current one.
400
"""Turn this branch into a mirror of another branch.
402
This command only works on branches that have not diverged. Branches are
403
considered diverged if the destination branch's most recent commit is one
404
that has not been merged (directly or indirectly) into the parent.
406
If branches have diverged, you can use 'bzr merge' to integrate the changes
407
from one into the other. Once one branch has merged, the other should
408
be able to pull it again.
410
If branches have diverged, you can use 'bzr merge' to pull the text changes
411
from one into the other. Once one branch has merged, the other should
412
be able to pull it again.
414
If you want to forget your local changes and just update your branch to
415
match the remote one, use pull --overwrite.
383
417
If there is no default location set, the first pull will set it. After
384
418
that, you can omit the location to use the default. To change the
385
default, use --remember.
387
This command only works on branches that have not diverged. Branches are
388
considered diverged if both branches have had commits without first
389
pulling from the other.
391
If branches have diverged, you can use 'bzr merge' to pull the text changes
392
from one into the other. Once one branch has merged, the other should
393
be able to pull it again.
395
If you want to forget your local changes and just update your branch to
396
match the remote one, use --overwrite.
419
default, use --remember. The value will only be saved if the remote
420
location can be accessed.
398
takes_options = ['remember', 'overwrite', 'verbose']
423
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
399
424
takes_args = ['location?']
401
def run(self, location=None, remember=False, overwrite=False, verbose=False):
402
from bzrlib.merge import merge
403
from shutil import rmtree
405
# FIXME: too much stuff is in the command class
406
tree_to = WorkingTree.open_containing(u'.')[0]
407
stored_loc = tree_to.branch.get_parent()
425
encoding_type = 'replace'
427
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
428
# FIXME: too much stuff is in the command class
430
tree_to = WorkingTree.open_containing(u'.')[0]
431
branch_to = tree_to.branch
432
except NoWorkingTree:
434
branch_to = Branch.open_containing(u'.')[0]
437
if location is not None:
439
reader = read_bundle_from_url(location)
441
pass # Continue on considering this url a Branch
443
stored_loc = branch_to.get_parent()
408
444
if location is None:
409
445
if stored_loc is None:
410
446
raise BzrCommandError("No pull location known or specified.")
412
print "Using saved location: %s" % stored_loc
448
display_url = urlutils.unescape_for_display(stored_loc,
450
self.outf.write("Using saved location: %s\n" % display_url)
413
451
location = stored_loc
415
br_from = Branch.open(location)
416
br_to = tree_to.branch
418
old_rh = br_to.revision_history()
419
count = tree_to.pull(br_from, overwrite)
421
if br_to.get_parent() is None or remember:
422
br_to.set_parent(location)
454
if reader is not None:
455
install_bundle(branch_to.repository, reader)
456
branch_from = branch_to
458
branch_from = Branch.open(location)
460
if branch_to.get_parent() is None or remember:
461
branch_to.set_parent(branch_from.base)
465
if reader is not None:
466
rev_id = reader.info.target
467
elif len(revision) == 1:
468
rev_id = revision[0].in_history(branch_from).rev_id
470
raise BzrCommandError('bzr pull --revision takes one value.')
472
old_rh = branch_to.revision_history()
473
if tree_to is not None:
474
count = tree_to.pull(branch_from, overwrite, rev_id)
476
count = branch_to.pull(branch_from, overwrite, rev_id)
423
477
note('%d revision(s) pulled.' % (count,))
426
new_rh = tree_to.branch.revision_history()
480
new_rh = branch_to.revision_history()
427
481
if old_rh != new_rh:
428
482
# Something changed
429
483
from bzrlib.log import show_changed_revisions
430
show_changed_revisions(tree_to.branch, old_rh, new_rh)
484
show_changed_revisions(branch_to, old_rh, new_rh,
433
488
class cmd_push(Command):
434
"""Push this branch into another branch.
436
The remote branch will not have its working tree populated because this
437
is both expensive, and may not be supported on the remote file system.
439
Some smart servers or protocols *may* put the working tree in place.
489
"""Update a mirror of this branch.
491
The target branch will not have its working tree populated because this
492
is both expensive, and is not supported on remote file systems.
494
Some smart servers or protocols *may* put the working tree in place in
497
This command only works on branches that have not diverged. Branches are
498
considered diverged if the destination branch's most recent commit is one
499
that has not been merged (directly or indirectly) by the source branch.
501
If branches have diverged, you can use 'bzr push --overwrite' to replace
502
the other branch completely, discarding its unmerged changes.
504
If you want to ensure you have the different changes in the other branch,
505
do a merge (see bzr help merge) from the other branch, and commit that.
506
After that you will be able to do a push without '--overwrite'.
441
508
If there is no default push location set, the first push will set it.
442
509
After that, you can omit the location to use the default. To change the
443
default, use --remember.
445
This command only works on branches that have not diverged. Branches are
446
considered diverged if the branch being pushed to is not an older version
449
If branches have diverged, you can use 'bzr push --overwrite' to replace
450
the other branch completely.
452
If you want to ensure you have the different changes in the other branch,
453
do a merge (see bzr help merge) from the other branch, and commit that
454
before doing a 'push --overwrite'.
510
default, use --remember. The value will only be saved if the remote
511
location can be accessed.
456
takes_options = ['remember', 'overwrite',
514
takes_options = ['remember', 'overwrite', 'verbose',
457
515
Option('create-prefix',
458
516
help='Create the path leading up to the branch '
459
517
'if it does not already exist')]
460
518
takes_args = ['location?']
519
encoding_type = 'replace'
462
521
def run(self, location=None, remember=False, overwrite=False,
463
522
create_prefix=False, verbose=False):
464
523
# FIXME: Way too big! Put this into a function called from the
467
from shutil import rmtree
468
525
from bzrlib.transport import get_transport
470
tree_from = WorkingTree.open_containing(u'.')[0]
471
br_from = tree_from.branch
472
stored_loc = tree_from.branch.get_push_location()
527
br_from = Branch.open_containing('.')[0]
528
stored_loc = br_from.get_push_location()
473
529
if location is None:
474
530
if stored_loc is None:
475
531
raise BzrCommandError("No push location known or specified.")
477
print "Using saved location: %s" % stored_loc
533
display_url = urlutils.unescape_for_display(stored_loc,
535
self.outf.write("Using saved location: %s\n" % display_url)
478
536
location = stored_loc
538
transport = get_transport(location)
539
location_url = transport.base
480
br_to = Branch.open(location)
543
dir_to = bzrlib.bzrdir.BzrDir.open(location_url)
544
br_to = dir_to.open_branch()
481
545
except NotBranchError:
482
546
# create a branch.
483
transport = get_transport(location).clone('..')
547
transport = transport.clone('..')
484
548
if not create_prefix:
486
transport.mkdir(transport.relpath(location))
550
relurl = transport.relpath(location_url)
551
mutter('creating directory %s => %s', location_url, relurl)
552
transport.mkdir(relurl)
487
553
except NoSuchFile:
488
554
raise BzrCommandError("Parent directory of %s "
489
555
"does not exist." % location)
491
557
current = transport.base
492
needed = [(transport, transport.relpath(location))]
558
needed = [(transport, transport.relpath(location_url))]
495
561
transport, relpath = needed[-1]
500
566
needed.append((new_transport,
501
567
new_transport.relpath(transport.base)))
502
568
if new_transport.base == transport.base:
503
raise BzrCommandError("Could not creeate "
569
raise BzrCommandError("Could not create "
505
br_to = Branch.initialize(location)
506
old_rh = br_to.revision_history()
571
dir_to = br_from.bzrdir.clone(location_url,
572
revision_id=br_from.last_revision())
573
br_to = dir_to.open_branch()
574
count = len(br_to.revision_history())
575
# We successfully created the target, remember it
576
if br_from.get_push_location() is None or remember:
577
br_from.set_push_location(br_to.base)
579
# We were able to connect to the remote location, so remember it
580
# we don't need to successfully push because of possible divergence.
581
if br_from.get_push_location() is None or remember:
582
br_from.set_push_location(br_to.base)
583
old_rh = br_to.revision_history()
509
tree_to = br_to.working_tree()
510
except NoWorkingTree:
511
# TODO: This should be updated for branches which don't have a
512
# working tree, as opposed to ones where we just couldn't
514
warning('Unable to update the working tree of: %s' % (br_to.base,))
515
count = br_to.pull(br_from, overwrite)
517
count = tree_to.pull(br_from, overwrite)
518
except DivergedBranches:
519
raise BzrCommandError("These branches have diverged."
520
" Try a merge then push with overwrite.")
521
if br_from.get_push_location() is None or remember:
522
br_from.set_push_location(location)
586
tree_to = dir_to.open_workingtree()
587
except errors.NotLocalUrl:
588
warning('This transport does not update the working '
589
'tree of: %s' % (br_to.base,))
590
count = br_to.pull(br_from, overwrite)
591
except NoWorkingTree:
592
count = br_to.pull(br_from, overwrite)
594
count = tree_to.pull(br_from, overwrite)
595
except DivergedBranches:
596
raise BzrCommandError("These branches have diverged."
597
" Try a merge then push with overwrite.")
523
598
note('%d revision(s) pushed.' % (count,))
567
642
br_from.lock_read()
569
644
if basis is not None:
570
basis_branch = WorkingTree.open_containing(basis)[0].branch
645
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
573
648
if len(revision) == 1 and revision[0] is not None:
574
649
revision_id = revision[0].in_history(br_from)[1]
651
# FIXME - wt.last_revision, fallback to branch, fall back to
652
# None or perhaps NULL_REVISION to mean copy nothing
654
revision_id = br_from.last_revision()
577
655
if to_location is None:
578
656
to_location = os.path.basename(from_location.rstrip("/\\"))
581
659
name = os.path.basename(to_location) + '\n'
583
os.mkdir(to_location)
585
if e.errno == errno.EEXIST:
586
raise BzrCommandError('Target directory "%s" already'
587
' exists.' % to_location)
588
if e.errno == errno.ENOENT:
589
raise BzrCommandError('Parent of "%s" does not exist.' %
594
copy_branch(br_from, to_location, revision_id, basis_branch)
661
to_transport = get_transport(to_location)
663
to_transport.mkdir('.')
664
except bzrlib.errors.FileExists:
665
raise BzrCommandError('Target directory "%s" already'
666
' exists.' % to_location)
667
except bzrlib.errors.NoSuchFile:
668
raise BzrCommandError('Parent of "%s" does not exist.' %
671
# preserve whatever source format we have.
672
dir = br_from.bzrdir.sprout(to_transport.base,
673
revision_id, basis_dir)
674
branch = dir.open_branch()
595
675
except bzrlib.errors.NoSuchRevision:
676
to_transport.delete_tree('.')
597
677
msg = "The branch %s has no revision %s." % (from_location, revision[0])
598
678
raise BzrCommandError(msg)
599
679
except bzrlib.errors.UnlistableBranch:
600
680
rmtree(to_location)
601
msg = "The branch %s cannot be used as a --basis"
681
msg = "The branch %s cannot be used as a --basis" % (basis,)
602
682
raise BzrCommandError(msg)
603
branch = Branch.open(to_location)
605
name = StringIO(name)
606
branch.put_controlfile('branch-name', name)
684
branch.control_files.put_utf8('branch-name', name)
607
685
note('Branched %d revision(s).' % branch.revno())
690
class cmd_checkout(Command):
691
"""Create a new checkout of an existing branch.
693
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
694
the branch found in '.'. This is useful if you have removed the working tree
695
or if it was never created - i.e. if you pushed the branch to its current
698
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
699
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
701
To retrieve the branch as of a particular revision, supply the --revision
702
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
703
out of date [so you cannot commit] but it may be useful (i.e. to examine old
706
--basis is to speed up checking out from remote branches. When specified, it
707
uses the inventory and file contents from the basis branch in preference to the
708
branch being checked out.
710
takes_args = ['branch_location?', 'to_location?']
711
takes_options = ['revision', # , 'basis']
712
Option('lightweight',
713
help="perform a lightweight checkout. Lightweight "
714
"checkouts depend on access to the branch for "
715
"every operation. Normal checkouts can perform "
716
"common operations like diff and status without "
717
"such access, and also support local commits."
721
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
725
elif len(revision) > 1:
726
raise BzrCommandError(
727
'bzr checkout --revision takes exactly 1 revision value')
728
if branch_location is None:
729
branch_location = bzrlib.osutils.getcwd()
730
to_location = branch_location
731
source = Branch.open(branch_location)
732
if len(revision) == 1 and revision[0] is not None:
733
revision_id = revision[0].in_history(source)[1]
736
if to_location is None:
737
to_location = os.path.basename(branch_location.rstrip("/\\"))
738
# if the source and to_location are the same,
739
# and there is no working tree,
740
# then reconstitute a branch
741
if (bzrlib.osutils.abspath(to_location) ==
742
bzrlib.osutils.abspath(branch_location)):
744
source.bzrdir.open_workingtree()
745
except errors.NoWorkingTree:
746
source.bzrdir.create_workingtree()
749
os.mkdir(to_location)
751
if e.errno == errno.EEXIST:
752
raise BzrCommandError('Target directory "%s" already'
753
' exists.' % to_location)
754
if e.errno == errno.ENOENT:
755
raise BzrCommandError('Parent of "%s" does not exist.' %
759
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
760
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
763
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
764
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
766
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
767
to_location, force_new_tree=False)
768
checkout = checkout_branch.bzrdir
769
checkout_branch.bind(source)
770
if revision_id is not None:
771
rh = checkout_branch.revision_history()
772
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
773
checkout.create_workingtree(revision_id)
775
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
612
778
class cmd_renames(Command):
613
779
"""Show list of renamed files.
621
787
def run(self, dir=u'.'):
622
788
tree = WorkingTree.open_containing(dir)[0]
623
old_inv = tree.branch.basis_tree().inventory
789
old_inv = tree.basis_tree().inventory
624
790
new_inv = tree.read_working_inventory()
626
792
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
628
794
for old_name, new_name in renames:
629
print "%s => %s" % (old_name, new_name)
795
self.outf.write("%s => %s\n" % (old_name, new_name))
798
class cmd_update(Command):
799
"""Update a tree to have the latest code committed to its branch.
801
This will perform a merge into the working tree, and may generate
802
conflicts. If you have any local changes, you will still
803
need to commit them after the update for the update to be complete.
805
If you want to discard your local changes, you can just do a
806
'bzr revert' instead of 'bzr commit' after the update.
808
takes_args = ['dir?']
810
def run(self, dir='.'):
811
tree = WorkingTree.open_containing(dir)[0]
814
if tree.last_revision() == tree.branch.last_revision():
815
# may be up to date, check master too.
816
master = tree.branch.get_master_branch()
817
if master is None or master.last_revision == tree.last_revision():
818
note("Tree is up to date.")
820
conflicts = tree.update()
821
note('Updated to revision %d.' %
822
(tree.branch.revision_id_to_revno(tree.last_revision()),))
632
831
class cmd_info(Command):
633
"""Show statistical information about a branch."""
634
takes_args = ['branch?']
832
"""Show information about a working tree, branch or repository.
834
This command will show all known locations and formats associated to the
835
tree, branch or repository. Statistical information is included with
838
Branches and working trees will also report any missing revisions.
840
takes_args = ['location?']
841
takes_options = ['verbose']
637
def run(self, branch=None):
639
b = WorkingTree.open_containing(branch)[0].branch
844
def run(self, location=None, verbose=False):
845
from bzrlib.info import show_bzrdir_info
846
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
643
850
class cmd_remove(Command):
690
919
raise BzrError("%r is not a versioned file" % filename)
691
920
for fip in inv.get_idpath(fid):
921
self.outf.write(fip + '\n')
924
class cmd_reconcile(Command):
925
"""Reconcile bzr metadata in a branch.
927
This can correct data mismatches that may have been caused by
928
previous ghost operations or bzr upgrades. You should only
929
need to run this command if 'bzr check' or a bzr developer
930
advises you to run it.
932
If a second branch is provided, cross-branch reconciliation is
933
also attempted, which will check that data like the tree root
934
id which was not present in very early bzr versions is represented
935
correctly in both branches.
937
At the same time it is run it may recompress data resulting in
938
a potential saving in disk space or performance gain.
940
The branch *MUST* be on a listable system such as local disk or sftp.
942
takes_args = ['branch?']
944
def run(self, branch="."):
945
from bzrlib.reconcile import reconcile
946
dir = bzrlib.bzrdir.BzrDir.open(branch)
695
950
class cmd_revision_history(Command):
696
"""Display list of revision ids on this branch."""
951
"""Display the list of revision ids on a branch."""
952
takes_args = ['location?']
700
branch = WorkingTree.open_containing(u'.')[0].branch
701
for patchid in branch.revision_history():
957
def run(self, location="."):
958
branch = Branch.open_containing(location)[0]
959
for revid in branch.revision_history():
960
self.outf.write(revid)
961
self.outf.write('\n')
705
964
class cmd_ancestry(Command):
706
965
"""List all revisions merged into this branch."""
966
takes_args = ['location?']
710
tree = WorkingTree.open_containing(u'.')[0]
712
# FIXME. should be tree.last_revision
713
for revision_id in b.get_ancestry(b.last_revision()):
971
def run(self, location="."):
973
wt = WorkingTree.open_containing(location)[0]
974
except errors.NoWorkingTree:
975
b = Branch.open(location)
976
last_revision = b.last_revision()
979
last_revision = wt.last_revision()
981
revision_ids = b.repository.get_ancestry(last_revision)
982
assert revision_ids[0] == None
984
for revision_id in revision_ids:
985
self.outf.write(revision_id + '\n')
717
988
class cmd_init(Command):
740
1029
# locations if the user supplies an extended path
741
1030
if not os.path.exists(location):
742
1031
os.mkdir(location)
743
Branch.initialize(location)
1033
existing_bzrdir = bzrdir.BzrDir.open(location)
1034
except NotBranchError:
1035
# really a NotBzrDir error...
1036
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1038
if existing_bzrdir.has_branch():
1039
if existing_bzrdir.has_workingtree():
1040
raise errors.AlreadyBranchError(location)
1042
raise errors.BranchExistsWithoutWorkingTree(location)
1044
existing_bzrdir.create_branch()
1045
existing_bzrdir.create_workingtree()
1048
class cmd_init_repository(Command):
1049
"""Create a shared repository to hold branches.
1051
New branches created under the repository directory will store their revisions
1052
in the repository, not in the branch directory, if the branch format supports
1058
bzr checkout --lightweight repo/trunk trunk-checkout
1062
takes_args = ["location"]
1063
takes_options = [Option('format',
1064
help='Specify a format for this repository.'
1065
' Current formats are: default, knit,'
1066
' metaweave and weave. Default is knit;'
1067
' metaweave and weave are deprecated',
1068
type=get_format_type),
1070
help='Allows branches in repository to have'
1072
aliases = ["init-repo"]
1073
def run(self, location, format=None, trees=False):
1074
from bzrlib.transport import get_transport
1076
format = get_format_type('default')
1077
transport = get_transport(location)
1078
if not transport.has('.'):
1080
newdir = format.initialize_on_transport(transport)
1081
repo = newdir.create_repository(shared=True)
1082
repo.set_make_working_trees(trees)
746
1085
class cmd_diff(Command):
749
1088
If files are listed, only the changes in those files are listed.
750
1089
Otherwise, all changes for the tree are listed.
1091
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1092
produces patches suitable for "patch -p1".
1098
bzr diff --diff-prefix old/:new/
1099
bzr diff bzr.mine bzr.dev
757
# TODO: Allow diff across branches.
758
1102
# TODO: Option to use external diff command; could be GNU diff, wdiff,
759
1103
# or a graphical diff.
761
1105
# TODO: Python difflib is not exactly the same as unidiff; should
762
1106
# either fix it up or prefer to use an external diff.
764
# TODO: If a directory is given, diff everything under that.
766
1108
# TODO: Selected-file diff is inefficient and doesn't show you
767
1109
# deleted files.
769
1111
# TODO: This probably handles non-Unix newlines poorly.
771
1113
takes_args = ['file*']
772
takes_options = ['revision', 'diff-options']
1114
takes_options = ['revision', 'diff-options', 'prefix']
773
1115
aliases = ['di', 'dif']
1116
encoding_type = 'exact'
775
1118
@display_command
776
def run(self, revision=None, file_list=None, diff_options=None):
777
from bzrlib.diff import show_diff
1119
def run(self, revision=None, file_list=None, diff_options=None,
1121
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1123
if (prefix is None) or (prefix == '0'):
1131
if not ':' in prefix:
1132
raise BzrError("--diff-prefix expects two values separated by a colon")
1133
old_label, new_label = prefix.split(":")
779
tree, file_list = internal_tree_files(file_list)
1136
tree1, file_list = internal_tree_files(file_list)
782
1140
except FileInWrongBranch:
783
1141
if len(file_list) != 2:
784
1142
raise BzrCommandError("Files are in different branches")
786
b, file1 = Branch.open_containing(file_list[0])
787
b2, file2 = Branch.open_containing(file_list[1])
1144
tree1, file1 = WorkingTree.open_containing(file_list[0])
1145
tree2, file2 = WorkingTree.open_containing(file_list[1])
788
1146
if file1 != "" or file2 != "":
789
1147
# FIXME diff those two files. rbc 20051123
790
1148
raise BzrCommandError("Files are in different branches")
791
1149
file_list = None
792
1150
if revision is not None:
1151
if tree2 is not None:
794
1152
raise BzrCommandError("Can't specify -r with two branches")
795
if len(revision) == 1:
796
return show_diff(tree.branch, revision[0], specific_files=file_list,
797
external_diff_options=diff_options)
1153
if (len(revision) == 1) or (revision[1].spec is None):
1154
return diff_cmd_helper(tree1, file_list, diff_options,
1156
old_label=old_label, new_label=new_label)
798
1157
elif len(revision) == 2:
799
return show_diff(tree.branch, revision[0], specific_files=file_list,
800
external_diff_options=diff_options,
801
revision2=revision[1])
1158
return diff_cmd_helper(tree1, file_list, diff_options,
1159
revision[0], revision[1],
1160
old_label=old_label, new_label=new_label)
803
1162
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
806
return show_diff(b, None, specific_files=file_list,
807
external_diff_options=diff_options, b2=b2)
1164
if tree2 is not None:
1165
return show_diff_trees(tree1, tree2, sys.stdout,
1166
specific_files=file_list,
1167
external_diff_options=diff_options,
1168
old_label=old_label, new_label=new_label)
809
return show_diff(tree.branch, None, specific_files=file_list,
810
external_diff_options=diff_options)
1170
return diff_cmd_helper(tree1, file_list, diff_options,
1171
old_label=old_label, new_label=new_label)
813
1174
class cmd_deleted(Command):
874
1236
def run(self, filename=None):
875
1237
"""Print the branch root."""
876
1238
tree = WorkingTree.open_containing(filename)[0]
1239
self.outf.write(tree.basedir + '\n')
880
1242
class cmd_log(Command):
881
"""Show log of this branch.
1243
"""Show log of a branch, file, or directory.
1245
By default show the log of the branch containing the working directory.
883
1247
To request a range of logs, you can use the command -r begin..end
884
1248
-r revision requests a specific revision, -r ..end or -r begin.. are
1254
bzr log -r -10.. http://server/branch
888
1257
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
890
takes_args = ['filename?']
1259
takes_args = ['location?']
891
1260
takes_options = [Option('forward',
892
1261
help='show from oldest to newest'),
893
'timezone', 'verbose',
1264
help='show files changed in each revision'),
894
1265
'show-ids', 'revision',
896
1268
Option('message',
897
1269
help='show revisions whose message matches this regexp',
1273
encoding_type = 'replace'
901
1275
@display_command
902
def run(self, filename=None, timezone='original',
1276
def run(self, location=None, timezone='original',
911
1286
from bzrlib.log import log_formatter, show_log
913
1287
assert message is None or isinstance(message, basestring), \
914
1288
"invalid message argument %r" % message
915
1289
direction = (forward and 'forward') or 'reverse'
921
tree, fp = WorkingTree.open_containing(filename)
924
inv = tree.read_working_inventory()
925
except NotBranchError:
928
b, fp = Branch.open_containing(filename)
930
inv = b.get_inventory(b.last_revision())
1294
# find the file id to log:
1296
dir, fp = bzrdir.BzrDir.open_containing(location)
1297
b = dir.open_branch()
1301
inv = dir.open_workingtree().inventory
1302
except (errors.NotBranchError, errors.NotLocalUrl):
1303
# either no tree, or is remote.
1304
inv = b.basis_tree().inventory
932
1305
file_id = inv.path2id(fp)
934
file_id = None # points to branch root
936
tree, relpath = WorkingTree.open_containing(u'.')
1308
# FIXME ? log the current subdir only RBC 20060203
1309
dir, relpath = bzrdir.BzrDir.open_containing('.')
1310
b = dir.open_branch()
940
1312
if revision is None:
1424
1836
If arguments are given, they are regular expressions that say
1425
1837
which tests should run.
1839
If the global option '--no-plugins' is given, plugins are not loaded
1840
before running the selftests. This has two effects: features provided or
1841
modified by plugins will not be tested, and tests provided by plugins will
1846
bzr --no-plugins selftest -v
1427
1848
# TODO: --list should give a list of all available tests
1850
# NB: this is used from the class without creating an instance, which is
1851
# why it does not have a self parameter.
1852
def get_transport_type(typestring):
1853
"""Parse and return a transport specifier."""
1854
if typestring == "sftp":
1855
from bzrlib.transport.sftp import SFTPAbsoluteServer
1856
return SFTPAbsoluteServer
1857
if typestring == "memory":
1858
from bzrlib.transport.memory import MemoryServer
1860
if typestring == "fakenfs":
1861
from bzrlib.transport.fakenfs import FakeNFSServer
1862
return FakeNFSServer
1863
msg = "No known transport type %s. Supported types are: sftp\n" %\
1865
raise BzrCommandError(msg)
1429
1868
takes_args = ['testspecs*']
1430
takes_options = ['verbose',
1869
takes_options = ['verbose',
1431
1870
Option('one', help='stop when one test fails'),
1432
1871
Option('keep-output',
1433
help='keep output directories when tests fail')
1872
help='keep output directories when tests fail'),
1874
help='Use a different transport by default '
1875
'throughout the test suite.',
1876
type=get_transport_type),
1877
Option('benchmark', help='run the bzr bencharks.'),
1878
Option('lsprof-timed',
1879
help='generate lsprof output for benchmarked'
1880
' sections of code.'),
1436
def run(self, testspecs_list=None, verbose=False, one=False,
1883
def run(self, testspecs_list=None, verbose=None, one=False,
1884
keep_output=False, transport=None, benchmark=None,
1438
1886
import bzrlib.ui
1439
1887
from bzrlib.tests import selftest
1888
import bzrlib.benchmarks as benchmarks
1440
1889
# we don't want progress meters from the tests to go to the
1441
1890
# real output; and we don't want log messages cluttering up
1442
1891
# the real logs.
1443
1892
save_ui = bzrlib.ui.ui_factory
1893
print '%10s: %s' % ('bzr', bzrlib.osutils.realpath(sys.argv[0]))
1894
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1444
1896
bzrlib.trace.info('running tests...')
1446
1898
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1575
2051
merge refuses to run if there are any uncommitted changes, unless
1576
2052
--force is given.
2054
The following merge types are available:
1578
2056
takes_args = ['branch?']
1579
takes_options = ['revision', 'force', 'merge-type', 'reprocess',
2057
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
1580
2058
Option('show-base', help="Show base revision text in "
2062
from merge import merge_type_help
2063
from inspect import getdoc
2064
return getdoc(self) + '\n' + merge_type_help()
1583
2066
def run(self, branch=None, revision=None, force=False, merge_type=None,
1584
show_base=False, reprocess=False):
1585
from bzrlib.merge import merge
1586
from bzrlib.merge_core import ApplyMerge3
2067
show_base=False, reprocess=False, remember=False):
1587
2068
if merge_type is None:
1588
merge_type = ApplyMerge3
1590
branch = WorkingTree.open_containing(u'.')[0].branch.get_parent()
1592
raise BzrCommandError("No merge location known or specified.")
2069
merge_type = Merge3Merger
2071
tree = WorkingTree.open_containing(u'.')[0]
2073
if branch is not None:
2075
reader = read_bundle_from_url(branch)
2077
pass # Continue on considering this url a Branch
1594
print "Using saved location: %s" % branch
2079
conflicts = merge_bundle(reader, tree, not force, merge_type,
2080
reprocess, show_base)
2086
branch = self._get_remembered_parent(tree, branch, 'Merging from')
1595
2088
if revision is None or len(revision) < 1:
1596
2089
base = [None, None]
1597
2090
other = [branch, -1]
2091
other_branch, path = Branch.open_containing(branch)
1599
2093
if len(revision) == 1:
1600
2094
base = [None, None]
1601
other_branch = Branch.open_containing(branch)[0]
2095
other_branch, path = Branch.open_containing(branch)
1602
2096
revno = revision[0].in_history(other_branch).revno
1603
2097
other = [branch, revno]
1628
2135
"and (if you want) report this to the bzr developers\n")
2138
# TODO: move up to common parent; this isn't merge-specific anymore.
2139
def _get_remembered_parent(self, tree, supplied_location, verb_string):
2140
"""Use tree.branch's parent if none was supplied.
2142
Report if the remembered location was used.
2144
if supplied_location is not None:
2145
return supplied_location
2146
stored_location = tree.branch.get_parent()
2147
mutter("%s", stored_location)
2148
if stored_location is None:
2149
raise BzrCommandError("No location specified or remembered")
2150
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2151
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2152
return stored_location
1632
2155
class cmd_remerge(Command):
1633
2156
"""Redo a merge.
2158
Use this if you want to try a different merge technique while resolving
2159
conflicts. Some merge techniques are better than others, and remerge
2160
lets you try different ones on different files.
2162
The options for remerge have the same meaning and defaults as the ones for
2163
merge. The difference is that remerge can (only) be run when there is a
2164
pending merge, and it lets you specify particular files.
2167
$ bzr remerge --show-base
2168
Re-do the merge of all conflicted files, and show the base text in
2169
conflict regions, in addition to the usual THIS and OTHER texts.
2171
$ bzr remerge --merge-type weave --reprocess foobar
2172
Re-do the merge of "foobar", using the weave merge algorithm, with
2173
additional processing to reduce the size of conflict regions.
2175
The following merge types are available:"""
1635
2176
takes_args = ['file*']
1636
2177
takes_options = ['merge-type', 'reprocess',
1637
2178
Option('show-base', help="Show base revision text in "
2182
from merge import merge_type_help
2183
from inspect import getdoc
2184
return getdoc(self) + '\n' + merge_type_help()
1640
2186
def run(self, file_list=None, merge_type=None, show_base=False,
1641
2187
reprocess=False):
1642
2188
from bzrlib.merge import merge_inner, transform_tree
1643
from bzrlib.merge_core import ApplyMerge3
1644
2189
if merge_type is None:
1645
merge_type = ApplyMerge3
2190
merge_type = Merge3Merger
1646
2191
tree, file_list = tree_files(file_list)
1647
2192
tree.lock_write()
1811
2356
raise BzrCommandError("No missing location known or specified.")
1812
2357
print "Using last location: " + local_branch.get_parent()
1813
2358
remote_branch = bzrlib.branch.Branch.open(other_branch)
1814
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
1815
log_format = get_log_format(long=long, short=short, line=line)
1816
lf = log_formatter(log_format, sys.stdout,
1818
show_timezone='original')
1819
if reverse is False:
1820
local_extra.reverse()
1821
remote_extra.reverse()
1822
if local_extra and not theirs_only:
1823
print "You have %d extra revision(s):" % len(local_extra)
1824
for data in iter_log_data(local_extra, local_branch, verbose):
1826
printed_local = True
1828
printed_local = False
1829
if remote_extra and not mine_only:
1830
if printed_local is True:
1832
print "You are missing %d revision(s):" % len(remote_extra)
1833
for data in iter_log_data(remote_extra, remote_branch, verbose):
1835
if not remote_extra and not local_extra:
1837
print "Branches are up to date."
1840
if parent is None and other_branch is not None:
1841
local_branch.set_parent(other_branch)
2359
if remote_branch.base == local_branch.base:
2360
remote_branch = local_branch
2361
local_branch.lock_read()
2363
remote_branch.lock_read()
2365
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2366
if (log_format == None):
2367
default = bzrlib.config.BranchConfig(local_branch).log_format()
2368
log_format = get_log_format(long=long, short=short, line=line, default=default)
2369
lf = log_formatter(log_format, sys.stdout,
2371
show_timezone='original')
2372
if reverse is False:
2373
local_extra.reverse()
2374
remote_extra.reverse()
2375
if local_extra and not theirs_only:
2376
print "You have %d extra revision(s):" % len(local_extra)
2377
for data in iter_log_data(local_extra, local_branch.repository,
2380
printed_local = True
2382
printed_local = False
2383
if remote_extra and not mine_only:
2384
if printed_local is True:
2386
print "You are missing %d revision(s):" % len(remote_extra)
2387
for data in iter_log_data(remote_extra, remote_branch.repository,
2390
if not remote_extra and not local_extra:
2392
print "Branches are up to date."
2396
remote_branch.unlock()
2398
local_branch.unlock()
2399
if not status_code and parent is None and other_branch is not None:
2400
local_branch.lock_write()
2402
# handle race conditions - a parent might be set while we run.
2403
if local_branch.get_parent() is None:
2404
local_branch.set_parent(remote_branch.base)
2406
local_branch.unlock()
1842
2407
return status_code
1953
2530
if from_revno is None or to_revno is None:
1954
2531
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
1955
2532
for revno in range(from_revno, to_revno + 1):
1956
b.sign_revision(b.get_rev_id(revno), gpg_strategy)
2533
b.repository.sign_revision(b.get_rev_id(revno),
1958
2536
raise BzrCommandError('Please supply either one revision, or a range.')
2539
class cmd_bind(Command):
2540
"""Bind the current branch to a master branch.
2542
After binding, commits must succeed on the master branch
2543
before they are executed on the local one.
2546
takes_args = ['location']
2549
def run(self, location=None):
2550
b, relpath = Branch.open_containing(u'.')
2551
b_other = Branch.open(location)
2554
except DivergedBranches:
2555
raise BzrCommandError('These branches have diverged.'
2556
' Try merging, and then bind again.')
2559
class cmd_unbind(Command):
2560
"""Unbind the current branch from its master branch.
2562
After unbinding, the local branch is considered independent.
2563
All subsequent commits will be local.
2570
b, relpath = Branch.open_containing(u'.')
2572
raise BzrCommandError('Local branch is not bound')
1961
2575
class cmd_uncommit(bzrlib.commands.Command):
1962
2576
"""Remove the last committed revision.
1964
By supplying the --all flag, it will not only remove the entry
1965
from revision_history, but also remove all of the entries in the
1968
2578
--verbose will print out what is being removed.
1969
2579
--dry-run will go through all the motions, but not actually
1970
2580
remove anything.
1972
In the future, uncommit will create a changeset, which can then
2582
In the future, uncommit will create a revision bundle, which can then
1975
takes_options = ['all', 'verbose', 'revision',
2586
# TODO: jam 20060108 Add an option to allow uncommit to remove
2587
# unreferenced information in 'branch-as-repository' branches.
2588
# TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
2589
# information in shared branches as well.
2590
takes_options = ['verbose', 'revision',
1976
2591
Option('dry-run', help='Don\'t actually make changes'),
1977
2592
Option('force', help='Say yes to all questions.')]
1978
2593
takes_args = ['location?']
1981
def run(self, location=None, all=False,
2596
def run(self, location=None,
1982
2597
dry_run=False, verbose=False,
1983
2598
revision=None, force=False):
1984
2599
from bzrlib.branch import Branch
2015
2636
print 'Canceled'
2018
uncommit(b, remove_files=all,
2019
dry_run=dry_run, verbose=verbose,
2639
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
2643
class cmd_break_lock(Command):
2644
"""Break a dead lock on a repository, branch or working directory.
2646
CAUTION: Locks should only be broken when you are sure that the process
2647
holding the lock has been stopped.
2649
You can get information on what locks are open via the 'bzr info' command.
2654
takes_args = ['location?']
2656
def run(self, location=None, show=False):
2657
if location is None:
2659
control, relpath = bzrdir.BzrDir.open_containing(location)
2661
control.break_lock()
2662
except NotImplementedError:
2667
# command-line interpretation helper for merge-related commands
2668
def merge(other_revision, base_revision,
2669
check_clean=True, ignore_zero=False,
2670
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2671
file_list=None, show_base=False, reprocess=False,
2672
pb=DummyProgress()):
2673
"""Merge changes into a tree.
2676
list(path, revno) Base for three-way merge.
2677
If [None, None] then a base will be automatically determined.
2679
list(path, revno) Other revision for three-way merge.
2681
Directory to merge changes into; '.' by default.
2683
If true, this_dir must have no uncommitted changes before the
2685
ignore_zero - If true, suppress the "zero conflicts" message when
2686
there are no conflicts; should be set when doing something we expect
2687
to complete perfectly.
2688
file_list - If supplied, merge only changes to selected files.
2690
All available ancestors of other_revision and base_revision are
2691
automatically pulled into the branch.
2693
The revno may be -1 to indicate the last revision on the branch, which is
2696
This function is intended for use from the command line; programmatic
2697
clients might prefer to call merge.merge_inner(), which has less magic
2700
from bzrlib.merge import Merger
2701
if this_dir is None:
2703
this_tree = WorkingTree.open_containing(this_dir)[0]
2704
if show_base and not merge_type is Merge3Merger:
2705
raise BzrCommandError("Show-base is not supported for this merge"
2706
" type. %s" % merge_type)
2707
if reprocess and not merge_type.supports_reprocess:
2708
raise BzrCommandError("Conflict reduction is not supported for merge"
2709
" type %s." % merge_type)
2710
if reprocess and show_base:
2711
raise BzrCommandError("Cannot do conflict reduction and show base.")
2713
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2714
merger.pp = ProgressPhase("Merge phase", 5, pb)
2715
merger.pp.next_phase()
2716
merger.check_basis(check_clean)
2717
merger.set_other(other_revision)
2718
merger.pp.next_phase()
2719
merger.set_base(base_revision)
2720
if merger.base_rev_id == merger.other_rev_id:
2721
note('Nothing to do.')
2723
merger.backup_files = backup_files
2724
merger.merge_type = merge_type
2725
merger.set_interesting_files(file_list)
2726
merger.show_base = show_base
2727
merger.reprocess = reprocess
2728
conflicts = merger.do_merge()
2729
if file_list is None:
2730
merger.set_pending()
2023
2736
# these get imported and then picked up by the scan for cmd_*
2024
2737
# TODO: Some more consistent way to split command definitions across files;
2025
2738
# we do need to load at least some information about them to know of
2739
# aliases. ideally we would avoid loading the implementation until the
2740
# details were needed.
2027
2741
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2742
from bzrlib.bundle.commands import cmd_bundle_revisions
2743
from bzrlib.sign_my_commits import cmd_sign_my_commits
2744
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
2745
cmd_weave_plan_merge, cmd_weave_merge_text