mirror of
				https://github.com/actions/checkout.git
				synced 2025-10-31 14:00:52 +00:00 
			
		
		
		
	Add support for sparse checkouts (#1369)
* Add support for sparse checkouts * sparse-checkout: optionally turn off cone mode While it _is_ true that cone mode is the default nowadays (mainly for performance reasons: code mode is much faster than non-cone mode), there _are_ legitimate use cases where non-cone mode is really useful. Let's add a flag to optionally disable cone mode. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> * Verify minimum Git version for sparse checkout The `git sparse-checkout` command is available only since Git version v2.25.0. The `actions/checkout` Action actually supports older Git versions than that; As of time of writing, the minimum version is v2.18.0. Instead of raising this minimum version even for users who do not require a sparse checkout, only check for this minimum version specifically when a sparse checkout was asked for. Suggested-by: Tingluo Huang <tingluohuang@github.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> * Support sparse checkout/LFS better Instead of fetching all the LFS objects present in the current revision in a sparse checkout, whether they are needed inside the sparse cone or not, let's instead only pull the ones that are actually needed. To do that, let's avoid running that preemptive `git lfs fetch` call in case of a sparse checkout. An alternative that was considered during the development of this patch (and ultimately rejected) was to use `git lfs pull --include <path>...`, but it turned out to be too inflexible because it requires exact paths, not the patterns that are available via the sparse checkout definition, and that risks running into command-line length limitations. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --------- Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Co-authored-by: Daniel <daniel.fernandez@feverup.com>
This commit is contained in:
		
					parent
					
						
							
								f095bcc56b
							
						
					
				
			
			
				commit
				
					
						d106d4669b
					
				
			
		
					 14 changed files with 395 additions and 31 deletions
				
			
		|  | @ -153,23 +153,26 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> { | |||
| 
 | ||||
|     // Fetch
 | ||||
|     core.startGroup('Fetching the repository') | ||||
|     const fetchOptions: {filter?: string; fetchDepth?: number} = {} | ||||
|     if (settings.sparseCheckout) fetchOptions.filter = 'blob:none' | ||||
|     if (settings.fetchDepth <= 0) { | ||||
|       // Fetch all branches and tags
 | ||||
|       let refSpec = refHelper.getRefSpecForAllHistory( | ||||
|         settings.ref, | ||||
|         settings.commit | ||||
|       ) | ||||
|       await git.fetch(refSpec) | ||||
|       await git.fetch(refSpec, fetchOptions) | ||||
| 
 | ||||
|       // When all history is fetched, the ref we're interested in may have moved to a different
 | ||||
|       // commit (push or force push). If so, fetch again with a targeted refspec.
 | ||||
|       if (!(await refHelper.testRef(git, settings.ref, settings.commit))) { | ||||
|         refSpec = refHelper.getRefSpec(settings.ref, settings.commit) | ||||
|         await git.fetch(refSpec) | ||||
|         await git.fetch(refSpec, fetchOptions) | ||||
|       } | ||||
|     } else { | ||||
|       fetchOptions.fetchDepth = settings.fetchDepth | ||||
|       const refSpec = refHelper.getRefSpec(settings.ref, settings.commit) | ||||
|       await git.fetch(refSpec, settings.fetchDepth) | ||||
|       await git.fetch(refSpec, fetchOptions) | ||||
|     } | ||||
|     core.endGroup() | ||||
| 
 | ||||
|  | @ -185,12 +188,24 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> { | |||
|     // LFS fetch
 | ||||
|     // Explicit lfs-fetch to avoid slow checkout (fetches one lfs object at a time).
 | ||||
|     // Explicit lfs fetch will fetch lfs objects in parallel.
 | ||||
|     if (settings.lfs) { | ||||
|     // For sparse checkouts, let `checkout` fetch the needed objects lazily.
 | ||||
|     if (settings.lfs && !settings.sparseCheckout) { | ||||
|       core.startGroup('Fetching LFS objects') | ||||
|       await git.lfsFetch(checkoutInfo.startPoint || checkoutInfo.ref) | ||||
|       core.endGroup() | ||||
|     } | ||||
| 
 | ||||
|     // Sparse checkout
 | ||||
|     if (settings.sparseCheckout) { | ||||
|       core.startGroup('Setting up sparse checkout') | ||||
|       if (settings.sparseCheckoutConeMode) { | ||||
|         await git.sparseCheckout(settings.sparseCheckout) | ||||
|       } else { | ||||
|         await git.sparseCheckoutNonConeMode(settings.sparseCheckout) | ||||
|       } | ||||
|       core.endGroup() | ||||
|     } | ||||
| 
 | ||||
|     // Checkout
 | ||||
|     core.startGroup('Checking out the ref') | ||||
|     await git.checkout(checkoutInfo.ref, checkoutInfo.startPoint) | ||||
|  | @ -261,7 +276,11 @@ export async function cleanup(repositoryPath: string): Promise<void> { | |||
| 
 | ||||
|   let git: IGitCommandManager | ||||
|   try { | ||||
|     git = await gitCommandManager.createCommandManager(repositoryPath, false) | ||||
|     git = await gitCommandManager.createCommandManager( | ||||
|       repositoryPath, | ||||
|       false, | ||||
|       false | ||||
|     ) | ||||
|   } catch { | ||||
|     return | ||||
|   } | ||||
|  | @ -297,7 +316,8 @@ async function getGitCommandManager( | |||
|   try { | ||||
|     return await gitCommandManager.createCommandManager( | ||||
|       settings.repositoryPath, | ||||
|       settings.lfs | ||||
|       settings.lfs, | ||||
|       settings.sparseCheckout != null | ||||
|     ) | ||||
|   } catch (err) { | ||||
|     // Git is required for LFS
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue