diff options
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java | 79 |
1 files changed, 73 insertions, 6 deletions
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 6b1d4f4d8a..d2a59c1310 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java @@ -56,6 +56,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.text.MessageFormat; +import java.time.Instant; import java.util.Arrays; import org.eclipse.jgit.errors.CorruptObjectException; @@ -145,8 +146,8 @@ public class DirCacheEntry { private byte inCoreFlags; DirCacheEntry(final byte[] sharedInfo, final MutableInteger infoAt, - final InputStream in, final MessageDigest md, final int smudge_s, - final int smudge_ns) throws IOException { + final InputStream in, final MessageDigest md, final Instant smudge) + throws IOException { info = sharedInfo; infoOffset = infoAt.value; @@ -215,8 +216,9 @@ public class DirCacheEntry { md.update(nullpad, 0, padLen); } - if (mightBeRacilyClean(smudge_s, smudge_ns)) + if (mightBeRacilyClean(smudge)) { smudgeRacilyClean(); + } } /** @@ -344,8 +346,29 @@ public class DirCacheEntry { * @param smudge_ns * nanoseconds component of the index's last modified time. * @return true if extra careful checks should be used. + * @deprecated use {@link #mightBeRacilyClean(Instant)} instead */ + @Deprecated public final boolean mightBeRacilyClean(int smudge_s, int smudge_ns) { + return mightBeRacilyClean(Instant.ofEpochSecond(smudge_s, smudge_ns)); + } + + /** + * Is it possible for this entry to be accidentally assumed clean? + * <p> + * The "racy git" problem happens when a work file can be updated faster + * than the filesystem records file modification timestamps. It is possible + * for an application to edit a work file, update the index, then edit it + * again before the filesystem will give the work file a new modification + * timestamp. This method tests to see if file was written out at the same + * time as the index. + * + * @param smudge + * index's last modified time. + * @return true if extra careful checks should be used. + * @since 5.1.9 + */ + public final boolean mightBeRacilyClean(Instant smudge) { // If the index has a modification time then it came from disk // and was not generated from scratch in memory. In such cases // the entry is 'racily clean' if the entry's cached modification @@ -355,8 +378,9 @@ public class DirCacheEntry { // final int base = infoOffset + P_MTIME; final int mtime = NB.decodeInt32(info, base); - if (smudge_s == mtime) - return smudge_ns <= NB.decodeInt32(info, base + 4); + if (smudge.getEpochSecond() == mtime) { + return smudge.getNano() <= NB.decodeInt32(info, base + 4); + } return false; } @@ -563,22 +587,51 @@ public class DirCacheEntry { * * @return last modification time of this file, in milliseconds since the * Java epoch (midnight Jan 1, 1970 UTC). + * @deprecated use {@link #getLastModifiedInstant()} instead */ + @Deprecated public long getLastModified() { return decodeTS(P_MTIME); } /** + * Get the cached last modification date of this file. + * <p> + * One of the indicators that the file has been modified by an application + * changing the working tree is if the last modification time for the file + * differs from the time stored in this entry. + * + * @return last modification time of this file. + * @since 5.1.9 + */ + public Instant getLastModifiedInstant() { + return decodeTSInstant(P_MTIME); + } + + /** * Set the cached last modification date of this file, using milliseconds. * * @param when * new cached modification date of the file, in milliseconds. + * @deprecated use {@link #setLastModified(Instant)} instead */ + @Deprecated public void setLastModified(long when) { encodeTS(P_MTIME, when); } /** + * Set the cached last modification date of this file. + * + * @param when + * new cached modification date of the file. + * @since 5.1.9 + */ + public void setLastModified(Instant when) { + encodeTS(P_MTIME, when); + } + + /** * Get the cached size (mod 4 GB) (in bytes) of this file. * <p> * One of the indicators that the file has been modified by an application @@ -692,7 +745,8 @@ public class DirCacheEntry { @SuppressWarnings("nls") @Override public String toString() { - return getFileMode() + " " + getLength() + " " + getLastModified() + return getFileMode() + " " + getLength() + " " + + getLastModifiedInstant() + " " + getObjectId() + " " + getStage() + " " + getPathString() + "\n"; } @@ -750,12 +804,25 @@ public class DirCacheEntry { return 1000L * sec + ms; } + private Instant decodeTSInstant(int pIdx) { + final int base = infoOffset + pIdx; + final int sec = NB.decodeInt32(info, base); + final int nano = NB.decodeInt32(info, base + 4); + return Instant.ofEpochSecond(sec, nano); + } + private void encodeTS(int pIdx, long when) { final int base = infoOffset + pIdx; NB.encodeInt32(info, base, (int) (when / 1000)); NB.encodeInt32(info, base + 4, ((int) (when % 1000)) * 1000000); } + private void encodeTS(int pIdx, Instant when) { + final int base = infoOffset + pIdx; + NB.encodeInt32(info, base, (int) when.getEpochSecond()); + NB.encodeInt32(info, base + 4, when.getNano()); + } + private int getExtendedFlags() { if (isExtended()) return NB.decodeUInt16(info, infoOffset + P_FLAGS2) << 16; |