@ -54,6 +54,8 @@ import java.util.List;
import java.util.Map ;
import java.util.Map ;
import org.eclipse.jgit.api.errors.FilterFailedException ;
import org.eclipse.jgit.api.errors.FilterFailedException ;
import org.eclipse.jgit.attributes.FilterCommand ;
import org.eclipse.jgit.attributes.FilterCommandRegistry ;
import org.eclipse.jgit.errors.CheckoutConflictException ;
import org.eclipse.jgit.errors.CheckoutConflictException ;
import org.eclipse.jgit.errors.CorruptObjectException ;
import org.eclipse.jgit.errors.CorruptObjectException ;
import org.eclipse.jgit.errors.IncorrectObjectTypeException ;
import org.eclipse.jgit.errors.IncorrectObjectTypeException ;
@ -86,11 +88,15 @@ import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.RawParseUtils ;
import org.eclipse.jgit.util.RawParseUtils ;
import org.eclipse.jgit.util.SystemReader ;
import org.eclipse.jgit.util.SystemReader ;
import org.eclipse.jgit.util.io.EolStreamTypeUtil ;
import org.eclipse.jgit.util.io.EolStreamTypeUtil ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/ * *
/ * *
* This class handles checking out one or two trees merging with the index .
* This class handles checking out one or two trees merging with the index .
* /
* /
public class DirCacheCheckout {
public class DirCacheCheckout {
private static Logger LOG = LoggerFactory . getLogger ( DirCacheCheckout . class ) ;
private static final int MAX_EXCEPTION_TEXT_SIZE = 10 * 1024 ;
private static final int MAX_EXCEPTION_TEXT_SIZE = 10 * 1024 ;
/ * *
/ * *
@ -1303,45 +1309,19 @@ public class DirCacheCheckout {
} else {
} else {
nonNullEolStreamType = EolStreamType . DIRECT ;
nonNullEolStreamType = EolStreamType . DIRECT ;
}
}
OutputStream channel = EolStreamTypeUtil . wrapOutputStream (
try ( OutputStream channel = EolStreamTypeUtil . wrapOutputStream (
new FileOutputStream ( tmpFile ) , nonNullEolStreamType ) ;
new FileOutputStream ( tmpFile ) , nonNullEolStreamType ) ) {
if ( checkoutMetadata . smudgeFilterCommand ! = null ) {
if ( checkoutMetadata . smudgeFilterCommand ! = null ) {
ProcessBuilder filterProcessBuilder = fs . runInShell (
if ( FilterCommandRegistry
checkoutMetadata . smudgeFilterCommand , new String [ 0 ] ) ;
. isRegistered ( checkoutMetadata . smudgeFilterCommand ) ) {
filterProcessBuilder . directory ( repo . getWorkTree ( ) ) ;
runBuiltinFilterCommand ( repo , checkoutMetadata , ol ,
filterProcessBuilder . environment ( ) . put ( Constants . GIT_DIR_KEY ,
channel ) ;
repo . getDirectory ( ) . getAbsolutePath ( ) ) ;
} else {
ExecutionResult result ;
runExternalFilterCommand ( repo , entry , checkoutMetadata , ol ,
int rc ;
fs , channel ) ;
try {
// TODO: wire correctly with AUTOCRLF
result = fs . execute ( filterProcessBuilder , ol . openStream ( ) ) ;
rc = result . getRc ( ) ;
if ( rc = = 0 ) {
result . getStdout ( ) . writeTo ( channel ,
NullProgressMonitor . INSTANCE ) ;
}
} catch ( IOException | InterruptedException e ) {
throw new IOException ( new FilterFailedException ( e ,
checkoutMetadata . smudgeFilterCommand ,
entry . getPathString ( ) ) ) ;
} finally {
channel . close ( ) ;
}
if ( rc ! = 0 ) {
throw new IOException ( new FilterFailedException ( rc ,
checkoutMetadata . smudgeFilterCommand ,
entry . getPathString ( ) ,
result . getStdout ( ) . toByteArray ( MAX_EXCEPTION_TEXT_SIZE ) ,
RawParseUtils . decode ( result . getStderr ( )
. toByteArray ( MAX_EXCEPTION_TEXT_SIZE ) ) ) ) ;
}
}
} else {
} else {
try {
ol . copyTo ( channel ) ;
ol . copyTo ( channel ) ;
} finally {
channel . close ( ) ;
}
}
}
}
// The entry needs to correspond to the on-disk filesize. If the content
// The entry needs to correspond to the on-disk filesize. If the content
@ -1382,6 +1362,63 @@ public class DirCacheCheckout {
entry . setLastModified ( fs . lastModified ( f ) ) ;
entry . setLastModified ( fs . lastModified ( f ) ) ;
}
}
// Run an external filter command
private static void runExternalFilterCommand ( Repository repo ,
DirCacheEntry entry ,
CheckoutMetadata checkoutMetadata , ObjectLoader ol , FS fs ,
OutputStream channel ) throws IOException {
ProcessBuilder filterProcessBuilder = fs . runInShell (
checkoutMetadata . smudgeFilterCommand , new String [ 0 ] ) ;
filterProcessBuilder . directory ( repo . getWorkTree ( ) ) ;
filterProcessBuilder . environment ( ) . put ( Constants . GIT_DIR_KEY ,
repo . getDirectory ( ) . getAbsolutePath ( ) ) ;
ExecutionResult result ;
int rc ;
try {
// TODO: wire correctly with AUTOCRLF
result = fs . execute ( filterProcessBuilder , ol . openStream ( ) ) ;
rc = result . getRc ( ) ;
if ( rc = = 0 ) {
result . getStdout ( ) . writeTo ( channel ,
NullProgressMonitor . INSTANCE ) ;
}
} catch ( IOException | InterruptedException e ) {
throw new IOException ( new FilterFailedException ( e ,
checkoutMetadata . smudgeFilterCommand ,
entry . getPathString ( ) ) ) ;
}
if ( rc ! = 0 ) {
throw new IOException ( new FilterFailedException ( rc ,
checkoutMetadata . smudgeFilterCommand ,
entry . getPathString ( ) ,
result . getStdout ( ) . toByteArray ( MAX_EXCEPTION_TEXT_SIZE ) ,
RawParseUtils . decode ( result . getStderr ( )
. toByteArray ( MAX_EXCEPTION_TEXT_SIZE ) ) ) ) ;
}
}
// Run a builtin filter command
private static void runBuiltinFilterCommand ( Repository repo ,
CheckoutMetadata checkoutMetadata , ObjectLoader ol ,
OutputStream channel ) throws MissingObjectException , IOException {
FilterCommand command = null ;
try {
command = FilterCommandRegistry . createFilterCommand (
checkoutMetadata . smudgeFilterCommand , repo , ol . openStream ( ) ,
channel ) ;
} catch ( IOException e ) {
LOG . error ( JGitText . get ( ) . failedToDetermineFilterDefinition , e ) ;
// In case an IOException occurred during creating of the command
// then proceed as if there would not have been a builtin filter.
ol . copyTo ( channel ) ;
}
if ( command ! = null ) {
while ( command . run ( ) ! = - 1 ) {
// loop as long as command.run() tells there is work to do
}
}
}
@SuppressWarnings ( "deprecation" )
@SuppressWarnings ( "deprecation" )
private static void checkValidPath ( CanonicalTreeParser t )
private static void checkValidPath ( CanonicalTreeParser t )
throws InvalidPathException {
throws InvalidPathException {