~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-07-19 16:09:34 UTC
  • mfrom: (2520.4.135 bzr.mpbundle)
  • Revision ID: pqm@pqm.ubuntu.com-20070719160934-d51fyijw69oto88p
Add new bundle and merge-directive formats

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
    urlutils,
54
54
    )
55
55
from bzrlib.branch import Branch
56
 
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
57
56
from bzrlib.conflicts import ConflictList
58
57
from bzrlib.revisionspec import RevisionSpec
59
58
from bzrlib.smtp_connection import SMTPConnection
618
617
            if revision is not None:
619
618
                raise errors.BzrCommandError(
620
619
                    'Cannot use -r with merge directives or bundles')
621
 
            revision_id = mergeable.install_revisions(branch_to.repository)
 
620
            mergeable.install_revisions(branch_to.repository)
 
621
            base_revision_id, revision_id, verified = \
 
622
                mergeable.get_merge_request(branch_to.repository)
622
623
            branch_from = branch_to
623
624
        else:
624
625
            branch_from = Branch.open(location)
2641
2642
            ):
2642
2643
        from bzrlib.tag import _merge_tags_if_possible
2643
2644
        other_revision_id = None
 
2645
        base_revision_id = None
2644
2646
        if merge_type is None:
2645
2647
            merge_type = _mod_merge.Merge3Merger
2646
2648
 
2666
2668
                if revision is not None:
2667
2669
                    raise errors.BzrCommandError(
2668
2670
                        'Cannot use -r with merge directives or bundles')
2669
 
                other_revision_id = mergeable.install_revisions(
2670
 
                    tree.branch.repository)
2671
 
                revision = [RevisionSpec.from_string(
2672
 
                    'revid:' + other_revision_id)]
2673
 
 
2674
 
        if revision is None \
2675
 
                or len(revision) < 1 or revision[0].needs_branch():
2676
 
            branch = self._get_remembered_parent(tree, branch, 'Merging from')
2677
 
 
2678
 
        if revision is None or len(revision) < 1:
2679
 
            if uncommitted:
2680
 
                base = [branch, -1]
2681
 
                other = [branch, None]
 
2671
                mergeable.install_revisions(tree.branch.repository)
 
2672
                base_revision_id, other_revision_id, verified =\
 
2673
                    mergeable.get_merge_request(tree.branch.repository)
 
2674
                if base_revision_id in tree.branch.repository.get_ancestry(
 
2675
                    tree.branch.last_revision(), topo_sorted=False):
 
2676
                    base_revision_id = None
 
2677
                other_branch = None
 
2678
                path = ''
 
2679
                other = None
 
2680
                base = None
 
2681
 
 
2682
        if other_revision_id is None:
 
2683
            verified = 'inapplicable'
 
2684
            if revision is None \
 
2685
                    or len(revision) < 1 or revision[0].needs_branch():
 
2686
                branch = self._get_remembered_parent(tree, branch,
 
2687
                    'Merging from')
 
2688
 
 
2689
            if revision is None or len(revision) < 1:
 
2690
                if uncommitted:
 
2691
                    base = [branch, -1]
 
2692
                    other = [branch, None]
 
2693
                else:
 
2694
                    base = [None, None]
 
2695
                    other = [branch, -1]
 
2696
                other_branch, path = Branch.open_containing(branch)
2682
2697
            else:
2683
 
                base = [None, None]
2684
 
                other = [branch, -1]
2685
 
            other_branch, path = Branch.open_containing(branch)
2686
 
        else:
2687
 
            if uncommitted:
2688
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
2689
 
                                             ' --revision at the same time.')
2690
 
            branch = revision[0].get_branch() or branch
2691
 
            if len(revision) == 1:
2692
 
                base = [None, None]
2693
 
                if other_revision_id is not None:
2694
 
                    other_branch = None
2695
 
                    path = ""
2696
 
                    other = None
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]
2698
2704
                    other_branch, path = Branch.open_containing(branch)
2699
2705
                    revno = revision[0].in_history(other_branch).revno
2700
2706
                    other = [branch, revno]
2701
 
            else:
2702
 
                assert len(revision) == 2
2703
 
                if None in revision:
2704
 
                    raise errors.BzrCommandError(
2705
 
                        "Merge doesn't permit empty revision specifier.")
2706
 
                base_branch, path = Branch.open_containing(branch)
2707
 
                branch1 = revision[1].get_branch() or branch
2708
 
                other_branch, path1 = Branch.open_containing(branch1)
2709
 
                if revision[0].get_branch() is not None:
2710
 
                    # then path was obtained from it, and is None.
2711
 
                    path = path1
 
2707
                else:
 
2708
                    assert len(revision) == 2
 
2709
                    if None in revision:
 
2710
                        raise errors.BzrCommandError(
 
2711
                            "Merge doesn't permit empty revision specifier.")
 
2712
                    base_branch, path = Branch.open_containing(branch)
 
2713
                    branch1 = revision[1].get_branch() or branch
 
2714
                    other_branch, path1 = Branch.open_containing(branch1)
 
2715
                    if revision[0].get_branch() is not None:
 
2716
                        # then path was obtained from it, and is None.
 
2717
                        path = path1
2712
2718
 
2713
 
                base = [branch, revision[0].in_history(base_branch).revno]
2714
 
                other = [branch1, revision[1].in_history(other_branch).revno]
 
2719
                    base = [branch, revision[0].in_history(base_branch).revno]
 
2720
                    other = [branch1,
 
2721
                             revision[1].in_history(other_branch).revno]
2715
2722
 
2716
2723
        if ((tree.branch.get_parent() is None or remember) and
2717
2724
            other_branch is not None):
2731
2738
            try:
2732
2739
                conflict_count = _merge_helper(
2733
2740
                    other, base, other_rev_id=other_revision_id,
 
2741
                    base_rev_id=base_revision_id,
2734
2742
                    check_clean=(not force),
2735
2743
                    merge_type=merge_type,
2736
2744
                    reprocess=reprocess,
2741
2749
                    change_reporter=change_reporter)
2742
2750
            finally:
2743
2751
                pb.finished()
 
2752
            if verified == 'failed':
 
2753
                warning('Preview patch does not match changes')
2744
2754
            if conflict_count != 0:
2745
2755
                return 1
2746
2756
            else:
3574
3584
 
3575
3585
    takes_args = ['submit_branch?', 'public_branch?']
3576
3586
 
 
3587
    hidden = True
 
3588
 
 
3589
    _see_also = ['submit']
 
3590
 
3577
3591
    takes_options = [
3578
3592
        RegistryOption.from_kwargs('patch-type',
3579
3593
            'The type of patch to include in the directive',
3595
3609
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3596
3610
            sign=False, revision=None, mail_to=None, message=None):
3597
3611
        from bzrlib.revision import ensure_null, NULL_REVISION
3598
 
        if patch_type == 'plain':
3599
 
            patch_type = None
 
3612
        include_patch, include_bundle = {
 
3613
            'plain': (False, False),
 
3614
            'diff': (True, False),
 
3615
            'bundle': (True, True),
 
3616
            }[patch_type]
3600
3617
        branch = Branch.open('.')
3601
3618
        stored_submit_branch = branch.get_submit_branch()
3602
3619
        if submit_branch is None:
3614
3631
            public_branch = stored_public_branch
3615
3632
        elif stored_public_branch is None:
3616
3633
            branch.set_public_branch(public_branch)
3617
 
        if patch_type != "bundle" and public_branch is None:
 
3634
        if not include_bundle and public_branch is None:
3618
3635
            raise errors.BzrCommandError('No public branch specified or'
3619
3636
                                         ' known')
 
3637
        base_revision_id = None
3620
3638
        if revision is not None:
3621
 
            if len(revision) != 1:
 
3639
            if len(revision) > 2:
3622
3640
                raise errors.BzrCommandError('bzr merge-directive takes '
3623
 
                    'exactly one revision identifier')
3624
 
            else:
3625
 
                revision_id = revision[0].in_history(branch).rev_id
 
3641
                    'at most two one revision identifiers')
 
3642
            revision_id = revision[-1].in_history(branch).rev_id
 
3643
            if len(revision) == 2:
 
3644
                base_revision_id = revision[0].in_history(branch).rev_id
 
3645
                base_revision_id = ensure_null(base_revision_id)
3626
3646
        else:
3627
3647
            revision_id = branch.last_revision()
3628
3648
        revision_id = ensure_null(revision_id)
3629
3649
        if revision_id == NULL_REVISION:
3630
3650
            raise errors.BzrCommandError('No revisions to bundle.')
3631
 
        directive = merge_directive.MergeDirective.from_objects(
 
3651
        directive = merge_directive.MergeDirective2.from_objects(
3632
3652
            branch.repository, revision_id, time.time(),
3633
3653
            osutils.local_time_offset(), submit_branch,
3634
 
            public_branch=public_branch, patch_type=patch_type,
3635
 
            message=message)
 
3654
            public_branch=public_branch, include_patch=include_patch,
 
3655
            include_bundle=include_bundle, message=message,
 
3656
            base_revision_id=base_revision_id)
3636
3657
        if mail_to is None:
3637
3658
            if sign:
3638
3659
                self.outf.write(directive.to_signed(branch))
3644
3665
            s.send_email(message)
3645
3666
 
3646
3667
 
 
3668
class cmd_submit(Command):
 
3669
    """Create a merge-directive for submiting changes.
 
3670
 
 
3671
    A merge directive provides many things needed for requesting merges:
 
3672
    - A machine-readable description of the merge to perform
 
3673
    - An optional patch that is a preview of the changes requested
 
3674
    - An optional bundle of revision data, so that the changes can be applied
 
3675
      directly from the merge directive, without retrieving data from a
 
3676
      branch.
 
3677
 
 
3678
    If --no-bundle is specified, then public_branch is needed (and must be
 
3679
    up-to-date), so that the receiver can perform the merge using the
 
3680
    public_branch.  The public_branch is always included if known, so that
 
3681
    people can check it later.
 
3682
 
 
3683
    The submit branch defaults to the parent, but can be overridden.  Both
 
3684
    submit branch and public branch will be remembered if supplied.
 
3685
 
 
3686
    If a public_branch is known for the submit_branch, that public submit
 
3687
    branch is used in the merge instructions.  This means that a local mirror
 
3688
    can be used as your actual submit branch, once you have set public_branch
 
3689
    for that mirror.
 
3690
    """
 
3691
 
 
3692
    encoding_type = 'exact'
 
3693
 
 
3694
    aliases = ['bundle', 'bundle-revisions']
 
3695
 
 
3696
    _see_also = ['merge']
 
3697
 
 
3698
    takes_args = ['submit_branch?', 'public_branch?']
 
3699
    takes_options = [
 
3700
        Option('no-bundle',
 
3701
               help='Do not include a bundle in the merge directive.'),
 
3702
        Option('no-patch', help='Do not include a preview patch in the merge'
 
3703
               ' directive.'),
 
3704
        Option('remember',
 
3705
               help='Remember submit and public branch.'),
 
3706
        Option('from',
 
3707
               help='Branch to generate the submission from, '
 
3708
               'rather than the one containing the working directory.',
 
3709
               short_name='f',
 
3710
               type=unicode),
 
3711
        Option('output', short_name='o', help='Write directive to this file.',
 
3712
               type=unicode),
 
3713
        'revision',
 
3714
        ]
 
3715
 
 
3716
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
 
3717
            no_patch=False, revision=None, remember=False, output=None,
 
3718
            **kwargs):
 
3719
        from bzrlib.revision import ensure_null, NULL_REVISION
 
3720
        if output is None:
 
3721
            outfile = self.outf
 
3722
        else:
 
3723
            outfile = open(output, 'wb')
 
3724
        try:
 
3725
            from_ = kwargs.get('from', '.')
 
3726
            branch = Branch.open_containing(from_)[0]
 
3727
            if remember and submit_branch is None:
 
3728
                raise errors.BzrCommandError(
 
3729
                    '--remember requires a branch to be specified.')
 
3730
            stored_submit_branch = branch.get_submit_branch()
 
3731
            remembered_submit_branch = False
 
3732
            if submit_branch is None:
 
3733
                submit_branch = stored_submit_branch
 
3734
                remembered_submit_branch = True
 
3735
            else:
 
3736
                if stored_submit_branch is None or remember:
 
3737
                    branch.set_submit_branch(submit_branch)
 
3738
            if submit_branch is None:
 
3739
                submit_branch = branch.get_parent()
 
3740
                remembered_submit_branch = True
 
3741
            if submit_branch is None:
 
3742
                raise errors.BzrCommandError('No submit branch known or'
 
3743
                                             ' specified')
 
3744
            if remembered_submit_branch:
 
3745
                note('Using saved location: %s', submit_branch)
 
3746
 
 
3747
            stored_public_branch = branch.get_public_branch()
 
3748
            if public_branch is None:
 
3749
                public_branch = stored_public_branch
 
3750
            elif stored_public_branch is None or remember:
 
3751
                branch.set_public_branch(public_branch)
 
3752
            if no_bundle and public_branch is None:
 
3753
                raise errors.BzrCommandError('No public branch specified or'
 
3754
                                             ' known')
 
3755
            base_revision_id = None
 
3756
            if revision is not None:
 
3757
                if len(revision) > 2:
 
3758
                    raise errors.BzrCommandError('bzr submit takes '
 
3759
                        'at most two one revision identifiers')
 
3760
                revision_id = revision[-1].in_history(branch).rev_id
 
3761
                if len(revision) == 2:
 
3762
                    base_revision_id = revision[0].in_history(branch).rev_id
 
3763
                    base_revision_id = ensure_null(base_revision_id)
 
3764
            else:
 
3765
                revision_id = branch.last_revision()
 
3766
            revision_id = ensure_null(revision_id)
 
3767
            if revision_id == NULL_REVISION:
 
3768
                raise errors.BzrCommandError('No revisions to submit.')
 
3769
            directive = merge_directive.MergeDirective2.from_objects(
 
3770
                branch.repository, revision_id, time.time(),
 
3771
                osutils.local_time_offset(), submit_branch,
 
3772
                public_branch=public_branch, include_patch=not no_patch,
 
3773
                include_bundle=not no_bundle, message=None,
 
3774
                base_revision_id=base_revision_id)
 
3775
            outfile.writelines(directive.to_lines())
 
3776
        finally:
 
3777
            if output is not None:
 
3778
                outfile.close()
 
3779
 
3647
3780
class cmd_tag(Command):
3648
3781
    """Create a tag naming a revision.
3649
3782
    
3737
3870
                  pull=False,
3738
3871
                  pb=DummyProgress(),
3739
3872
                  change_reporter=None,
3740
 
                  other_rev_id=None):
 
3873
                  other_rev_id=None, base_rev_id=None):
3741
3874
    """Merge changes into a tree.
3742
3875
 
3743
3876
    base_revision
3798
3931
        else:
3799
3932
            merger.set_other(other_revision)
3800
3933
        merger.pp.next_phase()
3801
 
        merger.set_base(base_revision)
 
3934
        if base_rev_id is not None:
 
3935
            merger.set_base_revision(base_rev_id, this_tree.branch)
 
3936
        elif base_revision is not None:
 
3937
            merger.set_base(base_revision)
 
3938
        else:
 
3939
            merger.find_base()
3802
3940
        if merger.base_rev_id == merger.other_rev_id:
3803
3941
            note('Nothing to do.')
3804
3942
            return 0
3858
3996
# details were needed.
3859
3997
from bzrlib.cmd_version_info import cmd_version_info
3860
3998
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
3861
 
from bzrlib.bundle.commands import cmd_bundle_revisions
 
3999
from bzrlib.bundle.commands import (
 
4000
    cmd_bundle_info,
 
4001
    )
3862
4002
from bzrlib.sign_my_commits import cmd_sign_my_commits
3863
4003
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
3864
4004
        cmd_weave_plan_merge, cmd_weave_merge_text