Commit 316b820b by Carlos Martín Nieto

index: zero the size of racily-clean entries

If a file entry has the same timestamp as the index itself, it is
considered racily-clean, as it may have been modified after the index
was written, but during the same second. We take extra steps to check
the contents, but this is just one part of avoiding races.

For files which do have changes but have not been updated in the index,
updating the on-disk index means updating its timestamp, which means we
would no longer recognise these entries as racy and we would trust the
timestamp to tell us whether they have changed.

In order to work around this, git zeroes out the file-size field in
entries with the same timestamp as the index in order to force the next
diff to check the contents. Do so in libgit2 as well.
parent 77596fcf
...@@ -658,11 +658,29 @@ int git_index__changed_relative_to( ...@@ -658,11 +658,29 @@ int git_index__changed_relative_to(
index->stamp.ino != fs->ino); index->stamp.ino != fs->ino);
} }
/*
* Force the next diff to take a look at those entries which have the
* same timestamp as the current index.
*/
static void truncate_racily_clean(git_index *index)
{
size_t i;
git_index_entry *entry;
git_time_t ts = index->stamp.mtime;
git_vector_foreach(&index->entries, i, entry) {
if (entry->mtime.seconds == ts || ts == 0)
entry->file_size = 0;
}
}
int git_index_write(git_index *index) int git_index_write(git_index *index)
{ {
git_indexwriter writer = GIT_INDEXWRITER_INIT; git_indexwriter writer = GIT_INDEXWRITER_INIT;
int error; int error;
truncate_racily_clean(index);
if ((error = git_indexwriter_init(&writer, index)) == 0) if ((error = git_indexwriter_init(&writer, index)) == 0)
error = git_indexwriter_commit(&writer); error = git_indexwriter_commit(&writer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment