diff options
author | Robin Rosenberg <robin.rosenberg@dewire.com> | 2013-12-26 01:22:04 +0100 |
---|---|---|
committer | Robin Stocker <robin@nibor.org> | 2014-02-02 13:16:19 +0100 |
commit | 5404e70dc64201786cd6a21efb41310912860122 (patch) | |
tree | bb3ac6ab7850c50f8a59e755578ca14b3a88e158 /org.eclipse.jgit/src/org/eclipse/jgit/treewalk | |
parent | 8352d1729ca63d4d6d831b2da0b168c950bc6f52 (diff) | |
download | jgit-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.java | 85 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java | 5 |
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()); } /** |