/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/testament.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
* the testament uses unix line-endings (\n)
60
60
"""
61
61
 
62
 
from __future__ import absolute_import
63
 
 
64
62
# XXX: At the moment, clients trust that the graph described in a weave
65
63
# is accurate, but that's not covered by the testament.  Perhaps the best
66
64
# fix is when verifying a revision to make sure that every file mentioned
73
71
 
74
72
from copy import copy
75
73
 
76
 
from ..osutils import (
 
74
from bzrlib.osutils import (
77
75
    contains_whitespace,
78
76
    contains_linebreaks,
79
 
    sha_strings,
 
77
    sha,
80
78
    )
81
 
from ..sixish import text_type
82
 
from ..tree import Tree
83
79
 
84
80
 
85
81
class Testament(object):
95
91
 
96
92
    long_header = 'bazaar-ng testament version 1\n'
97
93
    short_header = 'bazaar-ng testament short form 1\n'
98
 
    include_root = False
99
94
 
100
95
    @classmethod
101
96
    def from_revision(cls, repository, revision_id):
102
 
        """Produce a new testament from a historical revision."""
 
97
        """Produce a new testament from a historical revision"""
103
98
        rev = repository.get_revision(revision_id)
104
 
        tree = repository.revision_tree(revision_id)
105
 
        return cls(rev, tree)
106
 
 
107
 
    @classmethod
108
 
    def from_revision_tree(cls, tree):
109
 
        """Produce a new testament from a revision tree."""
110
 
        rev = tree._repository.get_revision(tree.get_revision_id())
111
 
        return cls(rev, tree)
112
 
 
113
 
    def __init__(self, rev, tree):
114
 
        """Create a new testament for rev using tree."""
 
99
        inventory = repository.get_inventory(revision_id)
 
100
        return cls(rev, inventory)
 
101
 
 
102
    def __init__(self, rev, inventory):
 
103
        """Create a new testament for rev using inventory."""
115
104
        self.revision_id = rev.revision_id
116
105
        self.committer = rev.committer
117
106
        self.timezone = rev.timezone or 0
118
107
        self.timestamp = rev.timestamp
119
108
        self.message = rev.message
120
109
        self.parent_ids = rev.parent_ids[:]
121
 
        if not isinstance(tree, Tree):
122
 
            raise TypeError("As of bzr 2.4 Testament.__init__() takes a "
123
 
                            "Revision and a Tree.")
124
 
        self.tree = tree
 
110
        self.inventory = inventory
125
111
        self.revprops = copy(rev.properties)
126
112
        if contains_whitespace(self.revision_id):
127
113
            raise ValueError(self.revision_id)
137
123
        r = []
138
124
        a = r.append
139
125
        a(self.long_header)
140
 
        a('revision-id: %s\n' % self.revision_id.decode('utf-8'))
 
126
        a('revision-id: %s\n' % self.revision_id)
141
127
        a('committer: %s\n' % self.committer)
142
128
        a('timestamp: %d\n' % self.timestamp)
143
129
        a('timezone: %d\n' % self.timezone)
146
132
        for parent_id in sorted(self.parent_ids):
147
133
            if contains_whitespace(parent_id):
148
134
                raise ValueError(parent_id)
149
 
            a('  %s\n' % parent_id.decode('utf-8'))
 
135
            a('  %s\n' % parent_id)
150
136
        a('message:\n')
151
137
        for l in self.message.splitlines():
152
138
            a('  %s\n' % l)
157
143
        return [line.encode('utf-8') for line in r]
158
144
 
159
145
    def _get_entries(self):
160
 
        return ((path, ie) for (path, file_class, kind, ie) in
161
 
                self.tree.list_files(include_root=self.include_root))
 
146
        entries = self.inventory.iter_entries()
 
147
        entries.next()
 
148
        return entries
162
149
 
163
150
    def _escape_path(self, path):
164
151
        if contains_linebreaks(path):
165
152
            raise ValueError(path)
166
 
        if not isinstance(path, text_type):
167
 
            # TODO(jelmer): Clean this up for pad.lv/1696545
168
 
            path = path.decode('ascii')
169
 
        return path.replace(u'\\', u'/').replace(u' ', u'\\ ')
 
153
        return unicode(path.replace('\\', '/').replace(' ', '\ '))
170
154
 
171
155
    def _entry_to_line(self, path, ie):
172
156
        """Turn an inventory entry into a testament line"""
173
157
        if contains_whitespace(ie.file_id):
174
158
            raise ValueError(ie.file_id)
175
159
        content = ''
176
 
        content_spacer = ''
 
160
        content_spacer=''
177
161
        if ie.kind == 'file':
178
162
            # TODO: avoid switching on kind
179
163
            if not ie.text_sha1:
180
164
                raise AssertionError()
181
 
            content = ie.text_sha1.decode('ascii')
 
165
            content = ie.text_sha1
182
166
            content_spacer = ' '
183
167
        elif ie.kind == 'symlink':
184
168
            if not ie.symlink_target:
192
176
        return l
193
177
 
194
178
    def as_text(self):
195
 
        return b''.join(self.as_text_lines())
 
179
        return ''.join(self.as_text_lines())
196
180
 
197
181
    def as_short_text(self):
198
182
        """Return short digest-based testament."""
199
 
        return (self.short_header.encode('ascii') +
200
 
                b'revision-id: %s\n'
201
 
                b'sha1: %s\n'
 
183
        return (self.short_header +
 
184
                'revision-id: %s\n'
 
185
                'sha1: %s\n'
202
186
                % (self.revision_id, self.as_sha1()))
203
187
 
204
188
    def _revprops_to_lines(self):
215
199
        return r
216
200
 
217
201
    def as_sha1(self):
218
 
        return sha_strings(self.as_text_lines())
 
202
        s = sha()
 
203
        map(s.update, self.as_text_lines())
 
204
        return s.hexdigest()
219
205
 
220
206
 
221
207
class StrictTestament(Testament):
223
209
 
224
210
    long_header = 'bazaar-ng testament version 2.1\n'
225
211
    short_header = 'bazaar-ng testament short form 2.1\n'
226
 
    include_root = False
227
 
 
228
212
    def _entry_to_line(self, path, ie):
229
213
        l = Testament._entry_to_line(self, path, ie)[:-1]
230
 
        l += ' ' + ie.revision.decode('utf-8')
 
214
        l += ' ' + ie.revision
231
215
        l += {True: ' yes\n', False: ' no\n'}[ie.executable]
232
216
        return l
233
217
 
240
224
 
241
225
    long_header = 'bazaar testament version 3 strict\n'
242
226
    short_header = 'bazaar testament short form 3 strict\n'
243
 
    include_root = True
 
227
    def _get_entries(self):
 
228
        return self.inventory.iter_entries()
244
229
 
245
230
    def _escape_path(self, path):
246
231
        if contains_linebreaks(path):
247
232
            raise ValueError(path)
248
 
        if not isinstance(path, text_type):
249
 
            # TODO(jelmer): Clean this up for pad.lv/1696545
250
 
            path = path.decode('ascii')
251
 
        if path == u'':
252
 
            path = u'.'
253
 
        return path.replace(u'\\', u'/').replace(u' ', u'\\ ')
 
233
        if path == '':
 
234
            path = '.'
 
235
        return unicode(path.replace('\\', '/').replace(' ', '\ '))