@@ -361,6 +361,29 @@ private static bool IsForceCheckoutErrorCloneFailure(string checkoutError)
361361 return true ;
362362 }
363363
364+ private static bool HasUsablePrefetchPacks (
365+ GVFSGitObjects gitObjects ,
366+ GVFSEnlistment enlistment ,
367+ PhysicalFileSystem fileSystem )
368+ {
369+ string [ ] prefetchPacks = gitObjects . ReadPackFileNames (
370+ enlistment . GitPackRoot ,
371+ GVFSConstants . PrefetchPackPrefix ) ;
372+
373+ foreach ( string packPath in prefetchPacks )
374+ {
375+ string idxPath = Path . ChangeExtension ( packPath , ".idx" ) ;
376+ string incompletePath = Path . ChangeExtension ( packPath , GVFSConstants . InProgressPrefetchMarkerExtension ) ;
377+
378+ if ( fileSystem . FileExists ( idxPath ) && ! fileSystem . FileExists ( incompletePath ) )
379+ {
380+ return true ;
381+ }
382+ }
383+
384+ return false ;
385+ }
386+
364387 private Result TryCreateEnlistment (
365388 string fullEnlistmentRootPathParameter ,
366389 string normalizedEnlistementRootPath ,
@@ -617,15 +640,30 @@ private Result CreateClone(
617640 GVFSContext context = new GVFSContext ( tracer , fileSystem , gitRepo , enlistment ) ;
618641 GVFSGitObjects gitObjects = new GVFSGitObjects ( context , objectRequestor ) ;
619642
620- if ( ! this . TryDownloadCommit (
621- refs . GetTipCommitId ( branch ) ,
622- enlistment ,
623- objectRequestor ,
624- gitObjects ,
625- gitRepo ,
626- out errorMessage ) )
643+ string commitId = refs . GetTipCommitId ( branch ) ;
644+ bool skippedCommitDownload = false ;
645+
646+ if ( gitRepo . CommitAndRootTreeExists ( commitId , out _ ) )
627647 {
628- return new Result ( errorMessage ) ;
648+ tracer . RelatedInfo ( "Commit {0} already exists locally, skipping download" , commitId ) ;
649+ }
650+ else if ( HasUsablePrefetchPacks ( gitObjects , enlistment , fileSystem ) )
651+ {
652+ tracer . RelatedInfo ( "Prefetch packs found in shared cache but commit {0} is not present; deferring download" , commitId ) ;
653+ skippedCommitDownload = true ;
654+ }
655+ else
656+ {
657+ if ( ! this . TryDownloadCommit (
658+ commitId ,
659+ enlistment ,
660+ objectRequestor ,
661+ gitObjects ,
662+ gitRepo ,
663+ out errorMessage ) )
664+ {
665+ return new Result ( errorMessage ) ;
666+ }
629667 }
630668
631669 if ( ! GVFSVerb . TrySetRequiredGitConfigSettings ( enlistment ) ||
@@ -643,6 +681,24 @@ private Result CreateClone(
643681 GitProcess git = new GitProcess ( enlistment ) ;
644682 string originBranchName = "origin/" + branch ;
645683 GitProcess . Result createBranchResult = git . CreateBranchWithUpstream ( branch , originBranchName ) ;
684+ if ( createBranchResult . ExitCodeIsFailure && skippedCommitDownload )
685+ {
686+ tracer . RelatedInfo ( "Branch creation failed after deferring commit download, downloading commit now" ) ;
687+ if ( ! this . TryDownloadCommit (
688+ commitId ,
689+ enlistment ,
690+ objectRequestor ,
691+ gitObjects ,
692+ gitRepo ,
693+ out errorMessage ) )
694+ {
695+ return new Result ( errorMessage ) ;
696+ }
697+
698+ skippedCommitDownload = false ;
699+ createBranchResult = git . CreateBranchWithUpstream ( branch , originBranchName ) ;
700+ }
701+
646702 if ( createBranchResult . ExitCodeIsFailure )
647703 {
648704 return new Result ( "Unable to create branch '" + originBranchName + "': " + createBranchResult . Errors + "\r \n " + createBranchResult . Output ) ;
@@ -654,7 +710,31 @@ private Result CreateClone(
654710
655711 if ( ! this . TryDownloadRootGitAttributes ( enlistment , gitObjects , gitRepo , out errorMessage ) )
656712 {
657- return new Result ( errorMessage ) ;
713+ if ( skippedCommitDownload )
714+ {
715+ tracer . RelatedInfo ( "Root .gitattributes download failed after deferring commit download, downloading commit now" ) ;
716+ if ( ! this . TryDownloadCommit (
717+ commitId ,
718+ enlistment ,
719+ objectRequestor ,
720+ gitObjects ,
721+ gitRepo ,
722+ out errorMessage ) )
723+ {
724+ return new Result ( errorMessage ) ;
725+ }
726+
727+ skippedCommitDownload = false ;
728+
729+ if ( ! this . TryDownloadRootGitAttributes ( enlistment , gitObjects , gitRepo , out errorMessage ) )
730+ {
731+ return new Result ( errorMessage ) ;
732+ }
733+ }
734+ else
735+ {
736+ return new Result ( errorMessage ) ;
737+ }
658738 }
659739
660740 this . CreateGitScript ( enlistment ) ;
@@ -677,7 +757,7 @@ private Result CreateClone(
677757 // again and retry the checkout.
678758
679759 if ( ! this . TryDownloadCommit (
680- refs . GetTipCommitId ( branch ) ,
760+ commitId ,
681761 enlistment ,
682762 objectRequestor ,
683763 gitObjects ,
0 commit comments