/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/send.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-07-20 08:56:45 UTC
  • mfrom: (4526.9.23 apply-inventory-delta)
  • Revision ID: pqm@pqm.ubuntu.com-20090720085645-54mtgybxua0yx6hw
(robertc) Add checks for inventory deltas which try to ensure that
        deltas that are not an exact fit are not applied. (Robert
        Collins, bug 397705, bug 367633)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
import time
 
19
 
 
20
from bzrlib import (
 
21
    bzrdir,
 
22
    errors,
 
23
    merge_directive,
 
24
    osutils,
 
25
    registry,
 
26
    trace,
 
27
    )
 
28
from bzrlib.branch import (
 
29
    Branch,
 
30
    )
 
31
from bzrlib.revision import (
 
32
    NULL_REVISION,
 
33
    )
 
34
 
 
35
 
 
36
format_registry = registry.Registry()
 
37
 
 
38
 
 
39
def send(submit_branch, revision, public_branch, remember, format,
 
40
         no_bundle, no_patch, output, from_, mail_to, message, body,
 
41
         to_file, strict=None):
 
42
    tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
 
43
    # we may need to write data into branch's repository to calculate
 
44
    # the data to send.
 
45
    branch.lock_write()
 
46
    try:
 
47
        if output is None:
 
48
            config = branch.get_config()
 
49
            if mail_to is None:
 
50
                mail_to = config.get_user_option('submit_to')
 
51
            mail_client = config.get_mail_client()
 
52
            if (not getattr(mail_client, 'supports_body', False)
 
53
                and body is not None):
 
54
                raise errors.BzrCommandError(
 
55
                    'Mail client "%s" does not support specifying body' %
 
56
                    mail_client.__class__.__name__)
 
57
        if remember and submit_branch is None:
 
58
            raise errors.BzrCommandError(
 
59
                '--remember requires a branch to be specified.')
 
60
        stored_submit_branch = branch.get_submit_branch()
 
61
        remembered_submit_branch = None
 
62
        if submit_branch is None:
 
63
            submit_branch = stored_submit_branch
 
64
            remembered_submit_branch = "submit"
 
65
        else:
 
66
            if stored_submit_branch is None or remember:
 
67
                branch.set_submit_branch(submit_branch)
 
68
        if submit_branch is None:
 
69
            submit_branch = branch.get_parent()
 
70
            remembered_submit_branch = "parent"
 
71
        if submit_branch is None:
 
72
            raise errors.BzrCommandError('No submit branch known or'
 
73
                                         ' specified')
 
74
        if remembered_submit_branch is not None:
 
75
            trace.note('Using saved %s location "%s" to determine what '
 
76
                       'changes to submit.', remembered_submit_branch,
 
77
                       submit_branch)
 
78
 
 
79
        if mail_to is None or format is None:
 
80
            submit_br = Branch.open(submit_branch)
 
81
            submit_config = submit_br.get_config()
 
82
            if mail_to is None:
 
83
                mail_to = submit_config.get_user_option("child_submit_to")
 
84
            if format is None:
 
85
                formatname = submit_br.get_child_submit_format()
 
86
                try:
 
87
                    format = format_registry.get(formatname)
 
88
                except KeyError:
 
89
                    raise errors.BzrCommandError("No such send format '%s'." % 
 
90
                                                 formatname)
 
91
 
 
92
        stored_public_branch = branch.get_public_branch()
 
93
        if public_branch is None:
 
94
            public_branch = stored_public_branch
 
95
        elif stored_public_branch is None or remember:
 
96
            branch.set_public_branch(public_branch)
 
97
        if no_bundle and public_branch is None:
 
98
            raise errors.BzrCommandError('No public branch specified or'
 
99
                                         ' known')
 
100
        base_revision_id = None
 
101
        revision_id = None
 
102
        if revision is not None:
 
103
            if len(revision) > 2:
 
104
                raise errors.BzrCommandError('bzr send takes '
 
105
                    'at most two one revision identifiers')
 
106
            revision_id = revision[-1].as_revision_id(branch)
 
107
            if len(revision) == 2:
 
108
                base_revision_id = revision[0].as_revision_id(branch)
 
109
        if revision_id is None:
 
110
            if strict is None:
 
111
                strict = branch.get_config(
 
112
                    ).get_user_option_as_bool('send_strict')
 
113
            if strict is None: strict = True # default value
 
114
            if strict and tree is not None:
 
115
                if (tree.has_changes(tree.basis_tree())
 
116
                    or len(tree.get_parent_ids()) > 1):
 
117
                    raise errors.UncommittedChanges(
 
118
                        tree, more='Use --no-strict to force the send.')
 
119
                if tree.last_revision() != tree.branch.last_revision():
 
120
                    # The tree has lost sync with its branch, there is little
 
121
                    # chance that the user is aware of it but he can still force
 
122
                    # the push with --no-strict
 
123
                    raise errors.OutOfDateTree(
 
124
                        tree, more='Use --no-strict to force the send.')
 
125
            revision_id = branch.last_revision()
 
126
        if revision_id == NULL_REVISION:
 
127
            raise errors.BzrCommandError('No revisions to submit.')
 
128
        if format is None:
 
129
            # TODO: Query submit branch for its preferred format
 
130
            format = format_registry.get()
 
131
        directive = format(branch, revision_id, submit_branch,
 
132
            public_branch, no_patch, no_bundle, message, base_revision_id)
 
133
        if output is None:
 
134
            directive.compose_merge_request(mail_client, mail_to, body,
 
135
                                            branch, tree)
 
136
        else:
 
137
            if output == '-':
 
138
                outfile = to_file
 
139
            else:
 
140
                outfile = open(output, 'wb')
 
141
            try:
 
142
                outfile.writelines(directive.to_lines())
 
143
            finally:
 
144
                if outfile is not to_file:
 
145
                    outfile.close()
 
146
    finally:
 
147
        branch.unlock()
 
148
 
 
149
 
 
150
def _send_4(branch, revision_id, submit_branch, public_branch,
 
151
            no_patch, no_bundle, message, base_revision_id):
 
152
    return merge_directive.MergeDirective2.from_objects(
 
153
        branch.repository, revision_id, time.time(),
 
154
        osutils.local_time_offset(), submit_branch,
 
155
        public_branch=public_branch, include_patch=not no_patch,
 
156
        include_bundle=not no_bundle, message=message,
 
157
        base_revision_id=base_revision_id)
 
158
 
 
159
 
 
160
def _send_0_9(branch, revision_id, submit_branch, public_branch,
 
161
              no_patch, no_bundle, message, base_revision_id):
 
162
    if not no_bundle:
 
163
        if not no_patch:
 
164
            patch_type = 'bundle'
 
165
        else:
 
166
            raise errors.BzrCommandError('Format 0.9 does not'
 
167
                ' permit bundle with no patch')
 
168
    else:
 
169
        if not no_patch:
 
170
            patch_type = 'diff'
 
171
        else:
 
172
            patch_type = None
 
173
    return merge_directive.MergeDirective.from_objects(
 
174
        branch.repository, revision_id, time.time(),
 
175
        osutils.local_time_offset(), submit_branch,
 
176
        public_branch=public_branch, patch_type=patch_type,
 
177
        message=message)
 
178
 
 
179
 
 
180
format_registry.register('4', 
 
181
    _send_4, 'Bundle format 4, Merge Directive 2 (default)')
 
182
format_registry.register('0.9',
 
183
    _send_0_9, 'Bundle format 0.9, Merge Directive 1')
 
184
format_registry.default_key = '4'