This implements the 'get_direct' capability/instruction that makes
it possible for external odb helper scripts to pass blobs to Git
by directly writing them as loose objects files.

It is better to call this a "direct" mode rather than a "fault-in"
mode as we could have the same kind of mechanism to "put" objects
into an external odb, where the odb helper would access blobs it
wants to send to an external odb directly from files, but it
would be strange to call that a fault-in mode too.

Signed-off-by: Christian Couder <chrisc...@tuxfamily.org>
---
 external-odb.c |  3 ++-
 odb-helper.c   | 28 +++++++++++++++++++++++-----
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/external-odb.c b/external-odb.c
index 93971e9ce4..3ce3d111f3 100644
--- a/external-odb.c
+++ b/external-odb.c
@@ -109,7 +109,8 @@ int external_odb_get_object(const unsigned char *sha1)
                int ret;
                int fd;
 
-               if (!odb_helper_has_object(o, sha1))
+               if (!(o->supported_capabilities & ODB_HELPER_CAP_GET_RAW_OBJ) &&
+                   !(o->supported_capabilities & ODB_HELPER_CAP_GET_GIT_OBJ))
                        continue;
 
                fd = create_object_tmpfile(&tmpfile, path);
diff --git a/odb-helper.c b/odb-helper.c
index fc30c2fa57..0fa7af0348 100644
--- a/odb-helper.c
+++ b/odb-helper.c
@@ -429,24 +429,42 @@ static int odb_helper_get_git_object(struct odb_helper *o,
 int odb_helper_get_direct(struct odb_helper *o,
                          const unsigned char *sha1)
 {
-       int res = 0;
        uint64_t start = getnanotime();
 
-       fetch_object(o->dealer, sha1);
+       if (o->type == ODB_HELPER_GIT_REMOTE) {
+               fetch_object(o->dealer, sha1);
+       } else {
+               struct odb_helper_object *obj;
+               struct odb_helper_cmd cmd;
+
+               obj = odb_helper_lookup(o, sha1);
+               if (!obj)
+                       return -1;
+
+               if (odb_helper_start(o, &cmd, 0, "get_direct %s", 
sha1_to_hex(sha1)) < 0)
+                       return -1;
+
+               if (odb_helper_finish(o, &cmd))
+                       return -1;
+       }
 
        trace_performance_since(start, "odb_helper_get_direct");
 
-       return res;
+       return 0;
 }
 
 int odb_helper_get_object(struct odb_helper *o,
                          const unsigned char *sha1,
                          int fd)
 {
+       if (o->supported_capabilities & ODB_HELPER_CAP_GET_GIT_OBJ)
+               return odb_helper_get_git_object(o, sha1, fd);
        if (o->supported_capabilities & ODB_HELPER_CAP_GET_RAW_OBJ)
                return odb_helper_get_raw_object(o, sha1, fd);
-       else
-               return odb_helper_get_git_object(o, sha1, fd);
+       if (o->supported_capabilities & ODB_HELPER_CAP_GET_DIRECT)
+               return 0;
+
+       BUG("invalid get capability (capabilities: '%d')", 
o->supported_capabilities);
 }
 
 int odb_helper_put_object(struct odb_helper *o,
-- 
2.16.0.rc0.16.g82191dbc6c.dirty

Reply via email to