/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2007-07-11 23:45:20 UTC
  • mfrom: (2601 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2643.
  • Revision ID: john@arbash-meinel.com-20070711234520-do3h7zw8skbathpz
[merge] bzr.dev 2601

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
lazy_import(globals(), """
24
24
import codecs
25
25
import errno
26
 
import smtplib
27
26
import sys
28
27
import tempfile
29
28
import time
45
44
    osutils,
46
45
    registry,
47
46
    repository,
 
47
    revisionspec,
48
48
    symbol_versioning,
49
49
    transport,
50
50
    tree as _mod_tree,
54
54
from bzrlib.branch import Branch
55
55
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
56
56
from bzrlib.conflicts import ConflictList
57
 
from bzrlib.revision import common_ancestor
58
57
from bzrlib.revisionspec import RevisionSpec
 
58
from bzrlib.smtp_connection import SMTPConnection
59
59
from bzrlib.workingtree import WorkingTree
60
60
""")
61
61
 
155
155
    --short gives a status flags for each item, similar to the SVN's status
156
156
    command.
157
157
 
158
 
    Column 1: versioning / renames
159
 
      + File versioned
160
 
      - File unversioned
161
 
      R File renamed
162
 
      ? File unknown
163
 
      C File has conflicts
164
 
      P Entry for a pending merge (not a file)
165
 
 
166
 
    Column 2: Contents
167
 
      N File created
168
 
      D File deleted
169
 
      K File kind changed
170
 
      M File modified
171
 
 
172
 
    Column 3: Execute
173
 
      * The execute bit was changed
174
 
 
175
158
    If no arguments are specified, the status of the entire working
176
159
    directory is shown.  Otherwise, only the status of the specified
177
160
    files or directories is reported.  If a directory is given, status
185
168
    
186
169
    takes_args = ['file*']
187
170
    takes_options = ['show-ids', 'revision',
188
 
                     Option('short', help='Give short SVN-style status lines'),
189
 
                     Option('versioned', help='Only show versioned files')]
 
171
                     Option('short', help='Give short SVN-style status lines.'),
 
172
                     Option('versioned', help='Only show versioned files.')]
190
173
    aliases = ['st', 'stat']
191
174
 
192
175
    encoding_type = 'replace'
193
 
    _see_also = ['diff', 'revert']
 
176
    _see_also = ['diff', 'revert', 'status-flags']
194
177
    
195
178
    @display_command
196
179
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
249
232
 
250
233
    To re-create the working tree, use "bzr checkout".
251
234
    """
252
 
    _see_also = ['checkout']
 
235
    _see_also = ['checkout', 'working-trees']
253
236
 
254
237
    takes_args = ['location?']
255
238
 
304
287
        if revision_info_list is not None:
305
288
            for rev in revision_info_list:
306
289
                revs.append(RevisionSpec.from_string(rev))
 
290
 
 
291
        b = Branch.open_containing(u'.')[0]
 
292
 
307
293
        if len(revs) == 0:
308
 
            raise errors.BzrCommandError('You must supply a revision identifier')
309
 
 
310
 
        b = WorkingTree.open_containing(u'.')[0].branch
 
294
            revs.append(RevisionSpec.from_string('-1'))
311
295
 
312
296
        for rev in revs:
313
297
            revinfo = rev.in_history(b)
314
298
            if revinfo.revno is None:
315
 
                print '     %s' % revinfo.rev_id
 
299
                dotted_map = b.get_revision_id_to_revno_map()
 
300
                revno = '.'.join(str(i) for i in dotted_map[revinfo.rev_id])
 
301
                print '%s %s' % (revno, revinfo.rev_id)
316
302
            else:
317
303
                print '%4d %s' % (revinfo.revno, revinfo.rev_id)
318
304
 
354
340
    takes_args = ['file*']
355
341
    takes_options = ['no-recurse', 'dry-run', 'verbose',
356
342
                     Option('file-ids-from', type=unicode,
357
 
                            help='Lookup file ids from here')]
 
343
                            help='Lookup file ids from this tree.')]
358
344
    encoding_type = 'replace'
359
345
    _see_also = ['remove']
360
346
 
381
367
        if base_tree:
382
368
            base_tree.lock_read()
383
369
        try:
384
 
            added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
385
 
                action=action, save=not dry_run)
 
370
            file_list = self._maybe_expand_globs(file_list)
 
371
            if file_list:
 
372
                tree = WorkingTree.open_containing(file_list[0])[0]
 
373
            else:
 
374
                tree = WorkingTree.open_containing(u'.')[0]
 
375
            added, ignored = tree.smart_add(file_list, not
 
376
                no_recurse, action=action, save=not dry_run)
386
377
        finally:
387
378
            if base_tree is not None:
388
379
                base_tree.unlock()
515
506
    """
516
507
 
517
508
    takes_args = ['names*']
518
 
    takes_options = [Option("after", help="move only the bzr identifier"
519
 
        " of the file (file has already been moved). Use this flag if"
520
 
        " bzr is not able to detect this itself.")]
 
509
    takes_options = [Option("after", help="Move only the bzr identifier"
 
510
        " of the file, because the file has already been moved."),
 
511
        ]
521
512
    aliases = ['move', 'rename']
522
513
    encoding_type = 'replace'
523
514
 
562
553
    location can be accessed.
563
554
    """
564
555
 
565
 
    _see_also = ['push', 'update']
 
556
    _see_also = ['push', 'update', 'status-flags']
566
557
    takes_options = ['remember', 'overwrite', 'revision', 'verbose',
567
558
        Option('directory',
568
 
            help='branch to pull into, '
569
 
                 'rather than the one containing the working directory',
 
559
            help='Branch to pull into, '
 
560
                 'rather than the one containing the working directory.',
570
561
            short_name='d',
571
562
            type=unicode,
572
563
            ),
669
660
    location can be accessed.
670
661
    """
671
662
 
672
 
    _see_also = ['pull', 'update']
 
663
    _see_also = ['pull', 'update', 'working-trees']
673
664
    takes_options = ['remember', 'overwrite', 'verbose',
674
665
        Option('create-prefix',
675
666
               help='Create the path leading up to the branch '
676
 
                    'if it does not already exist'),
 
667
                    'if it does not already exist.'),
677
668
        Option('directory',
678
 
            help='branch to push from, '
679
 
                 'rather than the one containing the working directory',
 
669
            help='Branch to push from, '
 
670
                 'rather than the one containing the working directory.',
680
671
            short_name='d',
681
672
            type=unicode,
682
673
            ),
683
674
        Option('use-existing-dir',
684
675
               help='By default push will fail if the target'
685
676
                    ' directory exists, but does not already'
686
 
                    ' have a control directory. This flag will'
 
677
                    ' have a control directory.  This flag will'
687
678
                    ' allow push to proceed.'),
688
679
        ]
689
680
    takes_args = ['location?']
751
742
                        " leading parent directories."
752
743
                        % location)
753
744
 
754
 
                cur_transport = to_transport
755
 
                needed = [cur_transport]
756
 
                # Recurse upwards until we can create a directory successfully
757
 
                while True:
758
 
                    new_transport = cur_transport.clone('..')
759
 
                    if new_transport.base == cur_transport.base:
760
 
                        raise errors.BzrCommandError("Failed to create path"
761
 
                                                     " prefix for %s."
762
 
                                                     % location)
763
 
                    try:
764
 
                        new_transport.mkdir('.')
765
 
                    except errors.NoSuchFile:
766
 
                        needed.append(new_transport)
767
 
                        cur_transport = new_transport
768
 
                    else:
769
 
                        break
770
 
 
771
 
                # Now we only need to create child directories
772
 
                while needed:
773
 
                    cur_transport = needed.pop()
774
 
                    cur_transport.ensure_base()
 
745
                _create_prefix(to_transport)
775
746
 
776
747
            # Now the target directory exists, but doesn't have a .bzr
777
748
            # directory. So we need to create it, along with any work to create
812
783
                try:
813
784
                    tree_to = dir_to.open_workingtree()
814
785
                except errors.NotLocalUrl:
815
 
                    warning('This transport does not update the working '
816
 
                            'tree of: %s' % (br_to.base,))
 
786
                    warning("This transport does not update the working " 
 
787
                            "tree of: %s. See 'bzr help working-trees' for "
 
788
                            "more information." % br_to.base)
817
789
                    push_result = br_from.push(br_to, overwrite)
818
790
                except errors.NoWorkingTree:
819
791
                    push_result = br_from.push(br_to, overwrite)
847
819
 
848
820
    If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
849
821
    be used.  In other words, "branch ../foo/bar" will attempt to create ./bar.
 
822
    If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
 
823
    is derived from the FROM_LOCATION by stripping a leading scheme or drive
 
824
    identifier, if any. For example, "branch lp:foo-bar" will attempt to
 
825
    create ./foo-bar.
850
826
 
851
827
    To retrieve the branch as of a particular revision, supply the --revision
852
828
    parameter, as in "branch foo/bar -r 5".
876
852
                # RBC 20060209
877
853
                revision_id = br_from.last_revision()
878
854
            if to_location is None:
879
 
                to_location = os.path.basename(from_location.rstrip("/\\"))
 
855
                to_location = urlutils.derive_to_location(from_location)
880
856
                name = None
881
857
            else:
882
858
                name = os.path.basename(to_location) + '\n'
916
892
    
917
893
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
918
894
    be used.  In other words, "checkout ../foo/bar" will attempt to create ./bar.
 
895
    If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
 
896
    is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
 
897
    identifier, if any. For example, "checkout lp:foo-bar" will attempt to
 
898
    create ./foo-bar.
919
899
 
920
900
    To retrieve the branch as of a particular revision, supply the --revision
921
901
    parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
927
907
    takes_args = ['branch_location?', 'to_location?']
928
908
    takes_options = ['revision',
929
909
                     Option('lightweight',
930
 
                            help="perform a lightweight checkout. Lightweight "
 
910
                            help="Perform a lightweight checkout.  Lightweight "
931
911
                                 "checkouts depend on access to the branch for "
932
 
                                 "every operation. Normal checkouts can perform "
 
912
                                 "every operation.  Normal checkouts can perform "
933
913
                                 "common operations like diff and status without "
934
914
                                 "such access, and also support local commits."
935
915
                            ),
952
932
        else:
953
933
            revision_id = None
954
934
        if to_location is None:
955
 
            to_location = os.path.basename(branch_location.rstrip("/\\"))
 
935
            to_location = urlutils.derive_to_location(branch_location)
956
936
        # if the source and to_location are the same, 
957
937
        # and there is no working tree,
958
938
        # then reconstitute a branch
1017
997
    'bzr revert' instead of 'bzr commit' after the update.
1018
998
    """
1019
999
 
1020
 
    _see_also = ['pull']
 
1000
    _see_also = ['pull', 'working-trees']
1021
1001
    takes_args = ['dir?']
1022
1002
    aliases = ['up']
1023
1003
 
1038
1018
                    revno = tree.branch.revision_id_to_revno(last_rev)
1039
1019
                    note("Tree is up to date at revision %d." % (revno,))
1040
1020
                    return 0
1041
 
            conflicts = tree.update()
 
1021
            conflicts = tree.update(delta._ChangeReporter(
 
1022
                                        unversioned_filter=tree.is_ignored))
1042
1023
            revno = tree.branch.revision_id_to_revno(tree.last_revision())
1043
1024
            note('Updated to revision %d.' % (revno,))
1044
1025
            if tree.get_parent_ids()[1:] != existing_pending_merges:
1061
1042
 
1062
1043
    Branches and working trees will also report any missing revisions.
1063
1044
    """
1064
 
    _see_also = ['revno']
 
1045
    _see_also = ['revno', 'working-trees', 'repositories']
1065
1046
    takes_args = ['location?']
1066
1047
    takes_options = ['verbose']
1067
1048
 
1068
1049
    @display_command
1069
 
    def run(self, location=None, verbose=False):
 
1050
    def run(self, location=None, verbose=0):
1070
1051
        from bzrlib.info import show_bzrdir_info
1071
1052
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1072
1053
                         verbose=verbose)
1085
1066
    """
1086
1067
    takes_args = ['file*']
1087
1068
    takes_options = ['verbose',
1088
 
        Option('new', help='remove newly-added files'),
 
1069
        Option('new', help='Remove newly-added files.'),
1089
1070
        RegistryOption.from_kwargs('file-deletion-strategy',
1090
1071
            'The file deletion mode to be used',
1091
1072
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1257
1238
    _see_also = ['init-repo', 'branch', 'checkout']
1258
1239
    takes_args = ['location?']
1259
1240
    takes_options = [
 
1241
        Option('create-prefix',
 
1242
               help='Create the path leading up to the branch '
 
1243
                    'if it does not already exist.'),
1260
1244
         RegistryOption('format',
1261
1245
                help='Specify a format for this branch. '
1262
1246
                'See "help formats".',
1269
1253
                help='Never change revnos or the existing log.'
1270
1254
                '  Append revisions to it only.')
1271
1255
         ]
1272
 
    def run(self, location=None, format=None, append_revisions_only=False):
 
1256
    def run(self, location=None, format=None, append_revisions_only=False,
 
1257
            create_prefix=False):
1273
1258
        if format is None:
1274
1259
            format = bzrdir.format_registry.make_bzrdir('default')
1275
1260
        if location is None:
1282
1267
        # Just using os.mkdir, since I don't
1283
1268
        # believe that we want to create a bunch of
1284
1269
        # locations if the user supplies an extended path
1285
 
        # TODO: create-prefix
1286
 
        to_transport.ensure_base()
 
1270
        try:
 
1271
            to_transport.ensure_base()
 
1272
        except errors.NoSuchFile:
 
1273
            if not create_prefix:
 
1274
                raise errors.BzrCommandError("Parent directory of %s"
 
1275
                    " does not exist."
 
1276
                    "\nYou may supply --create-prefix to create all"
 
1277
                    " leading parent directories."
 
1278
                    % location)
 
1279
            _create_prefix(to_transport)
1287
1280
 
1288
1281
        try:
1289
1282
            existing_bzrdir = bzrdir.BzrDir.open(location)
1312
1305
class cmd_init_repository(Command):
1313
1306
    """Create a shared repository to hold branches.
1314
1307
 
1315
 
    New branches created under the repository directory will store their revisions
1316
 
    in the repository, not in the branch directory.
 
1308
    New branches created under the repository directory will store their
 
1309
    revisions in the repository, not in the branch directory.
 
1310
 
 
1311
    If the --no-trees option is used then the branches in the repository
 
1312
    will not have working trees by default.
1317
1313
 
1318
1314
    example:
1319
1315
        bzr init-repo --no-trees repo
1321
1317
        bzr checkout --lightweight repo/trunk trunk-checkout
1322
1318
        cd trunk-checkout
1323
1319
        (add files here)
 
1320
 
 
1321
    See 'bzr help repositories' for more information.
1324
1322
    """
1325
1323
 
1326
1324
    _see_also = ['init', 'branch', 'checkout']
1327
1325
    takes_args = ["location"]
1328
1326
    takes_options = [RegistryOption('format',
1329
1327
                            help='Specify a format for this repository. See'
1330
 
                                 ' "bzr help formats" for details',
 
1328
                                 ' "bzr help formats" for details.',
1331
1329
                            registry=bzrdir.format_registry,
1332
1330
                            converter=bzrdir.format_registry.make_bzrdir,
1333
1331
                            value_switches=True, title='Repository format'),
1334
1332
                     Option('no-trees',
1335
1333
                             help='Branches in the repository will default to'
1336
 
                                  ' not having a working tree'),
 
1334
                                  ' not having a working tree.'),
1337
1335
                    ]
1338
1336
    aliases = ["init-repo"]
1339
1337
 
1392
1390
        Option('prefix', type=str,
1393
1391
               short_name='p',
1394
1392
               help='Set prefixes to added to old and new filenames, as '
1395
 
                    'two values separated by a colon. (eg "old/:new/")'),
 
1393
                    'two values separated by a colon. (eg "old/:new/").'),
1396
1394
        ]
1397
1395
    aliases = ['di', 'dif']
1398
1396
    encoding_type = 'exact'
1557
1555
        self.outf.write(tree.basedir + '\n')
1558
1556
 
1559
1557
 
 
1558
def _parse_limit(limitstring):
 
1559
    try:
 
1560
        return int(limitstring)
 
1561
    except ValueError:
 
1562
        msg = "The limit argument must be an integer."
 
1563
        raise errors.BzrCommandError(msg)
 
1564
 
 
1565
 
1560
1566
class cmd_log(Command):
1561
1567
    """Show log of a branch, file, or directory.
1562
1568
 
1575
1581
    # TODO: Make --revision support uuid: and hash: [future tag:] notation.
1576
1582
 
1577
1583
    takes_args = ['location?']
1578
 
    takes_options = [Option('forward', 
1579
 
                            help='show from oldest to newest'),
1580
 
                     'timezone', 
1581
 
                     Option('verbose', 
1582
 
                             short_name='v',
1583
 
                             help='show files changed in each revision'),
1584
 
                     'show-ids', 'revision',
1585
 
                     'log-format',
1586
 
                     Option('message',
1587
 
                            short_name='m',
1588
 
                            help='show revisions whose message matches this regexp',
1589
 
                            type=str),
1590
 
                     ]
 
1584
    takes_options = [
 
1585
            Option('forward',
 
1586
                   help='Show from oldest to newest.'),
 
1587
            'timezone',
 
1588
            Option('verbose',
 
1589
                   short_name='v',
 
1590
                   help='Show files changed in each revision.'),
 
1591
            'show-ids',
 
1592
            'revision',
 
1593
            'log-format',
 
1594
            Option('message',
 
1595
                   short_name='m',
 
1596
                   help='Show revisions whose message matches this '
 
1597
                        'regular expression.',
 
1598
                   type=str),
 
1599
            Option('limit',
 
1600
                   help='Limit the output to the first N revisions.',
 
1601
                   argname='N',
 
1602
                   type=_parse_limit),
 
1603
            ]
1591
1604
    encoding_type = 'replace'
1592
1605
 
1593
1606
    @display_command
1597
1610
            forward=False,
1598
1611
            revision=None,
1599
1612
            log_format=None,
1600
 
            message=None):
 
1613
            message=None,
 
1614
            limit=None):
1601
1615
        from bzrlib.log import show_log
1602
1616
        assert message is None or isinstance(message, basestring), \
1603
1617
            "invalid message argument %r" % message
1635
1649
                rev1 = None
1636
1650
                rev2 = None
1637
1651
            elif len(revision) == 1:
1638
 
                rev1 = rev2 = revision[0].in_history(b).revno
 
1652
                rev1 = rev2 = revision[0].in_history(b)
1639
1653
            elif len(revision) == 2:
1640
1654
                if revision[1].get_branch() != revision[0].get_branch():
1641
1655
                    # b is taken from revision[0].get_branch(), and
1644
1658
                    raise errors.BzrCommandError(
1645
1659
                        "Log doesn't accept two revisions in different"
1646
1660
                        " branches.")
1647
 
                if revision[0].spec is None:
1648
 
                    # missing begin-range means first revision
1649
 
                    rev1 = 1
1650
 
                else:
1651
 
                    rev1 = revision[0].in_history(b).revno
1652
 
 
1653
 
                if revision[1].spec is None:
1654
 
                    # missing end-range means last known revision
1655
 
                    rev2 = b.revno()
1656
 
                else:
1657
 
                    rev2 = revision[1].in_history(b).revno
 
1661
                rev1 = revision[0].in_history(b)
 
1662
                rev2 = revision[1].in_history(b)
1658
1663
            else:
1659
1664
                raise errors.BzrCommandError(
1660
1665
                    'bzr log --revision takes one or two values.')
1661
1666
 
1662
 
            # By this point, the revision numbers are converted to the +ve
1663
 
            # form if they were supplied in the -ve form, so we can do
1664
 
            # this comparison in relative safety
1665
 
            if rev1 > rev2:
1666
 
                (rev2, rev1) = (rev1, rev2)
1667
 
 
1668
1667
            if log_format is None:
1669
1668
                log_format = log.log_formatter_registry.get_default(b)
1670
1669
 
1678
1677
                     direction=direction,
1679
1678
                     start_revision=rev1,
1680
1679
                     end_revision=rev2,
1681
 
                     search=message)
 
1680
                     search=message,
 
1681
                     limit=limit)
1682
1682
        finally:
1683
1683
            b.unlock()
1684
1684
 
1719
1719
    _see_also = ['status', 'cat']
1720
1720
    takes_args = ['path?']
1721
1721
    # TODO: Take a revision or remote path and list that tree instead.
1722
 
    takes_options = ['verbose', 'revision',
1723
 
                     Option('non-recursive',
1724
 
                            help='don\'t recurse into sub-directories'),
1725
 
                     Option('from-root',
1726
 
                            help='Print all paths from the root of the branch.'),
1727
 
                     Option('unknown', help='Print unknown files'),
1728
 
                     Option('versioned', help='Print versioned files'),
1729
 
                     Option('ignored', help='Print ignored files'),
1730
 
 
1731
 
                     Option('null', help='Null separate the files'),
1732
 
                     'kind', 'show-ids'
1733
 
                    ]
 
1722
    takes_options = [
 
1723
            'verbose',
 
1724
            'revision',
 
1725
            Option('non-recursive',
 
1726
                   help='Don\'t recurse into subdirectories.'),
 
1727
            Option('from-root',
 
1728
                   help='Print paths relative to the root of the branch.'),
 
1729
            Option('unknown', help='Print unknown files.'),
 
1730
            Option('versioned', help='Print versioned files.'),
 
1731
            Option('ignored', help='Print ignored files.'),
 
1732
            Option('null',
 
1733
                   help='Write an ascii NUL (\\0) separator '
 
1734
                   'between files rather than a newline.'),
 
1735
            'kind',
 
1736
            'show-ids',
 
1737
            ]
1734
1738
    @display_command
1735
1739
    def run(self, revision=None, verbose=False, 
1736
1740
            non_recursive=False, from_root=False,
1854
1858
    _see_also = ['status', 'ignored']
1855
1859
    takes_args = ['name_pattern*']
1856
1860
    takes_options = [
1857
 
                     Option('old-default-rules',
1858
 
                            help='Out the ignore rules bzr < 0.9 always used.')
1859
 
                     ]
 
1861
        Option('old-default-rules',
 
1862
               help='Write out the ignore rules bzr < 0.9 always used.')
 
1863
        ]
1860
1864
    
1861
1865
    def run(self, name_pattern_list=None, old_default_rules=None):
1862
1866
        from bzrlib.atomicfile import AtomicFile
2098
2102
 
2099
2103
    _see_also = ['bugs', 'uncommit']
2100
2104
    takes_args = ['selected*']
2101
 
    takes_options = ['message', 'verbose', 
2102
 
                     Option('unchanged',
2103
 
                            help='commit even if nothing has changed'),
2104
 
                     Option('file', type=str, 
2105
 
                            short_name='F',
2106
 
                            argname='msgfile',
2107
 
                            help='file containing commit message'),
2108
 
                     Option('strict',
2109
 
                            help="refuse to commit if there are unknown "
2110
 
                            "files in the working tree."),
2111
 
                     ListOption('fixes', type=str,
2112
 
                                help="mark a bug as being fixed by this "
2113
 
                                     "revision."),
2114
 
                     Option('local',
2115
 
                            help="perform a local only commit in a bound "
2116
 
                                 "branch. Such commits are not pushed to "
2117
 
                                 "the master branch until a normal commit "
2118
 
                                 "is performed."
2119
 
                            ),
2120
 
                     ]
 
2105
    takes_options = [
 
2106
            'message',
 
2107
            'verbose',
 
2108
             Option('unchanged',
 
2109
                    help='Commit even if nothing has changed.'),
 
2110
             Option('file', type=str,
 
2111
                    short_name='F',
 
2112
                    argname='msgfile',
 
2113
                    help='Take commit message from this file.'),
 
2114
             Option('strict',
 
2115
                    help="Refuse to commit if there are unknown "
 
2116
                    "files in the working tree."),
 
2117
             ListOption('fixes', type=str,
 
2118
                    help="Mark a bug as being fixed by this revision."),
 
2119
             Option('local',
 
2120
                    help="Perform a local commit in a bound "
 
2121
                         "branch.  Local commits are not pushed to "
 
2122
                         "the master branch until a normal commit "
 
2123
                         "is performed."
 
2124
                    ),
 
2125
             ]
2121
2126
    aliases = ['ci', 'checkin']
2122
2127
 
2123
2128
    def _get_bug_fix_properties(self, fixes, branch):
2254
2259
    takes_options = [
2255
2260
                    RegistryOption('format',
2256
2261
                        help='Upgrade to a specific format.  See "bzr help'
2257
 
                             ' formats" for details',
 
2262
                             ' formats" for details.',
2258
2263
                        registry=bzrdir.format_registry,
2259
2264
                        converter=bzrdir.format_registry.make_bzrdir,
2260
2265
                        value_switches=True, title='Branch format'),
2275
2280
        bzr whoami 'Frank Chu <fchu@example.com>'
2276
2281
    """
2277
2282
    takes_options = [ Option('email',
2278
 
                             help='display email address only'),
 
2283
                             help='Display email address only.'),
2279
2284
                      Option('branch',
2280
 
                             help='set identity for the current branch instead of '
2281
 
                                  'globally'),
 
2285
                             help='Set identity for the current branch instead of '
 
2286
                                  'globally.'),
2282
2287
                    ]
2283
2288
    takes_args = ['name?']
2284
2289
    encoding_type = 'replace'
2336
2341
class cmd_selftest(Command):
2337
2342
    """Run internal test suite.
2338
2343
    
2339
 
    This creates temporary test directories in the working directory, but no
2340
 
    existing data is affected.  These directories are deleted if the tests
2341
 
    pass, or left behind to help in debugging if they fail and --keep-output
2342
 
    is specified.
2343
 
    
2344
2344
    If arguments are given, they are regular expressions that say which tests
2345
2345
    should run.  Tests matching any expression are run, and other tests are
2346
2346
    not run.
2403
2403
    takes_args = ['testspecs*']
2404
2404
    takes_options = ['verbose',
2405
2405
                     Option('one',
2406
 
                             help='stop when one test fails',
 
2406
                             help='Stop when one test fails.',
2407
2407
                             short_name='1',
2408
2408
                             ),
2409
2409
                     Option('keep-output',
2410
 
                            help='keep output directories when tests fail'),
 
2410
                            help='Keep output directories when tests fail.'),
2411
2411
                     Option('transport',
2412
2412
                            help='Use a different transport by default '
2413
2413
                                 'throughout the test suite.',
2414
2414
                            type=get_transport_type),
2415
 
                     Option('benchmark', help='run the bzr benchmarks.'),
 
2415
                     Option('benchmark',
 
2416
                            help='Run the benchmarks rather than selftests.'),
2416
2417
                     Option('lsprof-timed',
2417
 
                            help='generate lsprof output for benchmarked'
 
2418
                            help='Generate lsprof output for benchmarked'
2418
2419
                                 ' sections of code.'),
2419
2420
                     Option('cache-dir', type=str,
2420
 
                            help='a directory to cache intermediate'
2421
 
                                 ' benchmark steps'),
 
2421
                            help='Cache intermediate benchmark output in this '
 
2422
                                 'directory.'),
2422
2423
                     Option('clean-output',
2423
 
                            help='clean temporary tests directories'
2424
 
                                 ' without running tests'),
 
2424
                            help='Clean temporary tests directories'
 
2425
                                 ' without running tests.'),
2425
2426
                     Option('first',
2426
 
                            help='run all tests, but run specified tests first',
 
2427
                            help='Run all tests, but run specified tests first.',
2427
2428
                            short_name='f',
2428
2429
                            ),
2429
2430
                     Option('numbered-dirs',
2430
 
                            help='use numbered dirs for TestCaseInTempDir'),
 
2431
                            help='Use numbered dirs for TestCaseInTempDir.'),
2431
2432
                     Option('list-only',
2432
 
                            help='list the tests instead of running them'),
 
2433
                            help='List the tests instead of running them.'),
2433
2434
                     Option('randomize', type=str, argname="SEED",
2434
 
                            help='randomize the order of tests using the given'
2435
 
                                 ' seed or "now" for the current time'),
 
2435
                            help='Randomize the order of tests using the given'
 
2436
                                 ' seed or "now" for the current time.'),
2436
2437
                     Option('exclude', type=str, argname="PATTERN",
2437
2438
                            short_name='x',
2438
 
                            help='exclude tests that match this regular'
2439
 
                                 ' expression'),
 
2439
                            help='Exclude tests that match this regular'
 
2440
                                 ' expression.'),
2440
2441
                     ]
2441
2442
    encoding_type = 'replace'
2442
2443
 
2454
2455
            from bzrlib.tests import clean_selftest_output
2455
2456
            clean_selftest_output()
2456
2457
            return 0
 
2458
        if keep_output:
 
2459
            warning("notice: selftest --keep-output "
 
2460
                    "is no longer supported; "
 
2461
                    "test output is always removed")
2457
2462
 
2458
2463
        if numbered_dirs is None and sys.platform == 'win32':
2459
2464
            numbered_dirs = True
2482
2487
            result = selftest(verbose=verbose, 
2483
2488
                              pattern=pattern,
2484
2489
                              stop_on_failure=one, 
2485
 
                              keep_output=keep_output,
2486
2490
                              transport=transport,
2487
2491
                              test_suite_factory=test_suite_factory,
2488
2492
                              lsprof_timed=lsprof_timed,
2531
2535
    
2532
2536
    @display_command
2533
2537
    def run(self, branch, other):
2534
 
        from bzrlib.revision import MultipleRevisionSources
 
2538
        from bzrlib.revision import ensure_null, MultipleRevisionSources
2535
2539
        
2536
2540
        branch1 = Branch.open_containing(branch)[0]
2537
2541
        branch2 = Branch.open_containing(other)[0]
2538
2542
 
2539
 
        last1 = branch1.last_revision()
2540
 
        last2 = branch2.last_revision()
 
2543
        last1 = ensure_null(branch1.last_revision())
 
2544
        last2 = ensure_null(branch2.last_revision())
2541
2545
 
2542
 
        source = MultipleRevisionSources(branch1.repository, 
2543
 
                                         branch2.repository)
2544
 
        
2545
 
        base_rev_id = common_ancestor(last1, last2, source)
 
2546
        graph = branch1.repository.get_graph(branch2.repository)
 
2547
        base_rev_id = graph.find_unique_lca(last1, last2)
2546
2548
 
2547
2549
        print 'merge base is revision %s' % base_rev_id
2548
2550
 
2591
2593
    --force is given.
2592
2594
    """
2593
2595
 
2594
 
    _see_also = ['update', 'remerge']
 
2596
    _see_also = ['update', 'remerge', 'status-flags']
2595
2597
    takes_args = ['branch?']
2596
2598
    takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2597
2599
        Option('show-base', help="Show base revision text in "
2598
 
               "conflicts"),
 
2600
               "conflicts."),
2599
2601
        Option('uncommitted', help='Apply uncommitted changes'
2600
 
               ' from a working copy, instead of branch changes'),
 
2602
               ' from a working copy, instead of branch changes.'),
2601
2603
        Option('pull', help='If the destination is already'
2602
2604
                ' completely merged into the source, pull from the'
2603
 
                ' source rather than merging. When this happens,'
 
2605
                ' source rather than merging.  When this happens,'
2604
2606
                ' you do not need to commit the result.'),
2605
2607
        Option('directory',
2606
2608
            help='Branch to merge into, '
2607
 
                 'rather than the one containing the working directory',
 
2609
                 'rather than the one containing the working directory.',
2608
2610
            short_name='d',
2609
2611
            type=unicode,
2610
2612
            ),
2769
2771
        additional processing to reduce the size of conflict regions.
2770
2772
    """
2771
2773
    takes_args = ['file*']
2772
 
    takes_options = ['merge-type', 'reprocess',
2773
 
                     Option('show-base', help="Show base revision text in "
2774
 
                            "conflicts")]
 
2774
    takes_options = [
 
2775
            'merge-type',
 
2776
            'reprocess',
 
2777
            Option('show-base',
 
2778
                   help="Show base revision text in conflicts."),
 
2779
            ]
2775
2780
 
2776
2781
    def run(self, file_list=None, merge_type=None, show_base=False,
2777
2782
            reprocess=False):
2786
2791
                                             " merges.  Not cherrypicking or"
2787
2792
                                             " multi-merges.")
2788
2793
            repository = tree.branch.repository
2789
 
            base_revision = common_ancestor(parents[0],
2790
 
                                            parents[1], repository)
 
2794
            graph = repository.get_graph()
 
2795
            base_revision = graph.find_unique_lca(parents[0], parents[1])
2791
2796
            base_tree = repository.revision_tree(base_revision)
2792
2797
            other_tree = repository.revision_tree(parents[1])
2793
2798
            interesting_ids = None
2901
2906
    """
2902
2907
 
2903
2908
    _see_also = ['topics']
2904
 
    takes_options = [Option('long', 'show help on all commands')]
 
2909
    takes_options = [
 
2910
            Option('long', 'Show help on all commands.'),
 
2911
            ]
2905
2912
    takes_args = ['topic?']
2906
2913
    aliases = ['?', '--help', '-?', '-h']
2907
2914
    
2944
2951
 
2945
2952
class cmd_missing(Command):
2946
2953
    """Show unmerged/unpulled revisions between two branches.
2947
 
 
 
2954
    
2948
2955
    OTHER_BRANCH may be local or remote.
2949
2956
    """
2950
2957
 
2951
2958
    _see_also = ['merge', 'pull']
2952
2959
    takes_args = ['other_branch?']
2953
 
    takes_options = [Option('reverse', 'Reverse the order of revisions'),
2954
 
                     Option('mine-only', 
2955
 
                            'Display changes in the local branch only'),
2956
 
                     Option('theirs-only', 
2957
 
                            'Display changes in the remote branch only'), 
2958
 
                     'log-format',
2959
 
                     'show-ids',
2960
 
                     'verbose'
2961
 
                     ]
 
2960
    takes_options = [
 
2961
            Option('reverse', 'Reverse the order of revisions.'),
 
2962
            Option('mine-only',
 
2963
                   'Display changes in the local branch only.'),
 
2964
            Option('this' , 'Same as --mine-only.'),
 
2965
            Option('theirs-only',
 
2966
                   'Display changes in the remote branch only.'),
 
2967
            Option('other', 'Same as --theirs-only.'),
 
2968
            'log-format',
 
2969
            'show-ids',
 
2970
            'verbose'
 
2971
            ]
2962
2972
    encoding_type = 'replace'
2963
2973
 
2964
2974
    @display_command
2965
2975
    def run(self, other_branch=None, reverse=False, mine_only=False,
2966
2976
            theirs_only=False, log_format=None, long=False, short=False, line=False, 
2967
 
            show_ids=False, verbose=False):
2968
 
        from bzrlib.missing import find_unmerged, iter_log_data
 
2977
            show_ids=False, verbose=False, this=False, other=False):
 
2978
        from bzrlib.missing import find_unmerged, iter_log_revisions
2969
2979
        from bzrlib.log import log_formatter
 
2980
 
 
2981
        if this:
 
2982
          mine_only = this
 
2983
        if other:
 
2984
          theirs_only = other
 
2985
 
2970
2986
        local_branch = Branch.open_containing(u".")[0]
2971
2987
        parent = local_branch.get_parent()
2972
2988
        if other_branch is None:
2996
3012
                    remote_extra.reverse()
2997
3013
                if local_extra and not theirs_only:
2998
3014
                    print "You have %d extra revision(s):" % len(local_extra)
2999
 
                    for data in iter_log_data(local_extra, local_branch.repository,
3000
 
                                              verbose):
3001
 
                        lf.show(*data)
 
3015
                    for revision in iter_log_revisions(local_extra, 
 
3016
                                        local_branch.repository,
 
3017
                                        verbose):
 
3018
                        lf.log_revision(revision)
3002
3019
                    printed_local = True
3003
3020
                else:
3004
3021
                    printed_local = False
3006
3023
                    if printed_local is True:
3007
3024
                        print "\n\n"
3008
3025
                    print "You are missing %d revision(s):" % len(remote_extra)
3009
 
                    for data in iter_log_data(remote_extra, remote_branch.repository, 
3010
 
                                              verbose):
3011
 
                        lf.show(*data)
 
3026
                    for revision in iter_log_revisions(remote_extra, 
 
3027
                                        remote_branch.repository, 
 
3028
                                        verbose):
 
3029
                        lf.log_revision(revision)
3012
3030
                if not remote_extra and not local_extra:
3013
3031
                    status_code = 0
3014
3032
                    print "Branches are up to date."
3051
3069
 
3052
3070
class cmd_testament(Command):
3053
3071
    """Show testament (signing-form) of a revision."""
3054
 
    takes_options = ['revision',
3055
 
                     Option('long', help='Produce long-format testament'), 
3056
 
                     Option('strict', help='Produce a strict-format'
3057
 
                            ' testament')]
 
3072
    takes_options = [
 
3073
            'revision',
 
3074
            Option('long', help='Produce long-format testament.'),
 
3075
            Option('strict',
 
3076
                   help='Produce a strict-format testament.')]
3058
3077
    takes_args = ['branch?']
3059
3078
    @display_command
3060
3079
    def run(self, branch=u'.', revision=None, long=False, strict=False):
3093
3112
    #       with new uncommitted lines marked
3094
3113
    aliases = ['ann', 'blame', 'praise']
3095
3114
    takes_args = ['filename']
3096
 
    takes_options = [Option('all', help='show annotations on all lines'),
3097
 
                     Option('long', help='show date in annotations'),
 
3115
    takes_options = [Option('all', help='Show annotations on all lines.'),
 
3116
                     Option('long', help='Show commit date in annotations.'),
3098
3117
                     'revision',
3099
3118
                     'show-ids',
3100
3119
                     ]
 
3120
    encoding_type = 'exact'
3101
3121
 
3102
3122
    @display_command
3103
3123
    def run(self, filename, all=False, long=False, revision=None,
3114
3134
            else:
3115
3135
                revision_id = revision[0].in_history(branch).rev_id
3116
3136
            file_id = tree.path2id(relpath)
 
3137
            if file_id is None:
 
3138
                raise errors.NotVersionedError(filename)
3117
3139
            tree = branch.repository.revision_tree(revision_id)
3118
3140
            file_version = tree.inventory[file_id].revision
3119
 
            annotate_file(branch, file_version, file_id, long, all, sys.stdout,
 
3141
            annotate_file(branch, file_version, file_id, long, all, self.outf,
3120
3142
                          show_ids=show_ids)
3121
3143
        finally:
3122
3144
            branch.unlock()
3227
3249
    # information in shared branches as well.
3228
3250
    _see_also = ['commit']
3229
3251
    takes_options = ['verbose', 'revision',
3230
 
                    Option('dry-run', help='Don\'t actually make changes'),
 
3252
                    Option('dry-run', help='Don\'t actually make changes.'),
3231
3253
                    Option('force', help='Say yes to all questions.')]
3232
3254
    takes_args = ['location?']
3233
3255
    aliases = []
3337
3359
 
3338
3360
    takes_options = [
3339
3361
        Option('inet',
3340
 
               help='serve on stdin/out for use from inetd or sshd'),
 
3362
               help='Serve on stdin/out for use from inetd or sshd.'),
3341
3363
        Option('port',
3342
 
               help='listen for connections on nominated port of the form '
3343
 
                    '[hostname:]portnumber. Passing 0 as the port number will '
3344
 
                    'result in a dynamically allocated port. Default port is '
 
3364
               help='Listen for connections on nominated port of the form '
 
3365
                    '[hostname:]portnumber.  Passing 0 as the port number will '
 
3366
                    'result in a dynamically allocated port.  The default port is '
3345
3367
                    '4155.',
3346
3368
               type=str),
3347
3369
        Option('directory',
3348
 
               help='serve contents of directory',
 
3370
               help='Serve contents of this directory.',
3349
3371
               type=unicode),
3350
3372
        Option('allow-writes',
3351
 
               help='By default the server is a readonly server. Supplying '
 
3373
               help='By default the server is a readonly server.  Supplying '
3352
3374
                    '--allow-writes enables write access to the contents of '
3353
 
                    'the served directory and below. '
 
3375
                    'the served directory and below.'
3354
3376
                ),
3355
3377
        ]
3356
3378
 
3416
3438
 
3417
3439
    _see_also = ['split']
3418
3440
    takes_args = ['tree']
3419
 
    takes_options = [Option('reference', 'join by reference')]
 
3441
    takes_options = [
 
3442
            Option('reference', help='Join by reference.'),
 
3443
            ]
3420
3444
    hidden = True
3421
3445
 
3422
3446
    def run(self, tree, reference=False):
3497
3521
    takes_options = [
3498
3522
        RegistryOption.from_kwargs('patch-type',
3499
3523
            'The type of patch to include in the directive',
3500
 
            title='Patch type', value_switches=True, enum_switch=False,
3501
 
            bundle='Bazaar revision bundle (default)',
3502
 
            diff='Normal unified diff',
3503
 
            plain='No patch, just directive'),
3504
 
        Option('sign', help='GPG-sign the directive'), 'revision',
 
3524
            title='Patch type',
 
3525
            value_switches=True,
 
3526
            enum_switch=False,
 
3527
            bundle='Bazaar revision bundle (default).',
 
3528
            diff='Normal unified diff.',
 
3529
            plain='No patch, just directive.'),
 
3530
        Option('sign', help='GPG-sign the directive.'), 'revision',
3505
3531
        Option('mail-to', type=str,
3506
 
            help='Instead of printing the directive, email to this address'),
 
3532
            help='Instead of printing the directive, email to this address.'),
3507
3533
        Option('message', type=str, short_name='m',
3508
 
            help='Message to use when committing this merge')
 
3534
            help='Message to use when committing this merge.')
3509
3535
        ]
3510
3536
 
 
3537
    encoding_type = 'exact'
 
3538
 
3511
3539
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3512
3540
            sign=False, revision=None, mail_to=None, message=None):
 
3541
        from bzrlib.revision import ensure_null, NULL_REVISION
3513
3542
        if patch_type == 'plain':
3514
3543
            patch_type = None
3515
3544
        branch = Branch.open('.')
3540
3569
                revision_id = revision[0].in_history(branch).rev_id
3541
3570
        else:
3542
3571
            revision_id = branch.last_revision()
 
3572
        revision_id = ensure_null(revision_id)
 
3573
        if revision_id == NULL_REVISION:
 
3574
            raise errors.BzrCommandError('No revisions to bundle.')
3543
3575
        directive = merge_directive.MergeDirective.from_objects(
3544
3576
            branch.repository, revision_id, time.time(),
3545
3577
            osutils.local_time_offset(), submit_branch,
3552
3584
                self.outf.writelines(directive.to_lines())
3553
3585
        else:
3554
3586
            message = directive.to_email(mail_to, branch, sign)
3555
 
            s = smtplib.SMTP()
3556
 
            server = branch.get_config().get_user_option('smtp_server')
3557
 
            if not server:
3558
 
                server = 'localhost'
3559
 
            s.connect(server)
3560
 
            s.sendmail(message['From'], message['To'], message.as_string())
 
3587
            s = SMTPConnection(branch.get_config())
 
3588
            s.send_email(message)
3561
3589
 
3562
3590
 
3563
3591
class cmd_tag(Command):
3586
3614
            type=unicode,
3587
3615
            ),
3588
3616
        Option('force',
3589
 
            help='Replace existing tags',
 
3617
            help='Replace existing tags.',
3590
3618
            ),
3591
3619
        'revision',
3592
3620
        ]
3629
3657
    _see_also = ['tag']
3630
3658
    takes_options = [
3631
3659
        Option('directory',
3632
 
            help='Branch whose tags should be displayed',
 
3660
            help='Branch whose tags should be displayed.',
3633
3661
            short_name='d',
3634
3662
            type=unicode,
3635
3663
            ),
3741
3769
    return conflicts
3742
3770
 
3743
3771
 
 
3772
def _create_prefix(cur_transport):
 
3773
    needed = [cur_transport]
 
3774
    # Recurse upwards until we can create a directory successfully
 
3775
    while True:
 
3776
        new_transport = cur_transport.clone('..')
 
3777
        if new_transport.base == cur_transport.base:
 
3778
            raise errors.BzrCommandError("Failed to create path"
 
3779
                                         " prefix for %s."
 
3780
                                         % location)
 
3781
        try:
 
3782
            new_transport.mkdir('.')
 
3783
        except errors.NoSuchFile:
 
3784
            needed.append(new_transport)
 
3785
            cur_transport = new_transport
 
3786
        else:
 
3787
            break
 
3788
 
 
3789
    # Now we only need to create child directories
 
3790
    while needed:
 
3791
        cur_transport = needed.pop()
 
3792
        cur_transport.ensure_base()
 
3793
 
3744
3794
# Compatibility
3745
3795
merge = _merge_helper
3746
3796
 
3754
3804
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
3755
3805
from bzrlib.bundle.commands import cmd_bundle_revisions
3756
3806
from bzrlib.sign_my_commits import cmd_sign_my_commits
3757
 
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
 
3807
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
3758
3808
        cmd_weave_plan_merge, cmd_weave_merge_text