Skip to content

Instantly share code, notes, and snippets.

@andreabradpitto
Created April 10, 2025 09:46
Show Gist options
  • Save andreabradpitto/26d3092b6ce5669baf03eaedd45264c0 to your computer and use it in GitHub Desktop.
Save andreabradpitto/26d3092b6ce5669baf03eaedd45264c0 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Perform Git sparse checkout programmatically.
.DESCRIPTION
This script performs a sparse checkout of a Git repository, allowing you to clone only specific subfolders instead of the entire repository.
It uses the `git sparse-checkout` command to specify which subfolders to include in the local clone.
.PARAMETER repoUrl
Mandatory parameter; it is the repository URL that will be `git clone`d.
.PARAMETER subfolderList
Mandatory parameter; it is an array of all the paths that should be checked out. Other paths will be ignored in local clone.
.EXAMPLE
Use like this: .\gitSparseCheckout.ps1 -repoUrl "https://github.com/cirosantilli/test-git-partial-clone-big-small-no-bigtree" -subfolderList "path1", "path2", "path3/subpath3"
.NOTES
Do not run this script from Git Bash, use PowerShell instead.
Othewise, .git/info/sparse-checkout will not be created correctly.
If you want to manually tweak the sparse checkout policy, proceed like this
(Bash syntax)
echo "/<CHOSEN_FOLDER_1>/" > .git/info/sparse-checkout
echo "/<CHOSEN_FOLDER_2>/" >> .git/info/sparse-checkout
git checkout
git read-tree -mu HEAD
(PowerShell syntax)
"/<CHOSEN_FOLDER_1>/" | Set-Content .git/info/sparse-checkout
"/<CHOSEN_FOLDER_1>/" | Add-Content .git/info/sparse-checkout
git checkout
git read-tree -mu HEAD
Credit: https://stackoverflow.com/a/52269934
#>
param (
[Parameter(Mandatory = $true)]
[string]$repoUrl,
[Parameter(Mandatory = $true)]
[string[]]$subfolderList
)
$repoUrl = $repoUrl.Replace('\', '/')
$origWorkDir = Get-Location
git clone -n --depth=1 --filter=tree:0 $repoUrl
$repoName = Split-Path -Leaf $repoUrl
Set-Location $repoName
$sparseCheckoutCmd = "git sparse-checkout set --no-cone"
for ($idx = 0; $idx -lt $subfolderList.Length; $idx++) {
$subfolderList[$idx] = $subfolderList[$idx].Replace('\', '/')
$subfolderList = $subfolderList.Trim('/')
$sparseCheckoutCmd += " /$($subfolderList[$idx])/"
}
Invoke-Expression $sparseCheckoutCmd
git checkout
Set-Location $origWorkDir
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment