@ -46,7 +46,6 @@ import static java.lang.Long.valueOf;
import static java.nio.charset.StandardCharsets.UTF_8 ;
import static org.junit.Assert.assertEquals ;
import static org.junit.Assert.assertTrue ;
import static org.junit.Assume.assumeTrue ;
import java.io.File ;
import java.io.FileOutputStream ;
@ -63,8 +62,8 @@ import org.junit.Test;
public class RacyGitTests extends RepositoryTestCase {
@Test
public void testIterator ( ) throws IllegalStateException , IOException ,
InterruptedException {
public void testIterator ( )
throws IllegalStateException , IOException , InterruptedException {
TreeSet < Long > modTimes = new TreeSet < > ( ) ;
File lastFile = null ;
for ( int i = 0 ; i < 10 ; i + + ) {
@ -128,9 +127,6 @@ public class RacyGitTests extends RepositoryTestCase {
@Test
public void testRacyGitDetection ( ) throws Exception {
TreeSet < Long > modTimes = new TreeSet < > ( ) ;
File lastFile ;
// Reset to force creation of index file
try ( Git git = new Git ( db ) ) {
git . reset ( ) . call ( ) ;
@ -138,44 +134,43 @@ public class RacyGitTests extends RepositoryTestCase {
// wait to ensure that modtimes of the file doesn't match last index
// file modtime
modTimes . add ( valueOf ( fsTick ( db . getIndexFile ( ) ) ) ) ;
fsTick ( db . getIndexFile ( ) ) ;
// create two files
addToWorkDir ( "a" , "a" ) ;
lastFile = addToWorkDir ( "b" , "b" ) ;
File a = addToWorkDir ( "a" , "a" ) ;
File b = addToWorkDir ( "b" , "b" ) ;
assertTrue ( a . setLastModified ( b . lastModified ( ) ) ) ;
assertTrue ( b . setLastModified ( b . lastModified ( ) ) ) ;
// wait to ensure that file-modTimes and therefore index entry modTime
// doesn't match the modtime of index-file after next persistance
modTimes . add ( valueOf ( fsTick ( lastFile ) ) ) ;
fsTick ( b ) ;
// now add both files to the index. No racy git expected
resetIndex ( new FileTreeIteratorWithTimeControl ( db , modTimes ) ) ;
resetIndex ( new FileTreeIterator ( db ) ) ;
assertEquals (
"[a, mode:100644, time:t0, length:1, content:a]" +
"[b, mode:100644, time:t0, length:1, content:b]" ,
"[a, mode:100644, time:t0, length:1, content:a]"
+ "[b, mode:100644, time:t0, length:1, content:b]" ,
indexState ( SMUDGE | MOD_TIME | LENGTH | CONTENT ) ) ;
// Remember the last modTime of index file. All modifications times of
// further modification are translated to this value so it looks that
// files have been modified in the same time slot as the index file
long indexMod = db . getIndexFile ( ) . lastModified ( ) ;
modTimes . add ( Long . valueOf ( indexMod ) ) ;
// modify one file
long aMod = addToWorkDir ( "a" , "a2" ) . lastModified ( ) ;
assumeTrue ( aMod = = indexMod ) ;
// wait to ensure the file 'a' is updated at t1.
fsTick ( db . getIndexFile ( ) ) ;
// now update the index the index. 'a' has to be racily clean -- because
// it's modification time is exactly the same as the previous index file
// mod time.
resetIndex ( new FileTreeIteratorWithTimeControl ( db , modTimes ) ) ;
// Create a racy git situation. This is a situation that the index is
// updated and then a file is modified within a second. By changing the
// index file artificially, we create a fake racy situation.
File updatedA = addToWorkDir ( "a" , "a2" ) ;
assertTrue ( updatedA . setLastModified ( updatedA . lastModified ( ) + 100 ) ) ;
resetIndex ( new FileTreeIterator ( db ) ) ;
assertTrue ( db . getIndexFile ( )
. setLastModified ( updatedA . lastModified ( ) + 90 ) ) ;
db . readDirCache ( ) ;
// although racily clean a should not be reported as being dirty
assertEquals (
"[a, mode:100644, time:t1, smudged, length:0, content:a2]" +
"[b, mode:100644, time:t0, length:1, content:b]" ,
"[a, mode:100644, time:t1, smudged, length:0, content:a2]"
+ "[b, mode:100644, time:t0, length:1, content:b]" ,
indexState ( SMUDGE | MOD_TIME | LENGTH | CONTENT ) ) ;
}