~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/testament.py

  • Committer: wang
  • Date: 2006-10-29 13:41:32 UTC
  • mto: (2104.4.1 wang_65714)
  • mto: This revision was merged to the branch mainline in revision 2109.
  • Revision ID: wang@ubuntu-20061029134132-3d7f4216f20c4aef
Replace python's difflib by patiencediff because the worst case 
performance is cubic for difflib and people commiting large data 
files are often hurt by this. The worst case performance of patience is 
quadratic. Fix bug 65714.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
 
1
# Copyright (C) 2005 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
70
70
# revisions can be serialized.
71
71
 
72
72
from copy import copy
73
 
from cStringIO import StringIO
74
 
import string
75
73
from sha import sha
76
74
 
77
75
from bzrlib.osutils import contains_whitespace, contains_linebreaks
78
76
 
 
77
 
79
78
class Testament(object):
80
79
    """Reduced summary of a revision.
81
80
 
132
131
        for l in self.message.splitlines():
133
132
            a('  %s\n' % l)
134
133
        a('inventory:\n')
135
 
        entries = self.inventory.iter_entries()
136
 
        entries.next()
137
 
        for path, ie in entries:
 
134
        for path, ie in self._get_entries():
138
135
            a(self._entry_to_line(path, ie))
139
136
        r.extend(self._revprops_to_lines())
140
137
        if __debug__:
143
140
                    '%r of type %s is not a plain string' % (l, type(l))
144
141
        return [line.encode('utf-8') for line in r]
145
142
 
 
143
    def _get_entries(self):
 
144
        entries = self.inventory.iter_entries()
 
145
        entries.next()
 
146
        return entries
 
147
 
146
148
    def _escape_path(self, path):
147
149
        assert not contains_linebreaks(path)
148
 
        return unicode(path.replace('\\', '/').replace(' ', '\ ')).encode('utf-8')
 
150
        return unicode(path.replace('\\', '/').replace(' ', '\ '))
149
151
 
150
152
    def _entry_to_line(self, path, ie):
151
153
        """Turn an inventory entry into a testament line"""
152
 
        l = '  ' + str(ie.kind)
153
 
        l += ' ' + self._escape_path(path)
154
154
        assert not contains_whitespace(ie.file_id)
155
 
        l += ' ' + unicode(ie.file_id).encode('utf-8')
 
155
 
 
156
        content = ''
 
157
        content_spacer=''
156
158
        if ie.kind == 'file':
157
159
            # TODO: avoid switching on kind
158
160
            assert ie.text_sha1
159
 
            l += ' ' + ie.text_sha1
 
161
            content = ie.text_sha1
 
162
            content_spacer = ' '
160
163
        elif ie.kind == 'symlink':
161
164
            assert ie.symlink_target
162
 
            l += ' ' + self._escape_path(ie.symlink_target)
163
 
        l += '\n'
164
 
        return l.decode('utf-8')
 
165
            content = self._escape_path(ie.symlink_target)
 
166
            content_spacer = ' '
 
167
 
 
168
        l = u'  %s %s %s%s%s\n' % (ie.kind, self._escape_path(path),
 
169
                                   unicode(ie.file_id),
 
170
                                   content_spacer, content)
 
171
        return l
165
172
 
166
173
    def as_text(self):
167
174
        return ''.join(self.as_text_lines())
183
190
            assert not contains_whitespace(name)
184
191
            r.append('  %s:\n' % name)
185
192
            for line in value.splitlines():
186
 
                if not isinstance(line, str):
187
 
                    line = line.encode('utf-8')
188
 
                r.append('    %s\n' % line)
 
193
                r.append(u'    %s\n' % line)
189
194
        return r
190
195
 
191
196
    def as_sha1(self):
195
200
 
196
201
 
197
202
class StrictTestament(Testament):
198
 
    """This testament format is for use as a checksum in changesets"""
 
203
    """This testament format is for use as a checksum in bundle format 0.8"""
199
204
 
200
205
    long_header = 'bazaar-ng testament version 2.1\n'
201
206
    short_header = 'bazaar-ng testament short form 2.1\n'
202
207
    def _entry_to_line(self, path, ie):
203
208
        l = Testament._entry_to_line(self, path, ie)[:-1]
204
 
        l += ' ' + ie.revision.decode('utf-8')
 
209
        l += ' ' + ie.revision
205
210
        l += {True: ' yes\n', False: ' no\n'}[ie.executable]
206
211
        return l
 
212
 
 
213
 
 
214
class StrictTestament3(StrictTestament):
 
215
    """This testament format is for use as a checksum in bundle format 0.9+
 
216
    
 
217
    It differs from StrictTestament by including data about the tree root.
 
218
    """
 
219
 
 
220
    long_header = 'bazaar testament version 3 strict\n'
 
221
    short_header = 'bazaar testament short form 3 strict\n'
 
222
    def _get_entries(self):
 
223
        return self.inventory.iter_entries()
 
224
 
 
225
    def _escape_path(self, path):
 
226
        assert not contains_linebreaks(path)
 
227
        if path == '':
 
228
            path = '.'
 
229
        return unicode(path.replace('\\', '/').replace(' ', '\ '))