~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
166
166
                     Option('short', help='Use short status indicators.',
167
167
                            short_name='S'),
168
168
                     Option('versioned', help='Only show versioned files.',
169
 
                            short_name='V'),
170
 
                     Option('no-pending', help='Don\'t show pending merges.',
171
 
                           ),
 
169
                            short_name='V')
172
170
                     ]
173
171
    aliases = ['st', 'stat']
174
172
 
177
175
    
178
176
    @display_command
179
177
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
180
 
            versioned=False, no_pending=False):
 
178
            versioned=False):
181
179
        from bzrlib.status import show_tree_status
182
180
 
183
181
        if revision and len(revision) > 2:
188
186
            
189
187
        show_tree_status(tree, show_ids=show_ids,
190
188
                         specific_files=file_list, revision=revision,
191
 
                         to_file=self.outf, short=short, versioned=versioned,
192
 
                         show_pending=not no_pending)
 
189
                         to_file=self.outf, short=short, versioned=versioned)
193
190
 
194
191
 
195
192
class cmd_cat_revision(Command):
224
221
                if rev is None:
225
222
                    raise errors.BzrCommandError('You cannot specify a NULL'
226
223
                                                 ' revision.')
227
 
                rev_id = rev.as_revision_id(b)
 
224
                revno, rev_id = rev.in_history(b)
228
225
                self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
229
226
    
230
227
 
298
295
            revs.append(RevisionSpec.from_string('-1'))
299
296
 
300
297
        for rev in revs:
301
 
            revision_id = rev.as_revision_id(b)
302
 
            try:
303
 
                revno = '%4d' % (b.revision_id_to_revno(revision_id))
304
 
            except errors.NoSuchRevision:
 
298
            revinfo = rev.in_history(b)
 
299
            if revinfo.revno is None:
305
300
                dotted_map = b.get_revision_id_to_revno_map()
306
 
                revno = '.'.join(str(i) for i in dotted_map[revision_id])
307
 
            print '%s %s' % (revno, revision_id)
 
301
                revno = '.'.join(str(i) for i in dotted_map[revinfo.rev_id])
 
302
                print '%s %s' % (revno, revinfo.rev_id)
 
303
            else:
 
304
                print '%4d %s' % (revinfo.revno, revinfo.rev_id)
308
305
 
309
306
    
310
307
class cmd_add(Command):
469
466
                    raise errors.BzrCommandError(
470
467
                        'bzr inventory --revision takes exactly one revision'
471
468
                        ' identifier')
472
 
                revision_id = revision[0].as_revision_id(work_tree.branch)
 
469
                revision_id = revision[0].in_history(work_tree.branch).rev_id
473
470
                tree = work_tree.branch.repository.revision_tree(revision_id)
474
471
 
475
472
                extra_trees = [work_tree]
537
534
        if len(names_list) < 2:
538
535
            raise errors.BzrCommandError("missing file argument")
539
536
        tree, rel_names = tree_files(names_list)
540
 
        tree.lock_write()
541
 
        try:
542
 
            self._run(tree, names_list, rel_names, after)
543
 
        finally:
544
 
            tree.unlock()
545
537
 
546
 
    def _run(self, tree, names_list, rel_names, after):
547
 
        into_existing = osutils.isdir(names_list[-1])
548
 
        if into_existing and len(names_list) == 2:
549
 
            # special cases:
550
 
            # a. case-insensitive filesystem and change case of dir
551
 
            # b. move directory after the fact (if the source used to be
552
 
            #    a directory, but now doesn't exist in the working tree
553
 
            #    and the target is an existing directory, just rename it)
554
 
            if (not tree.case_sensitive
555
 
                and rel_names[0].lower() == rel_names[1].lower()):
556
 
                into_existing = False
557
 
            else:
558
 
                inv = tree.inventory
559
 
                from_id = tree.path2id(rel_names[0])
560
 
                if (not osutils.lexists(names_list[0]) and
561
 
                    from_id and inv.get_file_kind(from_id) == "directory"):
562
 
                    into_existing = False
563
 
        # move/rename
564
 
        if into_existing:
 
538
        dest = names_list[-1]
 
539
        isdir = os.path.isdir(dest)
 
540
        if (isdir and not tree.case_sensitive and len(rel_names) == 2
 
541
            and rel_names[0].lower() == rel_names[1].lower()):
 
542
                isdir = False
 
543
        if isdir:
565
544
            # move into existing directory
566
545
            for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
567
546
                self.outf.write("%s => %s\n" % pair)
592
571
    that, you can omit the location to use the default.  To change the
593
572
    default, use --remember. The value will only be saved if the remote
594
573
    location can be accessed.
595
 
 
596
 
    Note: The location can be specified either in the form of a branch,
597
 
    or in the form of a path to a file containing a merge directive generated
598
 
    with bzr send.
599
574
    """
600
575
 
601
576
    _see_also = ['push', 'update', 'status-flags']
629
604
 
630
605
        possible_transports = []
631
606
        if location is not None:
632
 
            try:
633
 
                mergeable = bundle.read_mergeable_from_url(location,
634
 
                    possible_transports=possible_transports)
635
 
            except errors.NotABundle:
636
 
                mergeable = None
 
607
            mergeable, location_transport = _get_mergeable_helper(location)
 
608
            possible_transports.append(location_transport)
637
609
 
638
610
        stored_loc = branch_to.get_parent()
639
611
        if location is None:
646
618
                if not is_quiet():
647
619
                    self.outf.write("Using saved location: %s\n" % display_url)
648
620
                location = stored_loc
 
621
                location_transport = transport.get_transport(
 
622
                    location, possible_transports=possible_transports)
649
623
 
650
624
        if mergeable is not None:
651
625
            if revision is not None:
656
630
                mergeable.get_merge_request(branch_to.repository)
657
631
            branch_from = branch_to
658
632
        else:
659
 
            branch_from = Branch.open(location,
660
 
                possible_transports=possible_transports)
 
633
            branch_from = Branch.open_from_transport(location_transport)
661
634
 
662
635
            if branch_to.get_parent() is None or remember:
663
636
                branch_to.set_parent(branch_from.base)
664
637
 
665
638
        if revision is not None:
666
639
            if len(revision) == 1:
667
 
                revision_id = revision[0].as_revision_id(branch_from)
 
640
                revision_id = revision[0].in_history(branch_from).rev_id
668
641
            else:
669
642
                raise errors.BzrCommandError(
670
643
                    'bzr pull --revision takes one value.')
925
898
        br_from.lock_read()
926
899
        try:
927
900
            if len(revision) == 1 and revision[0] is not None:
928
 
                revision_id = revision[0].as_revision_id(br_from)
 
901
                revision_id = revision[0].in_history(br_from)[1]
929
902
            else:
930
903
                # FIXME - wt.last_revision, fallback to branch, fall back to
931
904
                # None or perhaps NULL_REVISION to mean copy nothing
1019
992
        if files_from is not None:
1020
993
            accelerator_tree = WorkingTree.open(files_from)
1021
994
        if len(revision) == 1 and revision[0] is not None:
1022
 
            revision_id = revision[0].as_revision_id(source)
 
995
            revision_id = _mod_revision.ensure_null(
 
996
                revision[0].in_history(source)[1])
1023
997
        else:
1024
998
            revision_id = None
1025
999
        if to_location is None:
1879
1853
            relpath += '/'
1880
1854
        if revision is not None:
1881
1855
            tree = branch.repository.revision_tree(
1882
 
                revision[0].as_revision_id(branch))
 
1856
                revision[0].in_history(branch).rev_id)
1883
1857
        elif tree is None:
1884
1858
            tree = branch.basis_tree()
1885
1859
 
2144
2118
        else:
2145
2119
            if len(revision) != 1:
2146
2120
                raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
2147
 
            rev_id = revision[0].as_revision_id(b)
 
2121
            rev_id = revision[0].in_history(b).rev_id
2148
2122
        t = b.repository.revision_tree(rev_id)
2149
2123
        try:
2150
2124
            export(t, dest, format, root)
2189
2163
        if revision is None:
2190
2164
            revision_id = b.last_revision()
2191
2165
        else:
2192
 
            revision_id = revision[0].as_revision_id(b)
 
2166
            revision_id = revision[0].in_history(b).rev_id
2193
2167
 
2194
2168
        cur_file_id = tree.path2id(relpath)
2195
2169
        rev_tree = b.repository.revision_tree(revision_id)
2674
2648
            print '   %s (%s python%s)' % (
2675
2649
                    bzrlib.__path__[0],
2676
2650
                    bzrlib.version_string,
2677
 
                    bzrlib._format_version_tuple(sys.version_info),
 
2651
                    '.'.join(map(str, sys.version_info)),
2678
2652
                    )
2679
2653
        print
2680
2654
        if testspecs_list is not None:
2719
2693
    """Show version of bzr."""
2720
2694
 
2721
2695
    encoding_type = 'replace'
2722
 
    takes_options = [
2723
 
        Option("short", help="Print just the version number."),
2724
 
        ]
2725
2696
 
2726
2697
    @display_command
2727
 
    def run(self, short=False):
 
2698
    def run(self):
2728
2699
        from bzrlib.version import show_version
2729
 
        if short:
2730
 
            self.outf.write(bzrlib.version_string + '\n')
2731
 
        else:
2732
 
            show_version(to_file=self.outf)
 
2700
        show_version(to_file=self.outf)
2733
2701
 
2734
2702
 
2735
2703
class cmd_rocks(Command):
2775
2743
class cmd_merge(Command):
2776
2744
    """Perform a three-way merge.
2777
2745
    
2778
 
    The source of the merge can be specified either in the form of a branch,
2779
 
    or in the form of a path to a file containing a merge directive generated
2780
 
    with bzr send. If neither is specified, the default is the upstream branch
2781
 
    or the branch most recently merged using --remember.
2782
 
 
2783
 
    When merging a branch, by default the tip will be merged. To pick a different
2784
 
    revision, pass --revision. If you specify two values, the first will be used as
2785
 
    BASE and the second one as OTHER. Merging individual revisions, or a subset of
2786
 
    available revisions, like this is commonly referred to as "cherrypicking".
2787
 
 
2788
 
    Revision numbers are always relative to the branch being merged.
 
2746
    The branch is the branch you will merge from.  By default, it will merge
 
2747
    the latest revision.  If you specify a revision, that revision will be
 
2748
    merged.  If you specify two revisions, the first will be used as a BASE,
 
2749
    and the second one as OTHER.  Revision numbers are always relative to the
 
2750
    specified branch.
2789
2751
 
2790
2752
    By default, bzr will try to merge in all new work from the other
2791
2753
    branch, automatically determining an appropriate base.  If this
2822
2784
        To merge the changes introduced by 82, without previous changes::
2823
2785
 
2824
2786
            bzr merge -r 81..82 ../bzr.dev
2825
 
 
2826
 
        To apply a merge directive contained in in /tmp/merge:
2827
 
 
2828
 
            bzr merge /tmp/merge
2829
2787
    """
2830
2788
 
2831
2789
    encoding_type = 'exact'
2832
2790
    _see_also = ['update', 'remerge', 'status-flags']
2833
 
    takes_args = ['location?']
 
2791
    takes_args = ['branch?']
2834
2792
    takes_options = [
2835
2793
        'change',
2836
2794
        'revision',
2856
2814
        Option('preview', help='Instead of merging, show a diff of the merge.')
2857
2815
    ]
2858
2816
 
2859
 
    def run(self, location=None, revision=None, force=False,
2860
 
            merge_type=None, show_base=False, reprocess=False, remember=False,
 
2817
    def run(self, branch=None, revision=None, force=False, merge_type=None,
 
2818
            show_base=False, reprocess=False, remember=False,
2861
2819
            uncommitted=False, pull=False,
2862
2820
            directory=None,
2863
2821
            preview=False,
2864
2822
            ):
 
2823
        # This is actually a branch (or merge-directive) *location*.
 
2824
        location = branch
 
2825
        del branch
 
2826
 
2865
2827
        if merge_type is None:
2866
2828
            merge_type = _mod_merge.Merge3Merger
2867
2829
 
2880
2842
            tree.lock_write()
2881
2843
            cleanups.append(tree.unlock)
2882
2844
            if location is not None:
2883
 
                try:
2884
 
                    mergeable = bundle.read_mergeable_from_url(location,
2885
 
                        possible_transports=possible_transports)
2886
 
                except errors.NotABundle:
2887
 
                    mergeable = None
2888
 
                else:
 
2845
                mergeable, other_transport = _get_mergeable_helper(location)
 
2846
                if mergeable:
2889
2847
                    if uncommitted:
2890
2848
                        raise errors.BzrCommandError('Cannot use --uncommitted'
2891
2849
                            ' with bundles or merge directives.')
2895
2853
                            'Cannot use -r with merge directives or bundles')
2896
2854
                    merger, verified = _mod_merge.Merger.from_mergeable(tree,
2897
2855
                       mergeable, pb)
 
2856
                possible_transports.append(other_transport)
2898
2857
 
2899
2858
            if merger is None and uncommitted:
2900
2859
                if revision is not None and len(revision) > 0:
3000
2959
            other_revision_id = _mod_revision.ensure_null(
3001
2960
                other_branch.last_revision())
3002
2961
        else:
3003
 
            other_revision_id = revision[-1].as_revision_id(other_branch)
 
2962
            other_revision_id = \
 
2963
                _mod_revision.ensure_null(
 
2964
                    revision[-1].in_history(other_branch).rev_id)
3004
2965
        if (revision is not None and len(revision) == 2
3005
2966
            and revision[0] is not None):
3006
 
            base_revision_id = revision[0].as_revision_id(base_branch)
 
2967
            base_revision_id = \
 
2968
                _mod_revision.ensure_null(
 
2969
                    revision[0].in_history(base_branch).rev_id)
3007
2970
        else:
3008
2971
            base_revision_id = None
3009
2972
        # Remember where we merge from
3222
3185
        elif len(revision) != 1:
3223
3186
            raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
3224
3187
        else:
3225
 
            rev_id = revision[0].as_revision_id(tree.branch)
 
3188
            rev_id = revision[0].in_history(tree.branch).rev_id
3226
3189
        pb = ui.ui_factory.nested_progress_bar()
3227
3190
        try:
3228
3191
            tree.revert(file_list,
3473
3436
            if revision is None:
3474
3437
                rev_id = b.last_revision()
3475
3438
            else:
3476
 
                rev_id = revision[0].as_revision_id(b)
 
3439
                rev_id = revision[0].in_history(b).rev_id
3477
3440
            t = testament_class.from_revision(b.repository, rev_id)
3478
3441
            if long:
3479
3442
                sys.stdout.writelines(t.as_text_lines())
3520
3483
            elif len(revision) != 1:
3521
3484
                raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
3522
3485
            else:
3523
 
                revision_id = revision[0].as_revision_id(branch)
 
3486
                revision_id = revision[0].in_history(branch).rev_id
3524
3487
            tree = branch.repository.revision_tree(revision_id)
3525
3488
            if wt is not None:
3526
3489
                file_id = wt.path2id(relpath)
3676
3639
    _see_also = ['commit']
3677
3640
    takes_options = ['verbose', 'revision',
3678
3641
                    Option('dry-run', help='Don\'t actually make changes.'),
3679
 
                    Option('force', help='Say yes to all questions.'),
3680
 
                    Option('local',
3681
 
                           help="Only remove the commits from the local branch"
3682
 
                                " when in a checkout."
3683
 
                           ),
3684
 
                    ]
 
3642
                    Option('force', help='Say yes to all questions.')]
3685
3643
    takes_args = ['location?']
3686
3644
    aliases = []
3687
3645
    encoding_type = 'replace'
3688
3646
 
3689
3647
    def run(self, location=None,
3690
3648
            dry_run=False, verbose=False,
3691
 
            revision=None, force=False, local=False):
 
3649
            revision=None, force=False):
3692
3650
        if location is None:
3693
3651
            location = u'.'
3694
3652
        control, relpath = bzrdir.BzrDir.open_containing(location)
3704
3662
        else:
3705
3663
            b.lock_write()
3706
3664
        try:
3707
 
            return self._run(b, tree, dry_run, verbose, revision, force,
3708
 
                             local=local)
 
3665
            return self._run(b, tree, dry_run, verbose, revision, force)
3709
3666
        finally:
3710
3667
            if tree is not None:
3711
3668
                tree.unlock()
3712
3669
            else:
3713
3670
                b.unlock()
3714
3671
 
3715
 
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
 
3672
    def _run(self, b, tree, dry_run, verbose, revision, force):
3716
3673
        from bzrlib.log import log_formatter, show_log
3717
3674
        from bzrlib.uncommit import uncommit
3718
3675
 
3760
3717
                    return 0
3761
3718
 
3762
3719
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
3763
 
                 revno=revno, local=local)
 
3720
                 revno=revno)
3764
3721
 
3765
3722
 
3766
3723
class cmd_break_lock(Command):
4021
3978
            if len(revision) > 2:
4022
3979
                raise errors.BzrCommandError('bzr merge-directive takes '
4023
3980
                    'at most two one revision identifiers')
4024
 
            revision_id = revision[-1].as_revision_id(branch)
 
3981
            revision_id = revision[-1].in_history(branch).rev_id
4025
3982
            if len(revision) == 2:
4026
 
                base_revision_id = revision[0].as_revision_id(branch)
 
3983
                base_revision_id = revision[0].in_history(branch).rev_id
 
3984
                base_revision_id = ensure_null(base_revision_id)
4027
3985
        else:
4028
3986
            revision_id = branch.last_revision()
4029
3987
        revision_id = ensure_null(revision_id)
4091
4049
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
4092
4050
    default.  "0.9" uses revision bundle format 0.9 and merge directive
4093
4051
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
4094
 
    
4095
 
    Merge directives are applied using the merge command or the pull command.
4096
4052
    """
4097
4053
 
4098
4054
    encoding_type = 'exact'
4099
4055
 
4100
 
    _see_also = ['merge', 'pull']
 
4056
    _see_also = ['merge']
4101
4057
 
4102
4058
    takes_args = ['submit_branch?', 'public_branch?']
4103
4059
 
4113
4069
               'rather than the one containing the working directory.',
4114
4070
               short_name='f',
4115
4071
               type=unicode),
4116
 
        Option('output', short_name='o',
4117
 
               help='Write merge directive to this file; '
4118
 
                    'use - for stdout.',
 
4072
        Option('output', short_name='o', help='Write directive to this file.',
4119
4073
               type=unicode),
4120
4074
        Option('mail-to', help='Mail the request to this address.',
4121
4075
               type=unicode),
4191
4145
                if len(revision) > 2:
4192
4146
                    raise errors.BzrCommandError('bzr send takes '
4193
4147
                        'at most two one revision identifiers')
4194
 
                revision_id = revision[-1].as_revision_id(branch)
 
4148
                revision_id = revision[-1].in_history(branch).rev_id
4195
4149
                if len(revision) == 2:
4196
 
                    base_revision_id = revision[0].as_revision_id(branch)
 
4150
                    base_revision_id = revision[0].in_history(branch).rev_id
4197
4151
            if revision_id is None:
4198
4152
                revision_id = branch.last_revision()
4199
4153
            if revision_id == NULL_REVISION:
4359
4313
                        raise errors.BzrCommandError(
4360
4314
                            "Tags can only be placed on a single revision, "
4361
4315
                            "not on a range")
4362
 
                    revision_id = revision[0].as_revision_id(branch)
 
4316
                    revision_id = revision[0].in_history(branch).rev_id
4363
4317
                else:
4364
4318
                    revision_id = branch.last_revision()
4365
4319
                if (not force) and branch.tags.has_tag(tag_name):
4444
4398
                     tree='Reconfigure to a tree.',
4445
4399
                     checkout='Reconfigure to a checkout.',
4446
4400
                     lightweight_checkout='Reconfigure to a lightweight'
4447
 
                     ' checkout.',
4448
 
                     standalone='Reconfigure to be standalone.',
4449
 
                     use_shared='Reconfigure to use a shared repository.'),
 
4401
                     ' checkout.'),
4450
4402
                     Option('bind-to', help='Branch to bind checkout to.',
4451
4403
                            type=str),
4452
4404
                     Option('force',
4468
4420
        elif target_type == 'lightweight-checkout':
4469
4421
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4470
4422
                directory, bind_to)
4471
 
        elif target_type == 'use-shared':
4472
 
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
4473
 
        elif target_type == 'standalone':
4474
 
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
4475
4423
        reconfiguration.apply(force)
4476
4424
 
4477
4425
 
4487
4435
    are merged. The user can commit or revert these as they desire.
4488
4436
 
4489
4437
    Pending merges need to be committed or reverted before using switch.
4490
 
 
4491
 
    The path to the branch to switch to can be specified relative to the parent
4492
 
    directory of the current branch. For example, if you are currently in a
4493
 
    checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4494
 
    /path/to/newbranch.
4495
4438
    """
4496
4439
 
4497
4440
    takes_args = ['to_location']
4501
4444
 
4502
4445
    def run(self, to_location, force=False):
4503
4446
        from bzrlib import switch
 
4447
        to_branch = Branch.open(to_location)
4504
4448
        tree_location = '.'
4505
4449
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4506
 
        try:
4507
 
            to_branch = Branch.open(to_location)
4508
 
        except errors.NotBranchError:
4509
 
            to_branch = Branch.open(
4510
 
                control_dir.open_branch().base + '../' + to_location)
4511
4450
        switch.switch(control_dir, to_branch, force)
4512
4451
        note('Switched to branch: %s',
4513
4452
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4557
4496
        cur_transport.ensure_base()
4558
4497
 
4559
4498
 
 
4499
def _get_mergeable_helper(location):
 
4500
    """Get a merge directive or bundle if 'location' points to one.
 
4501
 
 
4502
    Try try to identify a bundle and returns its mergeable form. If it's not,
 
4503
    we return the tried transport anyway so that it can reused to access the
 
4504
    branch
 
4505
 
 
4506
    :param location: can point to a bundle or a branch.
 
4507
 
 
4508
    :return: mergeable, transport
 
4509
    """
 
4510
    mergeable = None
 
4511
    url = urlutils.normalize_url(location)
 
4512
    url, filename = urlutils.split(url, exclude_trailing_slash=False)
 
4513
    location_transport = transport.get_transport(url)
 
4514
    if filename:
 
4515
        try:
 
4516
            # There may be redirections but we ignore the intermediate
 
4517
            # and final transports used
 
4518
            read = bundle.read_mergeable_from_transport
 
4519
            mergeable, t = read(location_transport, filename)
 
4520
        except errors.NotABundle:
 
4521
            # Continue on considering this url a Branch but adjust the
 
4522
            # location_transport
 
4523
            location_transport = location_transport.clone(filename)
 
4524
    return mergeable, location_transport
 
4525
 
 
4526
 
4560
4527
# these get imported and then picked up by the scan for cmd_*
4561
4528
# TODO: Some more consistent way to split command definitions across files;
4562
4529
# we do need to load at least some information about them to know of