Merge branch 'js/pull-rebase-type-shorthand'
[gitweb.git] / sha1-file.c
index 46072602fff00bc08960f08568e8bdb84255c60e..c6ca960eb2aa6b70841350d894bfda77856d980a 100644 (file)
 /* The maximum size for an object header. */
 #define MAX_HEADER_LEN 32
 
+
+#define EMPTY_TREE_SHA1_BIN_LITERAL \
+        "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
+        "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
+
+#define EMPTY_BLOB_SHA1_BIN_LITERAL \
+       "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
+       "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
+
 const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
-const struct object_id empty_tree_oid = {
+static const struct object_id empty_tree_oid = {
        EMPTY_TREE_SHA1_BIN_LITERAL
 };
-const struct object_id empty_blob_oid = {
+static const struct object_id empty_blob_oid = {
        EMPTY_BLOB_SHA1_BIN_LITERAL
 };
 
@@ -62,17 +71,17 @@ static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx)
 
 static void git_hash_unknown_init(git_hash_ctx *ctx)
 {
-       die("trying to init unknown hash");
+       BUG("trying to init unknown hash");
 }
 
 static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
 {
-       die("trying to update unknown hash");
+       BUG("trying to update unknown hash");
 }
 
 static void git_hash_unknown_final(unsigned char *hash, git_hash_ctx *ctx)
 {
-       die("trying to finalize unknown hash");
+       BUG("trying to finalize unknown hash");
 }
 
 const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
@@ -101,6 +110,18 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
        },
 };
 
+const char *empty_tree_oid_hex(void)
+{
+       static char buf[GIT_MAX_HEXSZ + 1];
+       return oid_to_hex_r(buf, the_hash_algo->empty_tree);
+}
+
+const char *empty_blob_oid_hex(void)
+{
+       static char buf[GIT_MAX_HEXSZ + 1];
+       return oid_to_hex_r(buf, the_hash_algo->empty_blob);
+}
+
 /*
  * This is meant to hold a *small* number of objects that you would
  * want read_sha1_file() to be able to return, but yet you do not want
@@ -108,7 +129,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
  * application).
  */
 static struct cached_object {
-       unsigned char sha1[20];
+       struct object_id oid;
        enum object_type type;
        void *buf;
        unsigned long size;
@@ -116,22 +137,22 @@ static struct cached_object {
 static int cached_object_nr, cached_object_alloc;
 
 static struct cached_object empty_tree = {
-       EMPTY_TREE_SHA1_BIN_LITERAL,
+       { EMPTY_TREE_SHA1_BIN_LITERAL },
        OBJ_TREE,
        "",
        0
 };
 
-static struct cached_object *find_cached_object(const unsigned char *sha1)
+static struct cached_object *find_cached_object(const struct object_id *oid)
 {
        int i;
        struct cached_object *co = cached_objects;
 
        for (i = 0; i < cached_object_nr; i++, co++) {
-               if (!hashcmp(co->sha1, sha1))
+               if (!oidcmp(&co->oid, oid))
                        return co;
        }
-       if (!hashcmp(sha1, empty_tree.sha1))
+       if (!oidcmp(oid, the_hash_algo->empty_tree))
                return &empty_tree;
        return NULL;
 }
@@ -315,7 +336,7 @@ int raceproof_create_file(const char *path, create_file_fn fn, void *cb)
 static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
 {
        int i;
-       for (i = 0; i < 20; i++) {
+       for (i = 0; i < the_hash_algo->rawsz; i++) {
                static char hex[] = "0123456789abcdef";
                unsigned int val = sha1[i];
                strbuf_addch(buf, hex[val >> 4]);
@@ -357,8 +378,8 @@ static int alt_odb_usable(struct raw_object_store *o,
 
        /* Detect cases where alternate disappeared */
        if (!is_directory(path->buf)) {
-               error("object directory %s does not exist; "
-                     "check .git/objects/info/alternates.",
+               error(_("object directory %s does not exist; "
+                       "check .git/objects/info/alternates"),
                      path->buf);
                return 0;
        }
@@ -408,7 +429,7 @@ static int link_alt_odb_entry(struct repository *r, const char *entry,
        strbuf_addstr(&pathbuf, entry);
 
        if (strbuf_normalize_path(&pathbuf) < 0 && relative_base) {
-               error("unable to normalize alternate object path: %s",
+               error(_("unable to normalize alternate object path: %s"),
                      pathbuf.buf);
                strbuf_release(&pathbuf);
                return -1;
@@ -479,14 +500,14 @@ static void link_alt_odb_entries(struct repository *r, const char *alt,
                return;
 
        if (depth > 5) {
-               error("%s: ignoring alternate object stores, nesting too deep.",
+               error(_("%s: ignoring alternate object stores, nesting too deep"),
                                relative_base);
                return;
        }
 
        strbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);
        if (strbuf_normalize_path(&objdirbuf) < 0)
-               die("unable to normalize object directory: %s",
+               die(_("unable to normalize object directory: %s"),
                    objdirbuf.buf);
 
        while (*alt) {
@@ -541,7 +562,7 @@ void add_to_alternates_file(const char *reference)
        hold_lock_file_for_update(&lock, alts, LOCK_DIE_ON_ERROR);
        out = fdopen_lock_file(&lock, "w");
        if (!out)
-               die_errno("unable to fdopen alternates lockfile");
+               die_errno(_("unable to fdopen alternates lockfile"));
 
        in = fopen(alts, "r");
        if (in) {
@@ -559,14 +580,14 @@ void add_to_alternates_file(const char *reference)
                fclose(in);
        }
        else if (errno != ENOENT)
-               die_errno("unable to read alternates file");
+               die_errno(_("unable to read alternates file"));
 
        if (found) {
                rollback_lock_file(&lock);
        } else {
                fprintf_or_die(out, "%s\n", reference);
                if (commit_lock_file(&lock))
-                       die_errno("unable to move new alternates file into place");
+                       die_errno(_("unable to move new alternates file into place"));
                if (the_repository->objects->alt_odb_tail)
                        link_alt_odb_entries(the_repository, reference,
                                             '\n', NULL, 0);
@@ -589,7 +610,7 @@ void add_to_alternates_memory(const char *reference)
 /*
  * Compute the exact path an alternate is at and returns it. In case of
  * error NULL is returned and the human readable error is added to `err`
- * `path` may be relative and should point to $GITDIR.
+ * `path` may be relative and should point to $GIT_DIR.
  * `err` must not be null.
  */
 char *compute_alternate_path(const char *path, struct strbuf *err)
@@ -710,42 +731,42 @@ int check_and_freshen_file(const char *fn, int freshen)
        return 1;
 }
 
-static int check_and_freshen_local(const unsigned char *sha1, int freshen)
+static int check_and_freshen_local(const struct object_id *oid, int freshen)
 {
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(the_repository, &buf, sha1);
+       sha1_file_name(the_repository, &buf, oid->hash);
 
        return check_and_freshen_file(buf.buf, freshen);
 }
 
-static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
+static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
 {
        struct alternate_object_database *alt;
        prepare_alt_odb(the_repository);
        for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) {
-               const char *path = alt_sha1_path(alt, sha1);
+               const char *path = alt_sha1_path(alt, oid->hash);
                if (check_and_freshen_file(path, freshen))
                        return 1;
        }
        return 0;
 }
 
-static int check_and_freshen(const unsigned char *sha1, int freshen)
+static int check_and_freshen(const struct object_id *oid, int freshen)
 {
-       return check_and_freshen_local(sha1, freshen) ||
-              check_and_freshen_nonlocal(sha1, freshen);
+       return check_and_freshen_local(oid, freshen) ||
+              check_and_freshen_nonlocal(oid, freshen);
 }
 
-int has_loose_object_nonlocal(const unsigned char *sha1)
+int has_loose_object_nonlocal(const struct object_id *oid)
 {
-       return check_and_freshen_nonlocal(sha1, 0);
+       return check_and_freshen_nonlocal(oid, 0);
 }
 
-static int has_loose_object(const unsigned char *sha1)
+static int has_loose_object(const struct object_id *oid)
 {
-       return check_and_freshen(sha1, 0);
+       return check_and_freshen(oid, 0);
 }
 
 static void mmap_limit_check(size_t length)
@@ -757,7 +778,7 @@ static void mmap_limit_check(size_t length)
                        limit = SIZE_MAX;
        }
        if (length > limit)
-               die("attempting to mmap %"PRIuMAX" over limit %"PRIuMAX,
+               die(_("attempting to mmap %"PRIuMAX" over limit %"PRIuMAX),
                    (uintmax_t)length, (uintmax_t)limit);
 }
 
@@ -782,7 +803,7 @@ void *xmmap(void *start, size_t length,
 {
        void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
        if (ret == MAP_FAILED)
-               die_errno("mmap failed");
+               die_errno(_("mmap failed"));
        return ret;
 }
 
@@ -949,7 +970,7 @@ static void *map_sha1_file_1(struct repository *r, const char *path,
                        *size = xsize_t(st.st_size);
                        if (!*size) {
                                /* mmap() is forbidden on empty files */
-                               error("object file %s is empty", path);
+                               error(_("object file %s is empty"), path);
                                return NULL;
                        }
                        map = xmmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
@@ -1069,9 +1090,9 @@ static void *unpack_sha1_rest(git_zstream *stream, void *buffer, unsigned long s
        }
 
        if (status < 0)
-               error("corrupt loose object '%s'", sha1_to_hex(sha1));
+               error(_("corrupt loose object '%s'"), sha1_to_hex(sha1));
        else if (stream->avail_in)
-               error("garbage at end of loose object '%s'",
+               error(_("garbage at end of loose object '%s'"),
                      sha1_to_hex(sha1));
        free(buf);
        return NULL;
@@ -1113,7 +1134,7 @@ static int parse_sha1_header_extended(const char *hdr, struct object_info *oi,
        if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE) && (type < 0))
                type = 0;
        else if (type < 0)
-               die("invalid object type");
+               die(_("invalid object type"));
        if (oi->typep)
                *oi->typep = type;
 
@@ -1195,19 +1216,19 @@ static int sha1_loose_object_info(struct repository *r,
                *oi->disk_sizep = mapsize;
        if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE)) {
                if (unpack_sha1_header_to_strbuf(&stream, map, mapsize, hdr, sizeof(hdr), &hdrbuf) < 0)
-                       status = error("unable to unpack %s header with --allow-unknown-type",
+                       status = error(_("unable to unpack %s header with --allow-unknown-type"),
                                       sha1_to_hex(sha1));
        } else if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
-               status = error("unable to unpack %s header",
+               status = error(_("unable to unpack %s header"),
                               sha1_to_hex(sha1));
        if (status < 0)
                ; /* Do nothing */
        else if (hdrbuf.len) {
                if ((status = parse_sha1_header_extended(hdrbuf.buf, oi, flags)) < 0)
-                       status = error("unable to parse %s header with --allow-unknown-type",
+                       status = error(_("unable to parse %s header with --allow-unknown-type"),
                                       sha1_to_hex(sha1));
        } else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0)
-               status = error("unable to parse %s header", sha1_to_hex(sha1));
+               status = error(_("unable to parse %s header"), sha1_to_hex(sha1));
 
        if (status >= 0 && oi->contentp) {
                *oi->contentp = unpack_sha1_rest(&stream, hdr,
@@ -1231,7 +1252,8 @@ static int sha1_loose_object_info(struct repository *r,
 
 int fetch_if_missing = 1;
 
-int oid_object_info_extended(const struct object_id *oid, struct object_info *oi, unsigned flags)
+int 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 pack_entry e;
@@ -1240,7 +1262,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
        int already_retried = 0;
 
        if (flags & OBJECT_INFO_LOOKUP_REPLACE)
-               real = lookup_replace_object(the_repository, oid);
+               real = lookup_replace_object(r, oid);
 
        if (is_null_oid(real))
                return -1;
@@ -1249,7 +1271,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
                oi = &blank_oi;
 
        if (!(flags & OBJECT_INFO_SKIP_CACHED)) {
-               struct cached_object *co = find_cached_object(real->hash);
+               struct cached_object *co = find_cached_object(real);
                if (co) {
                        if (oi->typep)
                                *(oi->typep) = co->type;
@@ -1269,29 +1291,31 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
        }
 
        while (1) {
-               if (find_pack_entry(the_repository, real->hash, &e))
+               if (find_pack_entry(r, real, &e))
                        break;
 
                if (flags & OBJECT_INFO_IGNORE_LOOSE)
                        return -1;
 
                /* Most likely it's a loose object. */
-               if (!sha1_loose_object_info(the_repository, real->hash, oi, flags))
+               if (!sha1_loose_object_info(r, real->hash, oi, flags))
                        return 0;
 
                /* Not a loose object; someone else may have just packed it. */
                if (!(flags & OBJECT_INFO_QUICK)) {
-                       reprepare_packed_git(the_repository);
-                       if (find_pack_entry(the_repository, real->hash, &e))
+                       reprepare_packed_git(r);
+                       if (find_pack_entry(r, real, &e))
                                break;
                }
 
                /* Check if it is a missing object */
                if (fetch_if_missing && repository_format_partial_clone &&
-                   !already_retried) {
+                   !already_retried && r == the_repository) {
                        /*
-                        * TODO Investigate haveing fetch_object() return
+                        * 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.
                         */
                        fetch_object(repository_format_partial_clone, real->hash);
                        already_retried = 1;
@@ -1307,10 +1331,10 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
                 * information below, so return early.
                 */
                return 0;
-       rtype = packed_object_info(e.p, e.offset, oi);
+       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(real, oi, 0);
+               return 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;
@@ -1322,15 +1346,17 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
 }
 
 /* returns enum object_type or negative */
-int oid_object_info(const struct object_id *oid, unsigned long *sizep)
+int oid_object_info(struct repository *r,
+                   const struct object_id *oid,
+                   unsigned long *sizep)
 {
        enum object_type type;
        struct object_info oi = OBJECT_INFO_INIT;
 
        oi.typep = &type;
        oi.sizep = sizep;
-       if (oid_object_info_extended(oid, &oi,
-                                    OBJECT_INFO_LOOKUP_REPLACE) < 0)
+       if (oid_object_info_extended(r, oid, &oi,
+                                     OBJECT_INFO_LOOKUP_REPLACE) < 0)
                return -1;
        return type;
 }
@@ -1347,7 +1373,7 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,
 
        hashcpy(oid.hash, sha1);
 
-       if (oid_object_info_extended(&oid, &oi, 0) < 0)
+       if (oid_object_info_extended(the_repository, &oid, &oi, 0) < 0)
                return NULL;
        return content;
 }
@@ -1358,7 +1384,7 @@ 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_sha1_file(oid->hash) || find_cached_object(oid->hash))
+       if (has_sha1_file(oid->hash) || find_cached_object(oid))
                return 0;
        ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
        co = &cached_objects[cached_object_nr++];
@@ -1366,7 +1392,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
        co->type = type;
        co->buf = xmalloc(len);
        memcpy(co->buf, buf, len);
-       hashcpy(co->sha1, oid->hash);
+       oidcpy(&co->oid, oid);
        return 0;
 }
 
@@ -1393,19 +1419,19 @@ void *read_object_file_extended(const struct object_id *oid,
                return data;
 
        if (errno && errno != ENOENT)
-               die_errno("failed to read object %s", oid_to_hex(oid));
+               die_errno(_("failed to read object %s"), oid_to_hex(oid));
 
        /* die if we replaced an object with one that does not exist */
        if (repl != oid)
-               die("replacement %s not found for %s",
+               die(_("replacement %s not found for %s"),
                    oid_to_hex(repl), oid_to_hex(oid));
 
        if (!stat_sha1_file(the_repository, repl->hash, &st, &path))
-               die("loose object %s (stored in %s) is corrupt",
+               die(_("loose object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), path);
 
        if ((p = has_packed_and_bad(repl->hash)) != NULL)
-               die("packed object %s (stored in %s) is corrupt",
+               die(_("packed object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), p->pack_name);
 
        return NULL;
@@ -1447,7 +1473,7 @@ void *read_object_with_reference(const struct object_id *oid,
                }
                ref_length = strlen(ref_type);
 
-               if (ref_length + GIT_SHA1_HEXSZ > isize ||
+               if (ref_length + the_hash_algo->hexsz > isize ||
                    memcmp(buffer, ref_type, ref_length) ||
                    get_oid_hex((char *) buffer + ref_length, &actual_oid)) {
                        free(buffer);
@@ -1507,21 +1533,21 @@ int finalize_object_file(const char *tmpfile, const char *filename)
        unlink_or_warn(tmpfile);
        if (ret) {
                if (ret != EEXIST) {
-                       return error_errno("unable to write sha1 filename %s", filename);
+                       return error_errno(_("unable to write sha1 filename %s"), filename);
                }
                /* FIXME!!! Collision check here ? */
        }
 
 out:
        if (adjust_shared_perm(filename))
-               return error("unable to set permission to '%s'", filename);
+               return error(_("unable to set permission to '%s'"), filename);
        return 0;
 }
 
 static int write_buffer(int fd, const void *buf, size_t len)
 {
        if (write_in_full(fd, buf, len) < 0)
-               return error_errno("file write error");
+               return error_errno(_("file write error"));
        return 0;
 }
 
@@ -1540,7 +1566,7 @@ static void close_sha1_file(int fd)
        if (fsync_object_files)
                fsync_or_die(fd, "sha1 file");
        if (close(fd) != 0)
-               die_errno("error when closing sha1 file");
+               die_errno(_("error when closing sha1 file"));
 }
 
 /* Size of directory component, including the ending '/' */
@@ -1606,9 +1632,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
        fd = create_tmpfile(&tmp_file, filename.buf);
        if (fd < 0) {
                if (errno == EACCES)
-                       return error("insufficient permission for adding an object to repository database %s", get_object_directory());
+                       return error(_("insufficient permission for adding an object to repository database %s"), get_object_directory());
                else
-                       return error_errno("unable to create temporary file");
+                       return error_errno(_("unable to create temporary file"));
        }
 
        /* Set it up */
@@ -1632,21 +1658,21 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
                ret = git_deflate(&stream, Z_FINISH);
                the_hash_algo->update_fn(&c, in0, stream.next_in - in0);
                if (write_buffer(fd, compressed, stream.next_out - compressed) < 0)
-                       die("unable to write sha1 file");
+                       die(_("unable to write sha1 file"));
                stream.next_out = compressed;
                stream.avail_out = sizeof(compressed);
        } while (ret == Z_OK);
 
        if (ret != Z_STREAM_END)
-               die("unable to deflate new object %s (%d)", oid_to_hex(oid),
+               die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid),
                    ret);
        ret = git_deflate_end_gently(&stream);
        if (ret != Z_OK)
-               die("deflateEnd on object %s failed (%d)", oid_to_hex(oid),
+               die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid),
                    ret);
        the_hash_algo->final_fn(parano_oid.hash, &c);
        if (oidcmp(oid, &parano_oid) != 0)
-               die("confused by unstable object source data for %s",
+               die(_("confused by unstable object source data for %s"),
                    oid_to_hex(oid));
 
        close_sha1_file(fd);
@@ -1656,21 +1682,21 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
                utb.actime = mtime;
                utb.modtime = mtime;
                if (utime(tmp_file.buf, &utb) < 0)
-                       warning_errno("failed utime() on %s", tmp_file.buf);
+                       warning_errno(_("failed utime() on %s"), tmp_file.buf);
        }
 
        return finalize_object_file(tmp_file.buf, filename.buf);
 }
 
-static int freshen_loose_object(const unsigned char *sha1)
+static int freshen_loose_object(const struct object_id *oid)
 {
-       return check_and_freshen(sha1, 1);
+       return check_and_freshen(oid, 1);
 }
 
-static int freshen_packed_object(const unsigned char *sha1)
+static int freshen_packed_object(const struct object_id *oid)
 {
        struct pack_entry e;
-       if (!find_pack_entry(the_repository, sha1, &e))
+       if (!find_pack_entry(the_repository, oid, &e))
                return 0;
        if (e.p->freshened)
                return 1;
@@ -1690,7 +1716,7 @@ int write_object_file(const void *buf, unsigned long len, const char *type,
         * it out into .git/objects/??/?{38} file.
         */
        write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
-       if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash))
+       if (freshen_packed_object(oid) || freshen_loose_object(oid))
                return 0;
        return write_loose_object(oid, hdr, hdrlen, buf, len, 0);
 }
@@ -1709,7 +1735,7 @@ int hash_object_file_literally(const void *buf, unsigned long len,
 
        if (!(flags & HASH_WRITE_OBJECT))
                goto cleanup;
-       if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash))
+       if (freshen_packed_object(oid) || freshen_loose_object(oid))
                goto cleanup;
        status = write_loose_object(oid, header, hdrlen, buf, len, 0);
 
@@ -1727,11 +1753,11 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        int hdrlen;
        int ret;
 
-       if (has_loose_object(oid->hash))
+       if (has_loose_object(oid))
                return 0;
        buf = read_object(oid->hash, &type, &len);
        if (!buf)
-               return error("cannot read sha1_file for %s", oid_to_hex(oid));
+               return error(_("cannot read sha1_file for %s"), oid_to_hex(oid));
        hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
        ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime);
        free(buf);
@@ -1745,7 +1771,7 @@ int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
        if (!startup_info->have_repository)
                return 0;
        hashcpy(oid.hash, sha1);
-       return oid_object_info_extended(&oid, NULL,
+       return oid_object_info_extended(the_repository, &oid, NULL,
                                        flags | OBJECT_INFO_SKIP_CACHED) >= 0;
 }
 
@@ -1775,16 +1801,16 @@ static void check_commit(const void *buf, size_t size)
 {
        struct commit c;
        memset(&c, 0, sizeof(c));
-       if (parse_commit_buffer(&c, buf, size))
-               die("corrupt commit");
+       if (parse_commit_buffer(the_repository, &c, buf, size, 0))
+               die(_("corrupt commit"));
 }
 
 static void check_tag(const void *buf, size_t size)
 {
        struct tag t;
        memset(&t, 0, sizeof(t));
-       if (parse_tag_buffer(&t, buf, size))
-               die("corrupt tag");
+       if (parse_tag_buffer(the_repository, &t, buf, size))
+               die(_("corrupt tag"));
 }
 
 static int index_mem(struct object_id *oid, void *buf, size_t size,
@@ -1877,10 +1903,10 @@ static int index_core(struct object_id *oid, int fd, size_t size,
                char *buf = xmalloc(size);
                ssize_t read_result = read_in_full(fd, buf, size);
                if (read_result < 0)
-                       ret = error_errno("read error while indexing %s",
+                       ret = error_errno(_("read error while indexing %s"),
                                          path ? path : "<unknown>");
                else if (read_result != size)
-                       ret = error("short read while indexing %s",
+                       ret = error(_("short read while indexing %s"),
                                    path ? path : "<unknown>");
                else
                        ret = index_mem(oid, buf, size, type, path, flags);
@@ -1951,7 +1977,7 @@ int index_path(struct object_id *oid, const char *path, struct stat *st, unsigne
                if (fd < 0)
                        return error_errno("open(\"%s\")", path);
                if (index_fd(oid, fd, st, OBJ_BLOB, path, flags) < 0)
-                       return error("%s: failed to insert into database",
+                       return error(_("%s: failed to insert into database"),
                                     path);
                break;
        case S_IFLNK:
@@ -1960,13 +1986,13 @@ int index_path(struct object_id *oid, const char *path, struct stat *st, unsigne
                if (!(flags & HASH_WRITE_OBJECT))
                        hash_object_file(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);
+                       rc = error(_("%s: failed to insert into database"), path);
                strbuf_release(&sb);
                break;
        case S_IFDIR:
                return resolve_gitlink_ref(path, "HEAD", oid);
        default:
-               return error("%s: unsupported file type", path);
+               return error(_("%s: unsupported file type"), path);
        }
        return rc;
 }
@@ -1988,11 +2014,11 @@ int read_pack_header(int fd, struct pack_header *header)
 
 void assert_oid_type(const struct object_id *oid, enum object_type expect)
 {
-       enum object_type type = oid_object_info(oid, NULL);
+       enum object_type type = oid_object_info(the_repository, oid, NULL);
        if (type < 0)
-               die("%s is not a valid object", oid_to_hex(oid));
+               die(_("%s is not a valid object"), oid_to_hex(oid));
        if (type != expect)
-               die("%s is not a valid '%s' object", oid_to_hex(oid),
+               die(_("%s is not a valid '%s' object"), oid_to_hex(oid),
                    type_name(expect));
 }
 
@@ -2019,7 +2045,7 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
        dir = opendir(path->buf);
        if (!dir) {
                if (errno != ENOENT)
-                       r = error_errno("unable to open %s", path->buf);
+                       r = error_errno(_("unable to open %s"), path->buf);
                strbuf_setlen(path, origlen);
                return r;
        }
@@ -2036,9 +2062,9 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
                namelen = strlen(de->d_name);
                strbuf_setlen(path, baselen);
                strbuf_add(path, de->d_name, namelen);
-               if (namelen == GIT_SHA1_HEXSZ - 2 &&
+               if (namelen == the_hash_algo->hexsz - 2 &&
                    !hex_to_bytes(oid.hash + 1, de->d_name,
-                                 GIT_SHA1_RAWSZ - 1)) {
+                                 the_hash_algo->rawsz - 1)) {
                        if (obj_cb) {
                                r = obj_cb(&oid, path->buf, data);
                                if (r)
@@ -2176,18 +2202,18 @@ static int check_stream_sha1(git_zstream *stream,
        git_inflate_end(stream);
 
        if (status != Z_STREAM_END) {
-               error("corrupt loose object '%s'", sha1_to_hex(expected_sha1));
+               error(_("corrupt loose object '%s'"), sha1_to_hex(expected_sha1));
                return -1;
        }
        if (stream->avail_in) {
-               error("garbage at end of loose object '%s'",
+               error(_("garbage at end of loose object '%s'"),
                      sha1_to_hex(expected_sha1));
                return -1;
        }
 
        the_hash_algo->final_fn(real_sha1, &c);
        if (hashcmp(expected_sha1, real_sha1)) {
-               error("sha1 mismatch for %s (expected %s)", path,
+               error(_("sha1 mismatch for %s (expected %s)"), path,
                      sha1_to_hex(expected_sha1));
                return -1;
        }
@@ -2211,35 +2237,35 @@ int read_loose_object(const char *path,
 
        map = map_sha1_file_1(the_repository, path, NULL, &mapsize);
        if (!map) {
-               error_errno("unable to mmap %s", path);
+               error_errno(_("unable to mmap %s"), path);
                goto out;
        }
 
        if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) {
-               error("unable to unpack header of %s", path);
+               error(_("unable to unpack header of %s"), path);
                goto out;
        }
 
        *type = parse_sha1_header(hdr, size);
        if (*type < 0) {
-               error("unable to parse header of %s", path);
+               error(_("unable to parse header of %s"), path);
                git_inflate_end(&stream);
                goto out;
        }
 
-       if (*type == OBJ_BLOB) {
+       if (*type == OBJ_BLOB && *size > big_file_threshold) {
                if (check_stream_sha1(&stream, hdr, *size, path, expected_oid->hash) < 0)
                        goto out;
        } else {
                *contents = unpack_sha1_rest(&stream, hdr, *size, expected_oid->hash);
                if (!*contents) {
-                       error("unable to unpack contents of %s", path);
+                       error(_("unable to unpack contents of %s"), path);
                        git_inflate_end(&stream);
                        goto out;
                }
                if (check_object_signature(expected_oid, *contents,
                                         *size, type_name(*type))) {
-                       error("sha1 mismatch for %s (expected %s)", path,
+                       error(_("sha1 mismatch for %s (expected %s)"), path,
                              oid_to_hex(expected_oid));
                        free(*contents);
                        goto out;