~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-06-28 07:08:27 UTC
  • mfrom: (2553.1.3 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20070628070827-h5s313dg5tnag9vj
(robertc) Show the names of commit hooks during commit.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    osutils,
45
45
    registry,
46
46
    repository,
47
 
    revision as _mod_revision,
48
47
    revisionspec,
49
48
    symbol_versioning,
50
49
    transport,
53
52
    urlutils,
54
53
    )
55
54
from bzrlib.branch import Branch
 
55
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
56
56
from bzrlib.conflicts import ConflictList
57
57
from bzrlib.revisionspec import RevisionSpec
58
58
from bzrlib.smtp_connection import SMTPConnection
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
 
158
175
    If no arguments are specified, the status of the entire working
159
176
    directory is shown.  Otherwise, only the status of the specified
160
177
    files or directories is reported.  If a directory is given, status
168
185
    
169
186
    takes_args = ['file*']
170
187
    takes_options = ['show-ids', 'revision',
171
 
                     Option('short', help='Give short SVN-style status lines.'),
172
 
                     Option('versioned', help='Only show versioned files.')]
 
188
                     Option('short', help='Give short SVN-style status lines'),
 
189
                     Option('versioned', help='Only show versioned files')]
173
190
    aliases = ['st', 'stat']
174
191
 
175
192
    encoding_type = 'replace'
176
 
    _see_also = ['diff', 'revert', 'status-flags']
 
193
    _see_also = ['diff', 'revert']
177
194
    
178
195
    @display_command
179
196
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
338
355
    into a subdirectory of this one.
339
356
    """
340
357
    takes_args = ['file*']
341
 
    takes_options = [
342
 
        Option('no-recurse',
343
 
               help="Don't recursively add the contents of directories."),
344
 
        Option('dry-run',
345
 
               help="Show what would be done, but don't actually do anything."),
346
 
        'verbose',
347
 
        Option('file-ids-from',
348
 
               type=unicode,
349
 
               help='Lookup file ids from this tree.'),
350
 
        ]
 
358
    takes_options = ['no-recurse', 'dry-run', 'verbose',
 
359
                     Option('file-ids-from', type=unicode,
 
360
                            help='Lookup file ids from here')]
351
361
    encoding_type = 'replace'
352
362
    _see_also = ['remove']
353
363
 
374
384
        if base_tree:
375
385
            base_tree.lock_read()
376
386
        try:
377
 
            file_list = self._maybe_expand_globs(file_list)
378
 
            if file_list:
379
 
                tree = WorkingTree.open_containing(file_list[0])[0]
380
 
            else:
381
 
                tree = WorkingTree.open_containing(u'.')[0]
382
 
            added, ignored = tree.smart_add(file_list, not
383
 
                no_recurse, action=action, save=not dry_run)
 
387
            added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
 
388
                action=action, save=not dry_run)
384
389
        finally:
385
390
            if base_tree is not None:
386
391
                base_tree.unlock()
443
448
 
444
449
    hidden = True
445
450
    _see_also = ['ls']
446
 
    takes_options = [
447
 
        'revision',
448
 
        'show-ids',
449
 
        Option('kind',
450
 
               help='List entries of a particular kind: file, directory, symlink.',
451
 
               type=unicode),
452
 
        ]
 
451
    takes_options = ['revision', 'show-ids', 'kind']
453
452
    takes_args = ['file*']
454
453
 
455
454
    @display_command
456
455
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
457
456
        if kind and kind not in ['file', 'directory', 'symlink']:
458
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
457
            raise errors.BzrCommandError('invalid kind specified')
459
458
 
460
459
        work_tree, file_list = tree_files(file_list)
461
460
        work_tree.lock_read()
519
518
    """
520
519
 
521
520
    takes_args = ['names*']
522
 
    takes_options = [Option("after", help="Move only the bzr identifier"
523
 
        " of the file, because the file has already been moved."),
524
 
        ]
 
521
    takes_options = [Option("after", help="move only the bzr identifier"
 
522
        " of the file (file has already been moved). Use this flag if"
 
523
        " bzr is not able to detect this itself.")]
525
524
    aliases = ['move', 'rename']
526
525
    encoding_type = 'replace'
527
526
 
566
565
    location can be accessed.
567
566
    """
568
567
 
569
 
    _see_also = ['push', 'update', 'status-flags']
 
568
    _see_also = ['push', 'update']
570
569
    takes_options = ['remember', 'overwrite', 'revision', 'verbose',
571
570
        Option('directory',
572
 
            help='Branch to pull into, '
573
 
                 'rather than the one containing the working directory.',
 
571
            help='branch to pull into, '
 
572
                 'rather than the one containing the working directory',
574
573
            short_name='d',
575
574
            type=unicode,
576
575
            ),
594
593
            tree_to = None
595
594
            branch_to = Branch.open_containing(directory)[0]
596
595
 
 
596
        reader = None
597
597
        if location is not None:
598
 
            mergeable, location_transport = _get_bundle_helper(location)
 
598
            try:
 
599
                mergeable = bundle.read_mergeable_from_url(
 
600
                    location)
 
601
            except errors.NotABundle:
 
602
                pass # Continue on considering this url a Branch
599
603
 
600
604
        stored_loc = branch_to.get_parent()
601
605
        if location is None:
607
611
                        self.outf.encoding)
608
612
                self.outf.write("Using saved location: %s\n" % display_url)
609
613
                location = stored_loc
610
 
                location_transport = transport.get_transport(location)
611
614
 
612
615
        if mergeable is not None:
613
616
            if revision is not None:
614
617
                raise errors.BzrCommandError(
615
618
                    'Cannot use -r with merge directives or bundles')
616
 
            mergeable.install_revisions(branch_to.repository)
617
 
            base_revision_id, revision_id, verified = \
618
 
                mergeable.get_merge_request(branch_to.repository)
 
619
            revision_id = mergeable.install_revisions(branch_to.repository)
619
620
            branch_from = branch_to
620
621
        else:
621
 
            branch_from = Branch.open_from_transport(location_transport)
 
622
            branch_from = Branch.open(location)
622
623
 
623
624
            if branch_to.get_parent() is None or remember:
624
625
                branch_to.set_parent(branch_from.base)
630
631
                raise errors.BzrCommandError(
631
632
                    'bzr pull --revision takes one value.')
632
633
 
633
 
        if verbose:
634
 
            old_rh = branch_to.revision_history()
 
634
        old_rh = branch_to.revision_history()
635
635
        if tree_to is not None:
636
636
            result = tree_to.pull(branch_from, overwrite, revision_id,
637
637
                delta._ChangeReporter(unversioned_filter=tree_to.is_ignored))
676
676
    takes_options = ['remember', 'overwrite', 'verbose',
677
677
        Option('create-prefix',
678
678
               help='Create the path leading up to the branch '
679
 
                    'if it does not already exist.'),
 
679
                    'if it does not already exist'),
680
680
        Option('directory',
681
 
            help='Branch to push from, '
682
 
                 'rather than the one containing the working directory.',
 
681
            help='branch to push from, '
 
682
                 'rather than the one containing the working directory',
683
683
            short_name='d',
684
684
            type=unicode,
685
685
            ),
686
686
        Option('use-existing-dir',
687
687
               help='By default push will fail if the target'
688
688
                    ' directory exists, but does not already'
689
 
                    ' have a control directory.  This flag will'
 
689
                    ' have a control directory. This flag will'
690
690
                    ' allow push to proceed.'),
691
691
        ]
692
692
    takes_args = ['location?']
733
733
                # Found a branch, so we must have found a repository
734
734
                repository_to = br_to.repository
735
735
        push_result = None
736
 
        if verbose:
737
 
            old_rh = []
 
736
        old_rh = []
738
737
        if dir_to is None:
739
738
            # The destination doesn't exist; create it.
740
739
            # XXX: Refactor the create_prefix/no_create_prefix code into a
754
753
                        "\nYou may supply --create-prefix to create all"
755
754
                        " leading parent directories."
756
755
                        % location)
 
756
 
757
757
                _create_prefix(to_transport)
758
758
 
759
759
            # Now the target directory exists, but doesn't have a .bzr
790
790
            # we don't need to successfully push because of possible divergence.
791
791
            if br_from.get_push_location() is None or remember:
792
792
                br_from.set_push_location(br_to.base)
793
 
            if verbose:
794
 
                old_rh = br_to.revision_history()
 
793
            old_rh = br_to.revision_history()
795
794
            try:
796
795
                try:
797
796
                    tree_to = dir_to.open_workingtree()
881
880
                                             % to_location)
882
881
            try:
883
882
                # preserve whatever source format we have.
884
 
                dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
885
 
                                            possible_transports=[to_transport])
 
883
                dir = br_from.bzrdir.sprout(to_transport.base, revision_id)
886
884
                branch = dir.open_branch()
887
885
            except errors.NoSuchRevision:
888
886
                to_transport.delete_tree('.')
921
919
    takes_args = ['branch_location?', 'to_location?']
922
920
    takes_options = ['revision',
923
921
                     Option('lightweight',
924
 
                            help="Perform a lightweight checkout.  Lightweight "
 
922
                            help="perform a lightweight checkout. Lightweight "
925
923
                                 "checkouts depend on access to the branch for "
926
 
                                 "every operation.  Normal checkouts can perform "
 
924
                                 "every operation. Normal checkouts can perform "
927
925
                                 "common operations like diff and status without "
928
926
                                 "such access, and also support local commits."
929
927
                            ),
942
940
            to_location = branch_location
943
941
        source = Branch.open(branch_location)
944
942
        if len(revision) == 1 and revision[0] is not None:
945
 
            revision_id = _mod_revision.ensure_null(
946
 
                revision[0].in_history(source)[1])
 
943
            revision_id = revision[0].in_history(source)[1]
947
944
        else:
948
945
            revision_id = None
949
946
        if to_location is None:
956
953
            try:
957
954
                source.bzrdir.open_workingtree()
958
955
            except errors.NoWorkingTree:
959
 
                source.bzrdir.create_workingtree(revision_id)
 
956
                source.bzrdir.create_workingtree()
960
957
                return
961
958
        try:
962
959
            os.mkdir(to_location)
1012
1009
    'bzr revert' instead of 'bzr commit' after the update.
1013
1010
    """
1014
1011
 
1015
 
    _see_also = ['pull', 'working-trees', 'status-flags']
 
1012
    _see_also = ['pull', 'working-trees']
1016
1013
    takes_args = ['dir?']
1017
1014
    aliases = ['up']
1018
1015
 
1025
1022
            tree.lock_tree_write()
1026
1023
        try:
1027
1024
            existing_pending_merges = tree.get_parent_ids()[1:]
1028
 
            last_rev = _mod_revision.ensure_null(tree.last_revision())
1029
 
            if last_rev == _mod_revision.ensure_null(
1030
 
                tree.branch.last_revision()):
 
1025
            last_rev = tree.last_revision()
 
1026
            if last_rev == tree.branch.last_revision():
1031
1027
                # may be up to date, check master too.
1032
1028
                master = tree.branch.get_master_branch()
1033
 
                if master is None or last_rev == _mod_revision.ensure_null(
1034
 
                    master.last_revision()):
 
1029
                if master is None or last_rev == master.last_revision():
1035
1030
                    revno = tree.branch.revision_id_to_revno(last_rev)
1036
1031
                    note("Tree is up to date at revision %d." % (revno,))
1037
1032
                    return 0
1038
 
            conflicts = tree.update(delta._ChangeReporter(
1039
 
                                        unversioned_filter=tree.is_ignored))
1040
 
            revno = tree.branch.revision_id_to_revno(
1041
 
                _mod_revision.ensure_null(tree.last_revision()))
 
1033
            conflicts = tree.update()
 
1034
            revno = tree.branch.revision_id_to_revno(tree.last_revision())
1042
1035
            note('Updated to revision %d.' % (revno,))
1043
1036
            if tree.get_parent_ids()[1:] != existing_pending_merges:
1044
1037
                note('Your local commits will now show as pending merges with '
1084
1077
    """
1085
1078
    takes_args = ['file*']
1086
1079
    takes_options = ['verbose',
1087
 
        Option('new', help='Remove newly-added files.'),
 
1080
        Option('new', help='remove newly-added files'),
1088
1081
        RegistryOption.from_kwargs('file-deletion-strategy',
1089
1082
            'The file deletion mode to be used',
1090
1083
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1258
1251
    takes_options = [
1259
1252
        Option('create-prefix',
1260
1253
               help='Create the path leading up to the branch '
1261
 
                    'if it does not already exist.'),
 
1254
                    'if it does not already exist'),
1262
1255
         RegistryOption('format',
1263
1256
                help='Specify a format for this branch. '
1264
1257
                'See "help formats".',
1297
1290
            _create_prefix(to_transport)
1298
1291
 
1299
1292
        try:
1300
 
            existing_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
1293
            existing_bzrdir = bzrdir.BzrDir.open(location)
1301
1294
        except errors.NotBranchError:
1302
1295
            # really a NotBzrDir error...
1303
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
1304
 
            branch = create_branch(to_transport.base, format=format,
1305
 
                                   possible_transports=[to_transport])
 
1296
            branch = bzrdir.BzrDir.create_branch_convenience(to_transport.base,
 
1297
                                                             format=format)
1306
1298
        else:
1307
1299
            from bzrlib.transport.local import LocalTransport
1308
1300
            if existing_bzrdir.has_branch():
1344
1336
    takes_args = ["location"]
1345
1337
    takes_options = [RegistryOption('format',
1346
1338
                            help='Specify a format for this repository. See'
1347
 
                                 ' "bzr help formats" for details.',
 
1339
                                 ' "bzr help formats" for details',
1348
1340
                            registry=bzrdir.format_registry,
1349
1341
                            converter=bzrdir.format_registry.make_bzrdir,
1350
1342
                            value_switches=True, title='Repository format'),
1351
1343
                     Option('no-trees',
1352
1344
                             help='Branches in the repository will default to'
1353
 
                                  ' not having a working tree.'),
 
1345
                                  ' not having a working tree'),
1354
1346
                    ]
1355
1347
    aliases = ["init-repo"]
1356
1348
 
1405
1397
 
1406
1398
    _see_also = ['status']
1407
1399
    takes_args = ['file*']
1408
 
    takes_options = [
1409
 
        Option('diff-options', type=str,
1410
 
               help='Pass these options to the external diff program.'),
 
1400
    takes_options = ['revision', 'diff-options',
1411
1401
        Option('prefix', type=str,
1412
1402
               short_name='p',
1413
1403
               help='Set prefixes to added to old and new filenames, as '
1414
 
                    'two values separated by a colon. (eg "old/:new/").'),
1415
 
        'revision',
 
1404
                    'two values separated by a colon. (eg "old/:new/")'),
1416
1405
        ]
1417
1406
    aliases = ['di', 'dif']
1418
1407
    encoding_type = 'exact'
1603
1592
    # TODO: Make --revision support uuid: and hash: [future tag:] notation.
1604
1593
 
1605
1594
    takes_args = ['location?']
1606
 
    takes_options = [
1607
 
            Option('forward',
1608
 
                   help='Show from oldest to newest.'),
1609
 
            Option('timezone',
1610
 
                   type=str,
1611
 
                   help='Display timezone as local, original, or utc.'),
1612
 
            Option('verbose',
1613
 
                   short_name='v',
1614
 
                   help='Show files changed in each revision.'),
1615
 
            'show-ids',
1616
 
            'revision',
1617
 
            'log-format',
1618
 
            Option('message',
1619
 
                   short_name='m',
1620
 
                   help='Show revisions whose message matches this '
1621
 
                        'regular expression.',
1622
 
                   type=str),
1623
 
            Option('limit',
1624
 
                   help='Limit the output to the first N revisions.',
1625
 
                   argname='N',
1626
 
                   type=_parse_limit),
1627
 
            ]
 
1595
    takes_options = [Option('forward', 
 
1596
                            help='show from oldest to newest'),
 
1597
                     'timezone', 
 
1598
                     Option('verbose', 
 
1599
                             short_name='v',
 
1600
                             help='show files changed in each revision'),
 
1601
                     'show-ids', 'revision',
 
1602
                     'log-format',
 
1603
                     Option('message',
 
1604
                            short_name='m',
 
1605
                            help='show revisions whose message matches this regexp',
 
1606
                            type=str),
 
1607
                     Option('limit', 
 
1608
                            help='limit the output to the first N revisions',
 
1609
                            type=_parse_limit),
 
1610
                     ]
1628
1611
    encoding_type = 'replace'
1629
1612
 
1630
1613
    @display_command
1673
1656
                rev1 = None
1674
1657
                rev2 = None
1675
1658
            elif len(revision) == 1:
1676
 
                rev1 = rev2 = revision[0].in_history(b)
 
1659
                rev1 = rev2 = revision[0].in_history(b).revno
1677
1660
            elif len(revision) == 2:
1678
1661
                if revision[1].get_branch() != revision[0].get_branch():
1679
1662
                    # b is taken from revision[0].get_branch(), and
1682
1665
                    raise errors.BzrCommandError(
1683
1666
                        "Log doesn't accept two revisions in different"
1684
1667
                        " branches.")
1685
 
                rev1 = revision[0].in_history(b)
1686
 
                rev2 = revision[1].in_history(b)
 
1668
                if revision[0].spec is None:
 
1669
                    # missing begin-range means first revision
 
1670
                    rev1 = 1
 
1671
                else:
 
1672
                    rev1 = revision[0].in_history(b).revno
 
1673
 
 
1674
                if revision[1].spec is None:
 
1675
                    # missing end-range means last known revision
 
1676
                    rev2 = b.revno()
 
1677
                else:
 
1678
                    rev2 = revision[1].in_history(b).revno
1687
1679
            else:
1688
1680
                raise errors.BzrCommandError(
1689
1681
                    'bzr log --revision takes one or two values.')
1690
1682
 
 
1683
            # By this point, the revision numbers are converted to the +ve
 
1684
            # form if they were supplied in the -ve form, so we can do
 
1685
            # this comparison in relative safety
 
1686
            if rev1 > rev2:
 
1687
                (rev2, rev1) = (rev1, rev2)
 
1688
 
1691
1689
            if log_format is None:
1692
1690
                log_format = log.log_formatter_registry.get_default(b)
1693
1691
 
1743
1741
    _see_also = ['status', 'cat']
1744
1742
    takes_args = ['path?']
1745
1743
    # TODO: Take a revision or remote path and list that tree instead.
1746
 
    takes_options = [
1747
 
            'verbose',
1748
 
            'revision',
1749
 
            Option('non-recursive',
1750
 
                   help='Don\'t recurse into subdirectories.'),
1751
 
            Option('from-root',
1752
 
                   help='Print paths relative to the root of the branch.'),
1753
 
            Option('unknown', help='Print unknown files.'),
1754
 
            Option('versioned', help='Print versioned files.'),
1755
 
            Option('ignored', help='Print ignored files.'),
1756
 
            Option('null',
1757
 
                   help='Write an ascii NUL (\\0) separator '
1758
 
                   'between files rather than a newline.'),
1759
 
            Option('kind',
1760
 
                   help='List entries of a particular kind: file, directory, symlink.',
1761
 
                   type=unicode),
1762
 
            'show-ids',
1763
 
            ]
 
1744
    takes_options = ['verbose', 'revision',
 
1745
                     Option('non-recursive',
 
1746
                            help='don\'t recurse into sub-directories'),
 
1747
                     Option('from-root',
 
1748
                            help='Print all paths from the root of the branch.'),
 
1749
                     Option('unknown', help='Print unknown files'),
 
1750
                     Option('versioned', help='Print versioned files'),
 
1751
                     Option('ignored', help='Print ignored files'),
 
1752
 
 
1753
                     Option('null', help='Null separate the files'),
 
1754
                     'kind', 'show-ids'
 
1755
                    ]
1764
1756
    @display_command
1765
 
    def run(self, revision=None, verbose=False,
 
1757
    def run(self, revision=None, verbose=False, 
1766
1758
            non_recursive=False, from_root=False,
1767
1759
            unknown=False, versioned=False, ignored=False,
1768
1760
            null=False, kind=None, show_ids=False, path=None):
1884
1876
    _see_also = ['status', 'ignored']
1885
1877
    takes_args = ['name_pattern*']
1886
1878
    takes_options = [
1887
 
        Option('old-default-rules',
1888
 
               help='Write out the ignore rules bzr < 0.9 always used.')
1889
 
        ]
 
1879
                     Option('old-default-rules',
 
1880
                            help='Out the ignore rules bzr < 0.9 always used.')
 
1881
                     ]
1890
1882
    
1891
1883
    def run(self, name_pattern_list=None, old_default_rules=None):
1892
1884
        from bzrlib.atomicfile import AtomicFile
2001
1993
         zip                          .zip
2002
1994
    """
2003
1995
    takes_args = ['dest', 'branch?']
2004
 
    takes_options = [
2005
 
        Option('format',
2006
 
               help="Type of file to export to.",
2007
 
               type=unicode),
2008
 
        'revision',
2009
 
        Option('root',
2010
 
               type=str,
2011
 
               help="Name of the root directory inside the exported file."),
2012
 
        ]
 
1996
    takes_options = ['revision', 'format', 'root']
2013
1997
    def run(self, dest, branch=None, revision=None, format=None, root=None):
2014
1998
        from bzrlib.export import export
2015
1999
 
2043
2027
    """
2044
2028
 
2045
2029
    _see_also = ['ls']
2046
 
    takes_options = [
2047
 
        Option('name-from-revision', help='The path name in the old tree.'),
2048
 
        'revision',
2049
 
        ]
 
2030
    takes_options = ['revision', 'name-from-revision']
2050
2031
    takes_args = ['filename']
2051
2032
    encoding_type = 'exact'
2052
2033
 
2139
2120
 
2140
2121
    _see_also = ['bugs', 'uncommit']
2141
2122
    takes_args = ['selected*']
2142
 
    takes_options = [
2143
 
            Option('message', type=unicode,
2144
 
                   short_name='m',
2145
 
                   help="Description of the new revision."),
2146
 
            'verbose',
2147
 
             Option('unchanged',
2148
 
                    help='Commit even if nothing has changed.'),
2149
 
             Option('file', type=str,
2150
 
                    short_name='F',
2151
 
                    argname='msgfile',
2152
 
                    help='Take commit message from this file.'),
2153
 
             Option('strict',
2154
 
                    help="Refuse to commit if there are unknown "
2155
 
                    "files in the working tree."),
2156
 
             ListOption('fixes', type=str,
2157
 
                    help="Mark a bug as being fixed by this revision."),
2158
 
             Option('local',
2159
 
                    help="Perform a local commit in a bound "
2160
 
                         "branch.  Local commits are not pushed to "
2161
 
                         "the master branch until a normal commit "
2162
 
                         "is performed."
2163
 
                    ),
2164
 
             ]
 
2123
    takes_options = ['message', 'verbose', 
 
2124
                     Option('unchanged',
 
2125
                            help='commit even if nothing has changed'),
 
2126
                     Option('file', type=str, 
 
2127
                            short_name='F',
 
2128
                            argname='msgfile',
 
2129
                            help='file containing commit message'),
 
2130
                     Option('strict',
 
2131
                            help="refuse to commit if there are unknown "
 
2132
                            "files in the working tree."),
 
2133
                     ListOption('fixes', type=str,
 
2134
                                help="mark a bug as being fixed by this "
 
2135
                                     "revision."),
 
2136
                     Option('local',
 
2137
                            help="perform a local only commit in a bound "
 
2138
                                 "branch. Such commits are not pushed to "
 
2139
                                 "the master branch until a normal commit "
 
2140
                                 "is performed."
 
2141
                            ),
 
2142
                     ]
2165
2143
    aliases = ['ci', 'checkin']
2166
2144
 
2167
2145
    def _get_bug_fix_properties(self, fixes, branch):
2298
2276
    takes_options = [
2299
2277
                    RegistryOption('format',
2300
2278
                        help='Upgrade to a specific format.  See "bzr help'
2301
 
                             ' formats" for details.',
 
2279
                             ' formats" for details',
2302
2280
                        registry=bzrdir.format_registry,
2303
2281
                        converter=bzrdir.format_registry.make_bzrdir,
2304
2282
                        value_switches=True, title='Branch format'),
2319
2297
        bzr whoami 'Frank Chu <fchu@example.com>'
2320
2298
    """
2321
2299
    takes_options = [ Option('email',
2322
 
                             help='Display email address only.'),
 
2300
                             help='display email address only'),
2323
2301
                      Option('branch',
2324
 
                             help='Set identity for the current branch instead of '
2325
 
                                  'globally.'),
 
2302
                             help='set identity for the current branch instead of '
 
2303
                                  'globally'),
2326
2304
                    ]
2327
2305
    takes_args = ['name?']
2328
2306
    encoding_type = 'replace'
2408
2386
    modified by plugins will not be tested, and tests provided by plugins will
2409
2387
    not be run.
2410
2388
 
2411
 
    Tests that need working space on disk use a common temporary directory, 
2412
 
    typically inside $TMPDIR or /tmp.
2413
 
 
2414
2389
    examples::
2415
2390
        bzr selftest ignore
2416
2391
            run only tests relating to 'ignore'
2417
2392
        bzr --no-plugins selftest -v
2418
2393
            disable plugins and list tests as they're run
 
2394
 
 
2395
    For each test, that needs actual disk access, bzr create their own
 
2396
    subdirectory in the temporary testing directory (testXXXX.tmp).
 
2397
    By default the name of such subdirectory is based on the name of the test.
 
2398
    If option '--numbered-dirs' is given, bzr will use sequent numbers
 
2399
    of running tests to create such subdirectories. This is default behavior
 
2400
    on Windows because of path length limitation.
2419
2401
    """
2420
2402
    # NB: this is used from the class without creating an instance, which is
2421
2403
    # why it does not have a self parameter.
2438
2420
    takes_args = ['testspecs*']
2439
2421
    takes_options = ['verbose',
2440
2422
                     Option('one',
2441
 
                             help='Stop when one test fails.',
 
2423
                             help='stop when one test fails',
2442
2424
                             short_name='1',
2443
2425
                             ),
 
2426
                     Option('keep-output',
 
2427
                            help='keep output directories when tests fail'),
2444
2428
                     Option('transport',
2445
2429
                            help='Use a different transport by default '
2446
2430
                                 'throughout the test suite.',
2447
2431
                            type=get_transport_type),
2448
 
                     Option('benchmark',
2449
 
                            help='Run the benchmarks rather than selftests.'),
 
2432
                     Option('benchmark', help='run the bzr benchmarks.'),
2450
2433
                     Option('lsprof-timed',
2451
 
                            help='Generate lsprof output for benchmarked'
 
2434
                            help='generate lsprof output for benchmarked'
2452
2435
                                 ' sections of code.'),
2453
2436
                     Option('cache-dir', type=str,
2454
 
                            help='Cache intermediate benchmark output in this '
2455
 
                                 'directory.'),
 
2437
                            help='a directory to cache intermediate'
 
2438
                                 ' benchmark steps'),
 
2439
                     Option('clean-output',
 
2440
                            help='clean temporary tests directories'
 
2441
                                 ' without running tests'),
2456
2442
                     Option('first',
2457
 
                            help='Run all tests, but run specified tests first.',
 
2443
                            help='run all tests, but run specified tests first',
2458
2444
                            short_name='f',
2459
2445
                            ),
 
2446
                     Option('numbered-dirs',
 
2447
                            help='use numbered dirs for TestCaseInTempDir'),
2460
2448
                     Option('list-only',
2461
 
                            help='List the tests instead of running them.'),
 
2449
                            help='list the tests instead of running them'),
2462
2450
                     Option('randomize', type=str, argname="SEED",
2463
 
                            help='Randomize the order of tests using the given'
2464
 
                                 ' seed or "now" for the current time.'),
 
2451
                            help='randomize the order of tests using the given'
 
2452
                                 ' seed or "now" for the current time'),
2465
2453
                     Option('exclude', type=str, argname="PATTERN",
2466
2454
                            short_name='x',
2467
 
                            help='Exclude tests that match this regular'
2468
 
                                 ' expression.'),
 
2455
                            help='exclude tests that match this regular'
 
2456
                                 ' expression'),
2469
2457
                     ]
2470
2458
    encoding_type = 'replace'
2471
2459
 
2472
2460
    def run(self, testspecs_list=None, verbose=None, one=False,
2473
 
            transport=None, benchmark=None,
2474
 
            lsprof_timed=None, cache_dir=None,
2475
 
            first=False, list_only=False,
 
2461
            keep_output=False, transport=None, benchmark=None,
 
2462
            lsprof_timed=None, cache_dir=None, clean_output=False,
 
2463
            first=False, numbered_dirs=None, list_only=False,
2476
2464
            randomize=None, exclude=None):
2477
2465
        import bzrlib.ui
2478
2466
        from bzrlib.tests import selftest
2479
2467
        import bzrlib.benchmarks as benchmarks
2480
2468
        from bzrlib.benchmarks import tree_creator
2481
 
        from bzrlib.version import show_version
 
2469
 
 
2470
        if clean_output:
 
2471
            from bzrlib.tests import clean_selftest_output
 
2472
            clean_selftest_output()
 
2473
            return 0
 
2474
        if keep_output:
 
2475
            warning("notice: selftest --keep-output "
 
2476
                    "is no longer supported; "
 
2477
                    "test output is always removed")
 
2478
 
 
2479
        if numbered_dirs is None and sys.platform == 'win32':
 
2480
            numbered_dirs = True
2482
2481
 
2483
2482
        if cache_dir is not None:
2484
2483
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2485
 
        if not list_only:
2486
 
            show_version(show_config=False, show_copyright=False)
 
2484
        print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
 
2485
        print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2487
2486
        print
2488
2487
        if testspecs_list is not None:
2489
2488
            pattern = '|'.join(testspecs_list)
2501
2500
                verbose = False
2502
2501
            benchfile = None
2503
2502
        try:
2504
 
            result = selftest(verbose=verbose,
 
2503
            result = selftest(verbose=verbose, 
2505
2504
                              pattern=pattern,
2506
 
                              stop_on_failure=one,
 
2505
                              stop_on_failure=one, 
2507
2506
                              transport=transport,
2508
2507
                              test_suite_factory=test_suite_factory,
2509
2508
                              lsprof_timed=lsprof_timed,
2510
2509
                              bench_history=benchfile,
2511
2510
                              matching_tests_first=first,
 
2511
                              numbered_dirs=numbered_dirs,
2512
2512
                              list_only=list_only,
2513
2513
                              random_seed=randomize,
2514
2514
                              exclude_pattern=exclude
2609
2609
    --force is given.
2610
2610
    """
2611
2611
 
2612
 
    _see_also = ['update', 'remerge', 'status-flags']
 
2612
    _see_also = ['update', 'remerge']
2613
2613
    takes_args = ['branch?']
2614
 
    takes_options = [
2615
 
        'revision',
2616
 
        Option('force',
2617
 
               help='Merge even if the destination tree has uncommitted changes.'),
2618
 
        'merge-type',
2619
 
        'reprocess',
2620
 
        'remember',
 
2614
    takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2621
2615
        Option('show-base', help="Show base revision text in "
2622
 
               "conflicts."),
 
2616
               "conflicts"),
2623
2617
        Option('uncommitted', help='Apply uncommitted changes'
2624
 
               ' from a working copy, instead of branch changes.'),
 
2618
               ' from a working copy, instead of branch changes'),
2625
2619
        Option('pull', help='If the destination is already'
2626
2620
                ' completely merged into the source, pull from the'
2627
 
                ' source rather than merging.  When this happens,'
 
2621
                ' source rather than merging. When this happens,'
2628
2622
                ' you do not need to commit the result.'),
2629
2623
        Option('directory',
2630
 
               help='Branch to merge into, '
2631
 
                    'rather than the one containing the working directory.',
2632
 
               short_name='d',
2633
 
               type=unicode,
2634
 
               ),
 
2624
            help='Branch to merge into, '
 
2625
                 'rather than the one containing the working directory',
 
2626
            short_name='d',
 
2627
            type=unicode,
 
2628
            ),
2635
2629
    ]
2636
2630
 
2637
2631
    def run(self, branch=None, revision=None, force=False, merge_type=None,
2640
2634
            directory=None,
2641
2635
            ):
2642
2636
        from bzrlib.tag import _merge_tags_if_possible
 
2637
        other_revision_id = None
2643
2638
        if merge_type is None:
2644
2639
            merge_type = _mod_merge.Merge3Merger
2645
2640
 
2655
2650
        change_reporter = delta._ChangeReporter(
2656
2651
            unversioned_filter=tree.is_ignored)
2657
2652
 
2658
 
        other_transport = None
2659
 
        other_revision_id = None
2660
 
        base_revision_id = None
2661
 
        possible_transports = []
2662
 
 
2663
2653
        if branch is not None:
2664
 
            mergeable, other_transport = _get_bundle_helper(branch)
2665
 
            if mergeable:
 
2654
            try:
 
2655
                mergeable = bundle.read_mergeable_from_url(
 
2656
                    branch)
 
2657
            except errors.NotABundle:
 
2658
                pass # Continue on considering this url a Branch
 
2659
            else:
2666
2660
                if revision is not None:
2667
2661
                    raise errors.BzrCommandError(
2668
2662
                        'Cannot use -r with merge directives or bundles')
2669
 
                mergeable.install_revisions(tree.branch.repository)
2670
 
                base_revision_id, other_revision_id, verified =\
2671
 
                    mergeable.get_merge_request(tree.branch.repository)
2672
 
                if base_revision_id in tree.branch.repository.get_ancestry(
2673
 
                    tree.branch.last_revision(), topo_sorted=False):
2674
 
                    base_revision_id = None
2675
 
                other_branch = None
2676
 
                path = ''
2677
 
                other = None
2678
 
                base = None
2679
 
            possible_transports.append(other_transport)
2680
 
 
2681
 
        if other_revision_id is None:
2682
 
            verified = 'inapplicable'
2683
 
            if revision is None \
2684
 
                    or len(revision) < 1 or revision[0].needs_branch():
2685
 
                branch = self._get_remembered_parent(tree, branch,
2686
 
                    'Merging from')
2687
 
 
2688
 
            if revision is None or len(revision) < 1:
2689
 
                if uncommitted:
2690
 
                    base = [branch, -1]
2691
 
                    other = [branch, None]
 
2663
                other_revision_id = mergeable.install_revisions(
 
2664
                    tree.branch.repository)
 
2665
                revision = [RevisionSpec.from_string(
 
2666
                    'revid:' + other_revision_id)]
 
2667
 
 
2668
        if revision is None \
 
2669
                or len(revision) < 1 or revision[0].needs_branch():
 
2670
            branch = self._get_remembered_parent(tree, branch, 'Merging from')
 
2671
 
 
2672
        if revision is None or len(revision) < 1:
 
2673
            if uncommitted:
 
2674
                base = [branch, -1]
 
2675
                other = [branch, None]
 
2676
            else:
 
2677
                base = [None, None]
 
2678
                other = [branch, -1]
 
2679
            other_branch, path = Branch.open_containing(branch)
 
2680
        else:
 
2681
            if uncommitted:
 
2682
                raise errors.BzrCommandError('Cannot use --uncommitted and'
 
2683
                                             ' --revision at the same time.')
 
2684
            branch = revision[0].get_branch() or branch
 
2685
            if len(revision) == 1:
 
2686
                base = [None, None]
 
2687
                if other_revision_id is not None:
 
2688
                    other_branch = None
 
2689
                    path = ""
 
2690
                    other = None
2692
2691
                else:
2693
 
                    base = [None, None]
2694
 
                    other = [branch, -1]
2695
 
                other_branch, path = Branch.open_containing(branch,
2696
 
                                                            possible_transports)
2697
 
            else:
2698
 
                if uncommitted:
2699
 
                    raise errors.BzrCommandError('Cannot use --uncommitted and'
2700
 
                        ' --revision at the same time.')
2701
 
                branch = revision[0].get_branch() or branch
2702
 
                if len(revision) == 1:
2703
 
                    base = [None, None]
2704
 
                    other_branch, path = Branch.open_containing(
2705
 
                        branch, possible_transports)
 
2692
                    other_branch, path = Branch.open_containing(branch)
2706
2693
                    revno = revision[0].in_history(other_branch).revno
2707
2694
                    other = [branch, revno]
2708
 
                else:
2709
 
                    assert len(revision) == 2
2710
 
                    if None in revision:
2711
 
                        raise errors.BzrCommandError(
2712
 
                            "Merge doesn't permit empty revision specifier.")
2713
 
                    base_branch, path = Branch.open_containing(
2714
 
                        branch, possible_transports)
2715
 
                    branch1 = revision[1].get_branch() or branch
2716
 
                    other_branch, path1 = Branch.open_containing(
2717
 
                        branch1, possible_transports)
2718
 
                    if revision[0].get_branch() is not None:
2719
 
                        # then path was obtained from it, and is None.
2720
 
                        path = path1
2721
 
 
2722
 
                    base = [branch, revision[0].in_history(base_branch).revno]
2723
 
                    other = [branch1,
2724
 
                             revision[1].in_history(other_branch).revno]
2725
 
 
2726
 
        # Remember where we merge from
 
2695
            else:
 
2696
                assert len(revision) == 2
 
2697
                if None in revision:
 
2698
                    raise errors.BzrCommandError(
 
2699
                        "Merge doesn't permit empty revision specifier.")
 
2700
                base_branch, path = Branch.open_containing(branch)
 
2701
                branch1 = revision[1].get_branch() or branch
 
2702
                other_branch, path1 = Branch.open_containing(branch1)
 
2703
                if revision[0].get_branch() is not None:
 
2704
                    # then path was obtained from it, and is None.
 
2705
                    path = path1
 
2706
 
 
2707
                base = [branch, revision[0].in_history(base_branch).revno]
 
2708
                other = [branch1, revision[1].in_history(other_branch).revno]
 
2709
 
2727
2710
        if ((tree.branch.get_parent() is None or remember) and
2728
2711
            other_branch is not None):
2729
2712
            tree.branch.set_parent(other_branch.base)
2742
2725
            try:
2743
2726
                conflict_count = _merge_helper(
2744
2727
                    other, base, other_rev_id=other_revision_id,
2745
 
                    base_rev_id=base_revision_id,
2746
2728
                    check_clean=(not force),
2747
2729
                    merge_type=merge_type,
2748
2730
                    reprocess=reprocess,
2750
2732
                    pull=pull,
2751
2733
                    this_dir=directory,
2752
2734
                    pb=pb, file_list=interesting_files,
2753
 
                    change_reporter=change_reporter,
2754
 
                    possible_transports=possible_transports)
 
2735
                    change_reporter=change_reporter)
2755
2736
            finally:
2756
2737
                pb.finished()
2757
 
            if verified == 'failed':
2758
 
                warning('Preview patch does not match changes')
2759
2738
            if conflict_count != 0:
2760
2739
                return 1
2761
2740
            else:
2808
2787
        additional processing to reduce the size of conflict regions.
2809
2788
    """
2810
2789
    takes_args = ['file*']
2811
 
    takes_options = [
2812
 
            'merge-type',
2813
 
            'reprocess',
2814
 
            Option('show-base',
2815
 
                   help="Show base revision text in conflicts."),
2816
 
            ]
 
2790
    takes_options = ['merge-type', 'reprocess',
 
2791
                     Option('show-base', help="Show base revision text in "
 
2792
                            "conflicts")]
2817
2793
 
2818
2794
    def run(self, file_list=None, merge_type=None, show_base=False,
2819
2795
            reprocess=False):
2862
2838
                    restore(tree.abspath(filename))
2863
2839
                except errors.NotConflicted:
2864
2840
                    pass
2865
 
            # Disable pending merges, because the file texts we are remerging
2866
 
            # have not had those merges performed.  If we use the wrong parents
2867
 
            # list, we imply that the working tree text has seen and rejected
2868
 
            # all the changes from the other tree, when in fact those changes
2869
 
            # have not yet been seen.
2870
 
            tree.set_parent_ids(parents[:1])
2871
 
            try:
2872
 
                conflicts = _mod_merge.merge_inner(
2873
 
                                          tree.branch, other_tree, base_tree,
2874
 
                                          this_tree=tree,
2875
 
                                          interesting_ids=interesting_ids,
2876
 
                                          other_rev_id=parents[1],
2877
 
                                          merge_type=merge_type,
2878
 
                                          show_base=show_base,
2879
 
                                          reprocess=reprocess)
2880
 
            finally:
2881
 
                tree.set_parent_ids(parents)
 
2841
            conflicts = _mod_merge.merge_inner(
 
2842
                                      tree.branch, other_tree, base_tree,
 
2843
                                      this_tree=tree,
 
2844
                                      interesting_ids=interesting_ids,
 
2845
                                      other_rev_id=parents[1],
 
2846
                                      merge_type=merge_type,
 
2847
                                      show_base=show_base,
 
2848
                                      reprocess=reprocess)
2882
2849
        finally:
2883
2850
            tree.unlock()
2884
2851
        if conflicts > 0:
2910
2877
    """
2911
2878
 
2912
2879
    _see_also = ['cat', 'export']
2913
 
    takes_options = [
2914
 
            'revision',
2915
 
            Option('no-backup', "Do not save backups of reverted files."),
2916
 
            ]
 
2880
    takes_options = ['revision', 'no-backup']
2917
2881
    takes_args = ['file*']
2918
2882
 
2919
2883
    def run(self, revision=None, no_backup=False, file_list=None):
2955
2919
    """
2956
2920
 
2957
2921
    _see_also = ['topics']
2958
 
    takes_options = [
2959
 
            Option('long', 'Show help on all commands.'),
2960
 
            ]
 
2922
    takes_options = [Option('long', 'show help on all commands')]
2961
2923
    takes_args = ['topic?']
2962
2924
    aliases = ['?', '--help', '-?', '-h']
2963
2925
    
3006
2968
 
3007
2969
    _see_also = ['merge', 'pull']
3008
2970
    takes_args = ['other_branch?']
3009
 
    takes_options = [
3010
 
            Option('reverse', 'Reverse the order of revisions.'),
3011
 
            Option('mine-only',
3012
 
                   'Display changes in the local branch only.'),
3013
 
            Option('this' , 'Same as --mine-only.'),
3014
 
            Option('theirs-only',
3015
 
                   'Display changes in the remote branch only.'),
3016
 
            Option('other', 'Same as --theirs-only.'),
3017
 
            'log-format',
3018
 
            'show-ids',
3019
 
            'verbose'
3020
 
            ]
 
2971
    takes_options = [Option('reverse', 'Reverse the order of revisions'),
 
2972
                     Option('mine-only', 
 
2973
                            'Display changes in the local branch only'),
 
2974
                     Option('this' , 'same as --mine-only'),
 
2975
                     Option('theirs-only', 
 
2976
                            'Display changes in the remote branch only'),
 
2977
                     Option('other', 'same as --theirs-only'),
 
2978
                     'log-format',
 
2979
                     'show-ids',
 
2980
                     'verbose'
 
2981
                     ]
3021
2982
    encoding_type = 'replace'
3022
2983
 
3023
2984
    @display_command
3037
2998
        if other_branch is None:
3038
2999
            other_branch = parent
3039
3000
            if other_branch is None:
3040
 
                raise errors.BzrCommandError("No peer location known"
3041
 
                                             " or specified.")
 
3001
                raise errors.BzrCommandError("No peer location known or specified.")
3042
3002
            display_url = urlutils.unescape_for_display(parent,
3043
3003
                                                        self.outf.encoding)
3044
 
            self.outf.write("Using last location: " + display_url + "\n")
 
3004
            print "Using last location: " + display_url
3045
3005
 
3046
3006
        remote_branch = Branch.open(other_branch)
3047
3007
        if remote_branch.base == local_branch.base:
3050
3010
        try:
3051
3011
            remote_branch.lock_read()
3052
3012
            try:
3053
 
                local_extra, remote_extra = find_unmerged(local_branch,
3054
 
                                                          remote_branch)
3055
 
                if log_format is None:
3056
 
                    registry = log.log_formatter_registry
3057
 
                    log_format = registry.get_default(local_branch)
 
3013
                local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
 
3014
                if (log_format is None):
 
3015
                    log_format = log.log_formatter_registry.get_default(
 
3016
                        local_branch)
3058
3017
                lf = log_format(to_file=self.outf,
3059
3018
                                show_ids=show_ids,
3060
3019
                                show_timezone='original')
3062
3021
                    local_extra.reverse()
3063
3022
                    remote_extra.reverse()
3064
3023
                if local_extra and not theirs_only:
3065
 
                    self.outf.write("You have %d extra revision(s):\n" %
3066
 
                                    len(local_extra))
3067
 
                    for revision in iter_log_revisions(local_extra,
 
3024
                    print "You have %d extra revision(s):" % len(local_extra)
 
3025
                    for revision in iter_log_revisions(local_extra, 
3068
3026
                                        local_branch.repository,
3069
3027
                                        verbose):
3070
3028
                        lf.log_revision(revision)
3073
3031
                    printed_local = False
3074
3032
                if remote_extra and not mine_only:
3075
3033
                    if printed_local is True:
3076
 
                        self.outf.write("\n\n\n")
3077
 
                    self.outf.write("You are missing %d revision(s):\n" %
3078
 
                                    len(remote_extra))
3079
 
                    for revision in iter_log_revisions(remote_extra,
3080
 
                                        remote_branch.repository,
 
3034
                        print "\n\n"
 
3035
                    print "You are missing %d revision(s):" % len(remote_extra)
 
3036
                    for revision in iter_log_revisions(remote_extra, 
 
3037
                                        remote_branch.repository, 
3081
3038
                                        verbose):
3082
3039
                        lf.log_revision(revision)
3083
3040
                if not remote_extra and not local_extra:
3084
3041
                    status_code = 0
3085
 
                    self.outf.write("Branches are up to date.\n")
 
3042
                    print "Branches are up to date."
3086
3043
                else:
3087
3044
                    status_code = 1
3088
3045
            finally:
3100
3057
        return status_code
3101
3058
 
3102
3059
 
3103
 
class cmd_pack(Command):
3104
 
    """Compress the data within a repository."""
3105
 
 
3106
 
    _see_also = ['repositories']
3107
 
    takes_args = ['branch_or_repo?']
3108
 
 
3109
 
    def run(self, branch_or_repo='.'):
3110
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3111
 
        try:
3112
 
            branch = dir.open_branch()
3113
 
            repository = branch.repository
3114
 
        except errors.NotBranchError:
3115
 
            repository = dir.open_repository()
3116
 
        repository.pack()
3117
 
 
3118
 
 
3119
3060
class cmd_plugins(Command):
3120
 
    """List the installed plugins.
3121
 
    
3122
 
    This command displays the list of installed plugins including the
3123
 
    path where each one is located and a short description of each.
3124
 
 
3125
 
    A plugin is an external component for Bazaar that extends the
3126
 
    revision control system, by adding or replacing code in Bazaar.
3127
 
    Plugins can do a variety of things, including overriding commands,
3128
 
    adding new commands, providing additional network transports and
3129
 
    customizing log output.
3130
 
 
3131
 
    See the Bazaar web site, http://bazaar-vcs.org, for further
3132
 
    information on plugins including where to find them and how to
3133
 
    install them. Instructions are also provided there on how to
3134
 
    write new plugins using the Python programming language.
3135
 
    """
3136
 
 
 
3061
    """List plugins"""
 
3062
    hidden = True
3137
3063
    @display_command
3138
3064
    def run(self):
3139
3065
        import bzrlib.plugin
3153
3079
 
3154
3080
class cmd_testament(Command):
3155
3081
    """Show testament (signing-form) of a revision."""
3156
 
    takes_options = [
3157
 
            'revision',
3158
 
            Option('long', help='Produce long-format testament.'),
3159
 
            Option('strict',
3160
 
                   help='Produce a strict-format testament.')]
 
3082
    takes_options = ['revision',
 
3083
                     Option('long', help='Produce long-format testament'), 
 
3084
                     Option('strict', help='Produce a strict-format'
 
3085
                            ' testament')]
3161
3086
    takes_args = ['branch?']
3162
3087
    @display_command
3163
3088
    def run(self, branch=u'.', revision=None, long=False, strict=False):
3196
3121
    #       with new uncommitted lines marked
3197
3122
    aliases = ['ann', 'blame', 'praise']
3198
3123
    takes_args = ['filename']
3199
 
    takes_options = [Option('all', help='Show annotations on all lines.'),
3200
 
                     Option('long', help='Show commit date in annotations.'),
 
3124
    takes_options = [Option('all', help='show annotations on all lines'),
 
3125
                     Option('long', help='show date in annotations'),
3201
3126
                     'revision',
3202
3127
                     'show-ids',
3203
3128
                     ]
3204
 
    encoding_type = 'exact'
3205
3129
 
3206
3130
    @display_command
3207
3131
    def run(self, filename, all=False, long=False, revision=None,
3218
3142
            else:
3219
3143
                revision_id = revision[0].in_history(branch).rev_id
3220
3144
            file_id = tree.path2id(relpath)
3221
 
            if file_id is None:
3222
 
                raise errors.NotVersionedError(filename)
3223
3145
            tree = branch.repository.revision_tree(revision_id)
3224
3146
            file_version = tree.inventory[file_id].revision
3225
 
            annotate_file(branch, file_version, file_id, long, all, self.outf,
 
3147
            annotate_file(branch, file_version, file_id, long, all, sys.stdout,
3226
3148
                          show_ids=show_ids)
3227
3149
        finally:
3228
3150
            branch.unlock()
3333
3255
    # information in shared branches as well.
3334
3256
    _see_also = ['commit']
3335
3257
    takes_options = ['verbose', 'revision',
3336
 
                    Option('dry-run', help='Don\'t actually make changes.'),
 
3258
                    Option('dry-run', help='Don\'t actually make changes'),
3337
3259
                    Option('force', help='Say yes to all questions.')]
3338
3260
    takes_args = ['location?']
3339
3261
    aliases = []
3443
3365
 
3444
3366
    takes_options = [
3445
3367
        Option('inet',
3446
 
               help='Serve on stdin/out for use from inetd or sshd.'),
 
3368
               help='serve on stdin/out for use from inetd or sshd'),
3447
3369
        Option('port',
3448
 
               help='Listen for connections on nominated port of the form '
3449
 
                    '[hostname:]portnumber.  Passing 0 as the port number will '
3450
 
                    'result in a dynamically allocated port.  The default port is '
 
3370
               help='listen for connections on nominated port of the form '
 
3371
                    '[hostname:]portnumber. Passing 0 as the port number will '
 
3372
                    'result in a dynamically allocated port. Default port is '
3451
3373
                    '4155.',
3452
3374
               type=str),
3453
3375
        Option('directory',
3454
 
               help='Serve contents of this directory.',
 
3376
               help='serve contents of directory',
3455
3377
               type=unicode),
3456
3378
        Option('allow-writes',
3457
 
               help='By default the server is a readonly server.  Supplying '
 
3379
               help='By default the server is a readonly server. Supplying '
3458
3380
                    '--allow-writes enables write access to the contents of '
3459
 
                    'the served directory and below.'
 
3381
                    'the served directory and below. '
3460
3382
                ),
3461
3383
        ]
3462
3384
 
3522
3444
 
3523
3445
    _see_also = ['split']
3524
3446
    takes_args = ['tree']
3525
 
    takes_options = [
3526
 
            Option('reference', help='Join by reference.'),
3527
 
            ]
 
3447
    takes_options = [Option('reference', 'join by reference')]
3528
3448
    hidden = True
3529
3449
 
3530
3450
    def run(self, tree, reference=False):
3602
3522
 
3603
3523
    takes_args = ['submit_branch?', 'public_branch?']
3604
3524
 
3605
 
    hidden = True
3606
 
 
3607
 
    _see_also = ['submit']
3608
 
 
3609
3525
    takes_options = [
3610
3526
        RegistryOption.from_kwargs('patch-type',
3611
3527
            'The type of patch to include in the directive',
3612
 
            title='Patch type',
3613
 
            value_switches=True,
3614
 
            enum_switch=False,
3615
 
            bundle='Bazaar revision bundle (default).',
3616
 
            diff='Normal unified diff.',
3617
 
            plain='No patch, just directive.'),
3618
 
        Option('sign', help='GPG-sign the directive.'), 'revision',
 
3528
            title='Patch type', value_switches=True, enum_switch=False,
 
3529
            bundle='Bazaar revision bundle (default)',
 
3530
            diff='Normal unified diff',
 
3531
            plain='No patch, just directive'),
 
3532
        Option('sign', help='GPG-sign the directive'), 'revision',
3619
3533
        Option('mail-to', type=str,
3620
 
            help='Instead of printing the directive, email to this address.'),
 
3534
            help='Instead of printing the directive, email to this address'),
3621
3535
        Option('message', type=str, short_name='m',
3622
 
            help='Message to use when committing this merge.')
 
3536
            help='Message to use when committing this merge')
3623
3537
        ]
3624
3538
 
3625
3539
    encoding_type = 'exact'
3627
3541
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3628
3542
            sign=False, revision=None, mail_to=None, message=None):
3629
3543
        from bzrlib.revision import ensure_null, NULL_REVISION
3630
 
        include_patch, include_bundle = {
3631
 
            'plain': (False, False),
3632
 
            'diff': (True, False),
3633
 
            'bundle': (True, True),
3634
 
            }[patch_type]
 
3544
        if patch_type == 'plain':
 
3545
            patch_type = None
3635
3546
        branch = Branch.open('.')
3636
3547
        stored_submit_branch = branch.get_submit_branch()
3637
3548
        if submit_branch is None:
3649
3560
            public_branch = stored_public_branch
3650
3561
        elif stored_public_branch is None:
3651
3562
            branch.set_public_branch(public_branch)
3652
 
        if not include_bundle and public_branch is None:
 
3563
        if patch_type != "bundle" and public_branch is None:
3653
3564
            raise errors.BzrCommandError('No public branch specified or'
3654
3565
                                         ' known')
3655
 
        base_revision_id = None
3656
3566
        if revision is not None:
3657
 
            if len(revision) > 2:
 
3567
            if len(revision) != 1:
3658
3568
                raise errors.BzrCommandError('bzr merge-directive takes '
3659
 
                    'at most two one revision identifiers')
3660
 
            revision_id = revision[-1].in_history(branch).rev_id
3661
 
            if len(revision) == 2:
3662
 
                base_revision_id = revision[0].in_history(branch).rev_id
3663
 
                base_revision_id = ensure_null(base_revision_id)
 
3569
                    'exactly one revision identifier')
 
3570
            else:
 
3571
                revision_id = revision[0].in_history(branch).rev_id
3664
3572
        else:
3665
3573
            revision_id = branch.last_revision()
3666
3574
        revision_id = ensure_null(revision_id)
3667
3575
        if revision_id == NULL_REVISION:
3668
3576
            raise errors.BzrCommandError('No revisions to bundle.')
3669
 
        directive = merge_directive.MergeDirective2.from_objects(
 
3577
        directive = merge_directive.MergeDirective.from_objects(
3670
3578
            branch.repository, revision_id, time.time(),
3671
3579
            osutils.local_time_offset(), submit_branch,
3672
 
            public_branch=public_branch, include_patch=include_patch,
3673
 
            include_bundle=include_bundle, message=message,
3674
 
            base_revision_id=base_revision_id)
 
3580
            public_branch=public_branch, patch_type=patch_type,
 
3581
            message=message)
3675
3582
        if mail_to is None:
3676
3583
            if sign:
3677
3584
                self.outf.write(directive.to_signed(branch))
3683
3590
            s.send_email(message)
3684
3591
 
3685
3592
 
3686
 
class cmd_submit(Command):
3687
 
    """Create a merge-directive for submiting changes.
3688
 
 
3689
 
    A merge directive provides many things needed for requesting merges:
3690
 
    - A machine-readable description of the merge to perform
3691
 
    - An optional patch that is a preview of the changes requested
3692
 
    - An optional bundle of revision data, so that the changes can be applied
3693
 
      directly from the merge directive, without retrieving data from a
3694
 
      branch.
3695
 
 
3696
 
    If --no-bundle is specified, then public_branch is needed (and must be
3697
 
    up-to-date), so that the receiver can perform the merge using the
3698
 
    public_branch.  The public_branch is always included if known, so that
3699
 
    people can check it later.
3700
 
 
3701
 
    The submit branch defaults to the parent, but can be overridden.  Both
3702
 
    submit branch and public branch will be remembered if supplied.
3703
 
 
3704
 
    If a public_branch is known for the submit_branch, that public submit
3705
 
    branch is used in the merge instructions.  This means that a local mirror
3706
 
    can be used as your actual submit branch, once you have set public_branch
3707
 
    for that mirror.
3708
 
    """
3709
 
 
3710
 
    encoding_type = 'exact'
3711
 
 
3712
 
    aliases = ['bundle', 'bundle-revisions']
3713
 
 
3714
 
    _see_also = ['merge']
3715
 
 
3716
 
    takes_args = ['submit_branch?', 'public_branch?']
3717
 
    takes_options = [
3718
 
        Option('no-bundle',
3719
 
               help='Do not include a bundle in the merge directive.'),
3720
 
        Option('no-patch', help='Do not include a preview patch in the merge'
3721
 
               ' directive.'),
3722
 
        Option('remember',
3723
 
               help='Remember submit and public branch.'),
3724
 
        Option('from',
3725
 
               help='Branch to generate the submission from, '
3726
 
               'rather than the one containing the working directory.',
3727
 
               short_name='f',
3728
 
               type=unicode),
3729
 
        Option('output', short_name='o', help='Write directive to this file.',
3730
 
               type=unicode),
3731
 
        'revision',
3732
 
        ]
3733
 
 
3734
 
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
3735
 
            no_patch=False, revision=None, remember=False, output=None,
3736
 
            **kwargs):
3737
 
        from bzrlib.revision import ensure_null, NULL_REVISION
3738
 
        if output is None:
3739
 
            outfile = self.outf
3740
 
        else:
3741
 
            outfile = open(output, 'wb')
3742
 
        try:
3743
 
            from_ = kwargs.get('from', '.')
3744
 
            branch = Branch.open_containing(from_)[0]
3745
 
            if remember and submit_branch is None:
3746
 
                raise errors.BzrCommandError(
3747
 
                    '--remember requires a branch to be specified.')
3748
 
            stored_submit_branch = branch.get_submit_branch()
3749
 
            remembered_submit_branch = False
3750
 
            if submit_branch is None:
3751
 
                submit_branch = stored_submit_branch
3752
 
                remembered_submit_branch = True
3753
 
            else:
3754
 
                if stored_submit_branch is None or remember:
3755
 
                    branch.set_submit_branch(submit_branch)
3756
 
            if submit_branch is None:
3757
 
                submit_branch = branch.get_parent()
3758
 
                remembered_submit_branch = True
3759
 
            if submit_branch is None:
3760
 
                raise errors.BzrCommandError('No submit branch known or'
3761
 
                                             ' specified')
3762
 
            if remembered_submit_branch:
3763
 
                note('Using saved location: %s', submit_branch)
3764
 
 
3765
 
            stored_public_branch = branch.get_public_branch()
3766
 
            if public_branch is None:
3767
 
                public_branch = stored_public_branch
3768
 
            elif stored_public_branch is None or remember:
3769
 
                branch.set_public_branch(public_branch)
3770
 
            if no_bundle and public_branch is None:
3771
 
                raise errors.BzrCommandError('No public branch specified or'
3772
 
                                             ' known')
3773
 
            base_revision_id = None
3774
 
            if revision is not None:
3775
 
                if len(revision) > 2:
3776
 
                    raise errors.BzrCommandError('bzr submit takes '
3777
 
                        'at most two one revision identifiers')
3778
 
                revision_id = revision[-1].in_history(branch).rev_id
3779
 
                if len(revision) == 2:
3780
 
                    base_revision_id = revision[0].in_history(branch).rev_id
3781
 
                    base_revision_id = ensure_null(base_revision_id)
3782
 
            else:
3783
 
                revision_id = branch.last_revision()
3784
 
            revision_id = ensure_null(revision_id)
3785
 
            if revision_id == NULL_REVISION:
3786
 
                raise errors.BzrCommandError('No revisions to submit.')
3787
 
            directive = merge_directive.MergeDirective2.from_objects(
3788
 
                branch.repository, revision_id, time.time(),
3789
 
                osutils.local_time_offset(), submit_branch,
3790
 
                public_branch=public_branch, include_patch=not no_patch,
3791
 
                include_bundle=not no_bundle, message=None,
3792
 
                base_revision_id=base_revision_id)
3793
 
            outfile.writelines(directive.to_lines())
3794
 
        finally:
3795
 
            if output is not None:
3796
 
                outfile.close()
3797
 
 
3798
3593
class cmd_tag(Command):
3799
3594
    """Create a tag naming a revision.
3800
3595
    
3821
3616
            type=unicode,
3822
3617
            ),
3823
3618
        Option('force',
3824
 
            help='Replace existing tags.',
 
3619
            help='Replace existing tags',
3825
3620
            ),
3826
3621
        'revision',
3827
3622
        ]
3864
3659
    _see_also = ['tag']
3865
3660
    takes_options = [
3866
3661
        Option('directory',
3867
 
            help='Branch whose tags should be displayed.',
 
3662
            help='Branch whose tags should be displayed',
3868
3663
            short_name='d',
3869
3664
            type=unicode,
3870
3665
            ),
3888
3683
                  pull=False,
3889
3684
                  pb=DummyProgress(),
3890
3685
                  change_reporter=None,
3891
 
                  other_rev_id=None, base_rev_id=None,
3892
 
                  possible_transports=None):
 
3686
                  other_rev_id=None):
3893
3687
    """Merge changes into a tree.
3894
3688
 
3895
3689
    base_revision
3948
3742
        if other_rev_id is not None:
3949
3743
            merger.set_other_revision(other_rev_id, this_tree.branch)
3950
3744
        else:
3951
 
            merger.set_other(other_revision, possible_transports)
 
3745
            merger.set_other(other_revision)
3952
3746
        merger.pp.next_phase()
3953
 
        if base_rev_id is not None:
3954
 
            merger.set_base_revision(base_rev_id, this_tree.branch)
3955
 
        elif base_revision is not None:
3956
 
            merger.set_base(base_revision)
3957
 
        else:
3958
 
            merger.find_base()
 
3747
        merger.set_base(base_revision)
3959
3748
        if merger.base_rev_id == merger.other_rev_id:
3960
3749
            note('Nothing to do.')
3961
3750
            return 0
3988
3777
    while True:
3989
3778
        new_transport = cur_transport.clone('..')
3990
3779
        if new_transport.base == cur_transport.base:
3991
 
            raise errors.BzrCommandError(
3992
 
                "Failed to create path prefix for %s."
3993
 
                % cur_transport.base)
 
3780
            raise errors.BzrCommandError("Failed to create path"
 
3781
                                         " prefix for %s."
 
3782
                                         % location)
3994
3783
        try:
3995
3784
            new_transport.mkdir('.')
3996
3785
        except errors.NoSuchFile:
3998
3787
            cur_transport = new_transport
3999
3788
        else:
4000
3789
            break
 
3790
 
4001
3791
    # Now we only need to create child directories
4002
3792
    while needed:
4003
3793
        cur_transport = needed.pop()
4004
3794
        cur_transport.ensure_base()
4005
3795
 
4006
 
 
4007
 
def _get_bundle_helper(location):
4008
 
    """Get a bundle if 'location' points to one.
4009
 
 
4010
 
    Try try to identify a bundle and returns its mergeable form. If it's not,
4011
 
    we return the tried transport anyway so that it can reused to access the
4012
 
    branch
4013
 
 
4014
 
    :param location: can point to a bundle or a branch.
4015
 
 
4016
 
    :return: mergeable, transport
4017
 
    """
4018
 
    mergeable = None
4019
 
    url = urlutils.normalize_url(location)
4020
 
    url, filename = urlutils.split(url, exclude_trailing_slash=False)
4021
 
    location_transport = transport.get_transport(url)
4022
 
    if filename:
4023
 
        try:
4024
 
            # There may be redirections but we ignore the intermediate
4025
 
            # and final transports used
4026
 
            read = bundle.read_mergeable_from_transport
4027
 
            mergeable, t = read(location_transport, filename)
4028
 
        except errors.NotABundle:
4029
 
            # Continue on considering this url a Branch but adjust the
4030
 
            # location_transport
4031
 
            location_transport = location_transport.clone(filename)
4032
 
    return mergeable, location_transport
4033
 
 
4034
 
 
4035
3796
# Compatibility
4036
3797
merge = _merge_helper
4037
3798
 
4043
3804
# details were needed.
4044
3805
from bzrlib.cmd_version_info import cmd_version_info
4045
3806
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
4046
 
from bzrlib.bundle.commands import (
4047
 
    cmd_bundle_info,
4048
 
    )
 
3807
from bzrlib.bundle.commands import cmd_bundle_revisions
4049
3808
from bzrlib.sign_my_commits import cmd_sign_my_commits
4050
3809
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
4051
3810
        cmd_weave_plan_merge, cmd_weave_merge_text