Git
2.0.0
Common Git workflow helpers: branch maintenance, tagging, and repository synchronization.
Minimum PowerShell version
5.1
Installation Options
Owners
Copyright
(c) 2026 mtb.me. All rights reserved.
Package Details
Author(s)
- Manuel
Tags
Git Branch Tag Workflow PowerShell Windows
Functions
Add-AssumedUnchanged Add-GitTag Clear-GitBranches Invoke-Gitk Invoke-GitkAll Merge-GitAllRemoteBranches Merge-GitBranchUseTheirs Push-GitAllTrackedBranches Remove-AssumedUnchanged Remove-GitAllBranches Reset-GitAllBranches Set-GitTrackAllRemoteBranches Set-GitTrackMatchedRemoteBranches Update-GitAllBranches Update-GitBranch
PSEditions
Dependencies
-
- Execution (>= 5.1.0)
Release Notes
Git v2.0.0+sha.9c72bc1
## [v2.0.0] - 2026-05-06
Major rewrite. Drops the `Common` and `SmartLogging` runtime
dependencies, migrates every native git invocation to
`Invoke-NativeCommand` from `Execution v5.1`, replaces the legacy
`$Host.UI.PromptForChoice(...)` confirmation pattern with
`SupportsShouldProcess`, fixes ten concrete bugs from the v1.x code,
and ships a ModuleBuilder-driven build pipeline with CI and a Pester
test suite. See the migration notes in [README.md](README.md) before
upgrading.
### Added
- `build.ps1` at repo root: ModuleBuilder pipeline with
CHANGELOG-driven version derivation, BOM-less UTF-8 normalization
of built artifacts, optional `-Sign` (Authenticode against
`$env:GIT_SIGN_THUMBPRINT`) and optional `-Publish` to PSGallery.
`-Publish` is gated on a populated `[Unreleased]`-empty CHANGELOG
and a manifest version strictly greater than the latest PSGallery
entry. (#1)
- GitHub Actions CI at `.github/workflows/test.yml`. Builds, then
runs `Test-ModuleManifest`, `Import-Module`, PSScriptAnalyzer
(against source) and Pester (against the built artifact). Matrix:
`windows-latest × {powershell, pwsh}`. (#1)
- Pester 5.x test suite under `tests/`. 46 tests covering the 15
Public functions, the `Invoke-Git` wrapper contract,
`Reset-GitAllBranches` confirm-propagation through the three
composed Public calls, and the cross-cutting manifest invariants.
- `Invoke-Git` private wrapper (`src/Git/Private/Invoke-Git.ps1`).
Single funnel for every git invocation in the module. Two reasons:
cross-module preference scoping (`-Confirm:$false` / `-WhatIf:$false`
pinned on the inner call so the user-facing confirmation gate lives
at the Public-function boundary, never on the bare git invocation -
PowerShell does not propagate Confirm/WhatIf preferences across
module SessionState), and PowerShell's prefix-match defenses
(`Invoke-Git` is intentionally NOT `[CmdletBinding()]` so that
`-D` for `git branch -D` does not bind to `-Debug` and so that `-a`,
`-t`, `-b`, `-s` etc. land in `$args` cleanly). (#1)
- `Invoke-Gitk` / `Invoke-GitkAll`: `-NoWait` forwarding so `gk` /
`gka` no longer block the prompt while the GUI is open. Extra
arguments forwarded via `[Parameter(ValueFromRemainingArguments)]`. (#1)
- `Update-GitBranch`: rebase-failure now emits a `Write-Warning` with
recovery instructions ("Resolve conflicts and run
`git rebase --continue`, or abort with `git rebase --abort`") before
re-throwing, so the user does not have to consult docs after a
conflict. (#1)
- `Set-StrictMode -Version Latest` compliance throughout the module:
defensive `@()`-wrapping of native-command results, explicit
null-initialization before conditional blocks, parameter-set
declarations on `Merge-GitAllRemoteBranches`. (#1)
- `MIT LICENSE`, `README.md`, `CHANGELOG.md`, `.gitignore`.
### Changed (BREAKING)
- `RequiredModules`: `Common` and `SmartLogging` are removed. The only
remaining runtime dependency is `Execution >= 5.1.0` (pinned, no
upper bound). Consumers that imported `Common` or `SmartLogging`
transitively via `Git` must now import them explicitly. (#1)
- `Merge-GitAllRemoteBranches`: parameter renamed from `-Strategie`
(German typo) to `-Strategy`. No compatibility alias. Callers
passing `-Strategie` need to update. (#1)
- `Merge-GitAllRemoteBranches`: `-UseTheirs` and `-UseOurs` are now
mutually exclusive via parameter sets (`Default` / `Theirs` /
`Ours`). Passing both raises a parameter-set-resolution error
rather than silently picking one. (#1)
- `Clear-GitBranches`, `Add-AssumedUnchanged`, `Remove-AssumedUnchanged`:
replace the legacy `$Host.UI.PromptForChoice(...)` confirmation
pattern with standard `[CmdletBinding(SupportsShouldProcess,
ConfirmImpact = 'High')]` plus per-item `$PSCmdlet.ShouldProcess(...)`.
Behaviour change for direct interactive use: prompts now appear per
branch / per file rather than batch. The standard `[A]ll` answer at
the confirm prompt accepts all remaining items in one keystroke.
Trade-off: `-WhatIf`, `-Confirm:$false`, `$ConfirmPreference` and
`Invoke-StubScript` preference-forwarding now work where they did
not before. (#1)
- All other state-changing Public functions (`Remove-GitAllBranches`,
`Reset-GitAllBranches`, `Update-GitAllBranches`, `Update-GitBranch`,
`Push-GitAllTrackedBranches`, `Merge-*`, `Set-GitTrack*`) gain
`SupportsShouldProcess` with appropriate `ConfirmImpact`. They now
honour `-WhatIf` and `-Confirm:$false` cleanly. (#1)
- Build output moves to `_build/Git/` (was no build pipeline
previously). Distribution / installation should target the built
form (`Import-Module ./_build/Git/Git.psd1`); source-form
`Import-Module ./src/Git/Git.psd1` still works for fast development
iteration. (#1)
### Changed
- All `Start-NativeExecution`-based and bare-`git`-based command
invocations migrated to `Invoke-NativeCommand` from `Execution v5.1`
(via the local `Invoke-Git` wrapper). Backend selection is automatic:
ScriptBlock for status / state-change calls (faster), Process for
`Invoke-Gitk` (`-NoWait` GUI). `$LASTEXITCODE`-checking is replaced
by the wrapper's exit-code surfacing combined with per-function
`$ErrorActionPreference = 'Stop'`. (#1)
- All `| Out-Null` suppressions replaced with `> $null` for
parser-level performance (3-5x faster on PS 5.1, ~2x on PS 7) and
consistency with `ww3d/execution`. Includes both source and Pester
test files. (#2)
- `New-GitTempBranchName` (private helper) renamed to
`Get-GitTempBranchName`. Semantically more correct (returns a
string, does not mutate state) and sidesteps an instability with
`PSScriptAnalyzer`'s `PSUseShouldProcessForStateChangingFunctions`
rule on the `windows-latest` pwsh runner. (#1)
- `Push-GitAllTrackedBranches`, `Update-GitAllBranches`,
`Merge-GitAllRemoteBranches`, `Merge-GitBranchUseTheirs`,
`Remove-GitAllBranches`: working-tree restoration is now wrapped in
`try/finally`. An interrupted multi-branch operation always returns
the user to their original branch. Cleanup steps in `finally` are
best-effort (each wrapped in its own `try/catch + Write-Debug`) so
a cleanup failure cannot mask the original in-flight error. (#1)
- Public/Private folder split with dot-sourcing loader. 15 Public
functions under `src/Git/Public/`, 8 Private helpers under
`src/Git/Private/`. Source `.psm1` is the loader; the built `.psm1`
is concatenated by ModuleBuilder. (#1)
- All Public functions get `[CmdletBinding()]`, `[OutputType()]` and
comment-based help with realistic `.EXAMPLE` entries. (#1)
- `# SIG #` Authenticode signature blocks removed from `Git.psd1`
and `Git.psm1`. Source files are no longer signed; only the built
artifact is, via `build.ps1 -Sign`. (#1)
### Fixed
- `Update-GitBranch`: called undefined `Print-Warning`. Replaced with
`Write-Warning`. Plus: redundant `for-each-ref` loop removed. The
upstream ref was already resolved by
`git rev-parse --abbrev-ref @{upstream}`; the loop both was an
unnecessary O(n) and had a real correctness bug - it iterated
upstreams of all local branches instead of confirming the current
upstream's existence, so the rebase silently skipped when the
current branch was the only tracker of its upstream. (#1)
- `Clear-GitBranches`: `$remoteGoneBranches` was conditionally
initialized but unconditionally referenced (StrictMode crash). Now
initialized to `@()` ahead of the conditional. Plus: branch-list
concatenation is now defensively `@()`-wrapped per operand to
handle the single-element collapse case (PowerShell `+` between
two arrays where one is collapsed to a scalar by single-element
auto-unwrapping). (#1)
- `Add-GitTag`: doubled assignment `$shortSha = $shortSha = ...`.
Trivial typo, dropped. (#1)
- `Set-GitTrackAllRemoteBranches` / `Set-GitTrackMatchedRemoteBranches`:
parameter casing inconsistency (`$RemoteRefs` declared,
`$remoteRefs` referenced in body). Normalized to `$RemoteRefs`. (#1)
- `Get-Distincted`: over-engineered with `[HashSet[Object]]` and a
jagged `[object[][]]` parameter type. Replaced with
`Where-Object { $_ } | Select-Object -Unique`; parameter type fixed
to `[string[]]`. (#1)
- `Get-GitMergedBranches`, `Get-GitRemoteGoneBranches`: returned
implicit `$null` on error paths (StrictMode crash for callers).
Now `return @()`. (#1)
- `Update-GitBranch`: iterated captured native-command result without
null-check (StrictMode crash on empty output). Now `@()`-wrapped.
Pattern applied consistently across the module. (#1)
- `$LASTEXITCODE` was silently ignored at roughly 90% of bare-`git`
call sites. Now centralised: `Invoke-NativeCommand` (via
`Invoke-Git`) raises a Write-Error on non-zero exit, combined with
per-function `$ErrorActionPreference = 'Stop'`. (#1)
- `Add-AssumedUnchanged` / `Remove-AssumedUnchanged`: `Get-Item`
crashed on non-existent paths with an unfriendly stack. Now typed
`catch [System.Management.Automation.ItemNotFoundException]`
produces a clean `WriteError` ("Path not found: ..."); other
exceptions (`Permission denied`, IO errors) `throw` with full
detail rather than being misattributed as "Path not found". (#1)
- `Get-RebasedAndSquashedBranches`: leaked merge state on Ctrl-C.
Now `try/finally`-wrapped per branch with a `MERGE_HEAD`-gated
`git merge --abort` in the `finally`. The `MERGE_HEAD` gate avoids
the "fatal: There is no merge to abort" stderr that Pester
surfaces as a `NativeCommandError` even with `-IgnoreExitCode`. (#1)
### Removed
- `RequiredModules`: `Common`, `SmartLogging`. (#1)
- The legacy `# SIG #` Authenticode signature blocks at the bottom of
`Git.psd1` and `Git.psm1`. (#1)
### Note on v1.x
The v1.x release history is not migrated into this changelog. The old
manifest's `ReleaseNotes` block was malformed (mixed bullet styles,
leading whitespace) and was discarded during the PR 1 refactor. The
v1.x packages remain on PSGallery as published; this changelog starts
fresh from v2.0.0.
FileList
Version History
| Version | Downloads | Last updated |
|---|---|---|
| 2.1.1 | 15 | 5/6/2026 |
| 2.1.0 | 9 | 5/6/2026 |
| 2.0.0 (current version) | 39 | 5/6/2026 |
| 1.5.0 | 262 | 4/25/2026 |
| 1.4.2 | 61,227 | 5/16/2024 |
| 1.4.1 | 22,218 | 3/9/2020 |
| 1.4.0 | 132 | 3/9/2020 |
| 1.3.3 | 494 | 2/5/2020 |
| 1.3.2 | 2,646 | 5/9/2019 |
| 1.3.1 | 335 | 4/4/2019 |
| 1.3.0 | 160 | 3/29/2019 |
| 1.2.0 | 134 | 3/28/2019 |
| 1.1.0 | 192 | 3/18/2019 |
| 1.0.1 | 123 | 3/17/2019 |
| 1.0.0 | 30 | 3/17/2019 |