summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-09-24 10:30:46 -0700
committerJunio C Hamano <gitster@pobox.com>2018-09-24 10:30:46 -0700
commit48a81ed29795da3e4cc40d4e5ea535878e4f2d9f (patch)
tree0bbe3588f5728fa03ae0ef69dc9111ef91479a83
parent9715f10e4206c681313d45efa239a594a0027e60 (diff)
parent6c003d6ffb7ebd1599e73921cab5e01d7428001d (diff)
downloadgit-48a81ed29795da3e4cc40d4e5ea535878e4f2d9f.tar.gz
Merge branch 'jk/reopen-tempfile-truncate'
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
-rw-r--r--lockfile.h4
-rwxr-xr-xt/t0090-cache-tree.sh18
-rw-r--r--tempfile.c2
-rw-r--r--tempfile.h4
4 files changed, 23 insertions, 5 deletions
diff --git a/lockfile.h b/lockfile.h
index f401c979f0..35403ccc0d 100644
--- a/lockfile.h
+++ b/lockfile.h
@@ -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.
*/
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index 7de40141ca..94fcb4a78e 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -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 &&
diff --git a/tempfile.c b/tempfile.c
index 139ecd97f8..d43ad8c191 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -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;
}
diff --git a/tempfile.h b/tempfile.h
index 36434eb6fa..61d8dc4d1b 100644
--- a/tempfile.h
+++ b/tempfile.h
@@ -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.
*/