~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

[merge] bzr.dev 2294

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 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
38
38
    merge as _mod_merge,
39
39
    osutils,
40
40
    repository,
 
41
    symbol_versioning,
41
42
    transport,
42
43
    tree as _mod_tree,
43
44
    ui,
94
95
    return tree, new_list
95
96
 
96
97
 
 
98
@symbol_versioning.deprecated_function(symbol_versioning.zero_fifteen)
97
99
def get_format_type(typestring):
98
100
    """Parse and return a format specifier."""
99
101
    # Have to use BzrDirMetaFormat1 directly, so that
119
121
    This reports on versioned and unknown files, reporting them
120
122
    grouped by state.  Possible states are:
121
123
 
122
 
    added / A
 
124
    added
123
125
        Versioned in the working copy but not in the previous revision.
124
126
 
125
 
    removed / D
 
127
    removed
126
128
        Versioned in the previous revision but removed or deleted
127
129
        in the working copy.
128
130
 
129
 
    renamed / R
 
131
    renamed
130
132
        Path of this file changed from the previous revision;
131
133
        the text may also have changed.  This includes files whose
132
134
        parent directory was renamed.
133
135
 
134
 
    modified / M
 
136
    modified
135
137
        Text has changed since the previous revision.
136
138
 
137
 
    unknown / ?
 
139
    kind changed
 
140
        File kind has been changed (e.g. from file to directory).
 
141
 
 
142
    unknown
138
143
        Not versioned and not matching an ignore pattern.
139
144
 
140
145
    To see ignored files use 'bzr ignored'.  For details in the
141
146
    changes to file texts, use 'bzr diff'.
142
147
    
143
 
    --short gives a one character status flag for each item, similar
144
 
    to the SVN's status command.
 
148
    --short gives a status flags for each item, similar to the SVN's status
 
149
    command.
 
150
 
 
151
    Column 1: versioning / renames
 
152
      + File versioned
 
153
      - File unversioned
 
154
      R File renamed
 
155
      ? File unknown
 
156
      C File has conflicts
 
157
      P Entry for a pending merge (not a file)
 
158
 
 
159
    Column 2: Contents
 
160
      N File created
 
161
      D File deleted
 
162
      K File kind changed
 
163
      M File modified
 
164
 
 
165
    Column 3: Execute
 
166
      * The execute bit was changed
145
167
 
146
168
    If no arguments are specified, the status of the entire working
147
169
    directory is shown.  Otherwise, only the status of the specified
215
237
    this will refuse to run against one.
216
238
    """
217
239
 
218
 
    hidden = True
219
 
 
220
240
    takes_args = ['location?']
221
241
 
222
242
    def run(self, location='.'):
394
414
 
395
415
    It is also possible to restrict the list of files to a specific
396
416
    set. For example: bzr inventory --show-ids this/file
 
417
 
 
418
    See also: bzr ls
397
419
    """
398
420
 
 
421
    hidden = True
 
422
 
399
423
    takes_options = ['revision', 'show-ids', 'kind']
 
424
 
400
425
    takes_args = ['file*']
401
426
 
402
427
    @display_command
510
535
    location can be accessed.
511
536
    """
512
537
 
513
 
    takes_options = ['remember', 'overwrite', 'revision', 'verbose']
 
538
    takes_options = ['remember', 'overwrite', 'revision', 'verbose',
 
539
        Option('directory',
 
540
            help='branch to pull into, '
 
541
                 'rather than the one containing the working directory',
 
542
            short_name='d',
 
543
            type=unicode,
 
544
            ),
 
545
        ]
514
546
    takes_args = ['location?']
515
547
    encoding_type = 'replace'
516
548
 
517
 
    def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
 
549
    def run(self, location=None, remember=False, overwrite=False,
 
550
            revision=None, verbose=False,
 
551
            directory=None):
518
552
        # FIXME: too much stuff is in the command class
 
553
        if directory is None:
 
554
            directory = u'.'
519
555
        try:
520
 
            tree_to = WorkingTree.open_containing(u'.')[0]
 
556
            tree_to = WorkingTree.open_containing(directory)[0]
521
557
            branch_to = tree_to.branch
522
558
        except errors.NoWorkingTree:
523
559
            tree_to = None
524
 
            branch_to = Branch.open_containing(u'.')[0]
 
560
            branch_to = Branch.open_containing(directory)[0]
525
561
 
526
562
        reader = None
527
563
        if location is not None:
541
577
                self.outf.write("Using saved location: %s\n" % display_url)
542
578
                location = stored_loc
543
579
 
544
 
 
545
580
        if reader is not None:
546
581
            install_bundle(branch_to.repository, reader)
547
582
            branch_from = branch_to
562
597
 
563
598
        old_rh = branch_to.revision_history()
564
599
        if tree_to is not None:
565
 
            count = tree_to.pull(branch_from, overwrite, rev_id)
 
600
            count = tree_to.pull(branch_from, overwrite, rev_id,
 
601
                delta.ChangeReporter(tree_to.inventory))
566
602
        else:
567
603
            count = branch_to.pull(branch_from, overwrite, rev_id)
568
604
        note('%d revision(s) pulled.' % (count,))
603
639
    """
604
640
 
605
641
    takes_options = ['remember', 'overwrite', 'verbose',
606
 
                     Option('create-prefix', 
607
 
                            help='Create the path leading up to the branch '
608
 
                                 'if it does not already exist')]
 
642
        Option('create-prefix',
 
643
               help='Create the path leading up to the branch '
 
644
                    'if it does not already exist'),
 
645
        Option('directory',
 
646
            help='branch to push from, '
 
647
                 'rather than the one containing the working directory',
 
648
            short_name='d',
 
649
            type=unicode,
 
650
            ),
 
651
        Option('use-existing-dir',
 
652
               help='By default push will fail if the target'
 
653
                    ' directory exists, but does not already'
 
654
                    ' have a control directory. This flag will'
 
655
                    ' allow push to proceed.'),
 
656
        ]
609
657
    takes_args = ['location?']
610
658
    encoding_type = 'replace'
611
659
 
612
660
    def run(self, location=None, remember=False, overwrite=False,
613
 
            create_prefix=False, verbose=False):
 
661
            create_prefix=False, verbose=False,
 
662
            use_existing_dir=False,
 
663
            directory=None):
614
664
        # FIXME: Way too big!  Put this into a function called from the
615
665
        # command.
616
 
        
617
 
        br_from = Branch.open_containing('.')[0]
 
666
        if directory is None:
 
667
            directory = '.'
 
668
        br_from = Branch.open_containing(directory)[0]
618
669
        stored_loc = br_from.get_push_location()
619
670
        if location is None:
620
671
            if stored_loc is None:
629
680
        location_url = to_transport.base
630
681
 
631
682
        old_rh = []
 
683
        count = 0
 
684
 
 
685
        br_to = repository_to = dir_to = None
632
686
        try:
633
 
            dir_to = bzrdir.BzrDir.open(location_url)
634
 
            br_to = dir_to.open_branch()
 
687
            dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
635
688
        except errors.NotBranchError:
636
 
            # create a branch.
637
 
            to_transport = to_transport.clone('..')
638
 
            if not create_prefix:
 
689
            pass # Didn't find anything
 
690
        else:
 
691
            # If we can open a branch, use its direct repository, otherwise see
 
692
            # if there is a repository without a branch.
 
693
            try:
 
694
                br_to = dir_to.open_branch()
 
695
            except errors.NotBranchError:
 
696
                # Didn't find a branch, can we find a repository?
639
697
                try:
640
 
                    relurl = to_transport.relpath(location_url)
641
 
                    mutter('creating directory %s => %s', location_url, relurl)
642
 
                    to_transport.mkdir(relurl)
643
 
                except errors.NoSuchFile:
644
 
                    raise errors.BzrCommandError("Parent directory of %s "
645
 
                                                 "does not exist." % location)
 
698
                    repository_to = dir_to.find_repository()
 
699
                except errors.NoRepositoryPresent:
 
700
                    pass
646
701
            else:
647
 
                current = to_transport.base
648
 
                needed = [(to_transport, to_transport.relpath(location_url))]
 
702
                # Found a branch, so we must have found a repository
 
703
                repository_to = br_to.repository
 
704
 
 
705
        old_rh = []
 
706
        if dir_to is None:
 
707
            # XXX: Refactor the create_prefix/no_create_prefix code into a
 
708
            #      common helper function
 
709
            try:
 
710
                to_transport.mkdir('.')
 
711
            except errors.FileExists:
 
712
                if not use_existing_dir:
 
713
                    raise errors.BzrCommandError("Target directory %s"
 
714
                         " already exists, but does not have a valid .bzr"
 
715
                         " directory. Supply --use-existing-dir to push"
 
716
                         " there anyway." % location)
 
717
            except errors.NoSuchFile:
 
718
                if not create_prefix:
 
719
                    raise errors.BzrCommandError("Parent directory of %s"
 
720
                        " does not exist."
 
721
                        "\nYou may supply --create-prefix to create all"
 
722
                        " leading parent directories."
 
723
                        % location)
 
724
 
 
725
                cur_transport = to_transport
 
726
                needed = [cur_transport]
 
727
                # Recurse upwards until we can create a directory successfully
 
728
                while True:
 
729
                    new_transport = cur_transport.clone('..')
 
730
                    if new_transport.base == cur_transport.base:
 
731
                        raise errors.BzrCommandError("Failed to create path"
 
732
                                                     " prefix for %s."
 
733
                                                     % location)
 
734
                    try:
 
735
                        new_transport.mkdir('.')
 
736
                    except errors.NoSuchFile:
 
737
                        needed.append(new_transport)
 
738
                        cur_transport = new_transport
 
739
                    else:
 
740
                        break
 
741
 
 
742
                # Now we only need to create child directories
649
743
                while needed:
650
 
                    try:
651
 
                        to_transport, relpath = needed[-1]
652
 
                        to_transport.mkdir(relpath)
653
 
                        needed.pop()
654
 
                    except errors.NoSuchFile:
655
 
                        new_transport = to_transport.clone('..')
656
 
                        needed.append((new_transport,
657
 
                                       new_transport.relpath(to_transport.base)))
658
 
                        if new_transport.base == to_transport.base:
659
 
                            raise errors.BzrCommandError("Could not create "
660
 
                                                         "path prefix.")
 
744
                    cur_transport = needed.pop()
 
745
                    cur_transport.mkdir('.')
 
746
            
 
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.
661
750
            dir_to = br_from.bzrdir.clone(location_url,
662
751
                revision_id=br_from.last_revision())
663
752
            br_to = dir_to.open_branch()
 
753
            count = br_to.last_revision_info()[0]
 
754
            # We successfully created the target, remember it
 
755
            if br_from.get_push_location() is None or remember:
 
756
                br_from.set_push_location(br_to.base)
 
757
        elif repository_to is None:
 
758
            # we have a bzrdir but no branch or repository
 
759
            # XXX: Figure out what to do other than complain.
 
760
            raise errors.BzrCommandError("At %s you have a valid .bzr control"
 
761
                " directory, but not a branch or repository. This is an"
 
762
                " unsupported configuration. Please move the target directory"
 
763
                " out of the way and try again."
 
764
                % location)
 
765
        elif br_to is None:
 
766
            # We have a repository but no branch, copy the revisions, and then
 
767
            # create a branch.
 
768
            last_revision_id = br_from.last_revision()
 
769
            repository_to.fetch(br_from.repository,
 
770
                                revision_id=last_revision_id)
 
771
            br_to = br_from.clone(dir_to, revision_id=last_revision_id)
664
772
            count = len(br_to.revision_history())
665
 
            # We successfully created the target, remember it
666
773
            if br_from.get_push_location() is None or remember:
667
774
                br_from.set_push_location(br_to.base)
668
 
        else:
 
775
        else: # We have a valid to branch
669
776
            # We were able to connect to the remote location, so remember it
670
777
            # we don't need to successfully push because of possible divergence.
671
778
            if br_from.get_push_location() is None or remember:
724
831
        elif len(revision) > 1:
725
832
            raise errors.BzrCommandError(
726
833
                'bzr branch --revision takes exactly 1 revision value')
727
 
        try:
728
 
            br_from = Branch.open(from_location)
729
 
        except OSError, e:
730
 
            if e.errno == errno.ENOENT:
731
 
                raise errors.BzrCommandError('Source location "%s" does not'
732
 
                                             ' exist.' % to_location)
733
 
            else:
734
 
                raise
 
834
 
 
835
        br_from = Branch.open(from_location)
735
836
        br_from.lock_read()
736
837
        try:
737
838
            if basis is not None:
799
900
    --basis is to speed up checking out from remote branches.  When specified, it
800
901
    uses the inventory and file contents from the basis branch in preference to the
801
902
    branch being checked out.
 
903
 
 
904
    See "help checkouts" for more information on checkouts.
802
905
    """
803
906
    takes_args = ['branch_location?', 'to_location?']
804
907
    takes_options = ['revision', # , 'basis']
1095
1198
    """
1096
1199
    takes_args = ['location?']
1097
1200
    takes_options = [
1098
 
                     RegistryOption('format',
1099
 
                            help='Specify a format for this branch. Current'
1100
 
                                 ' formats are: default, knit, metaweave and'
1101
 
                                 ' weave. Default is knit; metaweave and'
1102
 
                                 ' weave are deprecated',
1103
 
                            registry=bzrdir.format_registry,
1104
 
                            converter=get_format_type,
1105
 
                            value_switches=True),
1106
 
                     ]
1107
 
    def run(self, location=None, format=None):
 
1201
         RegistryOption('format',
 
1202
                help='Specify a format for this branch. '
 
1203
                'See "help formats".',
 
1204
                registry=bzrdir.format_registry,
 
1205
                converter=bzrdir.format_registry.make_bzrdir,
 
1206
                value_switches=True,
 
1207
                title="Branch Format",
 
1208
                ),
 
1209
         Option('append-revisions-only',
 
1210
                help='Never change revnos or the existing log.'
 
1211
                '  Append revisions to it only.')
 
1212
         ]
 
1213
    def run(self, location=None, format=None, append_revisions_only=False):
1108
1214
        if format is None:
1109
 
            format = get_format_type('default')
 
1215
            format = bzrdir.format_registry.make_bzrdir('default')
1110
1216
        if location is None:
1111
1217
            location = u'.'
1112
1218
 
1127
1233
            existing_bzrdir = bzrdir.BzrDir.open(location)
1128
1234
        except errors.NotBranchError:
1129
1235
            # really a NotBzrDir error...
1130
 
            bzrdir.BzrDir.create_branch_convenience(location, format=format)
 
1236
            branch = bzrdir.BzrDir.create_branch_convenience(location,
 
1237
                                                             format=format)
1131
1238
        else:
1132
1239
            from bzrlib.transport.local import LocalTransport
1133
1240
            if existing_bzrdir.has_branch():
1136
1243
                        raise errors.BranchExistsWithoutWorkingTree(location)
1137
1244
                raise errors.AlreadyBranchError(location)
1138
1245
            else:
1139
 
                existing_bzrdir.create_branch()
 
1246
                branch = existing_bzrdir.create_branch()
1140
1247
                existing_bzrdir.create_workingtree()
 
1248
        if append_revisions_only:
 
1249
            try:
 
1250
                branch.set_append_revisions_only(True)
 
1251
            except errors.UpgradeRequired:
 
1252
                raise errors.BzrCommandError('This branch format cannot be set'
 
1253
                    ' to append-revisions-only.  Try --experimental-branch6')
1141
1254
 
1142
1255
 
1143
1256
class cmd_init_repository(Command):
1154
1267
        cd trunk-checkout
1155
1268
        (add files here)
1156
1269
    """
1157
 
    takes_args = ["location"] 
 
1270
    takes_args = ["location"]
1158
1271
    takes_options = [RegistryOption('format',
1159
 
                            help='Specify a format for this repository.'
1160
 
                                 ' Current formats are: default, knit,'
1161
 
                                 ' metaweave and weave. Default is knit;'
1162
 
                                 ' metaweave and weave are deprecated',
 
1272
                            help='Specify a format for this repository. See'
 
1273
                                 ' "bzr help formats" for details',
1163
1274
                            registry=bzrdir.format_registry,
1164
 
                            converter=get_format_type,
1165
 
                            value_switches=True),
 
1275
                            converter=bzrdir.format_registry.make_bzrdir,
 
1276
                            value_switches=True, title='Repository format'),
1166
1277
                     Option('trees',
1167
1278
                             help='Allows branches in repository to have'
1168
1279
                             ' a working tree')]
1169
1280
    aliases = ["init-repo"]
1170
1281
    def run(self, location, format=None, trees=False):
1171
1282
        if format is None:
1172
 
            format = get_format_type('default')
 
1283
            format = bzrdir.format_registry.make_bzrdir('default')
1173
1284
 
1174
1285
        if location is None:
1175
1286
            location = '.'
1319
1430
 
1320
1431
 
1321
1432
class cmd_modified(Command):
1322
 
    """List files modified in working tree."""
 
1433
    """List files modified in working tree.
 
1434
 
 
1435
    See also: "bzr status".
 
1436
    """
 
1437
 
1323
1438
    hidden = True
 
1439
 
1324
1440
    @display_command
1325
1441
    def run(self):
1326
1442
        tree = WorkingTree.open_containing(u'.')[0]
1330
1446
 
1331
1447
 
1332
1448
class cmd_added(Command):
1333
 
    """List files added in working tree."""
 
1449
    """List files added in working tree.
 
1450
 
 
1451
    See also: "bzr status".
 
1452
    """
 
1453
 
1334
1454
    hidden = True
 
1455
 
1335
1456
    @display_command
1336
1457
    def run(self):
1337
1458
        wt = WorkingTree.open_containing(u'.')[0]
1387
1508
                             help='show files changed in each revision'),
1388
1509
                     'show-ids', 'revision',
1389
1510
                     'log-format',
1390
 
                     'line', 'long', 
1391
1511
                     Option('message',
1392
1512
                            short_name='m',
1393
1513
                            help='show revisions whose message matches this regexp',
1394
1514
                            type=str),
1395
 
                     'short',
1396
1515
                     ]
1397
1516
    encoding_type = 'replace'
1398
1517
 
1403
1522
            forward=False,
1404
1523
            revision=None,
1405
1524
            log_format=None,
1406
 
            message=None,
1407
 
            long=False,
1408
 
            short=False,
1409
 
            line=False):
1410
 
        from bzrlib.log import log_formatter, show_log
 
1525
            message=None):
 
1526
        from bzrlib.log import show_log
1411
1527
        assert message is None or isinstance(message, basestring), \
1412
1528
            "invalid message argument %r" % message
1413
1529
        direction = (forward and 'forward') or 'reverse'
1417
1533
        if location:
1418
1534
            # find the file id to log:
1419
1535
 
1420
 
            dir, fp = bzrdir.BzrDir.open_containing(location)
1421
 
            b = dir.open_branch()
 
1536
            tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1537
                location)
1422
1538
            if fp != '':
1423
 
                try:
1424
 
                    # might be a tree:
1425
 
                    inv = dir.open_workingtree().inventory
1426
 
                except (errors.NotBranchError, errors.NotLocalUrl):
1427
 
                    # either no tree, or is remote.
1428
 
                    inv = b.basis_tree().inventory
 
1539
                if tree is None:
 
1540
                    tree = b.basis_tree()
 
1541
                inv = tree.inventory
1429
1542
                file_id = inv.path2id(fp)
1430
1543
                if file_id is None:
1431
1544
                    raise errors.BzrCommandError(
1442
1555
            dir, relpath = bzrdir.BzrDir.open_containing(location)
1443
1556
            b = dir.open_branch()
1444
1557
 
1445
 
        if revision is None:
1446
 
            rev1 = None
1447
 
            rev2 = None
1448
 
        elif len(revision) == 1:
1449
 
            rev1 = rev2 = revision[0].in_history(b).revno
1450
 
        elif len(revision) == 2:
1451
 
            if revision[1].get_branch() != revision[0].get_branch():
1452
 
                # b is taken from revision[0].get_branch(), and
1453
 
                # show_log will use its revision_history. Having
1454
 
                # different branches will lead to weird behaviors.
 
1558
        b.lock_read()
 
1559
        try:
 
1560
            if revision is None:
 
1561
                rev1 = None
 
1562
                rev2 = None
 
1563
            elif len(revision) == 1:
 
1564
                rev1 = rev2 = revision[0].in_history(b).revno
 
1565
            elif len(revision) == 2:
 
1566
                if revision[1].get_branch() != revision[0].get_branch():
 
1567
                    # b is taken from revision[0].get_branch(), and
 
1568
                    # show_log will use its revision_history. Having
 
1569
                    # different branches will lead to weird behaviors.
 
1570
                    raise errors.BzrCommandError(
 
1571
                        "Log doesn't accept two revisions in different"
 
1572
                        " branches.")
 
1573
                if revision[0].spec is None:
 
1574
                    # missing begin-range means first revision
 
1575
                    rev1 = 1
 
1576
                else:
 
1577
                    rev1 = revision[0].in_history(b).revno
 
1578
 
 
1579
                if revision[1].spec is None:
 
1580
                    # missing end-range means last known revision
 
1581
                    rev2 = b.revno()
 
1582
                else:
 
1583
                    rev2 = revision[1].in_history(b).revno
 
1584
            else:
1455
1585
                raise errors.BzrCommandError(
1456
 
                    "Log doesn't accept two revisions in different branches.")
1457
 
            if revision[0].spec is None:
1458
 
                # missing begin-range means first revision
1459
 
                rev1 = 1
1460
 
            else:
1461
 
                rev1 = revision[0].in_history(b).revno
1462
 
 
1463
 
            if revision[1].spec is None:
1464
 
                # missing end-range means last known revision
1465
 
                rev2 = b.revno()
1466
 
            else:
1467
 
                rev2 = revision[1].in_history(b).revno
1468
 
        else:
1469
 
            raise errors.BzrCommandError('bzr log --revision takes one or two values.')
1470
 
 
1471
 
        # By this point, the revision numbers are converted to the +ve
1472
 
        # form if they were supplied in the -ve form, so we can do
1473
 
        # this comparison in relative safety
1474
 
        if rev1 > rev2:
1475
 
            (rev2, rev1) = (rev1, rev2)
1476
 
 
1477
 
        if (log_format is None):
1478
 
            default = b.get_config().log_format()
1479
 
            log_format = get_log_format(long=long, short=short, line=line, 
1480
 
                                        default=default)
1481
 
        lf = log_formatter(log_format,
1482
 
                           show_ids=show_ids,
1483
 
                           to_file=self.outf,
1484
 
                           show_timezone=timezone)
1485
 
 
1486
 
        show_log(b,
1487
 
                 lf,
1488
 
                 file_id,
1489
 
                 verbose=verbose,
1490
 
                 direction=direction,
1491
 
                 start_revision=rev1,
1492
 
                 end_revision=rev2,
1493
 
                 search=message)
 
1586
                    'bzr log --revision takes one or two values.')
 
1587
 
 
1588
            # By this point, the revision numbers are converted to the +ve
 
1589
            # form if they were supplied in the -ve form, so we can do
 
1590
            # this comparison in relative safety
 
1591
            if rev1 > rev2:
 
1592
                (rev2, rev1) = (rev1, rev2)
 
1593
 
 
1594
            if log_format is None:
 
1595
                log_format = log.log_formatter_registry.get_default(b)
 
1596
 
 
1597
            lf = log_format(show_ids=show_ids, to_file=self.outf,
 
1598
                            show_timezone=timezone)
 
1599
 
 
1600
            show_log(b,
 
1601
                     lf,
 
1602
                     file_id,
 
1603
                     verbose=verbose,
 
1604
                     direction=direction,
 
1605
                     start_revision=rev1,
 
1606
                     end_revision=rev2,
 
1607
                     search=message)
 
1608
        finally:
 
1609
            b.unlock()
1494
1610
 
1495
1611
 
1496
1612
def get_log_format(long=False, short=False, line=False, default='long'):
1615
1731
 
1616
1732
 
1617
1733
class cmd_unknowns(Command):
1618
 
    """List unknown files."""
 
1734
    """List unknown files.
 
1735
 
 
1736
    See also: "bzr ls --unknown".
 
1737
    """
 
1738
 
 
1739
    hidden = True
 
1740
 
1619
1741
    @display_command
1620
1742
    def run(self):
1621
1743
        for f in WorkingTree.open_containing(u'.')[0].unknowns():
1996
2118
    takes_args = ['url?']
1997
2119
    takes_options = [
1998
2120
                    RegistryOption('format',
1999
 
                        help='Upgrade to a specific format. Current formats'
2000
 
                             ' are: default, knit, metaweave and weave.'
2001
 
                             ' Default is knit; metaweave and weave are'
2002
 
                             ' deprecated',
 
2121
                        help='Upgrade to a specific format.  See "bzr help'
 
2122
                             ' formats" for details',
2003
2123
                        registry=bzrdir.format_registry,
2004
 
                        converter=get_format_type,
2005
 
                        value_switches=True),
 
2124
                        converter=bzrdir.format_registry.make_bzrdir,
 
2125
                        value_switches=True, title='Branch format'),
2006
2126
                    ]
2007
2127
 
2008
2128
 
2009
2129
    def run(self, url='.', format=None):
2010
2130
        from bzrlib.upgrade import upgrade
2011
2131
        if format is None:
2012
 
            format = get_format_type('default')
 
2132
            format = bzrdir.format_registry.make_bzrdir('default')
2013
2133
        upgrade(url, format)
2014
2134
 
2015
2135
 
2237
2357
        branch1 = Branch.open_containing(branch)[0]
2238
2358
        branch2 = Branch.open_containing(other)[0]
2239
2359
 
2240
 
        history_1 = branch1.revision_history()
2241
 
        history_2 = branch2.revision_history()
2242
 
 
2243
2360
        last1 = branch1.last_revision()
2244
2361
        last2 = branch2.last_revision()
2245
2362
 
2276
2393
    default, use --remember. The value will only be saved if the remote
2277
2394
    location can be accessed.
2278
2395
 
 
2396
    The results of the merge are placed into the destination working
 
2397
    directory, where they can be reviewed (with bzr diff), tested, and then
 
2398
    committed to record the result of the merge.
 
2399
 
2279
2400
    Examples:
2280
2401
 
2281
2402
    To merge the latest revision from bzr.dev
2294
2415
    """
2295
2416
    takes_args = ['branch?']
2296
2417
    takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2297
 
                     Option('show-base', help="Show base revision text in "
2298
 
                            "conflicts"),
2299
 
                     Option('uncommitted', help='Apply uncommitted changes'
2300
 
                            ' from a working copy, instead of branch changes'),
2301
 
                     Option('pull', help='If the destination is already'
2302
 
                             ' completely merged into the source, pull from the'
2303
 
                             ' source rather than merging. When this happens,'
2304
 
                             ' you do not need to commit the result.'),
2305
 
                     ]
2306
 
 
2307
 
    def help(self):
2308
 
        from inspect import getdoc
2309
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
 
2418
        Option('show-base', help="Show base revision text in "
 
2419
               "conflicts"),
 
2420
        Option('uncommitted', help='Apply uncommitted changes'
 
2421
               ' from a working copy, instead of branch changes'),
 
2422
        Option('pull', help='If the destination is already'
 
2423
                ' completely merged into the source, pull from the'
 
2424
                ' source rather than merging. When this happens,'
 
2425
                ' you do not need to commit the result.'),
 
2426
        Option('directory',
 
2427
            help='branch to merge into, '
 
2428
                 'rather than the one containing the working directory',
 
2429
            short_name='d',
 
2430
            type=unicode,
 
2431
            ),
 
2432
    ]
2310
2433
 
2311
2434
    def run(self, branch=None, revision=None, force=False, merge_type=None,
2312
 
            show_base=False, reprocess=False, remember=False, 
2313
 
            uncommitted=False, pull=False):
 
2435
            show_base=False, reprocess=False, remember=False,
 
2436
            uncommitted=False, pull=False,
 
2437
            directory=None,
 
2438
            ):
2314
2439
        if merge_type is None:
2315
2440
            merge_type = _mod_merge.Merge3Merger
2316
2441
 
2317
 
        tree = WorkingTree.open_containing(u'.')[0]
 
2442
        if directory is None: directory = u'.'
 
2443
        tree = WorkingTree.open_containing(directory)[0]
 
2444
        change_reporter = delta.ChangeReporter(tree.inventory)
2318
2445
 
2319
2446
        if branch is not None:
2320
2447
            try:
2323
2450
                pass # Continue on considering this url a Branch
2324
2451
            else:
2325
2452
                conflicts = merge_bundle(reader, tree, not force, merge_type,
2326
 
                                            reprocess, show_base)
 
2453
                                         reprocess, show_base, change_reporter)
2327
2454
                if conflicts == 0:
2328
2455
                    return 0
2329
2456
                else:
2382
2509
                    reprocess=reprocess,
2383
2510
                    show_base=show_base,
2384
2511
                    pull=pull,
2385
 
                    pb=pb, file_list=interesting_files)
 
2512
                    this_dir=directory,
 
2513
                    pb=pb, file_list=interesting_files,
 
2514
                    change_reporter=change_reporter)
2386
2515
            finally:
2387
2516
                pb.finished()
2388
2517
            if conflict_count != 0:
2441
2570
                     Option('show-base', help="Show base revision text in "
2442
2571
                            "conflicts")]
2443
2572
 
2444
 
    def help(self):
2445
 
        from inspect import getdoc
2446
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2447
 
 
2448
2573
    def run(self, file_list=None, merge_type=None, show_base=False,
2449
2574
            reprocess=False):
2450
2575
        if merge_type is None:
2625
2750
                     Option('theirs-only', 
2626
2751
                            'Display changes in the remote branch only'), 
2627
2752
                     'log-format',
2628
 
                     'line',
2629
 
                     'long', 
2630
 
                     'short',
2631
2753
                     'show-ids',
2632
2754
                     'verbose'
2633
2755
                     ]
2658
2780
            try:
2659
2781
                local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2660
2782
                if (log_format is None):
2661
 
                    default = local_branch.get_config().log_format()
2662
 
                    log_format = get_log_format(long=long, short=short, 
2663
 
                                                line=line, default=default)
2664
 
                lf = log_formatter(log_format,
2665
 
                                   to_file=self.outf,
2666
 
                                   show_ids=show_ids,
2667
 
                                   show_timezone='original')
 
2783
                    log_format = log.log_formatter_registry.get_default(
 
2784
                        local_branch)
 
2785
                lf = log_format(to_file=self.outf,
 
2786
                                show_ids=show_ids,
 
2787
                                show_timezone='original')
2668
2788
                if reverse is False:
2669
2789
                    local_extra.reverse()
2670
2790
                    remote_extra.reverse()
2837
2957
 
2838
2958
 
2839
2959
class cmd_bind(Command):
2840
 
    """Bind the current branch to a master branch.
2841
 
 
2842
 
    After binding, commits must succeed on the master branch
2843
 
    before they are executed on the local one.
 
2960
    """Convert the current branch into a checkout of the supplied branch.
 
2961
 
 
2962
    Once converted into a checkout, commits must succeed on the master branch
 
2963
    before they will be applied to the local branch.
 
2964
 
 
2965
    See "help checkouts" for more information on checkouts.
2844
2966
    """
2845
2967
 
2846
 
    takes_args = ['location']
 
2968
    takes_args = ['location?']
2847
2969
    takes_options = []
2848
2970
 
2849
2971
    def run(self, location=None):
2850
2972
        b, relpath = Branch.open_containing(u'.')
 
2973
        if location is None:
 
2974
            try:
 
2975
                location = b.get_old_bound_location()
 
2976
            except errors.UpgradeRequired:
 
2977
                raise errors.BzrCommandError('No location supplied.  '
 
2978
                    'This format does not remember old locations.')
 
2979
            else:
 
2980
                if location is None:
 
2981
                    raise errors.BzrCommandError('No location supplied and no '
 
2982
                        'previous location known')
2851
2983
        b_other = Branch.open(location)
2852
2984
        try:
2853
2985
            b.bind(b_other)
2857
2989
 
2858
2990
 
2859
2991
class cmd_unbind(Command):
2860
 
    """Unbind the current branch from its master branch.
2861
 
 
2862
 
    After unbinding, the local branch is considered independent.
2863
 
    All subsequent commits will be local.
 
2992
    """Convert the current checkout into a regular branch.
 
2993
 
 
2994
    After unbinding, the local branch is considered independent and subsequent
 
2995
    commits will be local only.
 
2996
 
 
2997
    See "help checkouts" for more information on checkouts.
2864
2998
    """
2865
2999
 
2866
3000
    takes_args = []
3045
3179
                  merge_type=None,
3046
3180
                  file_list=None, show_base=False, reprocess=False,
3047
3181
                  pull=False,
3048
 
                  pb=DummyProgress()):
 
3182
                  pb=DummyProgress(),
 
3183
                  change_reporter=None):
3049
3184
    """Merge changes into a tree.
3050
3185
 
3051
3186
    base_revision
3089
3224
        raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3090
3225
    try:
3091
3226
        merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3092
 
                                   pb=pb)
 
3227
                                   pb=pb, change_reporter=change_reporter)
3093
3228
        merger.pp = ProgressPhase("Merge phase", 5, pb)
3094
3229
        merger.pp.next_phase()
3095
3230
        merger.check_basis(check_clean)