/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 dulwich/objects.py

  • Committer: Jelmer Vernooij
  • Date: 2008-12-11 10:52:43 UTC
  • mto: (0.215.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20081211105243-dokx6i1dofwnlrrm
Add simple pack dump utility.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
                    NotBlobError,
30
30
                    )
31
31
 
32
 
BLOB_ID = "blob"
33
 
TAG_ID = "tag"
34
 
TREE_ID = "tree"
35
 
COMMIT_ID = "commit"
36
 
PARENT_ID = "parent"
37
 
AUTHOR_ID = "author"
38
 
COMMITTER_ID = "committer"
 
32
blob_id = "blob"
 
33
tree_id = "tree"
 
34
commit_id = "commit"
 
35
parent_id = "parent"
 
36
author_id = "author"
 
37
committer_id = "committer"
39
38
 
40
39
def _decompress(string):
41
40
    dcomp = zlib.decompressobj()
52
51
         len(hexsha)
53
52
  return hexsha
54
53
 
55
 
 
56
54
class ShaFile(object):
57
55
  """A git SHA file."""
58
56
 
 
57
  def _update_contents(self):
 
58
    """Update the _contents from the _text"""
 
59
    self._contents = [ord(c) for c in self._text]
 
60
 
59
61
  @classmethod
60
62
  def _parse_legacy_object(cls, map):
61
63
    """Parse a legacy object, creating it and setting object._text"""
81
83
    assert text[0] == "\0", "Size not followed by null"
82
84
    text = text[1:]
83
85
    object._text = text
 
86
    object._update_contents()
84
87
    return object
85
88
 
86
 
  def as_raw_string(self):
87
 
    return self._num_type, self._text
88
 
 
89
89
  @classmethod
90
90
  def _parse_object(cls, map):
91
91
    """Parse a new style object , creating it and setting object._text"""
102
102
      used += 1
103
103
    raw = map[used:]
104
104
    object._text = _decompress(raw)
 
105
    object._update_contents()
105
106
    return object
106
107
 
107
108
  @classmethod
116
117
    """Don't call this directly"""
117
118
 
118
119
  def _parse_text(self):
119
 
    """For subclasses to do initialisation time parsing"""
 
120
    """For subclasses to do initialistion time parsing"""
120
121
 
121
122
  @classmethod
122
123
  def from_file(cls, filename):
140
141
    """
141
142
    real_class = num_type_map[type]
142
143
    obj = real_class()
143
 
    obj._num_type = type
144
144
    obj._text = string
145
 
    obj._parse_text()
 
145
    obj._update_contents()
146
146
    return obj
147
147
 
148
148
  def _header(self):
149
 
    return "%s %lu\0" % (self._type, len(self._text))
 
149
    return "%s %lu\0" % (self._type, len(self._contents))
150
150
 
151
 
  def crc32(self):
152
 
    return zlib.crc32(self._text)
 
151
  def contents(self):
 
152
    """The raw bytes of this object"""
 
153
    return self._contents
153
154
 
154
155
  def sha(self):
155
156
    """The SHA1 object that is the name of this object."""
158
159
    ressha.update(self._text)
159
160
    return ressha
160
161
 
161
 
  @property
162
 
  def id(self):
163
 
      return self.sha().hexdigest()
164
 
 
165
 
  def __repr__(self):
166
 
    return "<%s %s>" % (self.__class__.__name__, self.id)
167
 
 
168
162
  def __eq__(self, other):
169
163
    """Return true id the sha of the two objects match.
170
164
 
177
171
class Blob(ShaFile):
178
172
  """A Git Blob object."""
179
173
 
180
 
  _type = BLOB_ID
 
174
  _type = blob_id
181
175
 
182
 
  @property
183
 
  def data(self):
 
176
  def text(self):
184
177
    """The text contained within the blob object."""
185
178
    return self._text
186
179
 
196
189
    """Create a blob from a string."""
197
190
    shafile = cls()
198
191
    shafile._text = string
199
 
    return shafile
200
 
 
201
 
 
202
 
class Tag(ShaFile):
203
 
  """A Git Tag object."""
204
 
 
205
 
  _type = TAG_ID
206
 
 
207
 
  @classmethod
208
 
  def from_file(cls, filename):
209
 
    blob = ShaFile.from_file(filename)
210
 
    if blob._type != cls._type:
211
 
      raise NotBlobError(filename)
212
 
    return blob
213
 
 
214
 
  @classmethod
215
 
  def from_string(cls, string):
216
 
    """Create a blob from a string."""
217
 
    shafile = cls()
218
 
    shafile._text = string
 
192
    shafile._update_contents()
219
193
    return shafile
220
194
 
221
195
 
222
196
class Tree(ShaFile):
223
197
  """A Git tree object"""
224
198
 
225
 
  _type = TREE_ID
 
199
  _type = tree_id
226
200
 
227
201
  @classmethod
228
202
  def from_file(cls, filename):
232
206
    return tree
233
207
 
234
208
  def entries(self):
235
 
    """Return a list of tuples describing the tree entries"""
 
209
    """Reutrn a list of tuples describing the tree entries"""
236
210
    return self._entries
237
211
 
238
212
  def _parse_text(self):
264
238
class Commit(ShaFile):
265
239
  """A git commit object"""
266
240
 
267
 
  _type = COMMIT_ID
 
241
  _type = commit_id
268
242
 
269
243
  @classmethod
270
244
  def from_file(cls, filename):
276
250
  def _parse_text(self):
277
251
    text = self._text
278
252
    count = 0
279
 
    assert text.startswith(TREE_ID), "Invalid commit object, " \
280
 
         "must start with %s" % TREE_ID
281
 
    count += len(TREE_ID)
 
253
    assert text.startswith(tree_id), "Invlid commit object, " \
 
254
         "must start with %s" % tree_id
 
255
    count += len(tree_id)
282
256
    assert text[count] == ' ', "Invalid commit object, " \
283
 
         "%s must be followed by space not %s" % (TREE_ID, text[count])
 
257
         "%s must be followed by space not %s" % (tree_id, text[count])
284
258
    count += 1
285
259
    self._tree = text[count:count+40]
286
260
    count = count + 40
288
262
         "tree sha must be followed by newline"
289
263
    count += 1
290
264
    self._parents = []
291
 
    while text[count:].startswith(PARENT_ID):
292
 
      count += len(PARENT_ID)
 
265
    while text[count:].startswith(parent_id):
 
266
      count += len(parent_id)
293
267
      assert text[count] == ' ', "Invalid commit object, " \
294
 
           "%s must be followed by space not %s" % (PARENT_ID, text[count])
 
268
           "%s must be followed by space not %s" % (parent_id, text[count])
295
269
      count += 1
296
270
      self._parents.append(text[count:count+40])
297
271
      count += 40
299
273
           "parent sha must be followed by newline"
300
274
      count += 1
301
275
    self._author = None
302
 
    if text[count:].startswith(AUTHOR_ID):
303
 
      count += len(AUTHOR_ID)
 
276
    if text[count:].startswith(author_id):
 
277
      count += len(author_id)
304
278
      assert text[count] == ' ', "Invalid commit object, " \
305
 
           "%s must be followed by space not %s" % (AUTHOR_ID, text[count])
 
279
           "%s must be followed by space not %s" % (author_id, text[count])
306
280
      count += 1
307
281
      self._author = ''
308
282
      while text[count] != '>':
315
289
        count += 1
316
290
      count += 1
317
291
    self._committer = None
318
 
    if text[count:].startswith(COMMITTER_ID):
319
 
      count += len(COMMITTER_ID)
 
292
    if text[count:].startswith(committer_id):
 
293
      count += len(committer_id)
320
294
      assert text[count] == ' ', "Invalid commit object, " \
321
 
           "%s must be followed by space not %s" % (COMMITTER_ID, text[count])
 
295
           "%s must be followed by space not %s" % (committer_id, text[count])
322
296
      count += 1
323
297
      self._committer = ''
324
298
      while text[count] != '>':
339
313
    # XXX: There can be an encoding field.
340
314
    self._message = text[count:]
341
315
 
342
 
  @property
343
316
  def tree(self):
344
317
    """Returns the tree that is the state of this commit"""
345
318
    return self._tree
346
319
 
347
 
  @property
348
320
  def parents(self):
349
321
    """Return a list of parents of this commit."""
350
322
    return self._parents
351
323
 
352
 
  @property
353
324
  def author(self):
354
325
    """Returns the name of the author of the commit"""
355
326
    return self._author
356
327
 
357
 
  @property
358
328
  def committer(self):
359
329
    """Returns the name of the committer of the commit"""
360
330
    return self._committer
361
331
 
362
 
  @property
363
332
  def message(self):
364
333
    """Returns the commit message"""
365
334
    return self._message
366
335
 
367
 
  @property
368
336
  def commit_time(self):
369
337
    """Returns the timestamp of the commit.
370
338
    
373
341
    return self._commit_time
374
342
 
375
343
type_map = {
376
 
  BLOB_ID : Blob,
377
 
  TREE_ID : Tree,
378
 
  COMMIT_ID : Commit,
379
 
  TAG_ID: Tag,
 
344
  blob_id : Blob,
 
345
  tree_id : Tree,
 
346
  commit_id : Commit,
380
347
}
381
348
 
382
349
num_type_map = {
383
 
  0: None,
384
 
  1: Commit,
385
 
  2: Tree,
386
 
  3: Blob,
387
 
  4: Tag,
388
 
  # 5 Is reserved for further expansion
 
350
  1 : Commit,
 
351
  2 : Tree,
 
352
  3 : Blob,
389
353
}
390
354