Signed-off-by: Christian Couder <chrisc...@tuxfamily.org>
---
 external-odb.c | 15 +++++++++++++++
 external-odb.h |  2 ++
 odb-helper.c   | 41 +++++++++++++++++++++++++++++++++++++----
 odb-helper.h   |  3 +++
 sha1_file.c    |  2 ++
 5 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/external-odb.c b/external-odb.c
index 42978a3298..893937a7d4 100644
--- a/external-odb.c
+++ b/external-odb.c
@@ -127,3 +127,18 @@ int external_odb_for_each_object(each_external_object_fn 
fn, void *data)
        }
        return 0;
 }
+
+int external_odb_write_object(const void *buf, size_t len,
+                             const char *type, unsigned char *sha1)
+{
+       struct odb_helper *o;
+
+       external_odb_init();
+
+       for (o = helpers; o; o = o->next) {
+               int r = odb_helper_write_object(o, buf, len, type, sha1);
+               if (r <= 0)
+                       return r;
+       }
+       return 1;
+}
diff --git a/external-odb.h b/external-odb.h
index cea8570a49..53879e900d 100644
--- a/external-odb.h
+++ b/external-odb.h
@@ -10,5 +10,7 @@ typedef int (*each_external_object_fn)(const unsigned char 
*sha1,
                                       unsigned long size,
                                       void *data);
 int external_odb_for_each_object(each_external_object_fn, void *);
+int external_odb_write_object(const void *buf, size_t len,
+                             const char *type, unsigned char *sha1);
 
 #endif /* EXTERNAL_ODB_H */
diff --git a/odb-helper.c b/odb-helper.c
index d8ef5cbf4b..af7cc55ca2 100644
--- a/odb-helper.c
+++ b/odb-helper.c
@@ -33,9 +33,10 @@ static void prepare_helper_command(struct argv_array *argv, 
const char *cmd,
        strbuf_release(&buf);
 }
 
-__attribute__((format (printf,3,4)))
+__attribute__((format (printf,4,5)))
 static int odb_helper_start(struct odb_helper *o,
                            struct odb_helper_cmd *cmd,
+                           int use_stdin,
                            const char *fmt, ...)
 {
        va_list ap;
@@ -52,7 +53,10 @@ static int odb_helper_start(struct odb_helper *o,
 
        cmd->child.argv = cmd->argv.argv;
        cmd->child.use_shell = 1;
-       cmd->child.no_stdin = 1;
+       if (use_stdin)
+               cmd->child.in = -1;
+       else
+               cmd->child.no_stdin = 1;
        cmd->child.out = -1;
 
        if (start_command(&cmd->child) < 0) {
@@ -121,7 +125,7 @@ static void odb_helper_load_have(struct odb_helper *o)
                return;
        o->have_valid = 1;
 
-       if (odb_helper_start(o, &cmd, "have") < 0)
+       if (odb_helper_start(o, &cmd, 0, "have") < 0)
                return;
 
        fh = xfdopen(cmd.child.out, "r");
@@ -170,7 +174,7 @@ int odb_helper_fetch_object(struct odb_helper *o, const 
unsigned char *sha1,
        if (!obj)
                return -1;
 
-       if (odb_helper_start(o, &cmd, "get %s", sha1_to_hex(sha1)) < 0)
+       if (odb_helper_start(o, &cmd, 0, "get %s", sha1_to_hex(sha1)) < 0)
                return -1;
 
        memset(&stream, 0, sizeof(stream));
@@ -258,3 +262,32 @@ int odb_helper_for_each_object(struct odb_helper *o,
 
        return 0;
 }
+
+int odb_helper_write_object(struct odb_helper *o,
+                           const void *buf, size_t len,
+                           const char *type, unsigned char *sha1)
+{
+       struct odb_helper_cmd cmd;
+
+       if (odb_helper_start(o, &cmd, 1, "put %s %"PRIuMAX" %s",
+                            sha1_to_hex(sha1), (uintmax_t)len, type) < 0)
+               return -1;
+
+       do {
+               int w = xwrite(cmd.child.in, buf, len);
+               if (w < 0) {
+                       error("unable to write to odb helper '%s': %s",
+                             o->name, strerror(errno));
+                       close(cmd.child.in);
+                       close(cmd.child.out);
+                       odb_helper_finish(o, &cmd);
+                       return -1;
+               }
+               len -= w;
+       } while (len > 0);
+
+       close(cmd.child.in);
+       close(cmd.child.out);
+       odb_helper_finish(o, &cmd);
+       return 0;
+}
diff --git a/odb-helper.h b/odb-helper.h
index 8c3916d215..4e321195e8 100644
--- a/odb-helper.h
+++ b/odb-helper.h
@@ -25,5 +25,8 @@ int odb_helper_fetch_object(struct odb_helper *o, const 
unsigned char *sha1,
                            int fd);
 int odb_helper_for_each_object(struct odb_helper *o,
                               each_external_object_fn, void *);
+int odb_helper_write_object(struct odb_helper *o,
+                           const void *buf, size_t len,
+                           const char *type, unsigned char *sha1);
 
 #endif /* ODB_HELPER_H */
diff --git a/sha1_file.c b/sha1_file.c
index f87c59d711..8dd09334cf 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3450,6 +3450,8 @@ int write_sha1_file(const void *buf, unsigned long len, 
const char *type, unsign
         * it out into .git/objects/??/?{38} file.
         */
        write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
+       if (!external_odb_write_object(buf, len, type, sha1))
+               return 0;
        if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
                return 0;
        return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
-- 
2.13.1.565.gbfcd7a9048

Reply via email to