Merge branch 'jk/reopen-tempfile-truncate' into maint

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
This commit is contained in:
Junio C Hamano 2018-11-21 22:57:43 +09:00
commit 604f719838
4 changed files with 23 additions and 5 deletions

View 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.
*/

View File

@ -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 &&

View 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;
}

View 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.
*/