Merge branch 'nd/shared-index-fix' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 22 Mar 2018 21:24:16 +0000 (14:24 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 22 Mar 2018 21:24:16 +0000 (14:24 -0700)
Code clean-up.

* nd/shared-index-fix:
read-cache: don't write index twice if we can't write shared index
read-cache.c: move tempfile creation/cleanup out of write_shared_index
read-cache.c: change type of "temp" in write_shared_index()

1  2 
read-cache.c
t/t1700-split-index.sh
diff --combined read-cache.c
index d13ce83794340f36cc09596767d154952c8e42a3,c58c0a978a83529005326e3c2e15216ffd2b1df0..198e72b6851a13bd5bf3f8b1dc417a732cd5b147
@@@ -1603,7 -1603,7 +1603,7 @@@ int hold_locked_index(struct lock_file 
  
  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,19 -1863,20 +1863,19 @@@ unmap
   * 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)
                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 +2243,7 @@@ static int do_write_index(struct index_
        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)
@@@ -2472,32 -2472,21 +2472,21 @@@ static int clean_shared_index_files(con
  }
  
  static int write_shared_index(struct index_state *istate,
-                             struct lock_file *lock, unsigned flags)
+                             struct tempfile **temp)
  {
-       struct tempfile *temp;
        struct split_index *si = istate->split_index;
        int ret;
  
-       temp = mks_tempfile(git_path("sharedindex_XXXXXX"));
-       if (!temp) {
-               hashclr(si->base_sha1);
-               return do_write_locked_index(istate, lock, flags);
-       }
        move_cache_to_base_index(istate);
-       ret = do_write_index(si->base, temp, 1);
-       if (ret) {
-               delete_tempfile(&temp);
+       ret = do_write_index(si->base, *temp, 1);
+       if (ret)
                return ret;
-       }
-       ret = adjust_shared_perm(get_tempfile_path(temp));
+       ret = adjust_shared_perm(get_tempfile_path(*temp));
        if (ret) {
-               int save_errno = errno;
-               error("cannot fix permission bits on %s", get_tempfile_path(temp));
-               delete_tempfile(&temp);
-               errno = save_errno;
+               error("cannot fix permission bits on %s", get_tempfile_path(*temp));
                return ret;
        }
-       ret = rename_tempfile(&temp,
+       ret = rename_tempfile(temp,
                              git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
        if (!ret) {
                hashcpy(si->base_sha1, si->base->sha1);
@@@ -2565,7 -2554,22 +2554,22 @@@ int write_locked_index(struct index_sta
        new_shared_index = istate->cache_changed & SPLIT_INDEX_ORDERED;
  
        if (new_shared_index) {
-               ret = write_shared_index(istate, lock, flags);
+               struct tempfile *temp;
+               int saved_errno;
+               temp = mks_tempfile(git_path("sharedindex_XXXXXX"));
+               if (!temp) {
+                       hashclr(si->base_sha1);
+                       ret = do_write_locked_index(istate, lock, flags);
+                       goto out;
+               }
+               ret = write_shared_index(istate, &temp);
+               saved_errno = errno;
+               if (is_tempfile_active(temp))
+                       delete_tempfile(&temp);
+               errno = saved_errno;
                if (ret)
                        goto out;
        }
        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)
diff --combined t/t1700-split-index.sh
index c087b6336788054671a307759a9ac67654b624da,cbcefa6e5f84a7911d5de12a5d669b4a85392299..a66936fe9bde2ba20ab0e57400b6286b0710212a
@@@ -401,23 -401,23 +401,42 @@@ done <<\EO
  0642 -rw-r---w-
  EOF
  
+ test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
+       test_create_repo ro &&
+       (
+               cd ro &&
+               test_commit initial &&
+               git update-index --split-index &&
+               test -f .git/sharedindex.*
+       ) &&
+       cp ro/.git/index new-index &&
+       test_when_finished "chmod u+w ro/.git" &&
+       chmod u-w ro/.git &&
+       GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
+       chmod u+w ro/.git &&
+       rm ro/.git/sharedindex.* &&
+       GIT_INDEX_FILE=new-index git ls-files >actual &&
+       echo initial.t >expected &&
+       test_cmp expected actual
+ '
 +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