[PATCH 02/11] Factor out and export large blob writing code to arbitrary file handle
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
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