diff options
| author | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:38 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:39 -0700 |
| commit | 47de6b0425c79081e64756dcc019bb26344bf7ad (patch) | |
| tree | 74179a74db058b14979c3e7a5a5fc97b97965ce6 /sha1_file.c | |
| parent | 30fd3a54256a54e5a6006a203c923e97641fb2c2 (diff) | |
| parent | da591a7f4bbe1a208cc5f955523506eb857c45ca (diff) | |
Merge branch 'nd/stream-more'
Use API to read blob data in smaller chunks in more places to reduce the
memory footprint.
By Nguyễn Thái Ngọc Duy (6) and Junio C Hamano (1)
* nd/stream-more:
update-server-info: respect core.bigfilethreshold
fsck: use streaming API for writing lost-found blobs
show: use streaming API for showing blobs
parse_object: avoid putting whole blob in core
cat-file: use streaming API to print blobs
Add more large blob test cases
streaming: make streaming-write-entry to be more reusable
Diffstat (limited to 'sha1_file.c')
| -rw-r--r-- | sha1_file.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/sha1_file.c b/sha1_file.c index 4f06a0e450..ad314f08b9 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -19,6 +19,7 @@ #include "pack-revindex.h" #include "sha1-lookup.h" #include "bulk-checkin.h" +#include "streaming.h" #ifndef O_NOATIME #if defined(__linux__) && (defined(__i386__) || defined(__PPC__)) @@ -1146,10 +1147,47 @@ static const struct packed_git *has_packed_and_bad(const unsigned char *sha1) return NULL; } -int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type) +/* + * With an in-core object data in "map", rehash it to make sure the + * object name actually matches "sha1" to detect object corruption. + * With "map" == NULL, try reading the object named with "sha1" using + * the streaming interface and rehash it to do the same. + */ +int check_sha1_signature(const unsigned char *sha1, void *map, + unsigned long size, const char *type) { unsigned char real_sha1[20]; - hash_sha1_file(map, size, type, real_sha1); + enum object_type obj_type; + struct git_istream *st; + git_SHA_CTX c; + char hdr[32]; + int hdrlen; + + if (map) { + hash_sha1_file(map, size, type, real_sha1); + return hashcmp(sha1, real_sha1) ? -1 : 0; + } + + st = open_istream(sha1, &obj_type, &size, NULL); + if (!st) + return -1; + + /* Generate the header */ + hdrlen = sprintf(hdr, "%s %lu", typename(obj_type), size) + 1; + + /* Sha1.. */ + git_SHA1_Init(&c); + git_SHA1_Update(&c, hdr, hdrlen); + for (;;) { + char buf[1024 * 16]; + ssize_t readlen = read_istream(st, buf, sizeof(buf)); + + if (!readlen) + break; + git_SHA1_Update(&c, buf, readlen); + } + git_SHA1_Final(real_sha1, &c); + close_istream(st); return hashcmp(sha1, real_sha1) ? -1 : 0; } |
