DirCacheEntry: Do not treat gitlink entries as smudged DirCacheEntry.isSmudged() returns true whenever getLength() == 0 and the object ID is not Constants.EMPTY_BLOB_ID. However, a submodule gitlink entry (FileMode.GITLINK, mode 160000) represents a commit reference rather than a blob: its length in the index is always 0 and its object ID is the submodule commit SHA (never EMPTY_BLOB_ID). Consequently, isSmudged() returns true for every gitlink entry, causing DirCache.writeTo() to run updateSmudgedEntries() and scan the working tree on every index write when submodules are present. Exclude FileMode.GITLINK entries in DirCacheEntry.isSmudged(). Google-Bug-Id: b/573880998 Change-Id: I9b415a7852b63f57388099800000000000000002 Signed-off-by: Enrico Mrass <emrass@google.com>
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 158d9de..009556a 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
@@ -365,4 +365,14 @@ public void testNotRacilyCleanWhenSmudgeIsAfter() { final Instant smudge = entryTime.plus(Duration.ofNanos(1)); assertFalse(entry.mightBeRacilyClean(smudge)); } + + @Test + public void testGitlinkIsNotSmudged() { + DirCacheEntry entry = new DirCacheEntry("submodule"); + entry.setFileMode(FileMode.GITLINK); + entry.setObjectId(ObjectId + .fromString("0123456789012345678901234567890123456789")); + assertEquals(0, entry.getLength()); + assertFalse(entry.isSmudged()); + } }
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 aebea7a..6ebde79 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -454,7 +454,9 @@ public final void smudgeRacilyClean() { */ public final boolean isSmudged() { final int base = infoOffset + P_OBJECTID; - return (getLength() == 0) && (Constants.EMPTY_BLOB_ID.compareTo(info, base) != 0); + return (getLength() == 0) + && !FileMode.GITLINK.equals(getFileMode()) + && (Constants.EMPTY_BLOB_ID.compareTo(info, base) != 0); } final byte[] idBuffer() {