Skip to content

Commit 48a81ed

Browse files
committed
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
2 parents 9715f10 + 6c003d6 commit 48a81ed

File tree

4 files changed

+23
-5
lines changed

4 files changed

+23
-5
lines changed

lockfile.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ static inline int close_lock_file_gently(struct lock_file *lk)
263263
* nobody else) to inspect the contents you wrote, while still
264264
* holding the lock yourself.
265265
*
266-
* * `reopen_lock_file()` to reopen the lockfile. Make further updates
267-
* to the contents.
266+
* * `reopen_lock_file()` to reopen the lockfile, truncating the existing
267+
* contents. Write out the new contents.
268268
*
269269
* * `commit_lock_file()` to make the final version permanent.
270270
*/

t/t0090-cache-tree.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,24 @@ test_expect_success PERL 'commit --interactive gives cache-tree on partial commi
161161
test_cache_tree
162162
'
163163

164+
test_expect_success PERL 'commit -p with shrinking cache-tree' '
165+
mkdir -p deep/subdir &&
166+
echo content >deep/subdir/file &&
167+
git add deep &&
168+
git commit -m add &&
169+
git rm -r deep &&
170+
171+
before=$(wc -c <.git/index) &&
172+
git commit -m delete -p &&
173+
after=$(wc -c <.git/index) &&
174+
175+
# double check that the index shrank
176+
test $before -gt $after &&
177+
178+
# and that our index was not corrupted
179+
git fsck
180+
'
181+
164182
test_expect_success 'commit in child dir has cache-tree' '
165183
mkdir dir &&
166184
>dir/child.t &&

tempfile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ int reopen_tempfile(struct tempfile *tempfile)
279279
BUG("reopen_tempfile called for an inactive object");
280280
if (0 <= tempfile->fd)
281281
BUG("reopen_tempfile called for an open object");
282-
tempfile->fd = open(tempfile->filename.buf, O_WRONLY);
282+
tempfile->fd = open(tempfile->filename.buf, O_WRONLY|O_TRUNC);
283283
return tempfile->fd;
284284
}
285285

tempfile.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ extern int close_tempfile_gently(struct tempfile *tempfile);
236236
* it (and nobody else) to inspect or even modify the file's
237237
* contents.
238238
*
239-
* * `reopen_tempfile()` to reopen the temporary file. Make further
240-
* updates to the contents.
239+
* * `reopen_tempfile()` to reopen the temporary file, truncating the existing
240+
* contents. Write out the new contents.
241241
*
242242
* * `rename_tempfile()` to move the file to its permanent location.
243243
*/

0 commit comments

Comments
 (0)