~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/send.py

  • Committer: John Arbash Meinel
  • Date: 2009-03-04 18:31:31 UTC
  • mto: (0.17.34 trunk)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090304183131-p433dz5coqrmv8pw
Now using a zlib compressed format.
We encode the length of the compressed and uncompressed content,
and then compress the actual content.
Need to do some testing with real data to see if this is efficient
or if another structure would be better.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 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 os
19
 
import time
20
 
 
21
 
from bzrlib import (
22
 
    bzrdir,
23
 
    errors,
24
 
    osutils,
25
 
    registry,
26
 
    trace,
27
 
    )
28
 
from bzrlib.i18n import gettext
29
 
from bzrlib.branch import (
30
 
    Branch,
31
 
    )
32
 
from bzrlib.revision import (
33
 
    NULL_REVISION,
34
 
    )
35
 
 
36
 
 
37
 
format_registry = registry.Registry()
38
 
 
39
 
 
40
 
def send(submit_branch, revision, public_branch, remember, format,
41
 
         no_bundle, no_patch, output, from_, mail_to, message, body,
42
 
         to_file, strict=None):
43
 
    tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
44
 
    # we may need to write data into branch's repository to calculate
45
 
    # the data to send.
46
 
    branch.lock_write()
47
 
    try:
48
 
        if output is None:
49
 
            config = branch.get_config()
50
 
            if mail_to is None:
51
 
                mail_to = config.get_user_option('submit_to')
52
 
            mail_client = config.get_mail_client()
53
 
            if (not getattr(mail_client, 'supports_body', False)
54
 
                and body is not None):
55
 
                raise errors.BzrCommandError(gettext(
56
 
                    'Mail client "%s" does not support specifying body') %
57
 
                    mail_client.__class__.__name__)
58
 
        if remember and submit_branch is None:
59
 
            raise errors.BzrCommandError(gettext(
60
 
                '--remember requires a branch to be specified.'))
61
 
        stored_submit_branch = branch.get_submit_branch()
62
 
        remembered_submit_branch = None
63
 
        if submit_branch is None:
64
 
            submit_branch = stored_submit_branch
65
 
            remembered_submit_branch = "submit"
66
 
        else:
67
 
            # Remembers if asked explicitly or no previous location is set
68
 
            if remember or (remember is None and stored_submit_branch is None):
69
 
                branch.set_submit_branch(submit_branch)
70
 
        if submit_branch is None:
71
 
            submit_branch = branch.get_parent()
72
 
            remembered_submit_branch = "parent"
73
 
        if submit_branch is None:
74
 
            raise errors.BzrCommandError(gettext('No submit branch known or'
75
 
                                         ' specified'))
76
 
        if remembered_submit_branch is not None:
77
 
            trace.note(gettext('Using saved {0} location "{1}" to determine '
78
 
                       'what changes to submit.').format(
79
 
                                    remembered_submit_branch, submit_branch))
80
 
 
81
 
        if mail_to is None or format is None:
82
 
            # TODO: jam 20090716 we open the submit_branch here, but we *don't*
83
 
            #       pass it down into the format creation, so it will have to
84
 
            #       open it again
85
 
            submit_br = Branch.open(submit_branch)
86
 
            submit_config = submit_br.get_config()
87
 
            if mail_to is None:
88
 
                mail_to = submit_config.get_user_option("child_submit_to")
89
 
            if format is None:
90
 
                formatname = submit_br.get_child_submit_format()
91
 
                try:
92
 
                    format = format_registry.get(formatname)
93
 
                except KeyError:
94
 
                    raise errors.BzrCommandError(gettext("No such send format '%s'.") % 
95
 
                                                 formatname)
96
 
 
97
 
        stored_public_branch = branch.get_public_branch()
98
 
        if public_branch is None:
99
 
            public_branch = stored_public_branch
100
 
        # Remembers if asked explicitly or no previous location is set
101
 
        elif (remember
102
 
              or (remember is None and stored_public_branch is None)):
103
 
            branch.set_public_branch(public_branch)
104
 
        if no_bundle and public_branch is None:
105
 
            raise errors.BzrCommandError(gettext('No public branch specified or'
106
 
                                         ' known'))
107
 
        base_revision_id = None
108
 
        revision_id = None
109
 
        if revision is not None:
110
 
            if len(revision) > 2:
111
 
                raise errors.BzrCommandError(gettext('bzr send takes '
112
 
                    'at most two one revision identifiers'))
113
 
            revision_id = revision[-1].as_revision_id(branch)
114
 
            if len(revision) == 2:
115
 
                base_revision_id = revision[0].as_revision_id(branch)
116
 
        if revision_id is None:
117
 
            if tree is not None:
118
 
                tree.check_changed_or_out_of_date(
119
 
                    strict, 'send_strict',
120
 
                    more_error='Use --no-strict to force the send.',
121
 
                    more_warning='Uncommitted changes will not be sent.')
122
 
            revision_id = branch.last_revision()
123
 
        if revision_id == NULL_REVISION:
124
 
            raise errors.BzrCommandError(gettext('No revisions to submit.'))
125
 
        if format is None:
126
 
            format = format_registry.get()
127
 
        directive = format(branch, revision_id, submit_branch,
128
 
            public_branch, no_patch, no_bundle, message, base_revision_id)
129
 
        if output is None:
130
 
            directive.compose_merge_request(mail_client, mail_to, body,
131
 
                                            branch, tree)
132
 
        else:
133
 
            if directive.multiple_output_files:
134
 
                if output == '-':
135
 
                    raise errors.BzrCommandError(gettext('- not supported for '
136
 
                        'merge directives that use more than one output file.'))
137
 
                if not os.path.exists(output):
138
 
                    os.mkdir(output, 0755)
139
 
                for (filename, lines) in directive.to_files():
140
 
                    path = os.path.join(output, filename)
141
 
                    outfile = open(path, 'wb')
142
 
                    try:
143
 
                        outfile.writelines(lines)
144
 
                    finally:
145
 
                        outfile.close()
146
 
            else:
147
 
                if output == '-':
148
 
                    outfile = to_file
149
 
                else:
150
 
                    outfile = open(output, 'wb')
151
 
                try:
152
 
                    outfile.writelines(directive.to_lines())
153
 
                finally:
154
 
                    if outfile is not to_file:
155
 
                        outfile.close()
156
 
    finally:
157
 
        branch.unlock()
158
 
 
159
 
 
160
 
def _send_4(branch, revision_id, submit_branch, public_branch,
161
 
            no_patch, no_bundle, message, base_revision_id):
162
 
    from bzrlib import merge_directive
163
 
    return merge_directive.MergeDirective2.from_objects(
164
 
        branch.repository, revision_id, time.time(),
165
 
        osutils.local_time_offset(), submit_branch,
166
 
        public_branch=public_branch, include_patch=not no_patch,
167
 
        include_bundle=not no_bundle, message=message,
168
 
        base_revision_id=base_revision_id)
169
 
 
170
 
 
171
 
def _send_0_9(branch, revision_id, submit_branch, public_branch,
172
 
              no_patch, no_bundle, message, base_revision_id):
173
 
    if not no_bundle:
174
 
        if not no_patch:
175
 
            patch_type = 'bundle'
176
 
        else:
177
 
            raise errors.BzrCommandError(gettext('Format 0.9 does not'
178
 
                ' permit bundle with no patch'))
179
 
    else:
180
 
        if not no_patch:
181
 
            patch_type = 'diff'
182
 
        else:
183
 
            patch_type = None
184
 
    from bzrlib import merge_directive
185
 
    return merge_directive.MergeDirective.from_objects(
186
 
        branch.repository, revision_id, time.time(),
187
 
        osutils.local_time_offset(), submit_branch,
188
 
        public_branch=public_branch, patch_type=patch_type,
189
 
        message=message)
190
 
 
191
 
 
192
 
format_registry.register('4', 
193
 
    _send_4, 'Bundle format 4, Merge Directive 2 (default)')
194
 
format_registry.register('0.9',
195
 
    _send_0_9, 'Bundle format 0.9, Merge Directive 1')
196
 
format_registry.default_key = '4'