diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java index 11100b63c..c1b6cb259 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.lib; 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.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; @@ -53,10 +54,12 @@ import java.io.IOException; import java.util.TreeSet; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIteratorWithTimeControl; import org.eclipse.jgit.treewalk.NameConflictTreeWalk; +import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.util.FileUtils; import org.junit.Test; @@ -137,8 +140,8 @@ public class RacyGitTests extends RepositoryTestCase { fsTick(db.getIndexFile()); // create two files - File a = addToWorkDir("a", "a"); - File b = addToWorkDir("b", "b"); + File a = writeToWorkDir("a", "a"); + File b = writeToWorkDir("b", "b"); assertTrue(a.setLastModified(b.lastModified())); assertTrue(b.setLastModified(b.lastModified())); @@ -158,23 +161,35 @@ public class RacyGitTests extends RepositoryTestCase { fsTick(db.getIndexFile()); // 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)); + // updated and then a file is modified within the same tick of the + // filesystem timestamp resolution. By changing the index file + // artificially, we create a fake racy situation. + File updatedA = writeToWorkDir("a", "a2"); + long newLastModified = updatedA.lastModified() + 100; + assertTrue(updatedA.setLastModified(newLastModified)); resetIndex(new FileTreeIterator(db)); - assertTrue(db.getIndexFile() - .setLastModified(updatedA.lastModified() + 90)); + assertTrue(db.getIndexFile().setLastModified(newLastModified)); - db.readDirCache(); - // although racily clean a should not be reported as being dirty + DirCache dc = db.readDirCache(); + // check index state: although racily clean a should not be reported as + // being dirty since we forcefully reset the index to match the working + // tree assertEquals( "[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)); + + // compare state of files in working tree with index to check that + // FileTreeIterator.isModified() works as expected + FileTreeIterator f = new FileTreeIterator(db.getWorkTree(), db.getFS(), + db.getConfig().get(WorkingTreeOptions.KEY)); + assertTrue(f.findFile("a")); + try (ObjectReader reader = db.newObjectReader()) { + assertFalse(f.isModified(dc.getEntry("a"), false, reader)); + } } - private File addToWorkDir(String path, String content) throws IOException { + private File writeToWorkDir(String path, String content) throws IOException { File f = new File(db.getWorkTree(), path); try (FileOutputStream fos = new FileOutputStream(f)) { fos.write(content.getBytes(UTF_8));