Merge branch 'tg/split-index-fixes'
authorJunio C Hamano <gitster@pobox.com>
Tue, 13 Feb 2018 21:39:12 +0000 (13:39 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Feb 2018 21:39:13 +0000 (13:39 -0800)
The split-index mode had a few corner case bugs fixed.

* tg/split-index-fixes:
travis: run tests with GIT_TEST_SPLIT_INDEX
split-index: don't write cache tree with null oid entries
read-cache: fix reading the shared index for other repos

cache-tree.c
cache.h
ci/run-tests.sh
read-cache.c
repository.c
revision.c
split-index.c
t/t1700-split-index.sh
index e03e72c34a5c1fc618994ee63f38875d28d91886..0dd6292a94e55baff0a42df89c7006a757f61065 100644 (file)
@@ -608,7 +608,7 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
 
        hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
 
-       entries = read_index_from(index_state, index_path);
+       entries = read_index_from(index_state, index_path, get_git_dir());
        if (entries < 0) {
                ret = WRITE_TREE_UNREADABLE_INDEX;
                goto out;
diff --git a/cache.h b/cache.h
index 8cdcee544681829a409e6cb9fdf54c57a8b33b4c..9cac7bb5185fff37e9906dd0dcad9187673c7e1f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -345,7 +345,8 @@ struct index_state {
        struct split_index *split_index;
        struct cache_time timestamp;
        unsigned name_hash_initialized : 1,
-                initialized : 1;
+                initialized : 1,
+                drop_cache_tree : 1;
        struct hashmap name_hash;
        struct hashmap dir_hash;
        unsigned char sha1[20];
@@ -371,7 +372,7 @@ extern void free_name_hash(struct index_state *istate);
 #define active_cache_tree (the_index.cache_tree)
 
 #define read_cache() read_index(&the_index)
-#define read_cache_from(path) read_index_from(&the_index, (path))
+#define read_cache_from(path) read_index_from(&the_index, (path), (get_git_dir()))
 #define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec))
 #define is_cache_unborn() is_index_unborn(&the_index)
 #define read_cache_unmerged() read_index_unmerged(&the_index)
@@ -616,7 +617,8 @@ extern int read_index(struct index_state *);
 extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);
 extern int do_read_index(struct index_state *istate, const char *path,
                         int must_exist); /* for testting only! */
-extern int read_index_from(struct index_state *, const char *path);
+extern int read_index_from(struct index_state *, const char *path,
+                          const char *gitdir);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
 
index 22355f0091a0a3936472179249cf152d9f20fc17..9b6fedcc2a94b83f7243767915ad0327e100ef13 100755 (executable)
@@ -7,6 +7,10 @@
 
 ln -s $HOME/travis-cache/.prove t/.prove
 make --quiet test
+if test "$jobname" = "linux-gcc"
+then
+       GIT_TEST_SPLIT_INDEX=YesPlease make --quiet test
+fi
 
 check_unignored_build_artifacts
 
index 2eb81a66b941325dc339d61a0ab804a60cbb8be2..d13ce83794340f36cc09596767d154952c8e42a3 100644 (file)
@@ -1603,7 +1603,7 @@ int hold_locked_index(struct lock_file *lk, int lock_flags)
 
 int read_index(struct index_state *istate)
 {
-       return read_index_from(istate, get_index_file());
+       return read_index_from(istate, get_index_file(), get_git_dir());
 }
 
 static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *ondisk,
@@ -1863,20 +1863,19 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
  * This way, shared index can be removed if they have not been used
  * for some time.
  */
-static void freshen_shared_index(char *base_sha1_hex, int warn)
+static void freshen_shared_index(const char *shared_index, int warn)
 {
-       char *shared_index = git_pathdup("sharedindex.%s", base_sha1_hex);
        if (!check_and_freshen_file(shared_index, 1) && warn)
                warning("could not freshen shared index '%s'", shared_index);
-       free(shared_index);
 }
 
-int read_index_from(struct index_state *istate, const char *path)
+int read_index_from(struct index_state *istate, const char *path,
+                   const char *gitdir)
 {
        struct split_index *split_index;
        int ret;
        char *base_sha1_hex;
-       const char *base_path;
+       char *base_path;
 
        /* istate->initialized covers both .git/index and .git/sharedindex.xxx */
        if (istate->initialized)
@@ -1896,16 +1895,17 @@ int read_index_from(struct index_state *istate, const char *path)
                split_index->base = xcalloc(1, sizeof(*split_index->base));
 
        base_sha1_hex = sha1_to_hex(split_index->base_sha1);
-       base_path = git_path("sharedindex.%s", base_sha1_hex);
+       base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_sha1_hex);
        ret = do_read_index(split_index->base, base_path, 1);
        if (hashcmp(split_index->base_sha1, split_index->base->sha1))
                die("broken index, expect %s in %s, got %s",
                    base_sha1_hex, base_path,
                    sha1_to_hex(split_index->base->sha1));
 
-       freshen_shared_index(base_sha1_hex, 0);
+       freshen_shared_index(base_path, 0);
        merge_base_index(istate);
        post_read_index_from(istate);
+       free(base_path);
        return ret;
 }
 
@@ -2243,7 +2243,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
        struct stat st;
        struct ondisk_cache_entry_extended ondisk;
        struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
-       int drop_cache_tree = 0;
+       int drop_cache_tree = istate->drop_cache_tree;
 
        for (i = removed = extended = 0; i < entries; i++) {
                if (cache[i]->ce_flags & CE_REMOVE)
@@ -2573,8 +2573,11 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
        ret = write_split_index(istate, lock, flags);
 
        /* Freshen the shared index only if the split-index was written */
-       if (!ret && !new_shared_index)
-               freshen_shared_index(sha1_to_hex(si->base_sha1), 1);
+       if (!ret && !new_shared_index) {
+               const char *shared_index = git_path("sharedindex.%s",
+                                                   sha1_to_hex(si->base_sha1));
+               freshen_shared_index(shared_index, 1);
+       }
 
 out:
        if (flags & COMMIT_LOCK)
index f66fcb13425ab53e15ca47407e7c54be5dcdfc8b..4ffbe9bc94edc18314cb49c945038e2f20a40922 100644 (file)
@@ -236,5 +236,5 @@ int repo_read_index(struct repository *repo)
        if (!repo->index)
                repo->index = xcalloc(1, sizeof(*repo->index));
 
-       return read_index_from(repo->index, repo->index_file);
+       return read_index_from(repo->index, repo->index_file, repo->gitdir);
 }
index 236d0d579f0b6920127e586fe09391d172445318..5ce9b93baa72685893dd30b62c067bff1f18d636 100644 (file)
@@ -1362,7 +1362,8 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
                        continue; /* current index already taken care of */
 
                if (read_index_from(&istate,
-                                   worktree_git_path(wt, "index")) > 0)
+                                   worktree_git_path(wt, "index"),
+                                   get_worktree_git_dir(wt)) > 0)
                        do_add_index_objects_to_pending(revs, &istate);
                discard_index(&istate);
        }
index 83e39ec8d7739816188ba909a4cb9da302d48f73..284d04d67f885d8905130e138c45cc4ff4fbdc30 100644 (file)
@@ -238,6 +238,8 @@ void prepare_to_write_split_index(struct index_state *istate)
                                ALLOC_GROW(entries, nr_entries+1, nr_alloc);
                                entries[nr_entries++] = ce;
                        }
+                       if (is_null_oid(&ce->oid))
+                               istate->drop_cache_tree = 1;
                }
        }
 
index af9b847761f3c25ddbda8d1e1e978d1a323fa561..c087b6336788054671a307759a9ac67654b624da 100755 (executable)
@@ -401,4 +401,23 @@ done <<\EOF
 0642 -rw-r---w-
 EOF
 
+test_expect_success 'writing split index with null sha1 does not write cache tree' '
+       git config core.splitIndex true &&
+       git config splitIndex.maxPercentChange 0 &&
+       git commit -m "commit" &&
+       {
+               git ls-tree HEAD &&
+               printf "160000 commit $_z40\\tbroken\\n"
+       } >broken-tree &&
+       echo "add broken entry" >msg &&
+
+       tree=$(git mktree <broken-tree) &&
+       test_tick &&
+       commit=$(git commit-tree $tree -p HEAD <msg) &&
+       git update-ref HEAD "$commit" &&
+       GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
+       (test-dump-cache-tree >cache-tree.out || true) &&
+       test_line_count = 0 cache-tree.out
+'
+
 test_done