diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
index 3049ae7d0..c03c64929 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
@@ -419,6 +419,7 @@ unableToCheckConnectivity=Unable to check connectivity.
unableToStore=Unable to store {0}.
unableToWrite=Unable to write {0}
unencodeableFile=Unencodeable file: {0}
+unexpectedCompareResult=Unexpected metadata comparison result: {0}
unexpectedEndOfConfigFile=Unexpected end of config file
unexpectedHunkTrailer=Unexpected hunk trailer
unexpectedOddResult=odd: {0} + {1} - {2}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
index 9718e6294..4e3cb2035 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
@@ -479,6 +479,7 @@ public class JGitText extends TranslationBundle {
/***/ public String unableToStore;
/***/ public String unableToWrite;
/***/ public String unencodeableFile;
+ /***/ public String unexpectedCompareResult;
/***/ public String unexpectedEndOfConfigFile;
/***/ public String unexpectedHunkTrailer;
/***/ public String unexpectedOddResult;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 69d9b22d1..48e64831c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -528,29 +528,51 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
}
/**
- * Checks whether this entry differs from a given entry from the
- * {@link DirCache}.
- *
- * File status information is used and if status is same we consider the
- * file identical to the state in the working directory. Native git uses
- * more stat fields than we have accessible in Java.
+ * The result of a metadata-comparison between the current entry and a
+ * {@link DirCacheEntry}
+ */
+ public enum MetadataDiff {
+ /**
+ * The entries are equal by metaData (mode, length,
+ * modification-timestamp) or the assumeValid
attribute of
+ * the index entry is set
+ */
+ EQUAL,
+
+ /**
+ * The entries are not equal by metaData (mode, length) or the
+ * isUpdateNeeded
attribute of the index entry is set
+ */
+ DIFFER_BY_METADATA,
+
+ /** index entry is smudged - can't use that entry for comparison */
+ SMUDGED,
+
+ /**
+ * The entries are equal by metaData (mode, length) but differ by
+ * modification-timestamp.
+ */
+ DIFFER_BY_TIMESTAMP
+ }
+
+ /**
+ * Compare the metadata (mode, length, modification-timestamp) of the
+ * current entry and a {@link DirCacheEntry}
*
* @param entry
- * the entry from the dircache we want to compare against
- * @param forceContentCheck
- * True if the actual file content should be checked if
- * modification time differs.
- * @return true if content is most likely different.
+ * the {@link DirCacheEntry} to compare with
+ * @return a {@link MetadataDiff} which tells whether and how the entries
+ * metadata differ
*/
- public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
+ public MetadataDiff compareMetadata(DirCacheEntry entry) {
if (entry.isAssumeValid())
- return false;
+ return MetadataDiff.EQUAL;
if (entry.isUpdateNeeded())
- return true;
+ return MetadataDiff.DIFFER_BY_METADATA;
if (!entry.isSmudged() && (getEntryLength() != entry.getLength()))
- return true;
+ return MetadataDiff.DIFFER_BY_METADATA;
// Determine difference in mode-bits of file and index-entry. In the
// bitwise presentation of modeDiff we'll have a '1' when the two modes
@@ -567,7 +589,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
if (modeDiff != 0)
// Report a modification if the modes still (after potentially
// ignoring EXECUTABLE_FILE bits) differ
- return true;
+ return MetadataDiff.DIFFER_BY_METADATA;
}
// Git under windows only stores seconds so we round the timestamp
@@ -578,27 +600,52 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
if (cacheLastModified % 1000 == 0)
fileLastModified = fileLastModified - fileLastModified % 1000;
- if (fileLastModified != cacheLastModified) {
- // The file is dirty by timestamps
- if (forceContentCheck) {
+ if (fileLastModified != cacheLastModified)
+ return MetadataDiff.DIFFER_BY_TIMESTAMP;
+ else if (!entry.isSmudged())
+ // The file is clean when you look at timestamps.
+ return MetadataDiff.EQUAL;
+ else
+ return MetadataDiff.SMUDGED;
+ }
+
+ /**
+ * Checks whether this entry differs from a given entry from the
+ * {@link DirCache}.
+ *
+ * File status information is used and if status is same we consider the
+ * file identical to the state in the working directory. Native git uses
+ * more stat fields than we have accessible in Java.
+ *
+ * @param entry
+ * the entry from the dircache we want to compare against
+ * @param forceContentCheck
+ * True if the actual file content should be checked if
+ * modification time differs.
+ * @return true if content is most likely different.
+ */
+ public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
+ MetadataDiff diff = compareMetadata(entry);
+ switch (diff) {
+ case DIFFER_BY_TIMESTAMP:
+ if (forceContentCheck)
// But we are told to look at content even though timestamps
// tell us about modification
return contentCheck(entry);
- } else {
+ else
// We are told to assume a modification if timestamps differs
return true;
- }
- } else {
- // The file is clean when you look at timestamps.
- if (entry.isSmudged()) {
- // The file is clean by timestamps but the entry was smudged.
- // Lets do a content check
- return contentCheck(entry);
- } else {
- // The file is clean by timestamps and the entry is not
- // smudged: Can't get any cleaner!
- return false;
- }
+ case SMUDGED:
+ // The file is clean by timestamps but the entry was smudged.
+ // Lets do a content check
+ return contentCheck(entry);
+ case EQUAL:
+ return false;
+ case DIFFER_BY_METADATA:
+ return true;
+ default:
+ throw new IllegalStateException(MessageFormat.format(
+ JGitText.get().unexpectedCompareResult, diff.name()));
}
}