~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Lukáš Lalinský
  • Date: 2007-12-17 17:28:25 UTC
  • mfrom: (3120 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3123.
  • Revision ID: lalinsky@gmail.com-20071217172825-tr3pqm1mhvs3gwnn
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
747
747
            # The destination doesn't exist; create it.
748
748
            # XXX: Refactor the create_prefix/no_create_prefix code into a
749
749
            #      common helper function
 
750
 
 
751
            def make_directory(transport):
 
752
                transport.mkdir('.')
 
753
                return transport
 
754
 
 
755
            def redirected(redirected_transport, e, redirection_notice):
 
756
                return transport.get_transport(e.get_target_url())
 
757
 
750
758
            try:
751
 
                to_transport.mkdir('.')
 
759
                to_transport = transport.do_catching_redirections(
 
760
                    make_directory, to_transport, redirected)
752
761
            except errors.FileExists:
753
762
                if not use_existing_dir:
754
763
                    raise errors.BzrCommandError("Target directory %s"
763
772
                        " leading parent directories."
764
773
                        % location)
765
774
                _create_prefix(to_transport)
 
775
            except errors.TooManyRedirections:
 
776
                raise errors.BzrCommandError("Too many redirections trying "
 
777
                                             "to make %s." % location)
766
778
 
767
779
            # Now the target directory exists, but doesn't have a .bzr
768
780
            # directory. So we need to create it, along with any work to create
1255
1267
        bzr init
1256
1268
        bzr add .
1257
1269
        bzr status
1258
 
        bzr commit -m 'imported project'
 
1270
        bzr commit -m "imported project"
1259
1271
    """
1260
1272
 
1261
1273
    _see_also = ['init-repository', 'branch', 'checkout']
1378
1390
 
1379
1391
 
1380
1392
class cmd_diff(Command):
1381
 
    """Show differences in the working tree or between revisions.
 
1393
    """Show differences in the working tree, between revisions or branches.
1382
1394
    
1383
 
    If files are listed, only the changes in those files are listed.
1384
 
    Otherwise, all changes for the tree are listed.
 
1395
    If no arguments are given, all changes for the current tree are listed.
 
1396
    If files are given, only the changes in those files are listed.
 
1397
    Remote and multiple branches can be compared by using the --old and
 
1398
    --new options. If not provided, the default for both is derived from
 
1399
    the first argument, if any, or the current tree if no arguments are
 
1400
    given.
1385
1401
 
1386
1402
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1387
1403
    produces patches suitable for "patch -p1".
1405
1421
 
1406
1422
            bzr diff -r1..2
1407
1423
 
 
1424
        Difference between revision 2 and revision 1 for branch xxx::
 
1425
 
 
1426
            bzr diff -r1..2 xxx
 
1427
 
 
1428
        Show just the differences for file NEWS::
 
1429
 
 
1430
            bzr diff NEWS
 
1431
 
 
1432
        Show the differences in working tree xxx for file NEWS::
 
1433
 
 
1434
            bzr diff xxx/NEWS
 
1435
 
 
1436
        Show the differences from branch xxx to this working tree:
 
1437
 
 
1438
            bzr diff --old xxx
 
1439
 
 
1440
        Show the differences between two branches for file NEWS::
 
1441
 
 
1442
            bzr diff --old xxx --new yyy NEWS
 
1443
 
1408
1444
        Same as 'bzr diff' but prefix paths with old/ and new/::
1409
1445
 
1410
1446
            bzr diff --prefix old/:new/
1411
 
 
1412
 
        Show the differences between the two working trees::
1413
 
 
1414
 
            bzr diff bzr.mine bzr.dev
1415
 
 
1416
 
        Show just the differences for 'foo.c'::
1417
 
 
1418
 
            bzr diff foo.c
1419
1447
    """
1420
1448
    # TODO: Option to use external diff command; could be GNU diff, wdiff,
1421
1449
    #       or a graphical diff.
1437
1465
               short_name='p',
1438
1466
               help='Set prefixes added to old and new filenames, as '
1439
1467
                    'two values separated by a colon. (eg "old/:new/").'),
 
1468
        Option('old',
 
1469
            help='Branch/tree to compare from.',
 
1470
            type=unicode,
 
1471
            ),
 
1472
        Option('new',
 
1473
            help='Branch/tree to compare to.',
 
1474
            type=unicode,
 
1475
            ),
1440
1476
        'revision',
1441
1477
        'change',
1442
1478
        ]
1445
1481
 
1446
1482
    @display_command
1447
1483
    def run(self, revision=None, file_list=None, diff_options=None,
1448
 
            prefix=None):
1449
 
        from bzrlib.diff import diff_cmd_helper, show_diff_trees
 
1484
            prefix=None, old=None, new=None):
 
1485
        from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1450
1486
 
1451
1487
        if (prefix is None) or (prefix == '0'):
1452
1488
            # diff -p0 format
1466
1502
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
1467
1503
                                         ' one or two revision specifiers')
1468
1504
 
1469
 
        try:
1470
 
            tree1, file_list = internal_tree_files(file_list)
1471
 
            tree2 = None
1472
 
            b = None
1473
 
            b2 = None
1474
 
        except errors.FileInWrongBranch:
1475
 
            if len(file_list) != 2:
1476
 
                raise errors.BzrCommandError("Files are in different branches")
1477
 
 
1478
 
            tree1, file1 = WorkingTree.open_containing(file_list[0])
1479
 
            tree2, file2 = WorkingTree.open_containing(file_list[1])
1480
 
            if file1 != "" or file2 != "":
1481
 
                # FIXME diff those two files. rbc 20051123
1482
 
                raise errors.BzrCommandError("Files are in different branches")
1483
 
            file_list = None
1484
 
        except errors.NotBranchError:
1485
 
            if (revision is not None and len(revision) == 2
1486
 
                and not revision[0].needs_branch()
1487
 
                and not revision[1].needs_branch()):
1488
 
                # If both revision specs include a branch, we can
1489
 
                # diff them without needing a local working tree
1490
 
                tree1, tree2 = None, None
1491
 
            else:
1492
 
                raise
1493
 
 
1494
 
        if tree2 is not None:
1495
 
            if revision is not None:
1496
 
                # FIXME: but there should be a clean way to diff between
1497
 
                # non-default versions of two trees, it's not hard to do
1498
 
                # internally...
1499
 
                raise errors.BzrCommandError(
1500
 
                        "Sorry, diffing arbitrary revisions across branches "
1501
 
                        "is not implemented yet")
1502
 
            return show_diff_trees(tree1, tree2, sys.stdout, 
1503
 
                                   specific_files=file_list,
1504
 
                                   external_diff_options=diff_options,
1505
 
                                   old_label=old_label, new_label=new_label)
1506
 
 
1507
 
        return diff_cmd_helper(tree1, file_list, diff_options,
1508
 
                               revision_specs=revision,
1509
 
                               old_label=old_label, new_label=new_label)
 
1505
        old_tree, new_tree, specific_files, extra_trees = \
 
1506
                _get_trees_to_diff(file_list, revision, old, new)
 
1507
        return show_diff_trees(old_tree, new_tree, sys.stdout, 
 
1508
                               specific_files=specific_files,
 
1509
                               external_diff_options=diff_options,
 
1510
                               old_label=old_label, new_label=new_label,
 
1511
                               extra_trees=extra_trees)
1510
1512
 
1511
1513
 
1512
1514
class cmd_deleted(Command):
1654
1656
                        'regular expression.',
1655
1657
                   type=str),
1656
1658
            Option('limit',
 
1659
                   short_name='l',
1657
1660
                   help='Limit the output to the first N revisions.',
1658
1661
                   argname='N',
1659
1662
                   type=_parse_limit),
1915
1918
 
1916
1919
        Ignore class files in all directories::
1917
1920
 
1918
 
            bzr ignore '*.class'
1919
 
 
1920
 
        Ignore .o files under the lib directory::
1921
 
 
1922
 
            bzr ignore 'lib/**/*.o'
1923
 
 
1924
 
        Ignore .o files under the lib directory::
1925
 
 
1926
 
            bzr ignore 'RE:lib/.*\.o'
 
1921
            bzr ignore "*.class"
 
1922
 
 
1923
        Ignore .o files under the lib directory::
 
1924
 
 
1925
            bzr ignore "lib/**/*.o"
 
1926
 
 
1927
        Ignore .o files under the lib directory::
 
1928
 
 
1929
            bzr ignore "RE:lib/.*\.o"
1927
1930
    """
1928
1931
 
1929
1932
    _see_also = ['status', 'ignored']
2114
2117
    def run(self, filename, revision=None, name_from_revision=False):
2115
2118
        if revision is not None and len(revision) != 1:
2116
2119
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2117
 
                                        " one number")
2118
 
 
2119
 
        tree = None
 
2120
                                         " one revision specifier")
 
2121
        tree, branch, relpath = \
 
2122
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
2123
        branch.lock_read()
2120
2124
        try:
2121
 
            tree, b, relpath = \
2122
 
                    bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2123
 
        except errors.NotBranchError:
2124
 
            pass
 
2125
            return self._run(tree, branch, relpath, filename, revision,
 
2126
                             name_from_revision)
 
2127
        finally:
 
2128
            branch.unlock()
2125
2129
 
2126
 
        if revision is not None and revision[0].get_branch() is not None:
2127
 
            b = Branch.open(revision[0].get_branch())
 
2130
    def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2128
2131
        if tree is None:
2129
2132
            tree = b.basis_tree()
2130
2133
        if revision is None:
2219
2222
                    "files in the working tree."),
2220
2223
             ListOption('fixes', type=str,
2221
2224
                    help="Mark a bug as being fixed by this revision."),
2222
 
             Option('author', type=str,
 
2225
             Option('author', type=unicode,
2223
2226
                    help="Set the author's name, if it's different "
2224
2227
                         "from the committer."),
2225
2228
             Option('local',
2437
2440
 
2438
2441
        Set the current user::
2439
2442
 
2440
 
            bzr whoami 'Frank Chu <fchu@example.com>'
 
2443
            bzr whoami "Frank Chu <fchu@example.com>"
2441
2444
    """
2442
2445
    takes_options = [ Option('email',
2443
2446
                             help='Display email address only.'),
2592
2595
                                 ' expression.'),
2593
2596
                     Option('strict', help='Fail on missing dependencies or '
2594
2597
                            'known failures.'),
 
2598
                     Option('coverage', type=str, argname="DIRECTORY",
 
2599
                            help='Generate line coverage report in this '
 
2600
                                 'directory.'),
2595
2601
                     ]
2596
2602
    encoding_type = 'replace'
2597
2603
 
2599
2605
            transport=None, benchmark=None,
2600
2606
            lsprof_timed=None, cache_dir=None,
2601
2607
            first=False, list_only=False,
2602
 
            randomize=None, exclude=None, strict=False):
 
2608
            randomize=None, exclude=None, strict=False, coverage=None):
2603
2609
        import bzrlib.ui
2604
2610
        from bzrlib.tests import selftest
2605
2611
        import bzrlib.benchmarks as benchmarks
2641
2647
                              random_seed=randomize,
2642
2648
                              exclude_pattern=exclude,
2643
2649
                              strict=strict,
 
2650
                              coverage_dir=coverage,
2644
2651
                              )
2645
2652
        finally:
2646
2653
            if benchfile is not None:
2686
2693
        
2687
2694
        branch1 = Branch.open_containing(branch)[0]
2688
2695
        branch2 = Branch.open_containing(other)[0]
2689
 
 
2690
 
        last1 = ensure_null(branch1.last_revision())
2691
 
        last2 = ensure_null(branch2.last_revision())
2692
 
 
2693
 
        graph = branch1.repository.get_graph(branch2.repository)
2694
 
        base_rev_id = graph.find_unique_lca(last1, last2)
2695
 
 
2696
 
        print 'merge base is revision %s' % base_rev_id
 
2696
        branch1.lock_read()
 
2697
        try:
 
2698
            branch2.lock_read()
 
2699
            try:
 
2700
                last1 = ensure_null(branch1.last_revision())
 
2701
                last2 = ensure_null(branch2.last_revision())
 
2702
 
 
2703
                graph = branch1.repository.get_graph(branch2.repository)
 
2704
                base_rev_id = graph.find_unique_lca(last1, last2)
 
2705
 
 
2706
                print 'merge base is revision %s' % base_rev_id
 
2707
            finally:
 
2708
                branch2.unlock()
 
2709
        finally:
 
2710
            branch1.unlock()
2697
2711
 
2698
2712
 
2699
2713
class cmd_merge(Command):
2817
2831
                merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2818
2832
                    pb)
2819
2833
                allow_pending = False
 
2834
                if other_path != '':
 
2835
                    merger.interesting_files = [other_path]
2820
2836
 
2821
2837
            if merger is None:
2822
2838
                merger, allow_pending = self._get_merger_from_branch(tree,
3072
3088
    last committed revision is used.
3073
3089
 
3074
3090
    To remove only some changes, without reverting to a prior version, use
3075
 
    merge instead.  For example, "merge . --r-2..-3" will remove the changes
3076
 
    introduced by -2, without affecting the changes introduced by -1.  Or
3077
 
    to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
 
3091
    merge instead.  For example, "merge . --revision -2..-3" will remove the
 
3092
    changes introduced by -2, without affecting the changes introduced by -1.
 
3093
    Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3078
3094
    
3079
3095
    By default, any files that have been manually changed will be backed up
3080
3096
    first.  (Files changed only by merge are not backed up.)  Backup files have
3091
3107
 
3092
3108
    The working tree contains a list of pending merged revisions, which will
3093
3109
    be included as parents in the next commit.  Normally, revert clears that
3094
 
    list as well as reverting the files.  If any files, are specified, revert
3095
 
    leaves the pending merge list alnone and reverts only the files.  Use "bzr
 
3110
    list as well as reverting the files.  If any files are specified, revert
 
3111
    leaves the pending merge list alone and reverts only the files.  Use "bzr
3096
3112
    revert ." in the tree root to revert all files but keep the merge record,
3097
3113
    and "bzr revert --forget-merges" to clear the pending merge list without
3098
3114
    reverting any files.
3422
3438
    takes_options = ['revision']
3423
3439
    
3424
3440
    def run(self, revision_id_list=None, revision=None):
3425
 
        import bzrlib.gpg as gpg
3426
3441
        if revision_id_list is not None and revision is not None:
3427
3442
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
3428
3443
        if revision_id_list is None and revision is None:
3429
3444
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
3430
3445
        b = WorkingTree.open_containing(u'.')[0].branch
 
3446
        b.lock_write()
 
3447
        try:
 
3448
            return self._run(b, revision_id_list, revision)
 
3449
        finally:
 
3450
            b.unlock()
 
3451
 
 
3452
    def _run(self, b, revision_id_list, revision):
 
3453
        import bzrlib.gpg as gpg
3431
3454
        gpg_strategy = gpg.GPGStrategy(b.get_config())
3432
3455
        if revision_id_list is not None:
3433
 
            for revision_id in revision_id_list:
3434
 
                b.repository.sign_revision(revision_id, gpg_strategy)
 
3456
            b.repository.start_write_group()
 
3457
            try:
 
3458
                for revision_id in revision_id_list:
 
3459
                    b.repository.sign_revision(revision_id, gpg_strategy)
 
3460
            except:
 
3461
                b.repository.abort_write_group()
 
3462
                raise
 
3463
            else:
 
3464
                b.repository.commit_write_group()
3435
3465
        elif revision is not None:
3436
3466
            if len(revision) == 1:
3437
3467
                revno, rev_id = revision[0].in_history(b)
3438
 
                b.repository.sign_revision(rev_id, gpg_strategy)
 
3468
                b.repository.start_write_group()
 
3469
                try:
 
3470
                    b.repository.sign_revision(rev_id, gpg_strategy)
 
3471
                except:
 
3472
                    b.repository.abort_write_group()
 
3473
                    raise
 
3474
                else:
 
3475
                    b.repository.commit_write_group()
3439
3476
            elif len(revision) == 2:
3440
3477
                # are they both on rh- if so we can walk between them
3441
3478
                # might be nice to have a range helper for arbitrary
3446
3483
                    to_revno = b.revno()
3447
3484
                if from_revno is None or to_revno is None:
3448
3485
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
3449
 
                for revno in range(from_revno, to_revno + 1):
3450
 
                    b.repository.sign_revision(b.get_rev_id(revno), 
3451
 
                                               gpg_strategy)
 
3486
                b.repository.start_write_group()
 
3487
                try:
 
3488
                    for revno in range(from_revno, to_revno + 1):
 
3489
                        b.repository.sign_revision(b.get_rev_id(revno),
 
3490
                                                   gpg_strategy)
 
3491
                except:
 
3492
                    b.repository.abort_write_group()
 
3493
                    raise
 
3494
                else:
 
3495
                    b.repository.commit_write_group()
3452
3496
            else:
3453
3497
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
3454
3498
 
3526
3570
                    Option('force', help='Say yes to all questions.')]
3527
3571
    takes_args = ['location?']
3528
3572
    aliases = []
 
3573
    encoding_type = 'replace'
3529
3574
 
3530
3575
    def run(self, location=None,
3531
3576
            dry_run=False, verbose=False,
3532
3577
            revision=None, force=False):
3533
 
        from bzrlib.log import log_formatter, show_log
3534
 
        from bzrlib.uncommit import uncommit
3535
 
 
3536
3578
        if location is None:
3537
3579
            location = u'.'
3538
3580
        control, relpath = bzrdir.BzrDir.open_containing(location)
3543
3585
            tree = None
3544
3586
            b = control.open_branch()
3545
3587
 
 
3588
        if tree is not None:
 
3589
            tree.lock_write()
 
3590
        else:
 
3591
            b.lock_write()
 
3592
        try:
 
3593
            return self._run(b, tree, dry_run, verbose, revision, force)
 
3594
        finally:
 
3595
            if tree is not None:
 
3596
                tree.unlock()
 
3597
            else:
 
3598
                b.unlock()
 
3599
 
 
3600
    def _run(self, b, tree, dry_run, verbose, revision, force):
 
3601
        from bzrlib.log import log_formatter, show_log
 
3602
        from bzrlib.uncommit import uncommit
 
3603
 
 
3604
        last_revno, last_rev_id = b.last_revision_info()
 
3605
 
3546
3606
        rev_id = None
3547
3607
        if revision is None:
3548
 
            revno = b.revno()
 
3608
            revno = last_revno
 
3609
            rev_id = last_rev_id
3549
3610
        else:
3550
3611
            # 'bzr uncommit -r 10' actually means uncommit
3551
3612
            # so that the final tree is at revno 10.
3552
3613
            # but bzrlib.uncommit.uncommit() actually uncommits
3553
3614
            # the revisions that are supplied.
3554
3615
            # So we need to offset it by one
3555
 
            revno = revision[0].in_history(b).revno+1
 
3616
            revno = revision[0].in_history(b).revno + 1
 
3617
            if revno <= last_revno:
 
3618
                rev_id = b.get_rev_id(revno)
3556
3619
 
3557
 
        if revno <= b.revno():
3558
 
            rev_id = b.get_rev_id(revno)
3559
 
        if rev_id is None:
 
3620
        if rev_id is None or _mod_revision.is_null(rev_id):
3560
3621
            self.outf.write('No revisions to uncommit.\n')
3561
3622
            return 1
3562
3623
 
3569
3630
                 verbose=False,
3570
3631
                 direction='forward',
3571
3632
                 start_revision=revno,
3572
 
                 end_revision=b.revno())
 
3633
                 end_revision=last_revno)
3573
3634
 
3574
3635
        if dry_run:
3575
3636
            print 'Dry-run, pretending to remove the above revisions.'
3584
3645
                    return 0
3585
3646
 
3586
3647
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
3587
 
                revno=revno)
 
3648
                 revno=revno)
3588
3649
 
3589
3650
 
3590
3651
class cmd_break_lock(Command):
3652
3713
        from bzrlib.smart import medium, server
3653
3714
        from bzrlib.transport import get_transport
3654
3715
        from bzrlib.transport.chroot import ChrootServer
3655
 
        from bzrlib.transport.remote import BZR_DEFAULT_PORT, BZR_DEFAULT_INTERFACE
3656
3716
        if directory is None:
3657
3717
            directory = os.getcwd()
3658
3718
        url = urlutils.local_path_to_url(directory)
3665
3725
            smart_server = medium.SmartServerPipeStreamMedium(
3666
3726
                sys.stdin, sys.stdout, t)
3667
3727
        else:
3668
 
            host = BZR_DEFAULT_INTERFACE
 
3728
            host = medium.BZR_DEFAULT_INTERFACE
3669
3729
            if port is None:
3670
 
                port = BZR_DEFAULT_PORT
 
3730
                port = medium.BZR_DEFAULT_PORT
3671
3731
            else:
3672
3732
                if ':' in port:
3673
3733
                    host, port = port.split(':')
3898
3958
    for that mirror.
3899
3959
 
3900
3960
    Mail is sent using your preferred mail program.  This should be transparent
3901
 
    on Windows (it uses MAPI).  On *nix, it requires the xdg-email utility.  If
3902
 
    the preferred client can't be found (or used), your editor will be used.
 
3961
    on Windows (it uses MAPI).  On Linux, it requires the xdg-email utility.
 
3962
    If the preferred client can't be found (or used), your editor will be used.
3903
3963
    
3904
3964
    To use a specific mail program, set the mail_client configuration option.
3905
3965
    (For Thunderbird 1.5, this works around some bugs.)  Supported values for
3957
4017
    def _run(self, submit_branch, revision, public_branch, remember, format,
3958
4018
             no_bundle, no_patch, output, from_, mail_to, message):
3959
4019
        from bzrlib.revision import NULL_REVISION
 
4020
        branch = Branch.open_containing(from_)[0]
3960
4021
        if output is None:
3961
4022
            outfile = StringIO()
3962
4023
        elif output == '-':
3963
4024
            outfile = self.outf
3964
4025
        else:
3965
4026
            outfile = open(output, 'wb')
 
4027
        # we may need to write data into branch's repository to calculate
 
4028
        # the data to send.
 
4029
        branch.lock_write()
3966
4030
        try:
3967
 
            branch = Branch.open_containing(from_)[0]
3968
4031
            if output is None:
3969
4032
                config = branch.get_config()
3970
4033
                if mail_to is None:
3971
4034
                    mail_to = config.get_user_option('submit_to')
3972
 
                if mail_to is None:
3973
 
                    raise errors.BzrCommandError('No mail-to address'
3974
 
                                                 ' specified')
3975
4035
                mail_client = config.get_mail_client()
3976
4036
            if remember and submit_branch is None:
3977
4037
                raise errors.BzrCommandError(
4052
4112
        finally:
4053
4113
            if output != '-':
4054
4114
                outfile.close()
 
4115
            branch.unlock()
4055
4116
 
4056
4117
 
4057
4118
class cmd_bundle_revisions(cmd_send):
4187
4248
class cmd_tags(Command):
4188
4249
    """List tags.
4189
4250
 
4190
 
    This tag shows a table of tag names and the revisions they reference.
 
4251
    This command shows a table of tag names and the revisions they reference.
4191
4252
    """
4192
4253
 
4193
4254
    _see_also = ['tag']
4256
4317
                     value_switches=True, enum_switch=False,
4257
4318
                     branch='Reconfigure to a branch.',
4258
4319
                     tree='Reconfigure to a tree.',
4259
 
                     checkout='Reconfigure to a checkout.'),
 
4320
                     checkout='Reconfigure to a checkout.',
 
4321
                     lightweight_checkout='Reconfigure to a lightweight'
 
4322
                     ' checkout.'),
4260
4323
                     Option('bind-to', help='Branch to bind checkout to.',
4261
4324
                            type=str),
4262
4325
                     Option('force',
4275
4338
        elif target_type == 'checkout':
4276
4339
            reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4277
4340
                                                                  bind_to)
 
4341
        elif target_type == 'lightweight-checkout':
 
4342
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
 
4343
                directory, bind_to)
4278
4344
        reconfiguration.apply(force)
4279
4345
 
4280
4346
 
 
4347
class cmd_switch(Command):
 
4348
    """Set the branch of a checkout and update.
 
4349
    
 
4350
    For lightweight checkouts, this changes the branch being referenced.
 
4351
    For heavyweight checkouts, this checks that there are no local commits
 
4352
    versus the current bound branch, then it makes the local branch a mirror
 
4353
    of the new location and binds to it.
 
4354
    
 
4355
    In both cases, the working tree is updated and uncommitted changes
 
4356
    are merged. The user can commit or revert these as they desire.
 
4357
 
 
4358
    Pending merges need to be committed or reverted before using switch.
 
4359
    """
 
4360
 
 
4361
    takes_args = ['to_location']
 
4362
    takes_options = [Option('force',
 
4363
                        help='Switch even if local commits will be lost.')
 
4364
                     ]
 
4365
 
 
4366
    def run(self, to_location, force=False):
 
4367
        from bzrlib import switch
 
4368
        to_branch = Branch.open(to_location)
 
4369
        tree_location = '.'
 
4370
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
4371
        switch.switch(control_dir, to_branch, force)
 
4372
        note('Switched to branch: %s',
 
4373
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
 
4374
 
 
4375
 
4281
4376
def _create_prefix(cur_transport):
4282
4377
    needed = [cur_transport]
4283
4378
    # Recurse upwards until we can create a directory successfully