Functions/Restore-GitItem.ps1
function Restore-GitItem { <# .SYNOPSIS Restore working tree files. .DESCRIPTION Restore specified paths in the working tree with some contents from a restore source. If a path is tracked but does not exist in the restore source, it will be removed to match the source. Use the `Force` switch to remove any uncommitted/unstaged changes during the checkout. Otherwise, the update will fail. This function implements the `git restore` command. .INPUTS PSGitHub.PullRequest. You can pipe in the output of PSGitHub's Get-GitHubPullRequest. #> [CmdletBinding()] param( # Specifies which git repository to update. Defaults to the current directory. [string] $RepoRoot = (Get-Location).ProviderPath, # A revision can be a specific commit ID/sha (short or long), branch name, tag name, etc. # Go to https://git-scm.com/docs/gitrevisions for full documentation on Git's revision syntax. [Parameter(ValueFromPipelineByPropertyName)] [Alias('FriendlyName')] [Alias('HeadRef')] # PSGitHub.PullRequest [Alias('Sha')] [string] $Source = 'HEAD', [Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName, ValueFromRemainingArguments)] [Alias('FullName')] [ValidateNotNullOrEmpty()] [string[]] $Path, # Specifying -Staged will only restore the index. Specifying both restores both. [Parameter(Mandatory)] [switch] $Staged, # TODO # Specify the restore location. If neither option is specified, by default the working tree is restored. [Parameter(Mandatory)] [switch] $Worktree, # TODO # Remove any uncommitted changes when checking out/updating to `Revision`. [Switch] $Force ) Set-StrictMode -Version 'Latest' $repo = Find-GitRepository -Path $RepoRoot -Verify if (-not $repo) { return } $cancel = $false try { $checkoutOptions = [LibGit2Sharp.CheckoutOptions]::new() $checkoutOptions.OnCheckoutNotify = { param([string]$Path, [LibGit2Sharp.CheckoutNotifyFlags]$NotifyFlags) Write-Information "$($NotifyFlags): $Path" return -not $cancel -and -not $PSCmdlet.Stopping } $checkoutOptions.OnCheckoutProgress = { param([string]$Path, [int]$CompletedSteps, [int]$TotalSteps) if ($ProgressPreference -ne 'SilentlyContinue' -and $TotalSteps -ne 0) { $progressParams = @{ Activity = 'Checking files out' } if ($TotalSteps -ne 0) { $progressParams.PercentComplete = (($CompletedSteps / $TotalSteps) * 100) } if ($Path) { $progressParams.Status = $Path } Write-Progress @progressParams } } if ($Force) { $checkoutOptions.CheckoutModifiers = [LibGit2Sharp.CheckoutModifiers]::Force } # If -Source is not specified, the default restore source for the working tree is the index, and the # default restore source for the index is HEAD. When both --staged and --worktree are specified, --source # must also be specified. if ($Index) { $sourceCommit = $repo.Lookup($Source) $Path | ForEach-Object { [LibGit2Sharp.TreeEntry]$entry = $sourceCommit[$_] $repo.Index.Add($entry.Target, $_, $entry.Mode) } } if ($Worktree) { # ??? } } finally { $cancel = $true $repo.Dispose() } } |