git format-patch: patch-basierte Workflows ohne Pull Requests
AI generated
git
HEAD
Git · Patches · Workflow
git format-patch: Workflows ohne Pull Requests
Commits als versendbare Patch-Dateien statt als Merge Request

Nicht jedes Git-Projekt läuft über ein zentrales Forge mit Pull-Request-Oberfläche. git format-patch erzeugt aus einer Reihe von Commits versendbare Patch-Dateien, die Empfänger mit git am wieder zu vollständigen Commits zusammensetzen können, ganz ohne GitHub, GitLab oder ein anderes Web-Interface dazwischen. Dieser Artikel zeigt, wie sich Patch-Serien erzeugen, mit einem Cover Letter versehen, versionieren und über git send-email verschicken lassen, und wann sich dieser Workflow gegenüber Pull Requests tatsächlich lohnt.

11 Min. Lesezeit Git Patches

1. Grundidee: Commits als Patch-Dateien statt als Pull Request

Ein Pull Request ist im Kern ein Verweis auf zwei Branches, die auf einem zentralen Server verglichen werden. Diese zentrale Instanz existiert in vielen dezentral organisierten Projekten schlicht nicht, oder sie wird bewusst vermieden, etwa weil ein Projekt seit Jahrzehnten über eine Mailingliste organisiert ist und niemand die etablierten Abläufe einer eingespielten Beitrags- und Review-Kultur aufgeben möchte.

git format-patch löst diese Abhängigkeit von einer zentralen Instanz vollständig auf: Jeder Commit wird in eine eigenständige, textbasierte Datei umgewandelt, die alle nötigen Informationen enthält, um beim Empfänger wieder zu einem identischen Commit zu werden. Übertragen werden kann diese Datei über praktisch jeden Kanal, eine E-Mail, einen USB-Stick oder ein einfaches Dateiablage-System.

2. git format-patch: Aufbau der erzeugten Dateien

Ohne weitere Optionen erzeugt git format-patch für jeden Commit im angegebenen Bereich eine eigene Datei, benannt nach einer fortlaufenden Nummer und der aus der Commit-Betreffzeile abgeleiteten Kurzbeschreibung, etwa 0001-fix-cache-invalidation.patch. Jede dieser Dateien enthält die vollständigen E-Mail-Header mit Autor und Datum, die komplette Commit-Nachricht und den zugehörigen Diff im unified-diff-Format.

Als Bereich lässt sich entweder eine einzelne Commit-Referenz angeben, wodurch alle Commits seit diesem Punkt bis HEAD exportiert werden, oder ein expliziter Zwei-Punkt-Bereich zwischen zwei Commits. Die Option -o bestimmt dabei das Zielverzeichnis für die erzeugten Dateien, was sich gut eignet, um mehrere Serien sauber voneinander getrennt zu halten.


# Alle Commits seit dem Abzweigen von main als Patch-Dateien exportieren
git format-patch main --output-directory patches/

# Genau die letzten drei Commits exportieren
git format-patch -3

3. Eine Patch-Serie mit Cover Letter erzeugen

Bei mehreren zusammengehörigen Commits ist eine kurze, einleitende Beschreibung der gesamten Serie hilfreich, bevor der Empfänger jeden einzelnen Patch im Detail liest. Die Option --cover-letter erzeugt dafür automatisch eine zusätzliche Datei mit der Nummer 0000, die als Platzhalter für eine solche Zusammenfassung dient und vor dem Versand von Hand mit Motivation, Überblick und relevanten Hintergrundinformationen gefüllt werden sollte.

In Kombination mit -N beziehungsweise der automatisch aktivierten Nummerierung ab zwei Patches zeigt jede Datei zusätzlich an, um den wievielten Teil einer Gesamtserie es sich handelt, etwa [PATCH 2/5] in der Betreffzeile, was Empfängern sofort einen Überblick über Umfang und Position innerhalb der Serie gibt.


# Patch-Serie inklusive Cover-Letter-Datei erzeugen
git format-patch main --cover-letter --output-directory patches/

4. Patches per E-Mail versenden mit git send-email

Statt erzeugte Patch-Dateien manuell als Anhang zu versenden, was viele Mail-Clients durch automatische Umformatierung unbrauchbar macht, bindet git send-email direkt an einen konfigurierten SMTP-Server an und verschickt jede Patch-Datei als eigene, reine Text-E-Mail mit korrekt gesetzten Headern, sodass die enthaltenen Diffs beim Empfänger unverändert ankommen.

Die Konfiguration erfolgt einmalig über git config sendemail.smtpserver und die zugehörigen Zugangsdaten, danach genügt git send-email patches/*.patch, um eine gesamte Serie inklusive Cover Letter in der richtigen Reihenfolge und mit korrekt verketteten In-Reply-To-Headern als zusammenhängenden Thread zu verschicken.


# SMTP-Server einmalig konfigurieren
git config sendemail.smtpserver smtp.mironsoft.internal
git config sendemail.smtpserverport 587

# Gesamte Serie als zusammenhängenden E-Mail-Thread verschicken
git send-email --to=team@mironsoft.de patches/*.patch

5. Patch-Serien versionieren mit v2, v3 und Reroll-Count

Erhält eine bereits versendete Serie nach Rückmeldungen eine überarbeitete Fassung, wird sie üblicherweise nicht kommentarlos erneut verschickt, sondern klar als neue Version gekennzeichnet. Die Option --subject-prefix erlaubt es, das Standardpräfix PATCH in der Betreffzeile durch einen eigenen Text zu ersetzen, etwa PATCH v2, wodurch für alle Beteiligten sofort erkennbar wird, um welche Revision es sich handelt.

Noch komfortabler ist die Option -v, die direkt eine Versionsnummer entgegennimmt und sowohl das Präfix als auch die Dateinamen automatisch entsprechend anpasst, ohne dass ein eigener Präfix-Text manuell konstruiert werden muss. So bleibt für jede Revision einer Serie klar nachvollziehbar, welche Version tatsächlich vorliegt.


# Zweite Revision einer Patch-Serie erzeugen, Präfix und Dateinamen automatisch angepasst
git format-patch main -v2 --cover-letter --output-directory patches/

6. Serien miteinander vergleichen mit git range-diff

Wer eine zweite Version einer Patch-Serie prüft, möchte meist wissen, was sich seit der ersten Fassung inhaltlich tatsächlich verändert hat, statt jeden Patch erneut komplett von vorn zu lesen. git range-diff vergleicht dafür zwei Commit-Bereiche inhaltlich miteinander und markiert, welche Patches identisch geblieben sind, welche sich verändert haben und welche neu hinzukamen.

Für Reviewer einer neuen Version ist das der schnellste Weg, um sich ausschließlich auf die tatsächlichen Änderungen gegenüber der vorherigen Fassung zu konzentrieren, statt bei jeder Revision erneut die komplette Serie von Grund auf zu prüfen.


# Erste und zweite Version derselben Serie inhaltlich vergleichen
git range-diff main feature-v1 feature-v2

7. Empfängerseite: Patches prüfen und anwenden

Auf der Empfängerseite genügt für eine einzelne Datei oder ein Verzeichnis meist git am, um die Serie in vollständige Commits mit Original-Autor und Original-Datum zu verwandeln. Vor dem eigentlichen Anwenden lohnt sich häufig ein Blick mit git apply --check, das lediglich prüft, ob ein Patch sauber passen würde, ohne bereits irgendeine Änderung vorzunehmen.

Bei umfangreicheren Serien ist es üblich, die Patches zunächst in einem separaten, lokalen Test-Branch anzuwenden, dort die automatisierte Testsuite laufen zu lassen und erst danach über die Übernahme in den Hauptbranch zu entscheiden, ganz ähnlich wie bei einem Pull-Request-Merge, nur ohne das dazugehörige Web-Interface.


# Vor dem Anwenden prüfen, ob der Patch überhaupt sauber passt
git apply --check 0001-fix-cache-invalidation.patch

# In einem eigenen Test-Branch anwenden, um vor dem Merge zu testen
git checkout -b test-patch-serie main
git am patches/*.patch

8. Wann sich der patch-basierte Workflow gegenüber Pull Requests lohnt

Der patch-basierte Workflow zahlt sich vor allem dort aus, wo kein einzelnes, zentrales Forge alle Beteiligten verbindet, etwa bei Projekten mit mehreren unabhängigen Mirror-Repositories, bei Beiträgen über instabile oder eingeschränkte Internetverbindungen, oder wenn Beitragende aus rechtlichen oder organisatorischen Gründen keinen Account bei einem bestimmten Anbieter anlegen können oder wollen.

Für ein typisches, zentral über GitLab organisiertes Magento- oder Web-Projekt mit einem festen Team ist der Aufwand dagegen selten gerechtfertigt, weil Pull Requests dort Inline-Kommentare, automatische CI-Läufe und eine niedrigere Einstiegshürde für neue Teammitglieder bieten, die ein reiner E-Mail-Workflow nicht ohne Weiteres nachbilden kann.

9. Praktische Stolperfallen und Checkliste für den Einstieg

Die häufigste Fehlerquelle ist ein Mail-Client, der reinen Text automatisch in HTML umwandelt und dabei Zeilenumbrüche oder Einrückungen des Diffs verändert, wodurch der Patch beim Empfänger nicht mehr sauber anwendbar ist. Wer keinen textbasierten Mail-Client oder git send-email verwenden kann, sollte Patches deshalb möglichst als reine Textanhänge versenden, nicht als eingebetteten Nachrichtentext.

Eine weitere häufige Stolperfalle ist eine unklare Reihenfolge bei mehrteiligen Serien: Ohne konsistente Nummerierung und Cover Letter ist für Empfänger oft nicht sofort ersichtlich, in welcher Reihenfolge die Patches angewendet werden müssen. Konsequente Nutzung von --cover-letter und automatischer Nummerierung vermeidet dieses Problem von vornherein zuverlässig.

Aspekt Pull Request format-patch-Workflow Empfehlung
Zentrale Instanz nötig Ja, ein Forge wie GitLab Nein, beliebiger Übertragungsweg format-patch bei fehlendem Forge
Inline-Kommentare im Web Ja, eingebaut Nein, nur per E-Mail-Antwort Pull Request für Web-Review
Automatische CI-Läufe Meist eingebaut Nur mit zusätzlicher Infrastruktur Pull Request bei aktivem CI-Bedarf
Funktioniert offline vorbereitbar Eingeschränkt Ja, vollständig format-patch bei instabiler Anbindung
Versionierung einer Serie Force-Push auf denselben Branch Eigene v2, v3 Dateien und Threads format-patch für nachvollziehbare Historie

Mironsoft

Git-Workflows, Branching-Strategien und CI-Hooks

Chaotische Git-Historie und unklare Branching-Regeln im Team?

Wir richten saubere Git-Workflows ein, klären Branching-Strategien fürs Team und automatisieren Qualitätschecks über Git-Hooks und CI-Pipelines, damit die Historie nachvollziehbar bleibt.

Workflow-Audit

Bestehende Branching-Strategie und Merge-Praxis auf Schwachstellen prüfen.

Hook-Automatisierung

Pre-Commit- und Pre-Push-Hooks für Linting, Tests und Commit-Konventionen einrichten.

Team-Schulung

Rebase, Cherry-Pick und Konfliktauflösung im Team praxisnah vermitteln.

10. Zusammenfassung

format-patch-Workflow

Grundprinzip

git format-patch wandelt Commits in versendbare Textdateien um, die der Empfänger mit git am wieder zu Commits zusammensetzt.

Serie mit Kontext

Mit --cover-letter entsteht eine zusätzliche Übersichtsdatei, die Motivation und Umfang der gesamten Serie erklärt.

Versand

git send-email verschickt Patches als korrekt formatierte Text-E-Mails, ohne die Zeilenumbrüche des Diffs zu zerstören.

Revisionen vergleichen

git range-diff zeigt inhaltlich, was sich zwischen zwei Versionen einer Serie tatsächlich geändert hat.

11. FAQ: format-patch-Workflow

1Was macht git format-patch genau?
Es wandelt eine Reihe von Commits in einzelne, versendbare Textdateien um, die alle nötigen Informationen enthalten, um beim Empfänger mit git am wieder zu identischen Commits zu werden.
2Wie erzeuge ich eine Übersichtsdatei für eine ganze Patch-Serie?
Mit der Option --cover-letter erzeugt git format-patch zusätzlich eine Datei mit der Nummer 0000, die vor dem Versand von Hand mit Motivation und Überblick über die Serie gefüllt werden sollte.
3Wie verschicke ich eine Patch-Serie, ohne dass Mail-Clients den Diff beschädigen?
Mit git send-email, das direkt an einen konfigurierten SMTP-Server anbindet und jede Patch-Datei als korrekt formatierte, reine Text-E-Mail verschickt, ohne die Zeilenumbrüche zu verändern.
4Wie kennzeichne ich eine überarbeitete Version einer bereits versendeten Serie?
Mit der Option -v gefolgt von einer Versionsnummer, etwa -v2, passt git format-patch sowohl das Präfix in der Betreffzeile als auch die Dateinamen automatisch entsprechend an.
5Wie vergleiche ich zwei Versionen derselben Patch-Serie inhaltlich?
Mit git range-diff, das zwei Commit-Bereiche inhaltlich gegenüberstellt und anzeigt, welche Patches unverändert geblieben sind, welche sich verändert haben und welche neu hinzugekommen sind.
6Wie wende ich eine empfangene Patch-Serie als Empfänger an?
Meist genügt git am, das aus den Patch-Dateien vollständige Commits mit Original-Autor und Original-Datum rekonstruiert. Vorab kann git apply --check prüfen, ob die Patches überhaupt sauber passen würden.
7Wann lohnt sich der patch-basierte Workflow gegenüber einem klassischen Pull Request?
Vor allem, wenn kein zentrales Forge alle Beteiligten verbindet, bei instabilen Internetverbindungen oder wenn Beitragende aus organisatorischen Gründen keinen Account bei einem bestimmten Anbieter nutzen können oder wollen.
8Was ist die häufigste Fehlerquelle beim Versand von Patches per E-Mail?
Mail-Clients, die reinen Text automatisch in HTML umwandeln und dabei Zeilenumbrüche oder Einrückungen des Diffs verändern, wodurch der Patch beim Empfänger nicht mehr sauber anwendbar ist.
9Wie stelle ich sicher, dass Empfänger die richtige Reihenfolge einer mehrteiligen Serie erkennen?
Durch konsequente Nutzung von --cover-letter zusammen mit der automatischen Nummerierung, die jede Datei und jede Betreffzeile mit der Gesamtzahl und Position innerhalb der Serie versieht.
10Kann ich patch-basierte Workflows und Pull Requests im selben Projekt kombinieren?
Ja, viele Teams nutzen Pull Requests für den regulären Alltag und greifen nur für externe Beiträge ohne Forge-Zugang oder für Offline-Situationen auf format-patch und git am zurück.