]> git.ipfire.org Git - thirdparty/git.git/blobdiff - read-cache.c
treewide: be explicit about dependence on trace.h & trace2.h
[thirdparty/git.git] / read-cache.c
index cbe73f14e5e7efc63b20e80a2702fb5c0dea9a5d..a744eb89e4e638df8a3e44891576672a1ccd7c4f 100644 (file)
@@ -4,9 +4,11 @@
  * Copyright (C) Linus Torvalds, 2005
  */
 #include "cache.h"
+#include "alloc.h"
 #include "config.h"
 #include "diff.h"
 #include "diffcore.h"
+#include "hex.h"
 #include "tempfile.h"
 #include "lockfile.h"
 #include "cache-tree.h"
 #include "tree.h"
 #include "commit.h"
 #include "blob.h"
+#include "environment.h"
+#include "gettext.h"
 #include "resolve-undo.h"
 #include "run-command.h"
 #include "strbuf.h"
+#include "trace2.h"
 #include "varint.h"
 #include "split-index.h"
 #include "utf8.h"
@@ -28,6 +33,8 @@
 #include "sparse-index.h"
 #include "csum-file.h"
 #include "promisor-remote.h"
+#include "hook.h"
+#include "wrapper.h"
 
 /* Mask for the name length in ce_flags in the on-disk index */
 
@@ -111,7 +118,7 @@ static const char *alternate_index_output;
 static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
 {
        if (S_ISSPARSEDIR(ce->ce_mode))
-               istate->sparse_index = 1;
+               istate->sparse_index = INDEX_COLLAPSED;
 
        istate->cache[nr] = ce;
        add_name_hash(istate, ce);
@@ -133,7 +140,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
 
 void rename_index_entry_at(struct index_state *istate, int nr, const char *new_name)
 {
-       struct cache_entry *old_entry = istate->cache[nr], *new_entry;
+       struct cache_entry *old_entry = istate->cache[nr], *new_entry, *refreshed;
        int namelen = strlen(new_name);
 
        new_entry = make_empty_cache_entry(istate, namelen);
@@ -146,7 +153,20 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
        cache_tree_invalidate_path(istate, old_entry->name);
        untracked_cache_remove_from_index(istate, old_entry->name);
        remove_index_entry_at(istate, nr);
-       add_index_entry(istate, new_entry, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
+
+       /*
+        * Refresh the new index entry. Using 'refresh_cache_entry' ensures
+        * we only update stat info if the entry is otherwise up-to-date (i.e.,
+        * the contents/mode haven't changed). This ensures that we reflect the
+        * 'ctime' of the rename in the index without (incorrectly) updating
+        * the cached stat info to reflect unstaged changes on disk.
+        */
+       refreshed = refresh_cache_entry(istate, new_entry, CE_MATCH_REFRESH);
+       if (refreshed && refreshed != new_entry) {
+               add_index_entry(istate, refreshed, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
+               discard_cache_entry(new_entry);
+       } else
+               add_index_entry(istate, new_entry, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
 }
 
 void fill_stat_data(struct stat_data *sd, struct stat *st)
@@ -249,7 +269,7 @@ static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
        if (strbuf_readlink(&sb, ce->name, expected_size))
                return -1;
 
-       buffer = read_object_file(&ce->oid, &type, &size);
+       buffer = repo_read_object_file(the_repository, &ce->oid, &type, &size);
        if (buffer) {
                if (size == sb.len)
                        match = memcmp(buffer, sb.buf, size);
@@ -474,11 +494,11 @@ int ie_modified(struct index_state *istate,
        return 0;
 }
 
-int base_name_compare(const char *name1, int len1, int mode1,
-                     const char *name2, int len2, int mode2)
+int base_name_compare(const char *name1, size_t len1, int mode1,
+                     const char *name2, size_t len2, int mode2)
 {
        unsigned char c1, c2;
-       int len = len1 < len2 ? len1 : len2;
+       size_t len = len1 < len2 ? len1 : len2;
        int cmp;
 
        cmp = memcmp(name1, name2, len);
@@ -503,11 +523,12 @@ int base_name_compare(const char *name1, int len1, int mode1,
  * This is used by routines that want to traverse the git namespace
  * but then handle conflicting entries together when possible.
  */
-int df_name_compare(const char *name1, int len1, int mode1,
-                   const char *name2, int len2, int mode2)
+int df_name_compare(const char *name1, size_t len1, int mode1,
+                   const char *name2, size_t len2, int mode2)
 {
-       int len = len1 < len2 ? len1 : len2, cmp;
        unsigned char c1, c2;
+       size_t len = len1 < len2 ? len1 : len2;
+       int cmp;
 
        cmp = memcmp(name1, name2, len);
        if (cmp)
@@ -606,6 +627,11 @@ int index_name_pos(struct index_state *istate, const char *name, int namelen)
        return index_name_stage_pos(istate, name, namelen, 0, EXPAND_SPARSE);
 }
 
+int index_name_pos_sparse(struct index_state *istate, const char *name, int namelen)
+{
+       return index_name_stage_pos(istate, name, namelen, 0, NO_EXPAND_SPARSE);
+}
+
 int index_entry_exists(struct index_state *istate, const char *name, int namelen)
 {
        return index_name_stage_pos(istate, name, namelen, 0, NO_EXPAND_SPARSE) >= 0;
@@ -735,7 +761,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate,
 void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 {
        struct object_id oid;
-       if (write_object_file("", 0, blob_type, &oid))
+       if (write_object_file("", 0, OBJ_BLOB, &oid))
                die(_("cannot create an empty blob in the object database"));
        oidcpy(&ce->oid, &oid);
 }
@@ -1339,9 +1365,6 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
        int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
        int new_only = option & ADD_CACHE_NEW_ONLY;
 
-       if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
-               cache_tree_invalidate_path(istate, ce->name);
-
        /*
         * If this entry's path sorts after the last entry in the index,
         * we can avoid searching for it.
@@ -1352,6 +1375,13 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
        else
                pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce), EXPAND_SPARSE);
 
+       /*
+        * Cache tree path should be invalidated only after index_name_stage_pos,
+        * in case it expands a sparse index.
+        */
+       if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
+               cache_tree_invalidate_path(istate, ce->name);
+
        /* existing match? Just replace it. */
        if (pos >= 0) {
                if (!new_only)
@@ -1794,6 +1824,8 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)
        git_hash_ctx c;
        unsigned char hash[GIT_MAX_RAWSZ];
        int hdr_version;
+       unsigned char *start, *end;
+       struct object_id oid;
 
        if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
                return error(_("bad signature 0x%08x"), hdr->hdr_signature);
@@ -1804,10 +1836,16 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)
        if (!verify_index_checksum)
                return 0;
 
+       end = (unsigned char *)hdr + size;
+       start = end - the_hash_algo->rawsz;
+       oidread(&oid, start);
+       if (oideq(&oid, null_oid()))
+               return 0;
+
        the_hash_algo->init_fn(&c);
        the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);
        the_hash_algo->final_fn(hash, &c);
-       if (!hasheq(hash, (unsigned char *)hdr + size - the_hash_algo->rawsz))
+       if (!hasheq(hash, start))
                return error(_("bad index file sha1 signature"));
        return 0;
 }
@@ -1838,7 +1876,7 @@ static int read_index_extension(struct index_state *istate,
                break;
        case CACHE_EXT_SPARSE_DIRECTORIES:
                /* no content, only an indicator */
-               istate->sparse_index = 1;
+               istate->sparse_index = INDEX_COLLAPSED;
                break;
        default:
                if (*ext < 'A' || 'Z' < *ext)
@@ -1850,9 +1888,20 @@ static int read_index_extension(struct index_state *istate,
        return 0;
 }
 
+/*
+ * Parses the contents of the cache entry contained within the 'ondisk' buffer
+ * into a new incore 'cache_entry'.
+ *
+ * Note that 'char *ondisk' may not be aligned to a 4-byte address interval in
+ * index v4, so we cannot cast it to 'struct ondisk_cache_entry *' and access
+ * its members. Instead, we use the byte offsets of members within the struct to
+ * identify where 'get_be16()', 'get_be32()', and 'oidread()' (which can all
+ * read from an unaligned memory buffer) should read from the 'ondisk' buffer
+ * into the corresponding incore 'cache_entry' members.
+ */
 static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
                                            unsigned int version,
-                                           struct ondisk_cache_entry *ondisk,
+                                           const char *ondisk,
                                            unsigned long *ent_size,
                                            const struct cache_entry *previous_ce)
 {
@@ -1860,7 +1909,7 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
        size_t len;
        const char *name;
        const unsigned hashsz = the_hash_algo->rawsz;
-       const uint16_t *flagsp = (const uint16_t *)(ondisk->data + hashsz);
+       const char *flagsp = ondisk + offsetof(struct ondisk_cache_entry, data) + hashsz;
        unsigned int flags;
        size_t copy_len = 0;
        /*
@@ -1878,15 +1927,15 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
 
        if (flags & CE_EXTENDED) {
                int extended_flags;
-               extended_flags = get_be16(flagsp + 1) << 16;
+               extended_flags = get_be16(flagsp + sizeof(uint16_t)) << 16;
                /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
                if (extended_flags & ~CE_EXTENDED_FLAGS)
                        die(_("unknown index entry format 0x%08x"), extended_flags);
                flags |= extended_flags;
-               name = (const char *)(flagsp + 2);
+               name = (const char *)(flagsp + 2 * sizeof(uint16_t));
        }
        else
-               name = (const char *)(flagsp + 1);
+               name = (const char *)(flagsp + sizeof(uint16_t));
 
        if (expand_name_field) {
                const unsigned char *cp = (const unsigned char *)name;
@@ -1912,22 +1961,32 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
 
        ce = mem_pool__ce_alloc(ce_mem_pool, len);
 
-       ce->ce_stat_data.sd_ctime.sec = get_be32(&ondisk->ctime.sec);
-       ce->ce_stat_data.sd_mtime.sec = get_be32(&ondisk->mtime.sec);
-       ce->ce_stat_data.sd_ctime.nsec = get_be32(&ondisk->ctime.nsec);
-       ce->ce_stat_data.sd_mtime.nsec = get_be32(&ondisk->mtime.nsec);
-       ce->ce_stat_data.sd_dev   = get_be32(&ondisk->dev);
-       ce->ce_stat_data.sd_ino   = get_be32(&ondisk->ino);
-       ce->ce_mode  = get_be32(&ondisk->mode);
-       ce->ce_stat_data.sd_uid   = get_be32(&ondisk->uid);
-       ce->ce_stat_data.sd_gid   = get_be32(&ondisk->gid);
-       ce->ce_stat_data.sd_size  = get_be32(&ondisk->size);
+       /*
+        * NEEDSWORK: using 'offsetof()' is cumbersome and should be replaced
+        * with something more akin to 'load_bitmap_entries_v1()'s use of
+        * 'read_be16'/'read_be32'. For consistency with the corresponding
+        * ondisk entry write function ('copy_cache_entry_to_ondisk()'), this
+        * should be done at the same time as removing references to
+        * 'ondisk_cache_entry' there.
+        */
+       ce->ce_stat_data.sd_ctime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
+                                                       + offsetof(struct cache_time, sec));
+       ce->ce_stat_data.sd_mtime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
+                                                       + offsetof(struct cache_time, sec));
+       ce->ce_stat_data.sd_ctime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
+                                                        + offsetof(struct cache_time, nsec));
+       ce->ce_stat_data.sd_mtime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
+                                                        + offsetof(struct cache_time, nsec));
+       ce->ce_stat_data.sd_dev   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, dev));
+       ce->ce_stat_data.sd_ino   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ino));
+       ce->ce_mode  = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mode));
+       ce->ce_stat_data.sd_uid   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, uid));
+       ce->ce_stat_data.sd_gid   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, gid));
+       ce->ce_stat_data.sd_size  = get_be32(ondisk + offsetof(struct ondisk_cache_entry, size));
        ce->ce_flags = flags & ~CE_NAMEMASK;
        ce->ce_namelen = len;
        ce->index = 0;
-       oidread(&ce->oid, ondisk->data);
-       memcpy(ce->name, name, len);
-       ce->name[len] = '\0';
+       oidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data));
 
        if (expand_name_field) {
                if (copy_len)
@@ -2096,12 +2155,12 @@ static unsigned long load_cache_entry_block(struct index_state *istate,
        unsigned long src_offset = start_offset;
 
        for (i = offset; i < offset + nr; i++) {
-               struct ondisk_cache_entry *disk_ce;
                struct cache_entry *ce;
                unsigned long consumed;
 
-               disk_ce = (struct ondisk_cache_entry *)(mmap + src_offset);
-               ce = create_from_disk(ce_mem_pool, istate->version, disk_ce, &consumed, previous_ce);
+               ce = create_from_disk(ce_mem_pool, istate->version,
+                                     mmap + src_offset,
+                                     &consumed, previous_ce);
                set_index_entry(istate, i, ce);
 
                src_offset += consumed;
@@ -2242,6 +2301,18 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con
        return consumed;
 }
 
+static void set_new_index_sparsity(struct index_state *istate)
+{
+       /*
+        * If the index's repo exists, mark it sparse according to
+        * repo settings.
+        */
+       prepare_repo_settings(istate->repo);
+       if (!istate->repo->settings.command_requires_full_index &&
+           is_sparse_index_allowed(istate, 0))
+               istate->sparse_index = 1;
+}
+
 /* remember to discard_cache() before reading a different cache! */
 int do_read_index(struct index_state *istate, const char *path, int must_exist)
 {
@@ -2263,8 +2334,10 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        istate->timestamp.nsec = 0;
        fd = open(path, O_RDONLY);
        if (fd < 0) {
-               if (!must_exist && errno == ENOENT)
+               if (!must_exist && errno == ENOENT) {
+                       set_new_index_sparsity(istate);
                        return 0;
+               }
                die_errno(_("%s: index file open failed"), path);
        }
 
@@ -2363,9 +2436,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        trace2_data_intmax("index", the_repository, "read/cache_nr",
                           istate->cache_nr);
 
-       if (!istate->repo)
-               istate->repo = the_repository;
-
        /*
         * If the command explicitly requires a full index, force it
         * to be full. Otherwise, correct the sparsity based on repository
@@ -2428,9 +2498,10 @@ int read_index_from(struct index_state *istate, const char *path,
 
        trace_performance_enter();
        if (split_index->base)
-               discard_index(split_index->base);
+               release_index(split_index->base);
        else
-               CALLOC_ARRAY(split_index->base, 1);
+               ALLOC_ARRAY(split_index->base, 1);
+       index_state_init(split_index->base, istate->repo);
 
        base_oid_hex = oid_to_hex(&split_index->base_oid);
        base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex);
@@ -2441,15 +2512,15 @@ int read_index_from(struct index_state *istate, const char *path,
                                   the_repository, "%s", base_path);
        if (!ret) {
                char *path_copy = xstrdup(path);
-               const char *base_path2 = xstrfmt("%s/sharedindex.%s",
-                                                dirname(path_copy),
-                                                base_oid_hex);
+               char *base_path2 = xstrfmt("%s/sharedindex.%s",
+                                          dirname(path_copy), base_oid_hex);
                free(path_copy);
                trace2_region_enter_printf("index", "shared/do_read_index",
                                           the_repository, "%s", base_path2);
                ret = do_read_index(split_index->base, base_path2, 1);
                trace2_region_leave_printf("index", "shared/do_read_index",
                                           the_repository, "%s", base_path2);
+               free(base_path2);
        }
        if (!oideq(&split_index->base_oid, &split_index->base->oid))
                die(_("broken index, expect %s in %s, got %s"),
@@ -2469,7 +2540,13 @@ int is_index_unborn(struct index_state *istate)
        return (!istate->cache_nr && !istate->timestamp.sec);
 }
 
-int discard_index(struct index_state *istate)
+void index_state_init(struct index_state *istate, struct repository *r)
+{
+       struct index_state blank = INDEX_STATE_INIT(r);
+       memcpy(istate, &blank, sizeof(*istate));
+}
+
+void release_index(struct index_state *istate)
 {
        /*
         * Cache entries in istate->cache[] should have been allocated
@@ -2481,27 +2558,28 @@ int discard_index(struct index_state *istate)
        validate_cache_entries(istate);
 
        resolve_undo_clear_index(istate);
-       istate->cache_nr = 0;
-       istate->cache_changed = 0;
-       istate->timestamp.sec = 0;
-       istate->timestamp.nsec = 0;
        free_name_hash(istate);
        cache_tree_free(&(istate->cache_tree));
-       istate->initialized = 0;
-       istate->fsmonitor_has_run_once = 0;
-       FREE_AND_NULL(istate->fsmonitor_last_update);
-       FREE_AND_NULL(istate->cache);
-       istate->cache_alloc = 0;
+       free(istate->fsmonitor_last_update);
+       free(istate->cache);
        discard_split_index(istate);
        free_untracked_cache(istate->untracked);
-       istate->untracked = NULL;
+
+       if (istate->sparse_checkout_patterns) {
+               clear_pattern_list(istate->sparse_checkout_patterns);
+               FREE_AND_NULL(istate->sparse_checkout_patterns);
+       }
 
        if (istate->ce_mem_pool) {
                mem_pool_discard(istate->ce_mem_pool, should_validate_cache_entries());
                FREE_AND_NULL(istate->ce_mem_pool);
        }
+}
 
-       return 0;
+void discard_index(struct index_state *istate)
+{
+       release_index(istate);
+       index_state_init(istate, istate->repo);
 }
 
 /*
@@ -2556,7 +2634,7 @@ int repo_index_has_changes(struct repository *repo,
 
        if (tree)
                cmp = tree->object.oid;
-       if (tree || !get_oid_tree("HEAD", &cmp)) {
+       if (tree || !repo_get_oid_tree(repo, "HEAD", &cmp)) {
                struct diff_options opt;
 
                repo_diff_setup(repo, &opt);
@@ -2775,7 +2853,7 @@ static int repo_verify_index(struct repository *repo)
        return verify_index_from(repo->index, repo->index_file);
 }
 
-static int has_racy_timestamp(struct index_state *istate)
+int has_racy_timestamp(struct index_state *istate)
 {
        int entries = istate->cache_nr;
        int i;
@@ -2837,7 +2915,7 @@ static int record_ieot(void)
  * rely on it.
  */
 static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
-                         int strip_extensions)
+                         int strip_extensions, unsigned flags)
 {
        uint64_t start = getnanotime();
        struct hashfile *f;
@@ -2851,12 +2929,17 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
        struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
        int drop_cache_tree = istate->drop_cache_tree;
        off_t offset;
+       int csum_fsync_flag;
        int ieot_entries = 1;
        struct index_entry_offset_table *ieot = NULL;
        int nr, nr_threads;
+       struct repository *r = istate->repo;
 
        f = hashfd(tempfile->fd, tempfile->filename.buf);
 
+       prepare_repo_settings(r);
+       f->skip_hash = r->settings.index_skip_hash;
+
        for (i = removed = extended = 0; i < entries; i++) {
                if (cache[i]->ce_flags & CE_REMOVE)
                        removed++;
@@ -2870,7 +2953,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
        }
 
        if (!istate->version)
-               istate->version = get_index_format_default(the_repository);
+               istate->version = get_index_format_default(r);
 
        /* demote version 3 to version 2 when the latter suffices */
        if (istate->version == 3 || istate->version == 2)
@@ -3009,6 +3092,9 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
            !is_null_oid(&istate->split_index->base_oid)) {
                struct strbuf sb = STRBUF_INIT;
 
+               if (istate->sparse_index)
+                       die(_("cannot write split index for a sparse index"));
+
                err = write_link_extension(&sb, istate) < 0 ||
                        write_index_ext_header(f, eoie_c, CACHE_EXT_LINK,
                                               sb.len) < 0;
@@ -3081,7 +3167,13 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                        return -1;
        }
 
-       finalize_hashfile(f, istate->oid.hash, CSUM_HASH_IN_STREAM);
+       csum_fsync_flag = 0;
+       if (!alternate_index_output && (flags & COMMIT_LOCK))
+               csum_fsync_flag = CSUM_FSYNC;
+
+       finalize_hashfile(f, istate->oid.hash, FSYNC_COMPONENT_INDEX,
+                         CSUM_HASH_IN_STREAM | csum_fsync_flag);
+
        if (close_tempfile_gently(tempfile)) {
                error(_("could not close '%s'"), get_tempfile_path(tempfile));
                return -1;
@@ -3121,7 +3213,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
                                 unsigned flags)
 {
        int ret;
-       int was_full = !istate->sparse_index;
+       int was_full = istate->sparse_index == INDEX_EXPANDED;
 
        ret = convert_to_sparse(istate, 0);
 
@@ -3136,7 +3228,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
         */
        trace2_region_enter_printf("index", "do_write_index", the_repository,
                                   "%s", get_lock_file_path(lock));
-       ret = do_write_index(istate, lock->tempfile, 0);
+       ret = do_write_index(istate, lock->tempfile, 0, flags);
        trace2_region_leave_printf("index", "do_write_index", the_repository,
                                   "%s", get_lock_file_path(lock));
 
@@ -3150,7 +3242,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
        else
                ret = close_lock_file_gently(lock);
 
-       run_hook_le(NULL, "post-index-change",
+       run_hooks_l("post-index-change",
                        istate->updated_workdir ? "1" : "0",
                        istate->updated_skipworktree ? "1" : "0", NULL);
        istate->updated_workdir = 0;
@@ -3230,7 +3322,7 @@ static int clean_shared_index_files(const char *current_hex)
 }
 
 static int write_shared_index(struct index_state *istate,
-                             struct tempfile **temp)
+                             struct tempfile **temp, unsigned flags)
 {
        struct split_index *si = istate->split_index;
        int ret, was_full = !istate->sparse_index;
@@ -3240,7 +3332,7 @@ static int write_shared_index(struct index_state *istate,
 
        trace2_region_enter_printf("index", "shared/do_write_index",
                                   the_repository, "%s", get_tempfile_path(*temp));
-       ret = do_write_index(si->base, *temp, 1);
+       ret = do_write_index(si->base, *temp, 1, flags);
        trace2_region_leave_printf("index", "shared/do_write_index",
                                   the_repository, "%s", get_tempfile_path(*temp));
 
@@ -3349,7 +3441,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
                        ret = do_write_locked_index(istate, lock, flags);
                        goto out;
                }
-               ret = write_shared_index(istate, &temp);
+               ret = write_shared_index(istate, &temp, flags);
 
                saved_errno = errno;
                if (is_tempfile_active(temp))
@@ -3467,7 +3559,8 @@ void *read_blob_data_from_index(struct index_state *istate,
        }
        if (pos < 0)
                return NULL;
-       data = read_object_file(&istate->cache[pos]->oid, &type, &sz);
+       data = repo_read_object_file(the_repository, &istate->cache[pos]->oid,
+                                    &type, &sz);
        if (!data || type != OBJ_BLOB) {
                free(data);
                return NULL;