~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-09-26 05:47:03 UTC
  • mfrom: (3696.5.4 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080926054703-nxn5f1h7z7gvur96
(robertc) Improve the handling of the sha1 cache by updating it
        during commit and avoiding some of the sha generation during
        iter_changes. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
241
241
            content - stat, length, exec, sha/link target. This is only
242
242
            accessed when the entry has a revision of None - that is when it is
243
243
            a candidate to commit.
244
 
        :return: A tuple (change_delta, version_recorded). change_delta is 
245
 
            an inventory_delta change for this entry against the basis tree of
246
 
            the commit, or None if no change occured against the basis tree.
 
244
        :return: A tuple (change_delta, version_recorded, fs_hash).
 
245
            change_delta is an inventory_delta change for this entry against
 
246
            the basis tree of the commit, or None if no change occured against
 
247
            the basis tree.
247
248
            version_recorded is True if a new version of the entry has been
248
249
            recorded. For instance, committing a merge where a file was only
249
250
            changed on the other side will return (delta, False).
 
251
            fs_hash is either None, or the hash details for the path (currently
 
252
            a tuple of the contents sha1 and the statvalue returned by
 
253
            tree.get_file_with_stat()).
250
254
        """
251
255
        if self.new_inventory.root is None:
252
256
            if ie.parent_id is not None:
287
291
                else:
288
292
                    # add
289
293
                    delta = (None, path, ie.file_id, ie)
290
 
                return delta, False
 
294
                return delta, False, None
291
295
            else:
292
296
                # we don't need to commit this, because the caller already
293
297
                # determined that an existing revision of this file is
298
302
                    raise AssertionError("Impossible situation, a skipped "
299
303
                        "inventory entry (%r) claims to be modified in this "
300
304
                        "commit (%r).", (ie, self._new_revision_id))
301
 
                return None, False
 
305
                return None, False, None
302
306
        # XXX: Friction: parent_candidates should return a list not a dict
303
307
        #      so that we don't have to walk the inventories again.
304
308
        parent_candiate_entries = ie.parent_candidates(parent_invs)
334
338
            # if the kind changed the content obviously has
335
339
            if kind != parent_entry.kind:
336
340
                store = True
 
341
        # Stat cache fingerprint feedback for the caller - None as we usually
 
342
        # don't generate one.
 
343
        fingerprint = None
337
344
        if kind == 'file':
338
345
            if content_summary[2] is None:
339
346
                raise ValueError("Files must not have executable = None")
350
357
                    ie.text_size = parent_entry.text_size
351
358
                    ie.text_sha1 = parent_entry.text_sha1
352
359
                    ie.executable = parent_entry.executable
353
 
                    return self._get_delta(ie, basis_inv, path), False
 
360
                    return self._get_delta(ie, basis_inv, path), False, None
354
361
                else:
355
362
                    # Either there is only a hash change(no hash cache entry,
356
363
                    # or same size content change), or there is no change on
363
370
                # absence of a content change in the file.
364
371
                nostore_sha = None
365
372
            ie.executable = content_summary[2]
366
 
            lines = tree.get_file(ie.file_id, path).readlines()
 
373
            file_obj, stat_value = tree.get_file_with_stat(ie.file_id, path)
 
374
            try:
 
375
                lines = file_obj.readlines()
 
376
            finally:
 
377
                file_obj.close()
367
378
            try:
368
379
                ie.text_sha1, ie.text_size = self._add_text_to_weave(
369
380
                    ie.file_id, lines, heads, nostore_sha)
 
381
                # Let the caller know we generated a stat fingerprint.
 
382
                fingerprint = (ie.text_sha1, stat_value)
370
383
            except errors.ExistingContent:
371
384
                # Turns out that the file content was unchanged, and we were
372
385
                # only going to store a new node if it was changed. Carry over
375
388
                ie.text_size = parent_entry.text_size
376
389
                ie.text_sha1 = parent_entry.text_sha1
377
390
                ie.executable = parent_entry.executable
378
 
                return self._get_delta(ie, basis_inv, path), False
 
391
                return self._get_delta(ie, basis_inv, path), False, None
379
392
        elif kind == 'directory':
380
393
            if not store:
381
394
                # all data is meta here, nothing specific to directory, so
382
395
                # carry over:
383
396
                ie.revision = parent_entry.revision
384
 
                return self._get_delta(ie, basis_inv, path), False
 
397
                return self._get_delta(ie, basis_inv, path), False, None
385
398
            lines = []
386
399
            self._add_text_to_weave(ie.file_id, lines, heads, None)
387
400
        elif kind == 'symlink':
395
408
                # unchanged, carry over.
396
409
                ie.revision = parent_entry.revision
397
410
                ie.symlink_target = parent_entry.symlink_target
398
 
                return self._get_delta(ie, basis_inv, path), False
 
411
                return self._get_delta(ie, basis_inv, path), False, None
399
412
            ie.symlink_target = current_link_target
400
413
            lines = []
401
414
            self._add_text_to_weave(ie.file_id, lines, heads, None)
407
420
                # unchanged, carry over.
408
421
                ie.reference_revision = parent_entry.reference_revision
409
422
                ie.revision = parent_entry.revision
410
 
                return self._get_delta(ie, basis_inv, path), False
 
423
                return self._get_delta(ie, basis_inv, path), False, None
411
424
            ie.reference_revision = content_summary[3]
412
425
            lines = []
413
426
            self._add_text_to_weave(ie.file_id, lines, heads, None)
414
427
        else:
415
428
            raise NotImplementedError('unknown kind')
416
429
        ie.revision = self._new_revision_id
417
 
        return self._get_delta(ie, basis_inv, path), True
 
430
        return self._get_delta(ie, basis_inv, path), True, fingerprint
418
431
 
419
432
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
420
433
        # Note: as we read the content directly from the tree, we know its not