aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/treewalk
diff options
context:
space:
mode:
authorRobin Rosenberg <robin.rosenberg@dewire.com>2013-12-26 01:22:04 +0100
committerRobin Stocker <robin@nibor.org>2014-02-02 13:16:19 +0100
commit5404e70dc64201786cd6a21efb41310912860122 (patch)
treebb3ac6ab7850c50f8a59e755578ca14b3a88e158 /org.eclipse.jgit/src/org/eclipse/jgit/treewalk
parent8352d1729ca63d4d6d831b2da0b168c950bc6f52 (diff)
downloadjgit-5404e70dc64201786cd6a21efb41310912860122.tar.gz
jgit-5404e70dc64201786cd6a21efb41310912860122.zip
Fix for core.autocrlf=input resulting in modified file
This version does not attempt to unsmudge, unlike the first attempt in Idafad150553df14827eccfde2e3b95760e16a8b6. Bug: 372834 Change-Id: I9300e735cb16d6208e1df963abb1ff69f688155d Also-by: Robin Stocker <robin@nibor.org> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Robin Stocker <robin@nibor.org>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/treewalk')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java85
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java5
2 files changed, 81 insertions, 9 deletions
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 07ba9d73a4..280f64f4f0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -73,10 +73,12 @@ import org.eclipse.jgit.ignore.IgnoreRule;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.CoreConfig;
+import org.eclipse.jgit.lib.CoreConfig.CheckStat;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.CoreConfig.CheckStat;
import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
@@ -796,22 +798,46 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
* True if the actual file content should be checked if
* modification time differs.
* @return true if content is most likely different.
+ * @deprecated Use {@link #isModified(DirCacheEntry, boolean, ObjectReader)}
*/
public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
+ return isModified(entry, false, null);
+ }
+
+ /**
+ * 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.
+ * @param reader
+ * access to repository objects if necessary. Should not be null.
+ * @return true if content is most likely different.
+ * @since 3.3
+ */
+ public boolean isModified(DirCacheEntry entry, boolean forceContentCheck,
+ ObjectReader reader) {
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);
+ return contentCheck(entry, reader);
else
// We are told to assume a modification if timestamps differs
return true;
case SMUDGED:
// The file is clean by timestamps but the entry was smudged.
// Lets do a content check
- return contentCheck(entry);
+ return contentCheck(entry, reader);
case EQUAL:
return false;
case DIFFER_BY_METADATA:
@@ -854,10 +880,12 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
*
* @param entry
* the entry to be checked
- * @return <code>true</code> if the content matches, <code>false</code>
- * otherwise
+ * @param reader
+ * acccess to repository data if necessary
+ * @return <code>true</code> if the content doesn't match,
+ * <code>false</code> if it matches
*/
- private boolean contentCheck(DirCacheEntry entry) {
+ private boolean contentCheck(DirCacheEntry entry, ObjectReader reader) {
if (getEntryObjectId().equals(entry.getObjectId())) {
// Content has not changed
@@ -873,7 +901,50 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
return false;
} else {
- // Content differs: that's a real change!
+ // Content differs: that's a real change, perhaps
+ if (reader == null) // deprecated use, do no further checks
+ return true;
+ switch (getOptions().getAutoCRLF()) {
+ case INPUT:
+ case TRUE:
+ InputStream dcIn = null;
+ try {
+ ObjectLoader loader = reader.open(entry.getObjectId());
+ if (loader == null)
+ return true;
+
+ // We need to compute the length, but only if it is not
+ // a binary stream.
+ dcIn = new EolCanonicalizingInputStream(
+ loader.openStream(), true, true /* abort if binary */);
+ long dcInLen;
+ try {
+ dcInLen = computeLength(dcIn);
+ } catch (EolCanonicalizingInputStream.IsBinaryException e) {
+ return true;
+ } finally {
+ dcIn.close();
+ }
+
+ dcIn = new EolCanonicalizingInputStream(
+ loader.openStream(), true);
+ byte[] autoCrLfHash = computeHash(dcIn, dcInLen);
+ boolean changed = getEntryObjectId().compareTo(
+ autoCrLfHash, 0) != 0;
+ return changed;
+ } catch (IOException e) {
+ return true;
+ } finally {
+ if (dcIn != null)
+ try {
+ dcIn.close();
+ } catch (IOException e) {
+ // empty
+ }
+ }
+ case FALSE:
+ break;
+ }
return true;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
index c3323b8684..79cd2193f6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
@@ -53,6 +53,7 @@ import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
@@ -72,7 +73,7 @@ import org.eclipse.jgit.treewalk.WorkingTreeIterator;
* <p>
* If no difference is found then we have to compare index and working-tree as
* the last step. By making use of
- * {@link WorkingTreeIterator#isModified(org.eclipse.jgit.dircache.DirCacheEntry, boolean)}
+ * {@link WorkingTreeIterator#isModified(org.eclipse.jgit.dircache.DirCacheEntry, boolean, ObjectReader)}
* we can avoid the computation of the content id if the file is not dirty.
* <p>
* Instances of this filter should not be used for multiple {@link TreeWalk}s.
@@ -219,7 +220,7 @@ public class IndexDiffFilter extends TreeFilter {
// Only one chance left to detect a diff: between index and working
// tree. Make use of the WorkingTreeIterator#isModified() method to
// avoid computing SHA1 on filesystem content if not really needed.
- return wi.isModified(di.getDirCacheEntry(), true);
+ return wi.isModified(di.getDirCacheEntry(), true, tw.getObjectReader());
}
/**