@ -62,11 +62,13 @@ import java.util.Arrays;
import java.util.Collections ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.Comparator ;
import org.eclipse.jgit.api.errors.JGitInternalException ;
import org.eclipse.jgit.diff.RawText ;
import org.eclipse.jgit.diff.RawText ;
import org.eclipse.jgit.dircache.DirCache ;
import org.eclipse.jgit.dircache.DirCache ;
import org.eclipse.jgit.dircache.DirCacheEntry ;
import org.eclipse.jgit.dircache.DirCacheEntry ;
import org.eclipse.jgit.dircache.DirCacheIterator ;
import org.eclipse.jgit.dircache.DirCacheIterator ;
import org.eclipse.jgit.errors.CorruptObjectException ;
import org.eclipse.jgit.errors.CorruptObjectException ;
import org.eclipse.jgit.errors.MissingObjectException ;
import org.eclipse.jgit.errors.NoWorkTreeException ;
import org.eclipse.jgit.errors.NoWorkTreeException ;
import org.eclipse.jgit.ignore.IgnoreNode ;
import org.eclipse.jgit.ignore.IgnoreNode ;
import org.eclipse.jgit.ignore.IgnoreRule ;
import org.eclipse.jgit.ignore.IgnoreRule ;
@ -83,6 +85,7 @@ import org.eclipse.jgit.lib.Repository;
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 ;
import org.eclipse.jgit.util.RawParseUtils ;
import org.eclipse.jgit.util.io.EolCanonicalizingInputStream ;
import org.eclipse.jgit.util.io.EolCanonicalizingInputStream ;
/ * *
/ * *
@ -808,7 +811,11 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
* @deprecated Use { @link # isModified ( DirCacheEntry , boolean , ObjectReader ) }
* @deprecated Use { @link # isModified ( DirCacheEntry , boolean , ObjectReader ) }
* /
* /
public boolean isModified ( DirCacheEntry entry , boolean forceContentCheck ) {
public boolean isModified ( DirCacheEntry entry , boolean forceContentCheck ) {
try {
return isModified ( entry , forceContentCheck , null ) ;
return isModified ( entry , forceContentCheck , null ) ;
} catch ( IOException e ) {
throw new JGitInternalException ( e . getMessage ( ) , e ) ;
}
}
}
/ * *
/ * *
@ -827,10 +834,11 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
* @param reader
* @param reader
* access to repository objects if necessary . Should not be null .
* access to repository objects if necessary . Should not be null .
* @return true if content is most likely different .
* @return true if content is most likely different .
* @throws IOException
* @since 3 . 3
* @since 3 . 3
* /
* /
public boolean isModified ( DirCacheEntry entry , boolean forceContentCheck ,
public boolean isModified ( DirCacheEntry entry , boolean forceContentCheck ,
ObjectReader reader ) {
ObjectReader reader ) throws IOException {
MetadataDiff diff = compareMetadata ( entry ) ;
MetadataDiff diff = compareMetadata ( entry ) ;
switch ( diff ) {
switch ( diff ) {
case DIFFER_BY_TIMESTAMP :
case DIFFER_BY_TIMESTAMP :
@ -848,6 +856,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
case EQUAL :
case EQUAL :
return false ;
return false ;
case DIFFER_BY_METADATA :
case DIFFER_BY_METADATA :
if ( mode = = FileMode . SYMLINK . getBits ( ) )
return contentCheck ( entry , reader ) ;
return true ;
return true ;
default :
default :
throw new IllegalStateException ( MessageFormat . format (
throw new IllegalStateException ( MessageFormat . format (
@ -891,8 +901,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
* acccess to repository data if necessary
* acccess to repository data if necessary
* @return < code > true < / code > if the content doesn ' t match ,
* @return < code > true < / code > if the content doesn ' t match ,
* < code > false < / code > if it matches
* < code > false < / code > if it matches
* @throws IOException
* /
* /
private boolean contentCheck ( DirCacheEntry entry , ObjectReader reader ) {
private boolean contentCheck ( DirCacheEntry entry , ObjectReader reader )
throws IOException {
if ( getEntryObjectId ( ) . equals ( entry . getObjectId ( ) ) ) {
if ( getEntryObjectId ( ) . equals ( entry . getObjectId ( ) ) ) {
// Content has not changed
// Content has not changed
@ -908,6 +920,9 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
return false ;
return false ;
} else {
} else {
if ( mode = = FileMode . SYMLINK . getBits ( ) )
return ! new File ( readContentAsString ( current ( ) ) )
. equals ( new File ( readContentAsString ( entry ) ) ) ;
// Content differs: that's a real change, perhaps
// Content differs: that's a real change, perhaps
if ( reader = = null ) // deprecated use, do no further checks
if ( reader = = null ) // deprecated use, do no further checks
return true ;
return true ;
@ -956,6 +971,21 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
}
}
}
}
private String readContentAsString ( DirCacheEntry entry )
throws MissingObjectException , IOException {
ObjectLoader open = repository . open ( entry . getObjectId ( ) ) ;
byte [ ] cachedBytes = open . getCachedBytes ( ) ;
return RawParseUtils . decode ( cachedBytes ) ;
}
private static String readContentAsString ( Entry entry ) throws IOException {
long length = entry . getLength ( ) ;
byte [ ] content = new byte [ ( int ) length ] ;
InputStream is = entry . openInputStream ( ) ;
IO . readFully ( is , content , 0 , ( int ) length ) ;
return RawParseUtils . decode ( content ) ;
}
private long computeLength ( InputStream in ) throws IOException {
private long computeLength ( InputStream in ) throws IOException {
// Since we only care about the length, use skip. The stream
// Since we only care about the length, use skip. The stream
// may be able to more efficiently wade through its data.
// may be able to more efficiently wade through its data.