Git

2.2.0

Common Git workflow helpers: branch maintenance, tagging, and repository synchronization.

Minimum PowerShell version

5.1

Installation Options

Copy and Paste the following command to install this package using PowerShellGet More Info

Install-Module -Name Git

Copy and Paste the following command to install this package using Microsoft.PowerShell.PSResourceGet More Info

Install-PSResource -Name Git

You can deploy this package directly to Azure Automation. Note that deploying packages with dependencies will deploy all the dependencies to Azure Automation. Learn More

Manually download the .nupkg file to your system's default download location. Note that the file won't be unpacked, and won't include any dependencies. Learn More

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 Clear-GitBranchesIncludingGone 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

Desktop Core

Dependencies

Release Notes

Git v2.2.0+sha.759f721

## [v2.2.0] - 2026-07-31

### Added

- `Clear-GitBranchesIncludingGone` (Alias `cgbi`) als duenner Wrapper um
 `Clear-GitBranches -IncludeGoneRemoteBranches`. Der Aufraeum-Fall nach
 einem Merge, bei dem die Forge den Remote-Branch bereits geloescht hat,
 ist der haeufigste — der lange Schalter war dafuer unnoetige Reibung.
 Der Wrapper implementiert nichts nach: `-ProtectedBranches`, `-PassThru`,
 `-WhatIf` und `-Confirm` gehen unveraendert an `Clear-GitBranches`.
- `Clear-GitBranches -ProtectedBranches <string[]>`: zusaetzliche
 Branch-Namen, die nie geloescht werden, zusaetzlich zum Default-Branch
 und zum aktuellen Branch. Vergleich per exaktem Namen, nicht per Muster.
- Private `Get-GitDefaultBranch`: loest den Default-Branch ueber
 `git symbolic-ref refs/remotes/origin/HEAD` auf, faellt auf
 `git config --get init.defaultBranch` zurueck (nur wenn der Branch lokal
 existiert) und schuetzt bei Unklarheit `main` **und** `master`.
 Ueberschutz statt Raten: ein zu viel geschuetzter Branch kostet einen
 Handgriff, ein falsch geratener kostet den Default-Branch.
- Manifest-Invarianten-Test, der die `[Alias()]`-Attribute unter
 `src/Git/Public/` einsammelt und gegen `AliasesToExport` beider
 Manifeste sowie gegen die real exportierten Aliase prueft. Drift wird
 damit ein roter Test statt einer stillen Luecke.

### Changed

- **Schutz-Logik zentralisiert.** Die vier Detection-Funktionen liefern
 jetzt **rohe** Kandidaten; saemtliche Default-Branch- und
 Current-Branch-Filter sind aus ihnen entfernt. `Clear-GitBranches`
 filtert die zusammengefuehrte Kandidatenliste an genau **einer** Stelle:
 Default-Branch(es), aktueller Branch und `-ProtectedBranches`, jeweils
 per exaktem Namensvergleich. Vorher war der Schutz auf drei Funktionen
 mit je eigener, teils unverankerter Regex verteilt.
- `RequiredModules`-Pin `Execution` von `>= 5.1.0` auf `>= 5.6.0`
 angehoben — die Display-Writer (`Write-Ok`, `Write-Header`, `Write-Item`,
 `Write-Dim`) landen dort.
- `Clear-GitBranches` schreibt seine Statusausgabe ueber die
 Execution-Display-Writer statt ueber `Write-Host`: `Write-Header` vor der
 Kandidatenliste, `Write-Item` je Kandidat, `Write-Ok` je geloeschtem
 Branch (mit dem Branchnamen statt der git-Rohtextzeile) und `Write-Dim`
 fuer "No merged branches were found.". `Write-Warning` beim kaputten
 HEAD-Resolve bleibt `Write-Warning` — eine Warnung ist kein Statusglyph.
 Der `-PassThru`-Datenpfad (`Git.BranchResult`) ist unveraendert.
- `Clear-GitBranches` loest das Schutz-Set vor der Detection auf und reicht
 es als `-ExcludeBranches` an `Get-RebasedAndSquashedBranches` durch. Das ist
 ein reiner Performance-Skip — dieser Helfer faellt pro Kandidat auf ein
 echtes `git merge --no-commit --no-ff` zurueck, und das fuer den
 Default-Branch zu fahren ist Arbeit, deren Ergebnis das Gate ohnehin
 verwirft. Das zentrale Gate bleibt die einzige Policy-Stelle und filtert
 die Gesamtliste unveraendert danach.
- Aliase werden als `[Alias('…')]`-Attribut an der jeweiligen
 Public-Funktion deklariert statt als `Set-Alias`-Block in `Git.psm1` und
 im `Prefix` von `build.psd1`. ModuleBuilder leitet `AliasesToExport` im
 gebauten Manifest daraus ab; der Alias steht damit neben der Funktion,
 die er benennt, und es gibt keine zweite Liste mehr, die driften kann.

### Removed

- `Write-Progress`-Block in `Clear-GitBranches` inklusive `try/finally`
 und `$index`/`$total`. Die Fortschrittsanzeige war bei einer
 per-Item-Bestaetigung nie sichtbar — toter Code.

### Fixed

- `Get-GitMergedOrRebasedBranches`: unverankertes `-notmatch '(master|main)'`
 verwarf legitime Branches wie `feature/mainpage` oder `masterfix`.
 Zusaetzlich verwarf `-notmatch [regex]::Escape($currentBranch)` auf dem
 Branch `feat` auch `feat-2`. Beide Filter sind entfernt; der aktuelle
 Branch wird per exaktem Vergleich uebersprungen.
- `Get-GitRemoteGoneBranches`: `-notmatch '^(master|main)'` ohne Ende-Anker
 liess `maintenance` und `main-old` still verschwinden. Filter entfernt.
- `Get-GitMergedBranches`: drei gestapelte `Where-Object`-Filter durch
 einmaliges Parsen ersetzt. Der `* `-Marker wird beim Parsen gestrippt,
 nicht durch einen Filter, der die ganze Zeile verwarf.
- `Get-RebasedAndSquashedBranches` wurde von `Clear-GitBranches`
 parameterlos aufgerufen, obwohl es `-ExcludeBranches` kennt — dadurch
 war `main`/`master` loeschbar, sobald der User nicht darauf stand. Das
 zentrale Gate schliesst die Luecke; der Parameter bleibt fuer Aufrufer
 mit eigener Policy erhalten.
- `git branch`-Pseudo-Refs (`(HEAD detached at …)`,
 `(no branch, rebasing …)`) werden beim Parsen verworfen statt als
 Loesch-Kandidat weitergereicht.
- Branches, die in einem zweiten Worktree ausgecheckt sind (`+ `-Marker),
 werden beim Parsen verworfen. `git branch -D` verweigert sie
 ("Cannot delete branch … used by worktree"), und weil der Loeschaufruf
 ohne `-IgnoreExitCode` laeuft, brach der komplette Loeschlauf mitten in
 der Schleife mit einem terminierenden Fehler ab. Das zentrale Gate kann
 das nicht abfangen, weil es nur den aktuellen Branch kennt.
- Tote Fehler-Wachen in allen `-IgnoreExitCode`-Aufrufen der Detection-
 Funktionen und in `Clear-GitBranches`. `Invoke-NativeCommand` setzt
 `Success = $true` fest, sobald `-IgnoreExitCode` gesetzt ist, weshalb
 `if (-not $result.Success)` nie ausloesen konnte; die Pruefungen laufen
 jetzt ueber `ExitCode`. Sichtbare Folgen: `Get-GitMergedBranches` reichte
 bei kaputtem HEAD die git-Fehlerzeile als Branch-Kandidaten `error:`
 weiter; ein real fehlgeschlagenes `git cherry` in
 `Get-RebasedAndSquashedBranches` galt als "keine Commits, also merged"
 statt in den dokumentierten Test-Merge-Fallback zu fallen; und
 `Clear-GitBranches` warf ausserhalb eines Repositories eine Exception,
 statt die vorgesehene Warnung auszugeben. Der Aufrufer-Vertrag steht
 jetzt in der Hilfe von `Invoke-Git`.
- **Stiller Datenverlust in `Update-GitAllBranches`.** `$isAncestor` las das
 Ergebnis von `git merge-base --is-ancestor` ueber `.Success`, das unter
 `-IgnoreExitCode` konstant `$true` ist — damit galt *jeder* Branch als
 Ancestor seines Upstreams. Ein nicht-aktueller, divergierter Branch nahm
 deshalb den Fast-Forward-Pfad, und dessen Compare-and-Swap-`git update-ref`
 lief durch, weil der erwartete Alt-Wert genau der lokale Stand war, den es
 gerade verwarf: der Branch wurde auf den Upstream-Stand gesetzt, die
 lokalen Commits hingen nur noch im Reflog. Ohne Warnung, mit einem
 `-PassThru`-Record `FastForward` / `Success`. Betroffen waren dieselben
 Fundstellen auch bei `:94` (Upstream-Ref), `:111` (lokaler Ref), `:163`
 (CAS-Wache) und `Update-GitBranch.ps1:43` (Upstream-Aufloesung, wo
 git-Fehlertext als Branchname an `git rebase` ging). Alle fuenf pruefen
 jetzt `ExitCode`.
- `Get-GitMergedOrRebasedBranches`: ein fehlgeschlagenes `git cherry` brach
 mit `break` die gesamte Suche ab; alle danach iterierten Branches wurden
 still nicht mehr geprueft. Jetzt `continue` — Skip pro Branch, konsistent
 mit `Get-RebasedAndSquashedBranches`.
- `build.ps1`: ModuleBuilder-Abhängigkeit unter `3.2.0` pinnen. Die
 Upstream-Release `ModuleBuilder 3.2.0` (2026-05-11) verwendet im eigenen
 `.psm1` PowerShell-7-only-Syntax (Ternär-Operator `?:`, Pipe-leading
 Whitespace), sodass `Import-Module` auf Windows PowerShell 5.1 schon mit
 Parser-Fehlern abbricht und die CI-Matrix `PowerShell (powershell)`
 jedes Mal rot läuft. Sowohl `Install-Module` als auch `Import-Module`
 nutzen jetzt `-MaximumVersion '3.1.9'`; der `Where-Object`-Filter vor
 `Install-Module` verhindert unnötige Reinstalls, wenn lokal bereits eine
 passende 3.1.x-Version vorhanden ist. Patch-Releases der 3.1.x-Schiene
 bleiben offen; der Pin wird zurückgezogen, sobald ModuleBuilder upstream
 einen Fix für den 5.1-Pfad veröffentlicht.

FileList

Version History

Version Downloads Last updated
2.2.0 (current version) 38 7/30/2026
2.1.1 1,441 5/6/2026
2.1.0 11 5/6/2026
2.0.0 41 5/6/2026
1.5.0 265 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 497 2/5/2020
1.3.2 2,658 5/9/2019
1.3.1 338 4/4/2019
1.3.0 163 3/29/2019
1.2.0 136 3/28/2019
1.1.0 195 3/18/2019
1.0.1 126 3/17/2019
1.0.0 33 3/17/2019
Show more