Merge branch 'jk/reopen-tempfile-truncate'
authorJunio C Hamano <gitster@pobox.com>
Mon, 24 Sep 2018 17:30:46 +0000 (10:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 24 Sep 2018 17:30:46 +0000 (10:30 -0700)
Fix for a long-standing bug that leaves the index file corrupt when
it shrinks during a partial commit.

* jk/reopen-tempfile-truncate:
reopen_tempfile(): truncate opened file

lockfile.h
t/t0090-cache-tree.sh
tempfile.c
tempfile.h
index f401c979f0ed907b40bfb509ab8f06ad2632c19e..35403ccc0d586c4732411a5813cb97761dddc435 100644 (file)
@@ -263,8 +263,8 @@ static inline int close_lock_file_gently(struct lock_file *lk)
  *   nobody else) to inspect the contents you wrote, while still
  *   holding the lock yourself.
  *
- * * `reopen_lock_file()` to reopen the lockfile. Make further updates
- *   to the contents.
+ * * `reopen_lock_file()` to reopen the lockfile, truncating the existing
+ *   contents. Write out the new contents.
  *
  * * `commit_lock_file()` to make the final version permanent.
  */
index 7de40141ca84dc53657d81c0254870b387339f79..94fcb4a78e661ae793eef54ae98b4821218b1e29 100755 (executable)
@@ -161,6 +161,24 @@ test_expect_success PERL 'commit --interactive gives cache-tree on partial commi
        test_cache_tree
 '
 
+test_expect_success PERL 'commit -p with shrinking cache-tree' '
+       mkdir -p deep/subdir &&
+       echo content >deep/subdir/file &&
+       git add deep &&
+       git commit -m add &&
+       git rm -r deep &&
+
+       before=$(wc -c <.git/index) &&
+       git commit -m delete -p &&
+       after=$(wc -c <.git/index) &&
+
+       # double check that the index shrank
+       test $before -gt $after &&
+
+       # and that our index was not corrupted
+       git fsck
+'
+
 test_expect_success 'commit in child dir has cache-tree' '
        mkdir dir &&
        >dir/child.t &&
index 139ecd97f8eb88b597aab50c2eb2b171a11ef3ef..d43ad8c1912d977183270fabe7ac76c5bbb7a1a3 100644 (file)
@@ -279,7 +279,7 @@ int reopen_tempfile(struct tempfile *tempfile)
                BUG("reopen_tempfile called for an inactive object");
        if (0 <= tempfile->fd)
                BUG("reopen_tempfile called for an open object");
-       tempfile->fd = open(tempfile->filename.buf, O_WRONLY);
+       tempfile->fd = open(tempfile->filename.buf, O_WRONLY|O_TRUNC);
        return tempfile->fd;
 }
 
index 36434eb6fa64721bcafdb40db5f9e7d0400a50b4..61d8dc4d1bb2fc446ac7b452661064e615b4b5c9 100644 (file)
@@ -236,8 +236,8 @@ extern int close_tempfile_gently(struct tempfile *tempfile);
  *   it (and nobody else) to inspect or even modify the file's
  *   contents.
  *
- * * `reopen_tempfile()` to reopen the temporary file. Make further
- *   updates to the contents.
+ * * `reopen_tempfile()` to reopen the temporary file, truncating the existing
+ *   contents. Write out the new contents.
  *
  * * `rename_tempfile()` to move the file to its permanent location.
  */