@ -73,10 +73,12 @@ import org.eclipse.jgit.ignore.IgnoreRule;
import org.eclipse.jgit.internal.JGitText ;
import org.eclipse.jgit.internal.JGitText ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.CoreConfig ;
import org.eclipse.jgit.lib.CoreConfig ;
import org.eclipse.jgit.lib.CoreConfig.CheckStat ;
import org.eclipse.jgit.lib.FileMode ;
import org.eclipse.jgit.lib.FileMode ;
import org.eclipse.jgit.lib.ObjectId ;
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.Repository ;
import org.eclipse.jgit.lib.CoreConfig.CheckStat ;
import org.eclipse.jgit.submodule.SubmoduleWalk ;
import org.eclipse.jgit.submodule.SubmoduleWalk ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.IO ;
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
* True if the actual file content should be checked if
* modification time differs .
* modification time differs .
* @return true if content is most likely different .
* @return true if content is most likely different .
* @deprecated Use { @link # isModified ( DirCacheEntry , boolean , ObjectReader ) }
* /
* /
public boolean isModified ( DirCacheEntry entry , boolean forceContentCheck ) {
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 ) ;
MetadataDiff diff = compareMetadata ( entry ) ;
switch ( diff ) {
switch ( diff ) {
case DIFFER_BY_TIMESTAMP :
case DIFFER_BY_TIMESTAMP :
if ( forceContentCheck )
if ( forceContentCheck )
// But we are told to look at content even though timestamps
// But we are told to look at content even though timestamps
// tell us about modification
// tell us about modification
return contentCheck ( entry ) ;
return contentCheck ( entry , reader ) ;
else
else
// We are told to assume a modification if timestamps differs
// We are told to assume a modification if timestamps differs
return true ;
return true ;
case SMUDGED :
case SMUDGED :
// The file is clean by timestamps but the entry was smudged.
// The file is clean by timestamps but the entry was smudged.
// Lets do a content check
// Lets do a content check
return contentCheck ( entry ) ;
return contentCheck ( entry , reader ) ;
case EQUAL :
case EQUAL :
return false ;
return false ;
case DIFFER_BY_METADATA :
case DIFFER_BY_METADATA :
@ -854,10 +880,12 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
*
*
* @param entry
* @param entry
* the entry to be checked
* the entry to be checked
* @return < code > true < / code > if the content matches , < code > false < / code >
* @param reader
* otherwise
* 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 ( ) ) ) {
if ( getEntryObjectId ( ) . equals ( entry . getObjectId ( ) ) ) {
// Content has not changed
// Content has not changed
@ -873,7 +901,50 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
return false ;
return false ;
} else {
} 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 ;
return true ;
}
}
}
}