~bzr-pqm/bzr/bzr.dev

5452.4.3 by John Arbash Meinel
Merge bzr.dev to resolve bzr-2.3.txt (aka NEWS)
1
# Copyright (C) 2005, 2006, 2007, 2009, 2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
16
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
17
"""Serializer factory for reading and writing bundles.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
18
"""
19
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
20
from __future__ import absolute_import
21
1185.82.96 by Aaron Bentley
Got first binary test passing
22
import base64
23
from StringIO import StringIO
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
24
import re
25
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
26
from bzrlib import (
27
    errors,
28
    pyutils,
29
    )
1185.82.96 by Aaron Bentley
Got first binary test passing
30
from bzrlib.diff import internal_diff
1185.82.58 by Aaron Bentley
Handle empty branches properly
31
from bzrlib.revision import NULL_REVISION
1551.12.46 by Aaron Bentley
Import highres date functions to old location
32
# For backwards-compatibility
33
from bzrlib.timestamp import unpack_highres_date, format_highres_date
34
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
35
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
36
# New bundles should try to use this header format
37
BUNDLE_HEADER = '# Bazaar revision bundle v'
1907.2.2 by Hermann Kraus
Detect wrong eol markers.
38
BUNDLE_HEADER_RE = re.compile(
39
    r'^# Bazaar revision bundle v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
40
CHANGESET_OLD_HEADER_RE = re.compile(
41
    r'^# Bazaar-NG changeset v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
42
43
1793.3.16 by John Arbash Meinel
Add tests to ensure that we gracefully handle opening and trailing non-bundle text.
44
_serializers = {}
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
45
2520.4.136 by Aaron Bentley
Fix format strings
46
v4_string = '4'
2520.4.123 by Aaron Bentley
Cleanup of bundle code
47
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
48
def _get_bundle_header(version):
49
    return '%s%s\n' % (BUNDLE_HEADER, version)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
50
51
def _get_filename(f):
1963.2.4 by Robey Pointer
remove usage of hasattr
52
    return getattr(f, 'name', '<unknown>')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
53
54
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
55
def read_bundle(f):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
56
    """Read in a bundle from a filelike object.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
57
58
    :param f: A file-like object
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
59
    :return: A list of Bundle objects
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
60
    """
61
    version = None
62
    for line in f:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
63
        m = BUNDLE_HEADER_RE.match(line)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
64
        if m:
1907.2.2 by Hermann Kraus
Detect wrong eol markers.
65
            if m.group('lineending') != '':
66
                raise errors.UnsupportedEOLMarker()
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
67
            version = m.group('version')
68
            break
1793.2.7 by Aaron Bentley
Fix reporting of malformed, (especially, crlf) bundles
69
        elif line.startswith(BUNDLE_HEADER):
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
70
            raise errors.MalformedHeader(
71
                'Extra characters after version number')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
72
        m = CHANGESET_OLD_HEADER_RE.match(line)
73
        if m:
74
            version = m.group('version')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
75
            raise errors.BundleNotSupported(version,
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
76
                'old format bundles not supported')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
77
78
    if version is None:
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
79
        raise errors.NotABundle('Did not find an opening header')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
80
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
81
    # Now we have a version, to figure out how to read the bundle
1963.2.1 by Robey Pointer
remove usage of has_key()
82
    if version not in _serializers:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
83
        raise errors.BundleNotSupported(version,
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
84
            'version not listed in known versions')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
85
86
    serializer = _serializers[version](version)
87
88
    return serializer.read(f)
89
90
2520.4.53 by Aaron Bentley
refactor bundle serialization to make write_bundle primary
91
def get_serializer(version):
92
    try:
93
        return _serializers[version](version)
94
    except KeyError:
95
        raise errors.BundleNotSupported(version, 'unknown bundle format')
96
97
1185.82.74 by Aaron Bentley
Allow custom base for any revision
98
def write(source, revision_ids, f, version=None, forced_bases={}):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
99
    """Serialize a list of bundles to a filelike object.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
100
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
101
    :param source: A source for revision information
102
    :param revision_ids: The list of revision ids to serialize
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
103
    :param f: The file to output to
104
    :param version: [optional] target serialization version
105
    """
106
1927.1.1 by John Arbash Meinel
Lock the repository more often
107
    source.lock_read()
108
    try:
2520.4.53 by Aaron Bentley
refactor bundle serialization to make write_bundle primary
109
        return get_serializer(version).write(source, revision_ids,
110
                                             forced_bases, f)
1927.1.1 by John Arbash Meinel
Lock the repository more often
111
    finally:
112
        source.unlock()
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
113
114
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
115
def write_bundle(repository, revision_id, base_revision_id, out, format=None):
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
116
    """Write a bundle of revisions.
117
118
    :param repository: Repository containing revisions to serialize.
119
    :param revision_id: Head revision_id of the bundle.
120
    :param base_revision_id: Revision assumed to be present in repositories
121
         applying the bundle.
122
    :param out: Output file.
123
    """
2520.4.54 by Aaron Bentley
Hang a create_bundle method off repository
124
    repository.lock_read()
125
    try:
126
        return get_serializer(format).write_bundle(repository, revision_id,
127
                                                   base_revision_id, out)
128
    finally:
129
        repository.unlock()
1185.82.53 by Aaron Bentley
Factored out write_changeset to select revisions
130
131
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
132
class BundleSerializer(object):
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
133
    """The base class for Serializers.
134
135
    Common functionality should be included here.
136
    """
137
    def __init__(self, version):
138
        self.version = version
139
140
    def read(self, f):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
141
        """Read the rest of the bundles from the supplied file.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
142
143
        :param f: The file to read from
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
144
        :return: A list of bundle trees
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
145
        """
146
        raise NotImplementedError
147
2520.4.53 by Aaron Bentley
refactor bundle serialization to make write_bundle primary
148
    def write_bundle(self, repository, target, base, fileobj):
149
        """Write the bundle to the supplied file.
150
151
        :param repository: The repository to retrieve revision data from
152
        :param target: The revision to provide data for
153
        :param base: The most recent of ancestor of the revision that does not
154
            need to be included in the bundle
155
        :param fileobj: The file to output to
156
        """
157
        raise NotImplementedError
158
159
    def _write_bundle(self, repository, revision_id, base_revision_id, out):
160
        """Helper function for translating write_bundle to write"""
161
        forced_bases = {revision_id:base_revision_id}
162
        if base_revision_id is NULL_REVISION:
163
            base_revision_id = None
5972.3.4 by Jelmer Vernooij
Use find_unique_ancestors in bundle code.
164
        graph = repository.get_graph()
165
        revision_ids = graph.find_unique_ancestors(revision_id,
166
            [base_revision_id])
2520.4.63 by Aaron Bentley
Merge bzr.dev
167
        revision_ids = list(repository.get_graph().iter_topo_order(
168
            revision_ids))
169
        revision_ids.reverse()
2520.4.53 by Aaron Bentley
refactor bundle serialization to make write_bundle primary
170
        self.write(repository, revision_ids, forced_bases, out)
171
        return revision_ids
172
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
173
174
def register(version, klass, overwrite=False):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
175
    """Register a BundleSerializer version.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
176
177
    :param version: The version associated with this format
178
    :param klass: The class to instantiate, which must take a version argument
179
    """
180
    global _serializers
181
    if overwrite:
182
        _serializers[version] = klass
183
        return
184
1963.2.1 by Robey Pointer
remove usage of has_key()
185
    if version not in _serializers:
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
186
        _serializers[version] = klass
187
188
189
def register_lazy(version, module, classname, overwrite=False):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
190
    """Register lazy-loaded bundle serializer.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
191
192
    :param version: The version associated with this reader
193
    :param module: String indicating what module should be loaded
194
    :param classname: Name of the class that will be instantiated
195
    :param overwrite: Should this version override a default
196
    """
197
    def _loader(version):
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
198
        klass = pyutils.get_named_object(module, classname)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
199
        return klass(version)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
200
    register(version, _loader, overwrite=overwrite)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
201
202
1185.82.96 by Aaron Bentley
Got first binary test passing
203
def binary_diff(old_filename, old_lines, new_filename, new_lines, to_file):
204
    temp = StringIO()
205
    internal_diff(old_filename, old_lines, new_filename, new_lines, temp,
206
                  allow_binary=True)
207
    temp.seek(0)
208
    base64.encode(temp, to_file)
209
    to_file.write('\n')
210
1551.7.3 by Aaron Bentley
Fix strict testaments, as_sha1
211
register_lazy('0.8', 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
212
register_lazy('0.9', 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
2520.4.123 by Aaron Bentley
Cleanup of bundle code
213
register_lazy(v4_string, 'bzrlib.bundle.serializer.v4',
2520.4.72 by Aaron Bentley
Rename format to 4alpha
214
              'BundleSerializerV4')
215
register_lazy(None, 'bzrlib.bundle.serializer.v4', 'BundleSerializerV4')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
216