diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-11-17 16:26:54 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-11-30 14:27:59 -0800 |
commit | 6c526148644475acbc047faaeb57d42fde1f667d (patch) | |
tree | 1bf8400d2f5dff6ea15775b8b8af47af2e740617 /csum-file.c | |
parent | 0e990530ae6d6c6805d31c666953541f762dd402 (diff) | |
download | git-6c526148644475acbc047faaeb57d42fde1f667d.tar.gz |
csum-file: introduce sha1file_checkpoint
It is useful to be able to rewind a check-summed file to a certain
previous state after writing data into it using sha1write() API. The
fast-import command does this after streaming a blob data to the packfile
being generated and then noticing that the same blob has already been
written, and it does this with a private code truncate_pack() that is
commented as "Yes, this is a layering violation".
Introduce two API functions, sha1file_checkpoint(), that allows the caller
to save a state of a sha1file, and then later revert it to the saved state.
Use it to reimplement truncate_pack().
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'csum-file.c')
-rw-r--r-- | csum-file.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/csum-file.c b/csum-file.c index fc97d6e045..53f5375b6c 100644 --- a/csum-file.c +++ b/csum-file.c @@ -158,6 +158,26 @@ struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp return f; } +void sha1file_checkpoint(struct sha1file *f, struct sha1file_checkpoint *checkpoint) +{ + sha1flush(f); + checkpoint->offset = f->total; + checkpoint->ctx = f->ctx; +} + +int sha1file_truncate(struct sha1file *f, struct sha1file_checkpoint *checkpoint) +{ + off_t offset = checkpoint->offset; + + if (ftruncate(f->fd, offset) || + lseek(f->fd, offset, SEEK_SET) != offset) + return -1; + f->total = offset; + f->ctx = checkpoint->ctx; + f->offset = 0; /* sha1flush() was called in checkpoint */ + return 0; +} + void crc32_begin(struct sha1file *f) { f->crc32 = crc32(0, NULL, 0); |