Functions/Compare-GitTree.ps1
# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Compare-GitTree { <# .SYNOPSIS Gets a diff of the file tree changes in a repository between two commits. .DESCRIPTION The `Compare-GitTree` function returns a `LibGit2Sharp.TreeChanges` object representing the file tree changes in a repository between two commits. The tree changes are the names of the files that have been added, removed, modified, and renamed in a git repository. Pass the name of commits to diff, such as commit hash, branch name, or tag name, to the `ReferenceCommit` and `DifferenceCommit` parameters. You must specify a commit reference name for the `ReferenceCommit` parameter. The `DifferenceCommit` parameter is optional and defaults to `HEAD`. This function implements the `git diff --name-only` command. .EXAMPLE Compare-GitTree -ReferenceCommit 'HEAD^' Demonstrates how to get the diff between the default `HEAD` commit and its parent commit referenced by `HEAD^`. .EXAMPLE Compare-GitTree -RepoRoot 'C:\build\repo' -ReferenceCommit 'tags/1.0' -DifferenceCommit 'tags/2.0' Demonstrates how to get the diff between the commit tagged with `2.0` and the older commit tagged with `1.0` in the repository located at `C:\build\repo`. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [CmdletBinding(DefaultParameterSetName = 'RepositoryRoot')] [OutputType([LibGit2Sharp.TreeChanges])] param( [Parameter(ParameterSetName = 'RepositoryRoot')] [Alias('RepoRoot')] [string] # The root path to the repository. Defaults to the current directory. $RepositoryRoot = (Get-Location).ProviderPath, [Parameter(Mandatory = $true, ParameterSetName = 'RepositoryObject')] [LibGit2Sharp.Repository] $RepositoryObject, [Parameter(Mandatory = $true)] [string] # A commit to compare `DifferenceCommit` against, e.g. commit hash, branch name, tag name. $ReferenceCommit, [string] # A commit to compare `ReferenceCommit` against, e.g. commit hash, branch name, tag name. Defaults to `HEAD`. $DifferenceCommit = 'HEAD' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if ($RepositoryObject) { $repo = $RepositoryObject } else { $repo = Find-GitRepository -Path $RepositoryRoot -Verify if (-not $repo) { Write-Error -Message ('Unable to get diff between ''{0}'' and ''{1}''. See previous errors for more details.' -f $ReferenceCommit, $DifferenceCommit) return } } try { $oldCommit = $repo.Lookup($ReferenceCommit) $newCommit = $repo.Lookup($DifferenceCommit) if (-not $oldCommit) { Write-Error -Message ('Commit ''{0}'' not found in repository ''{1}''.' -f $ReferenceCommit, $repo.Info.WorkingDirectory) return } elseif (-not $newCommit) { Write-Error -Message ('Commit ''{0}'' not found in repository ''{1}''.' -f $DifferenceCommit, $repo.Info.WorkingDirectory) return } # use `,` to prevent unwrapping of enumerable TreeChanges type return , [PowerGit.Diff]::GetTreeChanges($repo, $oldCommit, $newCommit) } finally { if (-not $RepositoryObject) { Invoke-Command -NoNewScope -ScriptBlock { $repo.Dispose() } } } } |