~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: 2011-08-09 17:04:46 UTC
  • mfrom: (6055.1.3 822571-bzr-home-unicode)
  • Revision ID: pqm@pqm.ubuntu.com-20110809170446-f1wc1a8fhgnxi4cn
(vila) Decode BZR_HOME with fs encoding to allow unicode homes. (Vincent
 Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    rename_map,
45
45
    revision as _mod_revision,
46
46
    static_tuple,
47
 
    symbol_versioning,
48
47
    timestamp,
49
48
    transport,
50
49
    ui,
51
50
    urlutils,
52
51
    views,
 
52
    gpg,
53
53
    )
54
54
from bzrlib.branch import Branch
55
55
from bzrlib.conflicts import ConflictList
72
72
    _parse_revision_str,
73
73
    )
74
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
 
75
from bzrlib import (
 
76
    symbol_versioning,
 
77
    )
75
78
 
76
79
 
77
80
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
229
232
    unknown
230
233
        Not versioned and not matching an ignore pattern.
231
234
 
232
 
    Additionally for directories, symlinks and files with an executable
233
 
    bit, Bazaar indicates their type using a trailing character: '/', '@'
234
 
    or '*' respectively.
 
235
    Additionally for directories, symlinks and files with a changed
 
236
    executable bit, Bazaar indicates their type using a trailing
 
237
    character: '/', '@' or '*' respectively. These decorations can be
 
238
    disabled using the '--no-classify' option.
235
239
 
236
240
    To see ignored files use 'bzr ignored'.  For details on the
237
241
    changes to file texts, use 'bzr diff'.
268
272
                            short_name='V'),
269
273
                     Option('no-pending', help='Don\'t show pending merges.',
270
274
                           ),
 
275
                     Option('no-classify',
 
276
                            help='Do not mark object type using indicator.',
 
277
                           ),
271
278
                     ]
272
279
    aliases = ['st', 'stat']
273
280
 
276
283
 
277
284
    @display_command
278
285
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
279
 
            versioned=False, no_pending=False, verbose=False):
 
286
            versioned=False, no_pending=False, verbose=False,
 
287
            no_classify=False):
280
288
        from bzrlib.status import show_tree_status
281
289
 
282
290
        if revision and len(revision) > 2:
296
304
        show_tree_status(tree, show_ids=show_ids,
297
305
                         specific_files=relfile_list, revision=revision,
298
306
                         to_file=self.outf, short=short, versioned=versioned,
299
 
                         show_pending=(not no_pending), verbose=verbose)
 
307
                         show_pending=(not no_pending), verbose=verbose,
 
308
                         classify=not no_classify)
300
309
 
301
310
 
302
311
class cmd_cat_revision(Command):
794
803
                                      require_versioned=True)
795
804
            # find_ids_across_trees may include some paths that don't
796
805
            # exist in 'tree'.
797
 
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
798
 
                             for file_id in file_ids if file_id in tree)
 
806
            entries = sorted(
 
807
                (tree.id2path(file_id), tree.inventory[file_id])
 
808
                for file_id in file_ids if tree.has_id(file_id))
799
809
        else:
800
810
            entries = tree.inventory.entries()
801
811
 
1738
1748
            b = wt.branch
1739
1749
            last_revision = wt.last_revision()
1740
1750
 
1741
 
        revision_ids = b.repository.get_ancestry(last_revision)
1742
 
        revision_ids.pop(0)
1743
 
        for revision_id in revision_ids:
 
1751
        self.add_cleanup(b.repository.lock_read().unlock)
 
1752
        graph = b.repository.get_graph()
 
1753
        revisions = [revid for revid, parents in
 
1754
            graph.iter_ancestry([last_revision])]
 
1755
        for revision_id in reversed(revisions):
 
1756
            if _mod_revision.is_null(revision_id):
 
1757
                continue
1744
1758
            self.outf.write(revision_id + '\n')
1745
1759
 
1746
1760
 
2148
2162
        basis_inv = basis.inventory
2149
2163
        inv = wt.inventory
2150
2164
        for file_id in inv:
2151
 
            if file_id in basis_inv:
 
2165
            if basis_inv.has_id(file_id):
2152
2166
                continue
2153
2167
            if inv.is_root(file_id) and len(basis_inv) == 0:
2154
2168
                continue
2303
2317
 
2304
2318
    :Other filtering:
2305
2319
 
2306
 
      The --message option can be used for finding revisions that match a
2307
 
      regular expression in a commit message.
 
2320
      The --match option can be used for finding revisions that match a
 
2321
      regular expression in a commit message, committer, author or bug.
 
2322
      Specifying the option several times will match any of the supplied
 
2323
      expressions. --match-author, --match-bugs, --match-committer and
 
2324
      --match-message can be used to only match a specific field.
2308
2325
 
2309
2326
    :Tips & tricks:
2310
2327
 
2370
2387
                   argname='N',
2371
2388
                   type=_parse_levels),
2372
2389
            Option('message',
2373
 
                   short_name='m',
2374
2390
                   help='Show revisions whose message matches this '
2375
2391
                        'regular expression.',
2376
 
                   type=str),
 
2392
                   type=str,
 
2393
                   hidden=True),
2377
2394
            Option('limit',
2378
2395
                   short_name='l',
2379
2396
                   help='Limit the output to the first N revisions.',
2387
2404
            Option('exclude-common-ancestry',
2388
2405
                   help='Display only the revisions that are not part'
2389
2406
                   ' of both ancestries (require -rX..Y)'
2390
 
                   )
 
2407
                   ),
 
2408
            Option('signatures',
 
2409
                   help='Show digital signature validity'),
 
2410
            ListOption('match',
 
2411
                short_name='m',
 
2412
                help='Show revisions whose properties match this '
 
2413
                'expression.',
 
2414
                type=str),
 
2415
            ListOption('match-message',
 
2416
                   help='Show revisions whose message matches this '
 
2417
                   'expression.',
 
2418
                type=str),
 
2419
            ListOption('match-committer',
 
2420
                   help='Show revisions whose committer matches this '
 
2421
                   'expression.',
 
2422
                type=str),
 
2423
            ListOption('match-author',
 
2424
                   help='Show revisions whose authors match this '
 
2425
                   'expression.',
 
2426
                type=str),
 
2427
            ListOption('match-bugs',
 
2428
                   help='Show revisions whose bugs match this '
 
2429
                   'expression.',
 
2430
                type=str)
2391
2431
            ]
2392
2432
    encoding_type = 'replace'
2393
2433
 
2406
2446
            include_merges=False,
2407
2447
            authors=None,
2408
2448
            exclude_common_ancestry=False,
 
2449
            signatures=False,
 
2450
            match=None,
 
2451
            match_message=None,
 
2452
            match_committer=None,
 
2453
            match_author=None,
 
2454
            match_bugs=None,
2409
2455
            ):
2410
2456
        from bzrlib.log import (
2411
2457
            Logger,
2465
2511
            self.add_cleanup(b.lock_read().unlock)
2466
2512
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2467
2513
 
 
2514
        if b.get_config().validate_signatures_in_log():
 
2515
            signatures = True
 
2516
 
 
2517
        if signatures:
 
2518
            if not gpg.GPGStrategy.verify_signatures_available():
 
2519
                raise errors.GpgmeNotInstalled(None)
 
2520
 
2468
2521
        # Decide on the type of delta & diff filtering to use
2469
2522
        # TODO: add an --all-files option to make this configurable & consistent
2470
2523
        if not verbose:
2507
2560
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2508
2561
            or delta_type or partial_history)
2509
2562
 
 
2563
        match_dict = {}
 
2564
        if match:
 
2565
            match_dict[''] = match
 
2566
        if match_message:
 
2567
            match_dict['message'] = match_message
 
2568
        if match_committer:
 
2569
            match_dict['committer'] = match_committer
 
2570
        if match_author:
 
2571
            match_dict['author'] = match_author
 
2572
        if match_bugs:
 
2573
            match_dict['bugs'] = match_bugs
 
2574
            
2510
2575
        # Build the LogRequest and execute it
2511
2576
        if len(file_ids) == 0:
2512
2577
            file_ids = None
2515
2580
            start_revision=rev1, end_revision=rev2, limit=limit,
2516
2581
            message_search=message, delta_type=delta_type,
2517
2582
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2518
 
            exclude_common_ancestry=exclude_common_ancestry,
 
2583
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
 
2584
            signature=signatures
2519
2585
            )
2520
2586
        Logger(b, rqst).show(lf)
2521
2587
 
3007
3073
 
3008
3074
        old_file_id = rev_tree.path2id(relpath)
3009
3075
 
 
3076
        # TODO: Split out this code to something that generically finds the
 
3077
        # best id for a path across one or more trees; it's like
 
3078
        # find_ids_across_trees but restricted to find just one. -- mbp
 
3079
        # 20110705.
3010
3080
        if name_from_revision:
3011
3081
            # Try in revision if requested
3012
3082
            if old_file_id is None:
3014
3084
                    "%r is not present in revision %s" % (
3015
3085
                        filename, rev_tree.get_revision_id()))
3016
3086
            else:
3017
 
                content = rev_tree.get_file_text(old_file_id)
 
3087
                actual_file_id = old_file_id
3018
3088
        else:
3019
3089
            cur_file_id = tree.path2id(relpath)
3020
 
            found = False
3021
 
            if cur_file_id is not None:
3022
 
                # Then try with the actual file id
3023
 
                try:
3024
 
                    content = rev_tree.get_file_text(cur_file_id)
3025
 
                    found = True
3026
 
                except errors.NoSuchId:
3027
 
                    # The actual file id didn't exist at that time
3028
 
                    pass
3029
 
            if not found and old_file_id is not None:
3030
 
                # Finally try with the old file id
3031
 
                content = rev_tree.get_file_text(old_file_id)
3032
 
                found = True
3033
 
            if not found:
3034
 
                # Can't be found anywhere
 
3090
            if cur_file_id is not None and rev_tree.has_id(cur_file_id):
 
3091
                actual_file_id = cur_file_id
 
3092
            elif old_file_id is not None:
 
3093
                actual_file_id = old_file_id
 
3094
            else:
3035
3095
                raise errors.BzrCommandError(
3036
3096
                    "%r is not present in revision %s" % (
3037
3097
                        filename, rev_tree.get_revision_id()))
3038
3098
        if filtered:
3039
 
            from bzrlib.filters import (
3040
 
                ContentFilterContext,
3041
 
                filtered_output_bytes,
3042
 
                )
3043
 
            filters = rev_tree._content_filter_stack(relpath)
3044
 
            chunks = content.splitlines(True)
3045
 
            content = filtered_output_bytes(chunks, filters,
3046
 
                ContentFilterContext(relpath, rev_tree))
3047
 
            self.cleanup_now()
3048
 
            self.outf.writelines(content)
 
3099
            from bzrlib.filter_tree import ContentFilterTree
 
3100
            filter_tree = ContentFilterTree(rev_tree,
 
3101
                rev_tree._content_filter_stack)
 
3102
            content = filter_tree.get_file_text(actual_file_id)
3049
3103
        else:
3050
 
            self.cleanup_now()
3051
 
            self.outf.write(content)
 
3104
            content = rev_tree.get_file_text(actual_file_id)
 
3105
        self.cleanup_now()
 
3106
        self.outf.write(content)
3052
3107
 
3053
3108
 
3054
3109
class cmd_local_time_offset(Command):
3191
3246
        from bzrlib.msgeditor import (
3192
3247
            edit_commit_message_encoded,
3193
3248
            generate_commit_message_template,
3194
 
            make_commit_message_template_encoded
 
3249
            make_commit_message_template_encoded,
 
3250
            set_commit_message,
3195
3251
        )
3196
3252
 
3197
3253
        commit_stamp = offset = None
3263
3319
                # make_commit_message_template_encoded returns user encoding.
3264
3320
                # We probably want to be using edit_commit_message instead to
3265
3321
                # avoid this.
3266
 
                start_message = generate_commit_message_template(commit_obj)
3267
 
                my_message = edit_commit_message_encoded(text,
3268
 
                    start_message=start_message)
 
3322
                my_message = set_commit_message(commit_obj)
 
3323
                if my_message is None:
 
3324
                    start_message = generate_commit_message_template(commit_obj)
 
3325
                    my_message = edit_commit_message_encoded(text,
 
3326
                        start_message=start_message)
3269
3327
                if my_message is None:
3270
3328
                    raise errors.BzrCommandError("please specify a commit"
3271
3329
                        " message with either --message or --file")
3646
3704
        if typestring == "sftp":
3647
3705
            from bzrlib.tests import stub_sftp
3648
3706
            return stub_sftp.SFTPAbsoluteServer
3649
 
        if typestring == "memory":
 
3707
        elif typestring == "memory":
3650
3708
            from bzrlib.tests import test_server
3651
3709
            return memory.MemoryServer
3652
 
        if typestring == "fakenfs":
 
3710
        elif typestring == "fakenfs":
3653
3711
            from bzrlib.tests import test_server
3654
3712
            return test_server.FakeNFSServer
3655
3713
        msg = "No known transport type %s. Supported types are: sftp\n" %\
3689
3747
                     Option('randomize', type=str, argname="SEED",
3690
3748
                            help='Randomize the order of tests using the given'
3691
3749
                                 ' seed or "now" for the current time.'),
3692
 
                     Option('exclude', type=str, argname="PATTERN",
3693
 
                            short_name='x',
3694
 
                            help='Exclude tests that match this regular'
3695
 
                                 ' expression.'),
 
3750
                     ListOption('exclude', type=str, argname="PATTERN",
 
3751
                                short_name='x',
 
3752
                                help='Exclude tests that match this regular'
 
3753
                                ' expression.'),
3696
3754
                     Option('subunit',
3697
3755
                        help='Output test progress via subunit.'),
3698
3756
                     Option('strict', help='Fail on missing dependencies or '
3749
3807
                "--benchmark is no longer supported from bzr 2.2; "
3750
3808
                "use bzr-usertest instead")
3751
3809
        test_suite_factory = None
 
3810
        if not exclude:
 
3811
            exclude_pattern = None
 
3812
        else:
 
3813
            exclude_pattern = '(' + '|'.join(exclude) + ')'
3752
3814
        selftest_kwargs = {"verbose": verbose,
3753
3815
                          "pattern": pattern,
3754
3816
                          "stop_on_failure": one,
3759
3821
                          "matching_tests_first": first,
3760
3822
                          "list_only": list_only,
3761
3823
                          "random_seed": randomize,
3762
 
                          "exclude_pattern": exclude,
 
3824
                          "exclude_pattern": exclude_pattern,
3763
3825
                          "strict": strict,
3764
3826
                          "load_list": load_list,
3765
3827
                          "debug_flags": debugflag,
3834
3896
    The source of the merge can be specified either in the form of a branch,
3835
3897
    or in the form of a path to a file containing a merge directive generated
3836
3898
    with bzr send. If neither is specified, the default is the upstream branch
3837
 
    or the branch most recently merged using --remember.
 
3899
    or the branch most recently merged using --remember.  The source of the
 
3900
    merge may also be specified in the form of a path to a file in another
 
3901
    branch:  in this case, only the modifications to that file are merged into
 
3902
    the current working tree.
3838
3903
 
3839
3904
    When merging from a branch, by default bzr will try to merge in all new
3840
3905
    work from the other branch, automatically determining an appropriate base
3870
3935
    committed to record the result of the merge.
3871
3936
 
3872
3937
    merge refuses to run if there are any uncommitted changes, unless
3873
 
    --force is given. The --force option can also be used to create a
 
3938
    --force is given.  If --force is given, then the changes from the source 
 
3939
    will be merged with the current working tree, including any uncommitted
 
3940
    changes in the tree.  The --force option can also be used to create a
3874
3941
    merge revision which has more than two parents.
3875
3942
 
3876
3943
    If one would like to merge changes from the working tree of the other
4004
4071
        self.sanity_check_merger(merger)
4005
4072
        if (merger.base_rev_id == merger.other_rev_id and
4006
4073
            merger.other_rev_id is not None):
 
4074
            # check if location is a nonexistent file (and not a branch) to
 
4075
            # disambiguate the 'Nothing to do'
 
4076
            if merger.interesting_files:
 
4077
                if not merger.other_tree.has_filename(
 
4078
                    merger.interesting_files[0]):
 
4079
                    note("merger: " + str(merger))
 
4080
                    raise errors.PathsDoNotExist([location])
4007
4081
            note('Nothing to do.')
4008
4082
            return 0
4009
4083
        if pull and not preview:
4952
5026
 
4953
5027
        if not force:
4954
5028
            if not ui.ui_factory.confirm_action(
4955
 
                    'Uncommit these revisions',
 
5029
                    u'Uncommit these revisions',
4956
5030
                    'bzrlib.builtins.uncommit',
4957
5031
                    {}):
4958
5032
                self.outf.write('Canceled\n')
5636
5710
            unstacked=None):
5637
5711
        directory = bzrdir.BzrDir.open(location)
5638
5712
        if stacked_on and unstacked:
5639
 
            raise BzrCommandError("Can't use both --stacked-on and --unstacked")
 
5713
            raise errors.BzrCommandError("Can't use both --stacked-on and --unstacked")
5640
5714
        elif stacked_on is not None:
5641
5715
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5642
5716
        elif unstacked:
6194
6268
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6195
6269
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6196
6270
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6197
 
        ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
 
6271
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
 
6272
        ('cmd_verify_signatures', [],
 
6273
                                        'bzrlib.commit_signature_commands'),
6198
6274
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6199
6275
        ]:
6200
6276
        builtin_command_registry.register_lazy(name, aliases, module_name)