Imported Upstream version 2.30.0
[platform/upstream/git.git] / sha1-file.c
index 494606f..c3c49d2 100644 (file)
@@ -30,8 +30,8 @@
 #include "mergesort.h"
 #include "quote.h"
 #include "packfile.h"
-#include "fetch-object.h"
 #include "object-store.h"
+#include "promisor-remote.h"
 
 /* The maximum size for an object header. */
 #define MAX_HEADER_LEN 32
@@ -55,7 +55,6 @@
        "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
        "\x18\x13"
 
-const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
 static const struct object_id empty_tree_oid = {
        EMPTY_TREE_SHA1_BIN_LITERAL
@@ -75,6 +74,11 @@ static void git_hash_sha1_init(git_hash_ctx *ctx)
        git_SHA1_Init(&ctx->sha1);
 }
 
+static void git_hash_sha1_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+       git_SHA1_Clone(&dst->sha1, &src->sha1);
+}
+
 static void git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len)
 {
        git_SHA1_Update(&ctx->sha1, data, len);
@@ -91,6 +95,11 @@ static void git_hash_sha256_init(git_hash_ctx *ctx)
        git_SHA256_Init(&ctx->sha256);
 }
 
+static void git_hash_sha256_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+       git_SHA256_Clone(&dst->sha256, &src->sha256);
+}
+
 static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len)
 {
        git_SHA256_Update(&ctx->sha256, data, len);
@@ -106,6 +115,11 @@ static void git_hash_unknown_init(git_hash_ctx *ctx)
        BUG("trying to init unknown hash");
 }
 
+static void git_hash_unknown_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+       BUG("trying to clone unknown hash");
+}
+
 static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
 {
        BUG("trying to update unknown hash");
@@ -124,6 +138,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
                0,
                0,
                git_hash_unknown_init,
+               git_hash_unknown_clone,
                git_hash_unknown_update,
                git_hash_unknown_final,
                NULL,
@@ -137,6 +152,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
                GIT_SHA1_HEXSZ,
                GIT_SHA1_BLKSZ,
                git_hash_sha1_init,
+               git_hash_sha1_clone,
                git_hash_sha1_update,
                git_hash_sha1_final,
                &empty_tree_oid,
@@ -150,6 +166,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
                GIT_SHA256_HEXSZ,
                GIT_SHA256_BLKSZ,
                git_hash_sha256_init,
+               git_hash_sha256_clone,
                git_hash_sha256_update,
                git_hash_sha256_final,
                &empty_tree_oid_sha256,
@@ -189,6 +206,14 @@ int hash_algo_by_id(uint32_t format_id)
        return GIT_HASH_UNKNOWN;
 }
 
+int hash_algo_by_length(int len)
+{
+       int i;
+       for (i = 1; i < GIT_HASH_NALGOS; i++)
+               if (len == hash_algos[i].rawsz)
+                       return i;
+       return GIT_HASH_UNKNOWN;
+}
 
 /*
  * This is meant to hold a *small* number of objects that you would
@@ -266,7 +291,7 @@ int mkdir_in_gitdir(const char *path)
        return adjust_shared_perm(path);
 }
 
-enum scld_error safe_create_leading_directories(char *path)
+static enum scld_error safe_create_leading_directories_1(char *path, int share)
 {
        char *next_component = path + offset_1st_component(path);
        enum scld_error ret = SCLD_OK;
@@ -312,7 +337,7 @@ enum scld_error safe_create_leading_directories(char *path)
                                ret = SCLD_VANISHED;
                        else
                                ret = SCLD_FAILED;
-               } else if (adjust_shared_perm(path)) {
+               } else if (share && adjust_shared_perm(path)) {
                        ret = SCLD_PERMS;
                }
                *slash = slash_character;
@@ -320,6 +345,16 @@ enum scld_error safe_create_leading_directories(char *path)
        return ret;
 }
 
+enum scld_error safe_create_leading_directories(char *path)
+{
+       return safe_create_leading_directories_1(path, 1);
+}
+
+enum scld_error safe_create_leading_directories_no_share(char *path)
+{
+       return safe_create_leading_directories_1(path, 0);
+}
+
 enum scld_error safe_create_leading_directories_const(const char *path)
 {
        int save_errno;
@@ -669,20 +704,15 @@ void add_to_alternates_memory(const char *reference)
 char *compute_alternate_path(const char *path, struct strbuf *err)
 {
        char *ref_git = NULL;
-       const char *repo, *ref_git_s;
+       const char *repo;
        int seen_error = 0;
 
-       ref_git_s = real_path_if_valid(path);
-       if (!ref_git_s) {
+       ref_git = real_pathdup(path, 0);
+       if (!ref_git) {
                seen_error = 1;
                strbuf_addf(err, _("path '%s' does not exist"), path);
                goto out;
-       } else
-               /*
-                * Beware: read_gitfile(), real_path() and mkpath()
-                * return static buffer
-                */
-               ref_git = xstrdup(ref_git_s);
+       }
 
        repo = read_gitfile(ref_git);
        if (!repo)
@@ -735,6 +765,104 @@ out:
        return ref_git;
 }
 
+static void fill_alternate_refs_command(struct child_process *cmd,
+                                       const char *repo_path)
+{
+       const char *value;
+
+       if (!git_config_get_value("core.alternateRefsCommand", &value)) {
+               cmd->use_shell = 1;
+
+               strvec_push(&cmd->args, value);
+               strvec_push(&cmd->args, repo_path);
+       } else {
+               cmd->git_cmd = 1;
+
+               strvec_pushf(&cmd->args, "--git-dir=%s", repo_path);
+               strvec_push(&cmd->args, "for-each-ref");
+               strvec_push(&cmd->args, "--format=%(objectname)");
+
+               if (!git_config_get_value("core.alternateRefsPrefixes", &value)) {
+                       strvec_push(&cmd->args, "--");
+                       strvec_split(&cmd->args, value);
+               }
+       }
+
+       cmd->env = local_repo_env;
+       cmd->out = -1;
+}
+
+static void read_alternate_refs(const char *path,
+                               alternate_ref_fn *cb,
+                               void *data)
+{
+       struct child_process cmd = CHILD_PROCESS_INIT;
+       struct strbuf line = STRBUF_INIT;
+       FILE *fh;
+
+       fill_alternate_refs_command(&cmd, path);
+
+       if (start_command(&cmd))
+               return;
+
+       fh = xfdopen(cmd.out, "r");
+       while (strbuf_getline_lf(&line, fh) != EOF) {
+               struct object_id oid;
+               const char *p;
+
+               if (parse_oid_hex(line.buf, &oid, &p) || *p) {
+                       warning(_("invalid line while parsing alternate refs: %s"),
+                               line.buf);
+                       break;
+               }
+
+               cb(&oid, data);
+       }
+
+       fclose(fh);
+       finish_command(&cmd);
+       strbuf_release(&line);
+}
+
+struct alternate_refs_data {
+       alternate_ref_fn *fn;
+       void *data;
+};
+
+static int refs_from_alternate_cb(struct object_directory *e,
+                                 void *data)
+{
+       struct strbuf path = STRBUF_INIT;
+       size_t base_len;
+       struct alternate_refs_data *cb = data;
+
+       if (!strbuf_realpath(&path, e->path, 0))
+               goto out;
+       if (!strbuf_strip_suffix(&path, "/objects"))
+               goto out;
+       base_len = path.len;
+
+       /* Is this a git repository with refs? */
+       strbuf_addstr(&path, "/refs");
+       if (!is_directory(path.buf))
+               goto out;
+       strbuf_setlen(&path, base_len);
+
+       read_alternate_refs(path.buf, cb->fn, cb->data);
+
+out:
+       strbuf_release(&path);
+       return 0;
+}
+
+void for_each_alternate_ref(alternate_ref_fn fn, void *data)
+{
+       struct alternate_refs_data cb;
+       cb.fn = fn;
+       cb.data = data;
+       foreach_alt_odb(refs_from_alternate_cb, &cb);
+}
+
 int foreach_alt_odb(alt_odb_fn fn, void *cb)
 {
        struct object_directory *ent;
@@ -763,9 +891,7 @@ void prepare_alt_odb(struct repository *r)
 /* Returns 1 if we have successfully freshened the file, 0 otherwise. */
 static int freshen_file(const char *fn)
 {
-       struct utimbuf t;
-       t.actime = t.modtime = time(NULL);
-       return !utime(fn, &t);
+       return !utime(fn, NULL);
 }
 
 /*
@@ -846,12 +972,8 @@ void *xmmap_gently(void *start, size_t length,
 
        mmap_limit_check(length);
        ret = mmap(start, length, prot, flags, fd, offset);
-       if (ret == MAP_FAILED) {
-               if (!length)
-                       return NULL;
-               release_pack_memory(length);
-               ret = mmap(start, length, prot, flags, fd, offset);
-       }
+       if (ret == MAP_FAILED && !length)
+               ret = NULL;
        return ret;
 }
 
@@ -870,8 +992,8 @@ void *xmmap(void *start, size_t length,
  * With "map" == NULL, try reading the object named with "oid" using
  * the streaming interface and rehash it to do the same.
  */
-int check_object_signature(const struct object_id *oid, void *map,
-                          unsigned long size, const char *type)
+int check_object_signature(struct repository *r, const struct object_id *oid,
+                          void *map, unsigned long size, const char *type)
 {
        struct object_id real_oid;
        enum object_type obj_type;
@@ -881,11 +1003,11 @@ int check_object_signature(const struct object_id *oid, void *map,
        int hdrlen;
 
        if (map) {
-               hash_object_file(map, size, type, &real_oid);
+               hash_object_file(r->hash_algo, map, size, type, &real_oid);
                return !oideq(oid, &real_oid) ? -1 : 0;
        }
 
-       st = open_istream(oid, &obj_type, &size, NULL);
+       st = open_istream(r, oid, &obj_type, &size, NULL);
        if (!st)
                return -1;
 
@@ -893,8 +1015,8 @@ int check_object_signature(const struct object_id *oid, void *map,
        hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1;
 
        /* Sha1.. */
-       the_hash_algo->init_fn(&c);
-       the_hash_algo->update_fn(&c, hdr, hdrlen);
+       r->hash_algo->init_fn(&c);
+       r->hash_algo->update_fn(&c, hdr, hdrlen);
        for (;;) {
                char buf[1024 * 16];
                ssize_t readlen = read_istream(st, buf, sizeof(buf));
@@ -905,9 +1027,9 @@ int check_object_signature(const struct object_id *oid, void *map,
                }
                if (!readlen)
                        break;
-               the_hash_algo->update_fn(&c, buf, readlen);
+               r->hash_algo->update_fn(&c, buf, readlen);
        }
-       the_hash_algo->final_fn(real_oid.hash, &c);
+       r->hash_algo->final_fn(real_oid.hash, &c);
        close_istream(st);
        return !oideq(oid, &real_oid) ? -1 : 0;
 }
@@ -1046,6 +1168,8 @@ static int unpack_loose_short_header(git_zstream *stream,
                                     unsigned char *map, unsigned long mapsize,
                                     void *buffer, unsigned long bufsiz)
 {
+       int ret;
+
        /* Get the data stream */
        memset(stream, 0, sizeof(*stream));
        stream->next_in = map;
@@ -1054,7 +1178,11 @@ static int unpack_loose_short_header(git_zstream *stream,
        stream->avail_out = bufsiz;
 
        git_inflate_init(stream);
-       return git_inflate(stream, 0);
+       obj_read_unlock();
+       ret = git_inflate(stream, 0);
+       obj_read_lock();
+
+       return ret;
 }
 
 int unpack_loose_header(git_zstream *stream,
@@ -1099,7 +1227,9 @@ static int unpack_loose_header_to_strbuf(git_zstream *stream, unsigned char *map
        stream->avail_out = bufsiz;
 
        do {
+               obj_read_unlock();
                status = git_inflate(stream, 0);
+               obj_read_lock();
                strbuf_add(header, buffer, stream->next_out - (unsigned char *)buffer);
                if (memchr(buffer, '\0', stream->next_out - (unsigned char *)buffer))
                        return 0;
@@ -1139,8 +1269,11 @@ static void *unpack_loose_rest(git_zstream *stream,
                 */
                stream->next_out = buf + bytes;
                stream->avail_out = size - bytes;
-               while (status == Z_OK)
+               while (status == Z_OK) {
+                       obj_read_unlock();
                        status = git_inflate(stream, Z_FINISH);
+                       obj_read_lock();
+               }
        }
        if (status == Z_STREAM_END && !stream->avail_in) {
                git_inflate_end(stream);
@@ -1242,8 +1375,8 @@ static int loose_object_info(struct repository *r,
        struct strbuf hdrbuf = STRBUF_INIT;
        unsigned long size_scratch;
 
-       if (oi->delta_base_sha1)
-               hashclr(oi->delta_base_sha1);
+       if (oi->delta_base_oid)
+               oidclr(oi->delta_base_oid);
 
        /*
         * If we don't care about type or size, then we don't
@@ -1310,17 +1443,41 @@ static int loose_object_info(struct repository *r,
        return (status < 0) ? status : 0;
 }
 
+int obj_read_use_lock = 0;
+pthread_mutex_t obj_read_mutex;
+
+void enable_obj_read_lock(void)
+{
+       if (obj_read_use_lock)
+               return;
+
+       obj_read_use_lock = 1;
+       init_recursive_mutex(&obj_read_mutex);
+}
+
+void disable_obj_read_lock(void)
+{
+       if (!obj_read_use_lock)
+               return;
+
+       obj_read_use_lock = 0;
+       pthread_mutex_destroy(&obj_read_mutex);
+}
+
 int fetch_if_missing = 1;
 
-int oid_object_info_extended(struct repository *r, const struct object_id *oid,
-                            struct object_info *oi, unsigned flags)
+static int do_oid_object_info_extended(struct repository *r,
+                                      const struct object_id *oid,
+                                      struct object_info *oi, unsigned flags)
 {
        static struct object_info blank_oi = OBJECT_INFO_INIT;
+       struct cached_object *co;
        struct pack_entry e;
        int rtype;
        const struct object_id *real = oid;
        int already_retried = 0;
 
+
        if (flags & OBJECT_INFO_LOOKUP_REPLACE)
                real = lookup_replace_object(r, oid);
 
@@ -1330,24 +1487,22 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
        if (!oi)
                oi = &blank_oi;
 
-       if (!(flags & OBJECT_INFO_SKIP_CACHED)) {
-               struct cached_object *co = find_cached_object(real);
-               if (co) {
-                       if (oi->typep)
-                               *(oi->typep) = co->type;
-                       if (oi->sizep)
-                               *(oi->sizep) = co->size;
-                       if (oi->disk_sizep)
-                               *(oi->disk_sizep) = 0;
-                       if (oi->delta_base_sha1)
-                               hashclr(oi->delta_base_sha1);
-                       if (oi->type_name)
-                               strbuf_addstr(oi->type_name, type_name(co->type));
-                       if (oi->contentp)
-                               *oi->contentp = xmemdupz(co->buf, co->size);
-                       oi->whence = OI_CACHED;
-                       return 0;
-               }
+       co = find_cached_object(real);
+       if (co) {
+               if (oi->typep)
+                       *(oi->typep) = co->type;
+               if (oi->sizep)
+                       *(oi->sizep) = co->size;
+               if (oi->disk_sizep)
+                       *(oi->disk_sizep) = 0;
+               if (oi->delta_base_oid)
+                       oidclr(oi->delta_base_oid);
+               if (oi->type_name)
+                       strbuf_addstr(oi->type_name, type_name(co->type));
+               if (oi->contentp)
+                       *oi->contentp = xmemdupz(co->buf, co->size);
+               oi->whence = OI_CACHED;
+               return 0;
        }
 
        while (1) {
@@ -1369,15 +1524,17 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
                }
 
                /* Check if it is a missing object */
-               if (fetch_if_missing && repository_format_partial_clone &&
-                   !already_retried && r == the_repository) {
+               if (fetch_if_missing && has_promisor_remote() &&
+                   !already_retried && r == the_repository &&
+                   !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
                        /*
-                        * TODO Investigate having fetch_object() return
-                        * TODO error/success and stopping the music here.
-                        * TODO Pass a repository struct through fetch_object,
-                        * such that arbitrary repositories work.
+                        * TODO Investigate checking promisor_remote_get_direct()
+                        * TODO return value and stopping on error here.
+                        * TODO Pass a repository struct through
+                        * promisor_remote_get_direct(), such that arbitrary
+                        * repositories work.
                         */
-                       fetch_objects(repository_format_partial_clone, real, 1);
+                       promisor_remote_get_direct(r, real, 1);
                        already_retried = 1;
                        continue;
                }
@@ -1394,7 +1551,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
        rtype = packed_object_info(r, e.p, e.offset, oi);
        if (rtype < 0) {
                mark_bad_packed_object(e.p, real->hash);
-               return oid_object_info_extended(r, real, oi, 0);
+               return do_oid_object_info_extended(r, real, oi, 0);
        } else if (oi->whence == OI_PACKED) {
                oi->u.packed.offset = e.offset;
                oi->u.packed.pack = e.p;
@@ -1405,6 +1562,17 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
        return 0;
 }
 
+int oid_object_info_extended(struct repository *r, const struct object_id *oid,
+                            struct object_info *oi, unsigned flags)
+{
+       int ret;
+       obj_read_lock();
+       ret = do_oid_object_info_extended(r, oid, oi, flags);
+       obj_read_unlock();
+       return ret;
+}
+
+
 /* returns enum object_type or negative */
 int oid_object_info(struct repository *r,
                    const struct object_id *oid,
@@ -1441,8 +1609,9 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
 {
        struct cached_object *co;
 
-       hash_object_file(buf, len, type_name(type), oid);
-       if (has_object_file(oid) || find_cached_object(oid))
+       hash_object_file(the_hash_algo, buf, len, type_name(type), oid);
+       if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) ||
+           find_cached_object(oid))
                return 0;
        ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
        co = &cached_objects[cached_object_nr++];
@@ -1477,6 +1646,7 @@ void *read_object_file_extended(struct repository *r,
        if (data)
                return data;
 
+       obj_read_lock();
        if (errno && errno != ENOENT)
                die_errno(_("failed to read object %s"), oid_to_hex(oid));
 
@@ -1492,11 +1662,13 @@ void *read_object_file_extended(struct repository *r,
        if ((p = has_packed_and_bad(r, repl->hash)) != NULL)
                die(_("packed object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), p->pack_name);
+       obj_read_unlock();
 
        return NULL;
 }
 
-void *read_object_with_reference(const struct object_id *oid,
+void *read_object_with_reference(struct repository *r,
+                                const struct object_id *oid,
                                 const char *required_type_name,
                                 unsigned long *size,
                                 struct object_id *actual_oid_return)
@@ -1512,7 +1684,7 @@ void *read_object_with_reference(const struct object_id *oid,
                int ref_length = -1;
                const char *ref_type = NULL;
 
-               buffer = read_object_file(&actual_oid, &type, &isize);
+               buffer = repo_read_object_file(r, &actual_oid, &type, &isize);
                if (!buffer)
                        return NULL;
                if (type == required_type) {
@@ -1544,7 +1716,8 @@ void *read_object_with_reference(const struct object_id *oid,
        }
 }
 
-static void write_object_file_prepare(const void *buf, unsigned long len,
+static void write_object_file_prepare(const struct git_hash_algo *algo,
+                                     const void *buf, unsigned long len,
                                      const char *type, struct object_id *oid,
                                      char *hdr, int *hdrlen)
 {
@@ -1554,10 +1727,10 @@ static void write_object_file_prepare(const void *buf, unsigned long len,
        *hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
 
        /* Sha1.. */
-       the_hash_algo->init_fn(&c);
-       the_hash_algo->update_fn(&c, hdr, *hdrlen);
-       the_hash_algo->update_fn(&c, buf, len);
-       the_hash_algo->final_fn(oid->hash, &c);
+       algo->init_fn(&c);
+       algo->update_fn(&c, hdr, *hdrlen);
+       algo->update_fn(&c, buf, len);
+       algo->final_fn(oid->hash, &c);
 }
 
 /*
@@ -1610,12 +1783,13 @@ static int write_buffer(int fd, const void *buf, size_t len)
        return 0;
 }
 
-int hash_object_file(const void *buf, unsigned long len, const char *type,
+int hash_object_file(const struct git_hash_algo *algo, const void *buf,
+                    unsigned long len, const char *type,
                     struct object_id *oid)
 {
        char hdr[MAX_HEADER_LEN];
        int hdrlen = sizeof(hdr);
-       write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
+       write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
        return 0;
 }
 
@@ -1773,7 +1947,8 @@ int write_object_file(const void *buf, unsigned long len, const char *type,
        /* Normally if we have it in the pack then we do not bother writing
         * it out into .git/objects/??/?{38} file.
         */
-       write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
+       write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
+                                 &hdrlen);
        if (freshen_packed_object(oid) || freshen_loose_object(oid))
                return 0;
        return write_loose_object(oid, hdr, hdrlen, buf, len, 0);
@@ -1789,7 +1964,8 @@ int hash_object_file_literally(const void *buf, unsigned long len,
        /* type string, SP, %lu of the length plus NUL must fit this */
        hdrlen = strlen(type) + MAX_HEADER_LEN;
        header = xmalloc(hdrlen);
-       write_object_file_prepare(buf, len, type, oid, header, &hdrlen);
+       write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
+                                 &hdrlen);
 
        if (!(flags & HASH_WRITE_OBJECT))
                goto cleanup;
@@ -1823,13 +1999,24 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        return ret;
 }
 
+int has_object(struct repository *r, const struct object_id *oid,
+              unsigned flags)
+{
+       int quick = !(flags & HAS_OBJECT_RECHECK_PACKED);
+       unsigned object_info_flags = OBJECT_INFO_SKIP_FETCH_OBJECT |
+               (quick ? OBJECT_INFO_QUICK : 0);
+
+       if (!startup_info->have_repository)
+               return 0;
+       return oid_object_info_extended(r, oid, NULL, object_info_flags) >= 0;
+}
+
 int repo_has_object_file_with_flags(struct repository *r,
                                    const struct object_id *oid, int flags)
 {
        if (!startup_info->have_repository)
                return 0;
-       return oid_object_info_extended(r, oid, NULL,
-                                       flags | OBJECT_INFO_SKIP_CACHED) >= 0;
+       return oid_object_info_extended(r, oid, NULL, flags) >= 0;
 }
 
 int repo_has_object_file(struct repository *r,
@@ -1900,7 +2087,8 @@ static int index_mem(struct index_state *istate,
        if (write_object)
                ret = write_object_file(buf, size, type_name(type), oid);
        else
-               ret = hash_object_file(buf, size, type_name(type), oid);
+               ret = hash_object_file(the_hash_algo, buf, size,
+                                      type_name(type), oid);
        if (re_allocated)
                free(buf);
        return ret;
@@ -1926,8 +2114,8 @@ static int index_stream_convert_blob(struct index_state *istate,
                ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
                                        oid);
        else
-               ret = hash_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
-                                      oid);
+               ret = hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
+                                      type_name(OBJ_BLOB), oid);
        strbuf_release(&sbuf);
        return ret;
 }
@@ -2045,7 +2233,8 @@ int index_path(struct index_state *istate, struct object_id *oid,
                if (strbuf_readlink(&sb, path, st->st_size))
                        return error_errno("readlink(\"%s\")", path);
                if (!(flags & HASH_WRITE_OBJECT))
-                       hash_object_file(sb.buf, sb.len, blob_type, oid);
+                       hash_object_file(the_hash_algo, sb.buf, sb.len,
+                                        blob_type, oid);
                else if (write_object_file(sb.buf, sb.len, blob_type, oid))
                        rc = error(_("%s: failed to insert into database"), path);
                strbuf_release(&sb);
@@ -2346,8 +2535,9 @@ int read_loose_object(const char *path,
                        git_inflate_end(&stream);
                        goto out;
                }
-               if (check_object_signature(expected_oid, *contents,
-                                        *size, type_name(*type))) {
+               if (check_object_signature(the_repository, expected_oid,
+                                          *contents, *size,
+                                          type_name(*type))) {
                        error(_("hash mismatch for %s (expected %s)"), path,
                              oid_to_hex(expected_oid));
                        free(*contents);