~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Rory Yorke
  • Date: 2010-10-20 14:38:53 UTC
  • mto: This revision was merged to the branch mainline in revision 5519.
  • Revision ID: rory.yorke@gmail.com-20101020143853-9kfd2ldcjfroh8jw
Show missing files in bzr status (bug 134168).

"bzr status" will now show missing files, that is, those added with "bzr
add" and then removed by non bzr means (e.g., rm).

Blackbox tests were added for this case, and tests were also added to
test_delta, since the implementation change is in bzrlib.delta.

Might also affect bug 189709.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
21
21
from bzrlib.lazy_import import lazy_import
22
22
lazy_import(globals(), """
23
23
import cStringIO
 
24
import itertools
 
25
import re
24
26
import sys
25
27
import time
26
28
 
328
330
        if revision_id is None and revision is None:
329
331
            raise errors.BzrCommandError('You must supply either'
330
332
                                         ' --revision or a revision_id')
331
 
 
332
 
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
 
333
        b = WorkingTree.open_containing(directory)[0].branch
333
334
 
334
335
        revisions = b.repository.revisions
335
336
        if revisions is None:
413
414
                self.outf.write(page_bytes[:header_end])
414
415
                page_bytes = data
415
416
            self.outf.write('\nPage %d\n' % (page_idx,))
416
 
            if len(page_bytes) == 0:
417
 
                self.outf.write('(empty)\n');
418
 
            else:
419
 
                decomp_bytes = zlib.decompress(page_bytes)
420
 
                self.outf.write(decomp_bytes)
421
 
                self.outf.write('\n')
 
417
            decomp_bytes = zlib.decompress(page_bytes)
 
418
            self.outf.write(decomp_bytes)
 
419
            self.outf.write('\n')
422
420
 
423
421
    def _dump_entries(self, trans, basename):
424
422
        try:
485
483
            d.destroy_workingtree()
486
484
 
487
485
 
488
 
class cmd_repair_workingtree(Command):
489
 
    __doc__ = """Reset the working tree state file.
490
 
 
491
 
    This is not meant to be used normally, but more as a way to recover from
492
 
    filesystem corruption, etc. This rebuilds the working inventory back to a
493
 
    'known good' state. Any new modifications (adding a file, renaming, etc)
494
 
    will be lost, though modified files will still be detected as such.
495
 
 
496
 
    Most users will want something more like "bzr revert" or "bzr update"
497
 
    unless the state file has become corrupted.
498
 
 
499
 
    By default this attempts to recover the current state by looking at the
500
 
    headers of the state file. If the state file is too corrupted to even do
501
 
    that, you can supply --revision to force the state of the tree.
502
 
    """
503
 
 
504
 
    takes_options = ['revision', 'directory',
505
 
        Option('force',
506
 
               help='Reset the tree even if it doesn\'t appear to be'
507
 
                    ' corrupted.'),
508
 
    ]
509
 
    hidden = True
510
 
 
511
 
    def run(self, revision=None, directory='.', force=False):
512
 
        tree, _ = WorkingTree.open_containing(directory)
513
 
        self.add_cleanup(tree.lock_tree_write().unlock)
514
 
        if not force:
515
 
            try:
516
 
                tree.check_state()
517
 
            except errors.BzrError:
518
 
                pass # There seems to be a real error here, so we'll reset
519
 
            else:
520
 
                # Refuse
521
 
                raise errors.BzrCommandError(
522
 
                    'The tree does not appear to be corrupt. You probably'
523
 
                    ' want "bzr revert" instead. Use "--force" if you are'
524
 
                    ' sure you want to reset the working tree.')
525
 
        if revision is None:
526
 
            revision_ids = None
527
 
        else:
528
 
            revision_ids = [r.as_revision_id(tree.branch) for r in revision]
529
 
        try:
530
 
            tree.reset_state(revision_ids)
531
 
        except errors.BzrError, e:
532
 
            if revision_ids is None:
533
 
                extra = (', the header appears corrupt, try passing -r -1'
534
 
                         ' to set the state to the last commit')
535
 
            else:
536
 
                extra = ''
537
 
            raise errors.BzrCommandError('failed to reset the tree state'
538
 
                                         + extra)
539
 
 
540
 
 
541
486
class cmd_revno(Command):
542
487
    __doc__ = """Show current revision number.
543
488
 
1072
1017
            log.show_branch_change(
1073
1018
                branch_to, self.outf, result.old_revno,
1074
1019
                result.old_revid)
1075
 
        if getattr(result, 'tag_conflicts', None):
1076
 
            return 1
1077
 
        else:
1078
 
            return 0
1079
1020
 
1080
1021
 
1081
1022
class cmd_push(Command):
1205
1146
 
1206
1147
    To retrieve the branch as of a particular revision, supply the --revision
1207
1148
    parameter, as in "branch foo/bar -r 5".
1208
 
 
1209
 
    The synonyms 'clone' and 'get' for this command are deprecated.
1210
1149
    """
1211
1150
 
1212
1151
    _see_also = ['checkout']
1242
1181
            files_from=None):
1243
1182
        from bzrlib import switch as _mod_switch
1244
1183
        from bzrlib.tag import _merge_tags_if_possible
1245
 
        if self.invoked_as in ['get', 'clone']:
1246
 
            ui.ui_factory.show_user_warning(
1247
 
                'deprecated_command',
1248
 
                deprecated_name=self.invoked_as,
1249
 
                recommended_name='branch',
1250
 
                deprecated_in_version='2.4')
1251
1184
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1252
1185
            from_location)
1253
1186
        if not (hardlink or files_from):
1933
1866
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1934
1867
    produces patches suitable for "patch -p1".
1935
1868
 
1936
 
    Note that when using the -r argument with a range of revisions, the
1937
 
    differences are computed between the two specified revisions.  That
1938
 
    is, the command does not show the changes introduced by the first 
1939
 
    revision in the range.  This differs from the interpretation of 
1940
 
    revision ranges used by "bzr log" which includes the first revision
1941
 
    in the range.
1942
 
 
1943
1869
    :Exit values:
1944
1870
        1 - changed
1945
1871
        2 - unrepresentable changes
1963
1889
 
1964
1890
            bzr diff -r1..3 xxx
1965
1891
 
1966
 
        The changes introduced by revision 2 (equivalent to -r1..2)::
1967
 
 
1968
 
            bzr diff -c2
1969
 
 
1970
 
        To see the changes introduced by revision X::
 
1892
        To see the changes introduced in revision X::
1971
1893
        
1972
1894
            bzr diff -cX
1973
1895
 
1977
1899
 
1978
1900
            bzr diff -r<chosen_parent>..X
1979
1901
 
1980
 
        The changes between the current revision and the previous revision
1981
 
        (equivalent to -c-1 and -r-2..-1)
 
1902
        The changes introduced by revision 2 (equivalent to -r1..2)::
1982
1903
 
1983
 
            bzr diff -r-2..
 
1904
            bzr diff -c2
1984
1905
 
1985
1906
        Show just the differences for file NEWS::
1986
1907
 
2030
1951
            type=unicode,
2031
1952
            ),
2032
1953
        RegistryOption('format',
2033
 
            short_name='F',
2034
1954
            help='Diff format to use.',
2035
1955
            lazy_registry=('bzrlib.diff', 'format_registry'),
2036
 
            title='Diff format'),
 
1956
            value_switches=False, title='Diff format'),
2037
1957
        ]
2038
1958
    aliases = ['di', 'dif']
2039
1959
    encoding_type = 'exact'
2120
2040
    @display_command
2121
2041
    def run(self, null=False, directory=u'.'):
2122
2042
        tree = WorkingTree.open_containing(directory)[0]
2123
 
        self.add_cleanup(tree.lock_read().unlock)
2124
2043
        td = tree.changes_from(tree.basis_tree())
2125
 
        self.cleanup_now()
2126
2044
        for path, id, kind, text_modified, meta_modified in td.modified:
2127
2045
            if null:
2128
2046
                self.outf.write(path + '\0')
2758
2676
    Patterns prefixed with '!!' act as regular ignore patterns, but have
2759
2677
    precedence over the '!' exception patterns.
2760
2678
 
2761
 
    :Notes: 
2762
 
        
2763
 
    * Ignore patterns containing shell wildcards must be quoted from
2764
 
      the shell on Unix.
2765
 
 
2766
 
    * Ignore patterns starting with "#" act as comments in the ignore file.
2767
 
      To ignore patterns that begin with that character, use the "RE:" prefix.
 
2679
    Note: ignore patterns containing shell wildcards must be quoted from
 
2680
    the shell on Unix.
2768
2681
 
2769
2682
    :Examples:
2770
2683
        Ignore the top level Makefile::
2779
2692
 
2780
2693
            bzr ignore "!special.class"
2781
2694
 
2782
 
        Ignore files whose name begins with the "#" character::
2783
 
 
2784
 
            bzr ignore "RE:^#"
2785
 
 
2786
2695
        Ignore .o files under the lib directory::
2787
2696
 
2788
2697
            bzr ignore "lib/**/*.o"
2796
2705
            bzr ignore "RE:(?!debian/).*"
2797
2706
        
2798
2707
        Ignore everything except the "local" toplevel directory,
2799
 
        but always ignore autosave files ending in ~, even under local/::
 
2708
        but always ignore "*~" autosave files, even under local/::
2800
2709
        
2801
2710
            bzr ignore "*"
2802
2711
            bzr ignore "!./local"
2930
2839
         zip                          .zip
2931
2840
      =================       =========================
2932
2841
    """
2933
 
    encoding = 'exact'
2934
2842
    takes_args = ['dest', 'branch_or_subdir?']
2935
2843
    takes_options = ['directory',
2936
2844
        Option('format',
3114
3022
      to trigger updates to external systems like bug trackers. The --fixes
3115
3023
      option can be used to record the association between a revision and
3116
3024
      one or more bugs. See ``bzr help bugs`` for details.
 
3025
 
 
3026
      A selective commit may fail in some cases where the committed
 
3027
      tree would be invalid. Consider::
 
3028
  
 
3029
        bzr init foo
 
3030
        mkdir foo/bar
 
3031
        bzr add foo/bar
 
3032
        bzr commit foo -m "committing foo"
 
3033
        bzr mv foo/bar foo/baz
 
3034
        mkdir foo/bar
 
3035
        bzr add foo/bar
 
3036
        bzr commit foo/bar -m "committing bar but not baz"
 
3037
  
 
3038
      In the example above, the last commit will fail by design. This gives
 
3039
      the user the opportunity to decide whether they want to commit the
 
3040
      rename at the same time, separately first, or not at all. (As a general
 
3041
      rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
3117
3042
    """
 
3043
    # TODO: Run hooks on tree to-be-committed, and after commit.
 
3044
 
 
3045
    # TODO: Strict commit that fails if there are deleted files.
 
3046
    #       (what does "deleted files" mean ??)
 
3047
 
 
3048
    # TODO: Give better message for -s, --summary, used by tla people
 
3049
 
 
3050
    # XXX: verbose currently does nothing
3118
3051
 
3119
3052
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3120
3053
    takes_args = ['selected*']
3152
3085
             Option('show-diff', short_name='p',
3153
3086
                    help='When no message is supplied, show the diff along'
3154
3087
                    ' with the status summary in the message editor.'),
3155
 
             Option('lossy', 
3156
 
                    help='When committing to a foreign version control '
3157
 
                    'system do not push data that can not be natively '
3158
 
                    'represented.'),
3159
3088
             ]
3160
3089
    aliases = ['ci', 'checkin']
3161
3090
 
3180
3109
 
3181
3110
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3182
3111
            unchanged=False, strict=False, local=False, fixes=None,
3183
 
            author=None, show_diff=False, exclude=None, commit_time=None,
3184
 
            lossy=False):
 
3112
            author=None, show_diff=False, exclude=None, commit_time=None):
3185
3113
        from bzrlib.errors import (
3186
3114
            PointlessCommit,
3187
3115
            ConflictsInTree,
3201
3129
                raise errors.BzrCommandError(
3202
3130
                    "Could not parse --commit-time: " + str(e))
3203
3131
 
 
3132
        # TODO: Need a blackbox test for invoking the external editor; may be
 
3133
        # slightly problematic to run this cross-platform.
 
3134
 
 
3135
        # TODO: do more checks that the commit will succeed before
 
3136
        # spending the user's valuable time typing a commit message.
 
3137
 
3204
3138
        properties = {}
3205
3139
 
3206
3140
        tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3283
3217
                        reporter=None, verbose=verbose, revprops=properties,
3284
3218
                        authors=author, timestamp=commit_stamp,
3285
3219
                        timezone=offset,
3286
 
                        exclude=tree.safe_relpath_files(exclude),
3287
 
                        lossy=lossy)
 
3220
                        exclude=tree.safe_relpath_files(exclude))
3288
3221
        except PointlessCommit:
3289
3222
            raise errors.BzrCommandError("No changes to commit."
3290
 
                " Please 'bzr add' the files you want to commit, or use"
3291
 
                " --unchanged to force an empty commit.")
 
3223
                              " Use --unchanged to commit anyhow.")
3292
3224
        except ConflictsInTree:
3293
3225
            raise errors.BzrCommandError('Conflicts detected in working '
3294
3226
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3375
3307
 
3376
3308
 
3377
3309
class cmd_upgrade(Command):
3378
 
    __doc__ = """Upgrade a repository, branch or working tree to a newer format.
3379
 
 
3380
 
    When the default format has changed after a major new release of
3381
 
    Bazaar, you may be informed during certain operations that you
3382
 
    should upgrade. Upgrading to a newer format may improve performance
3383
 
    or make new features available. It may however limit interoperability
3384
 
    with older repositories or with older versions of Bazaar.
3385
 
 
3386
 
    If you wish to upgrade to a particular format rather than the
3387
 
    current default, that can be specified using the --format option.
3388
 
    As a consequence, you can use the upgrade command this way to
3389
 
    "downgrade" to an earlier format, though some conversions are
3390
 
    a one way process (e.g. changing from the 1.x default to the
3391
 
    2.x default) so downgrading is not always possible.
3392
 
 
3393
 
    A backup.bzr.~#~ directory is created at the start of the conversion
3394
 
    process (where # is a number). By default, this is left there on
3395
 
    completion. If the conversion fails, delete the new .bzr directory
3396
 
    and rename this one back in its place. Use the --clean option to ask
3397
 
    for the backup.bzr directory to be removed on successful conversion.
3398
 
    Alternatively, you can delete it by hand if everything looks good
3399
 
    afterwards.
3400
 
 
3401
 
    If the location given is a shared repository, dependent branches
3402
 
    are also converted provided the repository converts successfully.
3403
 
    If the conversion of a branch fails, remaining branches are still
3404
 
    tried.
3405
 
 
3406
 
    For more information on upgrades, see the Bazaar Upgrade Guide,
3407
 
    http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
 
3310
    __doc__ = """Upgrade branch storage to current format.
 
3311
 
 
3312
    The check command or bzr developers may sometimes advise you to run
 
3313
    this command. When the default format has changed you may also be warned
 
3314
    during other operations to upgrade.
3408
3315
    """
3409
3316
 
3410
 
    _see_also = ['check', 'reconcile', 'formats']
 
3317
    _see_also = ['check']
3411
3318
    takes_args = ['url?']
3412
3319
    takes_options = [
3413
 
        RegistryOption('format',
3414
 
            help='Upgrade to a specific format.  See "bzr help'
3415
 
                 ' formats" for details.',
3416
 
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3417
 
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3418
 
            value_switches=True, title='Branch format'),
3419
 
        Option('clean',
3420
 
            help='Remove the backup.bzr directory if successful.'),
3421
 
        Option('dry-run',
3422
 
            help="Show what would be done, but don't actually do anything."),
3423
 
    ]
 
3320
                    RegistryOption('format',
 
3321
                        help='Upgrade to a specific format.  See "bzr help'
 
3322
                             ' formats" for details.',
 
3323
                        lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
3324
                        converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
3325
                        value_switches=True, title='Branch format'),
 
3326
                    ]
3424
3327
 
3425
 
    def run(self, url='.', format=None, clean=False, dry_run=False):
 
3328
    def run(self, url='.', format=None):
3426
3329
        from bzrlib.upgrade import upgrade
3427
 
        exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3428
 
        if exceptions:
3429
 
            if len(exceptions) == 1:
3430
 
                # Compatibility with historical behavior
3431
 
                raise exceptions[0]
3432
 
            else:
3433
 
                return 3
 
3330
        upgrade(url, format)
3434
3331
 
3435
3332
 
3436
3333
class cmd_whoami(Command):
3472
3369
                self.outf.write(c.username() + '\n')
3473
3370
            return
3474
3371
 
3475
 
        if email:
3476
 
            raise errors.BzrCommandError("--email can only be used to display existing "
3477
 
                                         "identity")
3478
 
 
3479
3372
        # display a warning if an email address isn't included in the given name.
3480
3373
        try:
3481
3374
            _mod_config.extract_email_address(name)
3835
3728
    with bzr send. If neither is specified, the default is the upstream branch
3836
3729
    or the branch most recently merged using --remember.
3837
3730
 
3838
 
    When merging from a branch, by default bzr will try to merge in all new
3839
 
    work from the other branch, automatically determining an appropriate base
3840
 
    revision.  If this fails, you may need to give an explicit base.
3841
 
 
3842
 
    To pick a different ending revision, pass "--revision OTHER".  bzr will
3843
 
    try to merge in all new work up to and including revision OTHER.
3844
 
 
3845
 
    If you specify two values, "--revision BASE..OTHER", only revisions BASE
3846
 
    through OTHER, excluding BASE but including OTHER, will be merged.  If this
3847
 
    causes some revisions to be skipped, i.e. if the destination branch does
3848
 
    not already contain revision BASE, such a merge is commonly referred to as
3849
 
    a "cherrypick".
3850
 
 
3851
 
    Revision numbers are always relative to the source branch.
 
3731
    When merging a branch, by default the tip will be merged. To pick a different
 
3732
    revision, pass --revision. If you specify two values, the first will be used as
 
3733
    BASE and the second one as OTHER. Merging individual revisions, or a subset of
 
3734
    available revisions, like this is commonly referred to as "cherrypicking".
 
3735
 
 
3736
    Revision numbers are always relative to the branch being merged.
 
3737
 
 
3738
    By default, bzr will try to merge in all new work from the other
 
3739
    branch, automatically determining an appropriate base.  If this
 
3740
    fails, you may need to give an explicit base.
3852
3741
 
3853
3742
    Merge will do its best to combine the changes in two branches, but there
3854
3743
    are some kinds of problems only a human can fix.  When it encounters those,
3878
3767
    you to apply each diff hunk and file change, similar to "shelve".
3879
3768
 
3880
3769
    :Examples:
3881
 
        To merge all new revisions from bzr.dev::
 
3770
        To merge the latest revision from bzr.dev::
3882
3771
 
3883
3772
            bzr merge ../bzr.dev
3884
3773
 
3999
3888
            merger.other_rev_id is not None):
4000
3889
            note('Nothing to do.')
4001
3890
            return 0
4002
 
        if pull and not preview:
 
3891
        if pull:
4003
3892
            if merger.interesting_files is not None:
4004
3893
                raise errors.BzrCommandError('Cannot pull individual files')
4005
3894
            if (merger.base_rev_id == tree.last_revision()):
4118
4007
        if ((remember or tree.branch.get_submit_branch() is None) and
4119
4008
             user_location is not None):
4120
4009
            tree.branch.set_submit_branch(other_branch.base)
4121
 
        # Merge tags (but don't set them in the master branch yet, the user
4122
 
        # might revert this merge).  Commit will propagate them.
4123
 
        _merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
 
4010
        _merge_tags_if_possible(other_branch, tree.branch)
4124
4011
        merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4125
4012
            other_revision_id, base_revision_id, other_branch, base_branch)
4126
4013
        if other_path != '':
4294
4181
    last committed revision is used.
4295
4182
 
4296
4183
    To remove only some changes, without reverting to a prior version, use
4297
 
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
4298
 
    will remove the changes introduced by the second last commit (-2), without
4299
 
    affecting the changes introduced by the last commit (-1).  To remove
4300
 
    certain changes on a hunk-by-hunk basis, see the shelve command.
 
4184
    merge instead.  For example, "merge . --revision -2..-3" will remove the
 
4185
    changes introduced by -2, without affecting the changes introduced by -1.
 
4186
    Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4301
4187
 
4302
4188
    By default, any files that have been manually changed will be backed up
4303
4189
    first.  (Files changed only by merge are not backed up.)  Backup files have
4333
4219
    target branches.
4334
4220
    """
4335
4221
 
4336
 
    _see_also = ['cat', 'export', 'merge', 'shelve']
 
4222
    _see_also = ['cat', 'export']
4337
4223
    takes_options = [
4338
4224
        'revision',
4339
4225
        Option('no-backup', "Do not save backups of reverted files."),
4632
4518
 
4633
4519
    @display_command
4634
4520
    def run(self, verbose=False):
4635
 
        from bzrlib import plugin
4636
 
        self.outf.writelines(
4637
 
            plugin.describe_plugins(show_paths=verbose))
 
4521
        import bzrlib.plugin
 
4522
        from inspect import getdoc
 
4523
        result = []
 
4524
        for name, plugin in bzrlib.plugin.plugins().items():
 
4525
            version = plugin.__version__
 
4526
            if version == 'unknown':
 
4527
                version = ''
 
4528
            name_ver = '%s %s' % (name, version)
 
4529
            d = getdoc(plugin.module)
 
4530
            if d:
 
4531
                doc = d.split('\n')[0]
 
4532
            else:
 
4533
                doc = '(no description)'
 
4534
            result.append((name_ver, doc, plugin.path()))
 
4535
        for name_ver, doc, path in sorted(result):
 
4536
            self.outf.write("%s\n" % name_ver)
 
4537
            self.outf.write("   %s\n" % doc)
 
4538
            if verbose:
 
4539
                self.outf.write("   %s\n" % path)
 
4540
            self.outf.write("\n")
4638
4541
 
4639
4542
 
4640
4543
class cmd_testament(Command):
4693
4596
    @display_command
4694
4597
    def run(self, filename, all=False, long=False, revision=None,
4695
4598
            show_ids=False, directory=None):
4696
 
        from bzrlib.annotate import (
4697
 
            annotate_file_tree,
4698
 
            )
 
4599
        from bzrlib.annotate import annotate_file, annotate_file_tree
4699
4600
        wt, branch, relpath = \
4700
4601
            _open_directory_or_containing_tree_or_branch(filename, directory)
4701
4602
        if wt is not None:
4704
4605
            self.add_cleanup(branch.lock_read().unlock)
4705
4606
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4706
4607
        self.add_cleanup(tree.lock_read().unlock)
4707
 
        if wt is not None and revision is None:
 
4608
        if wt is not None:
4708
4609
            file_id = wt.path2id(relpath)
4709
4610
        else:
4710
4611
            file_id = tree.path2id(relpath)
4711
4612
        if file_id is None:
4712
4613
            raise errors.NotVersionedError(filename)
 
4614
        file_version = tree.inventory[file_id].revision
4713
4615
        if wt is not None and revision is None:
4714
4616
            # If there is a tree and we're not annotating historical
4715
4617
            # versions, annotate the working tree's content.
4716
4618
            annotate_file_tree(wt, file_id, self.outf, long, all,
4717
4619
                show_ids=show_ids)
4718
4620
        else:
4719
 
            annotate_file_tree(tree, file_id, self.outf, long, all,
4720
 
                show_ids=show_ids, branch=branch)
 
4621
            annotate_file(branch, file_version, file_id, long, all, self.outf,
 
4622
                          show_ids=show_ids)
4721
4623
 
4722
4624
 
4723
4625
class cmd_re_sign(Command):
5517
5419
    takes_options = [
5518
5420
        custom_help('directory',
5519
5421
            help='Branch whose tags should be displayed.'),
5520
 
        RegistryOption('sort',
 
5422
        RegistryOption.from_kwargs('sort',
5521
5423
            'Sort tags by different criteria.', title='Sorting',
5522
 
            lazy_registry=('bzrlib.tag', 'tag_sort_methods')
 
5424
            natural='Sort numeric substrings as numbers:'
 
5425
                    ' suitable for version numbers. (default)',
 
5426
            alpha='Sort tags lexicographically.',
 
5427
            time='Sort tags chronologically.',
5523
5428
            ),
5524
5429
        'show-ids',
5525
5430
        'revision',
5526
5431
    ]
5527
5432
 
5528
5433
    @display_command
5529
 
    def run(self, directory='.', sort=None, show_ids=False, revision=None):
5530
 
        from bzrlib.tag import tag_sort_methods
 
5434
    def run(self,
 
5435
            directory='.',
 
5436
            sort='natural',
 
5437
            show_ids=False,
 
5438
            revision=None,
 
5439
            ):
5531
5440
        branch, relpath = Branch.open_containing(directory)
5532
5441
 
5533
5442
        tags = branch.tags.get_tag_dict().items()
5542
5451
            # only show revisions between revid1 and revid2 (inclusive)
5543
5452
            tags = [(tag, revid) for tag, revid in tags if
5544
5453
                graph.is_between(revid, revid1, revid2)]
5545
 
        if sort is None:
5546
 
            sort = tag_sort_methods.get()
5547
 
        sort(branch, tags)
 
5454
        if sort == 'natural':
 
5455
            def natural_sort_key(tag):
 
5456
                return [f(s) for f,s in 
 
5457
                        zip(itertools.cycle((unicode.lower,int)),
 
5458
                                            re.split('([0-9]+)', tag[0]))]
 
5459
            tags.sort(key=natural_sort_key)
 
5460
        elif sort == 'alpha':
 
5461
            tags.sort()
 
5462
        elif sort == 'time':
 
5463
            timestamps = {}
 
5464
            for tag, revid in tags:
 
5465
                try:
 
5466
                    revobj = branch.repository.get_revision(revid)
 
5467
                except errors.NoSuchRevision:
 
5468
                    timestamp = sys.maxint # place them at the end
 
5469
                else:
 
5470
                    timestamp = revobj.timestamp
 
5471
                timestamps[revid] = timestamp
 
5472
            tags.sort(key=lambda x: timestamps[x[1]])
5548
5473
        if not show_ids:
5549
5474
            # [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5550
5475
            for index, (tag, revid) in enumerate(tags):
5552
5477
                    revno = branch.revision_id_to_dotted_revno(revid)
5553
5478
                    if isinstance(revno, tuple):
5554
5479
                        revno = '.'.join(map(str, revno))
5555
 
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
5480
                except errors.NoSuchRevision:
5556
5481
                    # Bad tag data/merges can lead to tagged revisions
5557
5482
                    # which are not in this branch. Fail gracefully ...
5558
5483
                    revno = '?'
5948
5873
            location = "."
5949
5874
        branch = Branch.open_containing(location)[0]
5950
5875
        branch.bzrdir.destroy_branch()
5951
 
 
 
5876
        
5952
5877
 
5953
5878
class cmd_shelve(Command):
5954
5879
    __doc__ = """Temporarily set aside some changes from the current tree.
5973
5898
 
5974
5899
    You can put multiple items on the shelf, and by default, 'unshelve' will
5975
5900
    restore the most recently shelved changes.
5976
 
 
5977
 
    For complicated changes, it is possible to edit the changes in a separate
5978
 
    editor program to decide what the file remaining in the working copy
5979
 
    should look like.  To do this, add the configuration option
5980
 
 
5981
 
        change_editor = PROGRAM @new_path @old_path
5982
 
 
5983
 
    where @new_path is replaced with the path of the new version of the 
5984
 
    file and @old_path is replaced with the path of the old version of 
5985
 
    the file.  The PROGRAM should save the new file with the desired 
5986
 
    contents of the file in the working tree.
5987
 
        
5988
5901
    """
5989
5902
 
5990
5903
    takes_args = ['file*']
6002
5915
        Option('destroy',
6003
5916
               help='Destroy removed changes instead of shelving them.'),
6004
5917
    ]
6005
 
    _see_also = ['unshelve', 'configuration']
 
5918
    _see_also = ['unshelve']
6006
5919
 
6007
5920
    def run(self, revision=None, all=False, file_list=None, message=None,
6008
 
            writer=None, list=False, destroy=False, directory=None):
 
5921
            writer=None, list=False, destroy=False, directory=u'.'):
6009
5922
        if list:
6010
 
            return self.run_for_list(directory=directory)
 
5923
            return self.run_for_list()
6011
5924
        from bzrlib.shelf_ui import Shelver
6012
5925
        if writer is None:
6013
5926
            writer = bzrlib.option.diff_writer_registry.get()
6021
5934
        except errors.UserAbort:
6022
5935
            return 0
6023
5936
 
6024
 
    def run_for_list(self, directory=None):
6025
 
        if directory is None:
6026
 
            directory = u'.'
6027
 
        tree = WorkingTree.open_containing(directory)[0]
 
5937
    def run_for_list(self):
 
5938
        tree = WorkingTree.open_containing('.')[0]
6028
5939
        self.add_cleanup(tree.lock_read().unlock)
6029
5940
        manager = tree.get_shelf_manager()
6030
5941
        shelves = manager.active_shelves()
6089
6000
    """
6090
6001
    takes_options = ['directory',
6091
6002
                     Option('ignored', help='Delete all ignored files.'),
6092
 
                     Option('detritus', help='Delete conflict files, merge and revert'
 
6003
                     Option('detritus', help='Delete conflict files, merge'
6093
6004
                            ' backups, and failed selftest dirs.'),
6094
6005
                     Option('unknown',
6095
6006
                            help='Delete files unknown to bzr (default).'),
6154
6065
            self.outf.write('%s %s\n' % (path, location))
6155
6066
 
6156
6067
 
6157
 
class cmd_export_pot(Command):
6158
 
    __doc__ = """Export command helps and error messages in po format."""
6159
 
 
6160
 
    hidden = True
6161
 
 
6162
 
    def run(self):
6163
 
        from bzrlib.export_pot import export_pot
6164
 
        export_pot(self.outf)
6165
 
 
6166
 
 
6167
6068
def _register_lazy_builtins():
6168
6069
    # register lazy builtins from other modules; called at startup and should
6169
6070
    # be only called once.
6175
6076
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6176
6077
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6177
6078
        ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6178
 
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
 
6079
        ('cmd_test_script', [], 'bzrlib.tests.script'),
6179
6080
        ]:
6180
6081
        builtin_command_registry.register_lazy(name, aliases, module_name)