bhylu.com

Advertisements

Git Sparse Checkout

Sparse checkout limits which tracked paths appear in a working tree. It does not remove their commits or turn ignored content into a backup strategy.

How it works

The lab records guides and data in separate directories, then uses cone-mode sparse checkout to keep the guides directory. We verify that the data file is absent from the working tree but still readable from HEAD. Top-level tracked files may remain present in cone mode; the rule is not an arbitrary glob filter.

Run the disposable lab

Use Windows PowerShell 5.1 or later and Git 2.28 or later. The reviewed CLI is Git for Windows 2.53.0.windows.2. These are PowerShell examples, not Git Bash commands. Save the download as sparse-checkout.ps1 in a separate empty learning folder and run it in a separate process: powershell -NoProfile -ExecutionPolicy Bypass -File .\sparse-checkout.ps1. The execution-policy option applies to that process, not your machine policy.

The script creates bhylu-git-sparse-checkout and refuses an existing folder. It supplies two fictional seed files and repository-local settings, then runs the lesson commands. The literal separator is quoted as '--' so PowerShell passes it through the guard. A guard function named git calls the real CLI and stops on unexpected failures; Expect-GitFailure checks deliberately refused operations. Child-process configuration isolates your personal Git settings. File transports are allowed only for owned local remotes; internet transports are disabled in this lab. No hosting account, Apache or MySQL service is required. There is no Git playground. Leave the generated folder for inspection; choose another empty parent to run again.

Download the complete sparse-checkout.ps1 lab

Example

sparse-checkout.ps1

# Bhylu Git lab: Sparse Checkout
# Run in a separate PowerShell process, in an empty learning folder.
# Existing lab folders are refused; nothing is pushed to an internet host.
$ErrorActionPreference = 'Stop'
$script:GitExe = (Get-Command git -CommandType Application | Select-Object -First 1).Source
$script:LabRoot = Join-Path (Get-Location) 'bhylu-git-sparse-checkout'
if (Test-Path -LiteralPath $script:LabRoot) { throw 'Lab folder already exists. Choose another empty parent folder.' }
New-Item -ItemType Directory -Path $script:LabRoot | Out-Null
$env:GIT_CONFIG_NOSYSTEM = '1'
$env:GIT_CONFIG_GLOBAL = Join-Path $script:LabRoot 'empty-global-config'
[IO.File]::WriteAllText($env:GIT_CONFIG_GLOBAL, '')
$env:GIT_TERMINAL_PROMPT = '0'
$env:GIT_EDITOR = 'true'
$env:GIT_SEQUENCE_EDITOR = 'true'
$env:GIT_AUTHOR_DATE = '2026-01-10T10:00:00+00:00'
$env:GIT_COMMITTER_DATE = $env:GIT_AUTHOR_DATE
function git {
    & $script:GitExe -c protocol.allow=never -c protocol.file.allow=always @args
    if ($LASTEXITCODE -ne 0) { throw "Git exited with code $LASTEXITCODE" }
}
function Expect-GitFailure {
    & $script:GitExe -c protocol.allow=never -c protocol.file.allow=always @args
    if ($LASTEXITCODE -eq 0) { throw 'Expected Git to refuse this operation' }
}
function Assert-Equal($Actual, $Expected) {
    if ((($Actual | Out-String).Trim()) -cne (($Expected | Out-String).Trim())) { throw "Expected [$Expected], got [$Actual]" }
}
function Write-LabFile([string]$Name, [string]$Text) {
    $target = [IO.Path]::GetFullPath((Join-Path (Get-Location) $Name))
    if (!$target.StartsWith($script:LabRoot + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { throw 'Path outside lab' }
    [IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($target)) | Out-Null
    [IO.File]::WriteAllText($target, ($Text.Replace('\n', "`n") + "`n"), (New-Object Text.UTF8Encoding($false)))
}
function New-LabRepo([string]$Name) {
    New-Item -ItemType Directory -Path $Name | Out-Null
    Push-Location $Name
    try {
        git init --initial-branch=main
        git config --local user.name 'Repair Lab'
        git config --local user.email 'repair@example.invalid'
        git config --local core.autocrlf false
        git config --local commit.gpgSign false
        git config --local tag.gpgSign false
        git config --local core.hooksPath (Join-Path $script:LabRoot 'empty-hooks')
        Write-LabFile 'notes.md' 'Inspect hinge'
        Write-LabFile 'tasks.txt' 'desk=open'
        git add '--' notes.md tasks.txt
        git commit -m 'Record initial repair plan'
    } finally { Pop-Location }
}
Push-Location $script:LabRoot
try {
    New-LabRepo 'desk'
    Set-Location desk
    Write-LabFile 'guides/inspection.txt' 'Read the inspection guide'
    Write-LabFile 'data/parts.txt' 'hinge=2'
    git add '--' guides data
    git commit -m 'Separate guide and parts data'
    git sparse-checkout init --cone
    git sparse-checkout set guides
    if (!(Test-Path guides/inspection.txt)) { throw 'Guide missing' }
    if (Test-Path data/parts.txt) { throw 'Expected omitted working file' }
    Assert-Equal (git show HEAD:data/parts.txt) @('hinge=2')
    git sparse-checkout disable
    Write-Output 'Verified: sparse-checkout'
} finally { Pop-Location }

Focus on the lesson commands

This excerpt omits the seed repository and guard helpers. Use the complete download to run it.

Lesson excerpt

Write-LabFile 'guides/inspection.txt' 'Read the inspection guide'
Write-LabFile 'data/parts.txt' 'hinge=2'
git add '--' guides data
git commit -m 'Separate guide and parts data'
git sparse-checkout init --cone
git sparse-checkout set guides
if (!(Test-Path guides/inspection.txt)) { throw 'Guide missing' }
if (Test-Path data/parts.txt) { throw 'Expected omitted working file' }
Assert-Equal (git show HEAD:data/parts.txt) @('hinge=2')
git sparse-checkout disable

Expected result

The selected guide remains on disk, the data working file is omitted and its committed content remains available.

The complete script ends with Verified: sparse-checkout only after its checks pass. Object IDs, temporary paths and progress output can differ.

Sparse checkout and partial clone solve different problems: one controls the working tree, while the other can defer object transfer under a supporting transport. This local lab does not claim a partial-clone network performance result.

Advertisements