~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005 by Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
596
596
                else:
597
597
                    raise
598
598
            try:
 
599
                # preserve whatever source format we have.
599
600
                dir = br_from.bzrdir.sprout(to_location, revision_id, basis_dir)
600
601
                branch = dir.open_branch()
601
602
            except bzrlib.errors.NoSuchRevision:
604
605
                raise BzrCommandError(msg)
605
606
            except bzrlib.errors.UnlistableBranch:
606
607
                rmtree(to_location)
607
 
                msg = "The branch %s cannot be used as a --basis"
 
608
                msg = "The branch %s cannot be used as a --basis" % (basis,)
608
609
                raise BzrCommandError(msg)
609
610
            if name:
610
611
                branch.control_files.put_utf8('branch-name', name)
630
631
    branch being checked out. [Not implemented yet.]
631
632
    """
632
633
    takes_args = ['branch_location', 'to_location?']
633
 
    takes_options = ['revision'] # , 'basis']
 
634
    takes_options = ['revision', # , 'basis']
 
635
                     Option('lightweight',
 
636
                            help="perform a lightweight checkout. Lightweight "
 
637
                                 "checkouts depend on access to the branch for "
 
638
                                 "every operation. Normal checkouts can perform "
 
639
                                 "common operations like diff and status without "
 
640
                                 "such access, and also support local commits."
 
641
                            ),
 
642
                     ]
634
643
 
635
 
    def run(self, branch_location, to_location=None, revision=None, basis=None):
 
644
    def run(self, branch_location, to_location=None, revision=None, basis=None,
 
645
            lightweight=False):
636
646
        if revision is None:
637
647
            revision = [None]
638
648
        elif len(revision) > 1:
656
666
                                      to_location)
657
667
            else:
658
668
                raise
659
 
        checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
660
 
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
661
 
        checkout.create_workingtree(revision_id)
 
669
        old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
670
        bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
 
671
        try:
 
672
            if lightweight:
 
673
                checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
 
674
                bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
 
675
            else:
 
676
                checkout_branch =  bzrlib.bzrdir.BzrDir.create_branch_convenience(
 
677
                    to_location, force_new_tree=False)
 
678
                checkout = checkout_branch.bzrdir
 
679
                checkout_branch.bind(source)
 
680
                if revision_id is not None:
 
681
                    rh = checkout_branch.revision_history()
 
682
                    checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
 
683
            checkout.create_workingtree(revision_id)
 
684
        finally:
 
685
            bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
662
686
 
663
687
 
664
688
class cmd_renames(Command):
685
709
    """Update a tree to have the latest code committed to its branch.
686
710
    
687
711
    This will perform a merge into the working tree, and may generate
688
 
    conflicts. If you have any uncommitted changes, you will still 
689
 
    need to commit them after the update.
 
712
    conflicts. If you have any local changes, you will still 
 
713
    need to commit them after the update for the update to be complete.
 
714
    
 
715
    If you want to discard your local changes, you can just do a 
 
716
    'bzr revert' instead of 'bzr commit' after the update.
690
717
    """
691
718
    takes_args = ['dir?']
692
719
 
695
722
        tree.lock_write()
696
723
        try:
697
724
            if tree.last_revision() == tree.branch.last_revision():
698
 
                note("Tree is up to date.")
699
 
                return
 
725
                # may be up to date, check master too.
 
726
                master = tree.branch.get_master_branch()
 
727
                if master is None or master.last_revision == tree.last_revision():
 
728
                    note("Tree is up to date.")
 
729
                    return
700
730
            conflicts = tree.update()
701
731
            note('Updated to revision %d.' %
702
732
                 (tree.branch.revision_id_to_revno(tree.last_revision()),))
770
800
            print fip
771
801
 
772
802
 
 
803
class cmd_reconcile(Command):
 
804
    """Reconcile bzr metadata in a branch.
 
805
 
 
806
    This can correct data mismatches that may have been caused by
 
807
    previous ghost operations or bzr upgrades. You should only
 
808
    need to run this command if 'bzr check' or a bzr developer 
 
809
    advises you to run it.
 
810
 
 
811
    If a second branch is provided, cross-branch reconciliation is
 
812
    also attempted, which will check that data like the tree root
 
813
    id which was not present in very early bzr versions is represented
 
814
    correctly in both branches.
 
815
 
 
816
    At the same time it is run it may recompress data resulting in 
 
817
    a potential saving in disk space or performance gain.
 
818
 
 
819
    The branch *MUST* be on a listable system such as local disk or sftp.
 
820
    """
 
821
    takes_args = ['branch?']
 
822
 
 
823
    def run(self, branch="."):
 
824
        from bzrlib.reconcile import reconcile
 
825
        dir = bzrlib.bzrdir.BzrDir.open(branch)
 
826
        reconcile(dir)
 
827
 
 
828
 
773
829
class cmd_revision_history(Command):
774
830
    """Display list of revision ids on this branch."""
775
831
    hidden = True
1359
1415
                     Option('strict',
1360
1416
                            help="refuse to commit if there are unknown "
1361
1417
                            "files in the working tree."),
 
1418
                     Option('local',
 
1419
                            help="perform a local only commit in a bound "
 
1420
                                 "branch. Such commits are not pushed to "
 
1421
                                 "the master branch until a normal commit "
 
1422
                                 "is performed."
 
1423
                            ),
1362
1424
                     ]
1363
1425
    aliases = ['ci', 'checkin']
1364
1426
 
1365
1427
    def run(self, message=None, file=None, verbose=True, selected_list=None,
1366
 
            unchanged=False, strict=False):
 
1428
            unchanged=False, strict=False, local=False):
1367
1429
        from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1368
1430
                StrictCommitFailed)
1369
1431
        from bzrlib.msgeditor import edit_commit_message, \
1380
1442
        # TODO: if the commit *does* happen to fail, then save the commit 
1381
1443
        # message to a temporary file where it can be recovered
1382
1444
        tree, selected_list = tree_files(selected_list)
 
1445
        if local and not tree.branch.get_bound_location():
 
1446
            raise errors.LocalRequiresBoundBranch()
1383
1447
        if message is None and not file:
1384
1448
            template = make_commit_message_template(tree, selected_list)
1385
1449
            message = edit_commit_message(template)
1398
1462
            
1399
1463
        try:
1400
1464
            tree.commit(message, specific_files=selected_list,
1401
 
                        allow_pointless=unchanged, strict=strict)
 
1465
                        allow_pointless=unchanged, strict=strict, local=local)
1402
1466
        except PointlessCommit:
1403
1467
            # FIXME: This should really happen before the file is read in;
1404
1468
            # perhaps prepare the commit; get the message; then actually commit
1410
1474
        except StrictCommitFailed:
1411
1475
            raise BzrCommandError("Commit refused because there are unknown "
1412
1476
                                  "files in the working tree.")
 
1477
        except errors.BoundBranchOutOfDate, e:
 
1478
            raise BzrCommandError(str(e)
 
1479
                                  + ' Either unbind, update, or'
 
1480
                                    ' pass --local to commit.')
 
1481
 
1413
1482
        note('Committed revision %d.' % (tree.branch.revno(),))
1414
1483
 
1415
1484
 
2096
2165
                raise BzrCommandError('Please supply either one revision, or a range.')
2097
2166
 
2098
2167
 
 
2168
class cmd_bind(Command):
 
2169
    """Bind the current branch to a master branch.
 
2170
 
 
2171
    After binding, commits must succeed on the master branch
 
2172
    before they are executed on the local one.
 
2173
    """
 
2174
 
 
2175
    takes_args = ['location']
 
2176
    takes_options = []
 
2177
 
 
2178
    def run(self, location=None):
 
2179
        b, relpath = Branch.open_containing(u'.')
 
2180
        b_other = Branch.open(location)
 
2181
        try:
 
2182
            b.bind(b_other)
 
2183
        except DivergedBranches:
 
2184
            raise BzrCommandError('These branches have diverged.'
 
2185
                                  ' Try merging, and then bind again.')
 
2186
 
 
2187
 
 
2188
class cmd_unbind(Command):
 
2189
    """Bind the current branch to its parent.
 
2190
 
 
2191
    After unbinding, the local branch is considered independent.
 
2192
    """
 
2193
 
 
2194
    takes_args = []
 
2195
    takes_options = []
 
2196
 
 
2197
    def run(self):
 
2198
        b, relpath = Branch.open_containing(u'.')
 
2199
        if not b.unbind():
 
2200
            raise BzrCommandError('Local branch is not bound')
 
2201
 
 
2202
 
2099
2203
class cmd_uncommit(bzrlib.commands.Command):
2100
2204
    """Remove the last committed revision.
2101
2205
 
2109
2213
    
2110
2214
    In the future, uncommit will create a changeset, which can then
2111
2215
    be re-applied.
 
2216
    """
2112
2217
 
2113
 
    TODO: jam 20060108 Add an option to allow uncommit to remove unreferenced
2114
 
              information in 'branch-as-repostory' branches.
2115
 
    TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
2116
 
              information in shared branches as well.
2117
 
    """
 
2218
    # TODO: jam 20060108 Add an option to allow uncommit to remove
 
2219
    # unreferenced information in 'branch-as-repostory' branches.
 
2220
    # TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
 
2221
    # information in shared branches as well.
2118
2222
    takes_options = ['verbose', 'revision',
2119
2223
                    Option('dry-run', help='Don\'t actually make changes'),
2120
2224
                    Option('force', help='Say yes to all questions.')]
2167
2271
                revno=revno)
2168
2272
 
2169
2273
 
 
2274
class cmd_break_lock(Command):
 
2275
    """Break a dead lock on a repository, branch or working directory.
 
2276
 
 
2277
    CAUTION: Locks should only be broken when you are sure that the process
 
2278
    holding the lock has been stopped.
 
2279
    
 
2280
    example:
 
2281
        bzr break-lock .
 
2282
    """
 
2283
    takes_args = ['location']
 
2284
    takes_options = [Option('show',
 
2285
                            help="just show information on the lock, " \
 
2286
                                 "don't break it"),
 
2287
                    ]
 
2288
    def run(self, location, show=False):
 
2289
        d = bzrdir.BzrDir.open(location)
 
2290
        repo = d.open_repository()
 
2291
        if not repo.is_locked():
 
2292
            raise errors.ObjectNotLocked(repo)
 
2293
 
 
2294
 
 
2295
# command-line interpretation helper for merge-related commands
2170
2296
def merge(other_revision, base_revision,
2171
2297
          check_clean=True, ignore_zero=False,
2172
2298
          this_dir=None, backup_files=False, merge_type=Merge3Merger,
2173
 
          file_list=None, show_base=False, reprocess=False, 
 
2299
          file_list=None, show_base=False, reprocess=False,
2174
2300
          pb=DummyProgress()):
2175
2301
    """Merge changes into a tree.
2176
2302