@@ -706,53 +706,64 @@ private LooseObjectToWrite GetLooseObjectDestination(string sha)
706706
707707 bytesDownloaded += packLength ;
708708
709- // We can't trust the index file from the server, so we will always build our own.
710- // We still need to consume and handle any exceptions from the index stream though.
711- var canContinue = true ;
712- GitProcess . Result result ;
713- if ( this . TryBuildIndex ( activity , packTempPath , out result , gitProcess ) )
709+ // We will try to build an index if the server does not send one
710+ if ( pack . IndexStream == null )
714711 {
715- tempPacks . Add ( new TempPrefetchPackAndIdx ( pack . Timestamp , packName , packTempPath , packFlushTask , idxName , idxTempPath , idxFlushTask : null ) ) ;
716- if ( pack . IndexStream != null )
712+ GitProcess . Result result ;
713+ if ( ! this . TryBuildIndex ( activity , packTempPath , out result , gitProcess ) )
717714 {
718- try
719- {
720- bytesDownloaded += pack . IndexStream . Length ;
721- if ( pack . IndexStream . CanSeek )
722- {
723- pack . IndexStream . Seek ( 0 , SeekOrigin . End ) ;
724- }
725- else
726- {
727- pack . IndexStream . CopyTo ( Stream . Null ) ;
728- }
729- }
730- catch ( Exception e )
715+ if ( packFlushTask != null )
731716 {
732- canContinue = false ;
733- EventMetadata metadata = CreateEventMetadata ( e ) ;
734- activity . RelatedWarning ( metadata , "Failed to read to end of index stream" ) ;
717+ packFlushTask . Wait ( ) ;
735718 }
719+
720+ // Move whatever has been successfully downloaded so far
721+ Exception moveException ;
722+ this . TryFlushAndMoveTempPacks ( tempPacks , ref latestTimestamp , out moveException ) ;
723+
724+ return new RetryWrapper < GitObjectsHttpRequestor . GitObjectTaskResult > . CallbackResult ( null , true ) ;
736725 }
726+
727+ tempPacks . Add ( new TempPrefetchPackAndIdx ( pack . Timestamp , packName , packTempPath , packFlushTask , idxName , idxTempPath , idxFlushTask : null ) ) ;
737728 }
738729 else
739730 {
740- canContinue = false ;
741- }
742-
743- if ( ! canContinue )
744- {
745- if ( packFlushTask != null )
731+ Task indexFlushTask ;
732+ if ( this . TryWriteTempFile ( activity , pack . IndexStream , idxTempPath , out indexLength , out indexFlushTask ) )
746733 {
747- packFlushTask . Wait ( ) ;
734+ tempPacks . Add ( new TempPrefetchPackAndIdx ( pack . Timestamp , packName , packTempPath , packFlushTask , idxName , idxTempPath , indexFlushTask ) ) ;
748735 }
736+ else
737+ {
738+ bytesDownloaded += indexLength ;
739+
740+ // Try to build the index manually, then retry the prefetch
741+ GitProcess . Result result ;
742+ if ( this . TryBuildIndex ( activity , packTempPath , out result , gitProcess ) )
743+ {
744+ // If we were able to recreate the failed index
745+ // we can start the prefetch at the next timestamp
746+ tempPacks . Add ( new TempPrefetchPackAndIdx ( pack . Timestamp , packName , packTempPath , packFlushTask , idxName , idxTempPath , idxFlushTask : null ) ) ;
747+ }
748+ else
749+ {
750+ if ( packFlushTask != null )
751+ {
752+ packFlushTask . Wait ( ) ;
753+ }
754+ }
749755
750- // Move whatever has been successfully downloaded so far
751- Exception moveException ;
752- this . TryFlushAndMoveTempPacks ( tempPacks , ref latestTimestamp , out moveException ) ;
756+ // Move whatever has been successfully downloaded so far
757+ Exception moveException ;
758+ this . TryFlushAndMoveTempPacks ( tempPacks , ref latestTimestamp , out moveException ) ;
753759
754- return new RetryWrapper < GitObjectsHttpRequestor . GitObjectTaskResult > . CallbackResult ( null , true ) ;
760+ // The download stream will not be in a good state if the index download fails.
761+ // So we have to restart the prefetch
762+ return new RetryWrapper < GitObjectsHttpRequestor . GitObjectTaskResult > . CallbackResult ( null , true ) ;
763+ }
755764 }
765+
766+ bytesDownloaded += indexLength ;
756767 }
757768
758769 Exception exception = null ;
0 commit comments