Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- cache.h | 3 +++ entry.c | 39 ++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/cache.h b/cache.h index e12b15f..6ce691b 100644 --- a/cache.h +++ b/cache.h @@ -937,6 +937,9 @@ struct checkout { refresh_cache:1; }; +extern int streaming_write_sha1(int fd, int seekable, const unsigned char *sha1, + enum object_type exp_type, + struct stream_filter *filter); extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); struct cache_def { diff --git a/entry.c b/entry.c index 852fea1..dde0d17 100644 --- a/entry.c +++ b/entry.c @@ -115,26 +115,20 @@ static int fstat_output(int fd, const struct checkout *state, struct stat *st) return 0; } -static int streaming_write_entry(struct cache_entry *ce, char *path, - struct stream_filter *filter, - const struct checkout *state, int to_tempfile, - int *fstat_done, struct stat *statbuf) +int streaming_write_sha1(int fd, int seekable, const unsigned char *sha1, + enum object_type exp_type, + struct stream_filter *filter) { struct git_istream *st; enum object_type type; unsigned long sz; int result = -1; ssize_t kept = 0; - int fd = -1; - st = open_istream(ce->sha1, &type, &sz, filter); + st = open_istream(sha1, &type, &sz, filter); if (!st) return -1; - if (type != OBJ_BLOB) - goto close_and_exit; - - fd = open_output_fd(path, ce, to_tempfile); - if (fd < 0) + if (exp_type != OBJ_ANY && type != exp_type) goto close_and_exit; for (;;) { @@ -144,7 +138,7 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, if (!readlen) break; - if (sizeof(buf) == readlen) { + if (seekable && sizeof(buf) == readlen) { for (holeto = 0; holeto < readlen; holeto++) if (buf[holeto]) break; @@ -166,10 +160,29 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 || write(fd, "", 1) != 1)) goto close_and_exit; - *fstat_done = fstat_output(fd, state, statbuf); + result = 0; close_and_exit: close_istream(st); + return result; +} + +static int streaming_write_entry(struct cache_entry *ce, char *path, + struct stream_filter *filter, + const struct checkout *state, int to_tempfile, + int *fstat_done, struct stat *statbuf) +{ + int result = -1; + int fd = open_output_fd(path, ce, to_tempfile); + if (fd < 0) + goto close_and_exit; + + if (streaming_write_sha1(fd, 1, ce->sha1, OBJ_BLOB, filter)) + goto close_and_exit; + + *fstat_done = fstat_output(fd, state, statbuf); + +close_and_exit: if (0 <= fd) result = close(fd); if (result && 0 <= fd) -- 1.7.3.1.256.g2539c.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html