Merge "DirCacheEntry: Fix mightBeRacilyClean() time difference calculation"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
index 01d1e02..158d9de 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
@@ -22,6 +22,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
+import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
@@ -339,4 +340,29 @@ private static void copyMetaDataHelper(boolean keepStage) {
assertTrue(e.isUpdateNeeded());
assertEquals("some/path", e.getPathString());
}
+
+ @Test
+ public void testMightBeRacilyCleanNanoOverflow() {
+ DirCacheEntry entry = new DirCacheEntry("some/path");
+ final Instant instant = Instant.ofEpochSecond(1, 999_999_999);
+ entry.setLastModified(instant.plus(Duration.ofNanos(1)));
+ assertTrue(entry.mightBeRacilyClean(instant));
+ }
+
+ @Test
+ public void testMightBeRacilyCleanOneSecondAfter() {
+ DirCacheEntry entry = new DirCacheEntry("some/path");
+ final Instant instant = Instant.ofEpochSecond(1, 0);
+ entry.setLastModified(instant.plus(Duration.ofSeconds(1)));
+ assertTrue(entry.mightBeRacilyClean(instant));
+ }
+
+ @Test
+ public void testNotRacilyCleanWhenSmudgeIsAfter() {
+ DirCacheEntry entry = new DirCacheEntry("some/path");
+ final Instant entryTime = Instant.ofEpochSecond(1, 0);
+ entry.setLastModified(entryTime);
+ final Instant smudge = entryTime.plus(Duration.ofNanos(1));
+ assertFalse(entry.mightBeRacilyClean(smudge));
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
index 5a22938..aebea7a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -411,9 +411,14 @@ public final boolean mightBeRacilyClean(Instant smudge) {
// it is clean or not based on the modification time alone.
//
final int base = infoOffset + P_MTIME;
- final int mtime = NB.decodeInt32(info, base);
- if ((int) smudge.getEpochSecond() == mtime) {
- return smudge.getNano() <= NB.decodeInt32(info, base + 4);
+ final int entryMtimeSec = NB.decodeInt32(info, base);
+ final int smudgeSec = (int) smudge.getEpochSecond();
+ if (smudgeSec != 0) {
+ if (smudgeSec < entryMtimeSec) {
+ return true;
+ } else if (smudgeSec == entryMtimeSec) {
+ return smudge.getNano() <= NB.decodeInt32(info, base + 4);
+ }
}
return false;
}