Einrichtung und Konfiguration
Projekte holen und erstellen
Grundlegende Snapshots
Branching und Merging
Projekte teilen und aktualisieren
Inspektion und Vergleich
Patching
Debugging
Externe Systeme
Server-Administration
Anleitungen
- gitattributes
- Konventionen der Kommandozeile
- Tägliches Git
- Häufig gestellte Fragen (FAQ)
- Glossar
- Hooks
- gitignore
- gitmodules
- Revisionen
- Submodule
- Tutorial
- Workflows
- Alle Anleitungen...
Administration
Plumbing-Befehle
- 2.35.1 → 2.52.0 keine Änderungen
-
2.35.0
2022-01-24
- 2.28.1 → 2.34.8 keine Änderungen
-
2.28.0
2020-07-27
- 2.23.1 → 2.27.1 keine Änderungen
-
2.23.0
2019-08-16
- 2.18.1 → 2.22.5 keine Änderungen
-
2.18.0
2018-06-21
- 2.17.0 → 2.17.6 keine Änderungen
-
2.16.6
2019-12-06
- 2.13.7 → 2.15.4 keine Änderungen
-
2.12.5
2017-09-22
- 2.1.4 → 2.11.4 keine Änderungen
-
2.0.5
2014-12-17
BESCHREIBUNG
Dieses Dokument versucht, einige der Workflow-Elemente niederzuschreiben und zu motivieren, die für git.git selbst verwendet werden. Viele Ideen sind allgemein anwendbar, obwohl der vollständige Workflow für kleinere Projekte mit weniger Beteiligten selten erforderlich ist.
Wir formulieren eine Reihe von Regeln zur schnellen Referenz, während der Text versucht, jede davon zu motivieren. Nehmen Sie sie nicht immer wörtlich; Sie sollten gute Gründe für Ihre Handlungen höher bewerten als Manpages wie diese.
GETRENNTE ÄNDERUNGEN
Als allgemeine Regel sollten Sie versuchen, Ihre Änderungen in kleine logische Schritte aufzuteilen und jeden davon zu committen. Sie sollten konsistent sein, unabhängig von späteren Commits funktionieren, die Test-Suite bestehen usw. Dies erleichtert den Überprüfungsprozess erheblich und die Historie ist für spätere Inspektion und Analyse, z. B. mit git-blame[1] und git-bisect[1], viel nützlicher.
Um dies zu erreichen, versuchen Sie, Ihre Arbeit von Anfang an in kleine Schritte aufzuteilen. Es ist immer einfacher, ein paar Commits zusammenzufassen, als einen großen Commit in mehrere aufzuteilen. Haben Sie keine Angst davor, unterwegs zu kleine oder unvollkommene Schritte zu machen. Sie können später immer noch zurückgehen und die Commits mit git rebase --interactive bearbeiten, bevor Sie sie veröffentlichen. Sie können git stash push --keep-index verwenden, um die Test-Suite unabhängig von anderen nicht committeten Änderungen auszuführen; siehe den ABSCHNITT BEISPIELE von git-stash[1].
BRANCHES VERWALTEN
Es gibt zwei Hauptwerkzeuge, die verwendet werden können, um Änderungen von einem Branch in einen anderen einzubinden: git-merge[1] und git-cherry-pick[1].
Merges haben viele Vorteile, daher versuchen wir, so viele Probleme wie möglich allein mit Merges zu lösen. Cherry-Picking ist immer noch gelegentlich nützlich; siehe "Nach oben mergen" unten für ein Beispiel.
Am wichtigsten ist, dass Merges auf Branch-Ebene funktionieren, während Cherry-Picking auf Commit-Ebene funktioniert. Das bedeutet, dass ein Merge die Änderungen von 1, 10 oder 1000 Commits mit gleicher Leichtigkeit übertragen kann, was wiederum bedeutet, dass der Workflow für eine große Anzahl von Mitwirkenden (und Beiträgen) viel besser skaliert. Merges sind auch leichter zu verstehen, da ein Merge-Commit ein "Versprechen" ist, dass alle Änderungen von allen seinen Eltern nun enthalten sind.
Natürlich gibt es einen Kompromiss: Merges erfordern ein sorgfältigeres Branch-Management. Die folgenden Unterabschnitte diskutieren die wichtigen Punkte.
Graduierung
Wenn ein Feature von experimentell zu stabil übergeht, "graduiert" es auch zwischen den entsprechenden Branches der Software. git.git verwendet die folgenden Integrations-Branches
-
maint verfolgt die Commits, die in die nächste "Wartungsversion" eingehen sollen, d.h. ein Update der zuletzt veröffentlichten stabilen Version;
-
master verfolgt die Commits, die in die nächste Veröffentlichung eingehen sollen;
-
next ist als Test-Branch für Themen gedacht, die auf Stabilität für master getestet werden.
Es gibt einen vierten offiziellen Branch, der etwas anders verwendet wird
-
seen (vom Maintainer gesehene Patches) ist ein Integrations-Branch für Dinge, die noch nicht ganz reif für die Aufnahme sind (siehe "Integrations-Branches" unten).
Jeder der vier Branches ist normalerweise ein direkter Nachfahre des darüber liegenden.
Konzeptionell gelangt das Feature in einen instabilen Branch (normalerweise next oder seen) und "graduiert" zu master für die nächste Veröffentlichung, sobald es als stabil genug erachtet wird.
Nach oben mergen
Die oben diskutierte "absteigende Graduierung" kann jedoch nicht durch tatsächliches absteigendes Mergen erfolgen, da dies alle Änderungen auf dem instabilen Branch in den stabilen mergen würde. Daher gilt:
Committen Sie Ihre Korrekturen immer in den ältesten unterstützten Branch, der sie benötigt. Mergen Sie dann (periodisch) die Integrations-Branches aufeinander.
Dies ergibt einen sehr kontrollierten Fluss von Korrekturen. Wenn Sie feststellen, dass Sie eine Korrektur in z. B. master angewendet haben, die auch in maint benötigt wird, müssen Sie sie (mit git-cherry-pick[1]) nach unten cherry-picken. Dies wird ein paar Mal vorkommen und ist kein Grund zur Sorge, es sei denn, Sie tun es sehr häufig.
Topic-Branches
Jedes nicht triviale Feature erfordert mehrere Patches zur Implementierung und kann im Laufe seines Lebens zusätzliche Fehlerbehebungen oder Verbesserungen erhalten.
Alles direkt auf den Integrations-Branches zu committen, führt zu vielen Problemen: Schlechte Commits können nicht rückgängig gemacht werden, daher müssen sie einzeln zurückgesetzt werden, was verwirrende Historien und weiteres Fehlerpotenzial erzeugt, wenn Sie vergessen, einen Teil einer Änderungsgruppe zurückzusetzen. Paralleles Arbeiten vermischt die Änderungen und schafft weitere Verwirrung.
Die Verwendung von "Topic-Branches" löst diese Probleme. Der Name ist ziemlich selbsterklärend, mit einer Einschränkung, die sich aus der obigen Regel "Nach oben mergen" ergibt
Erstellen Sie für jedes Thema (Feature, Bugfix, …) einen separaten Branch. Verzweigen Sie ihn vom ältesten Integrations-Branch, in den Sie ihn schließlich mergen möchten.
Viele Dinge können dann sehr natürlich erfolgen
-
Um das Feature/den Bugfix in einen Integrations-Branch zu bekommen, mergen Sie ihn einfach. Wenn sich das Thema inzwischen weiterentwickelt hat, mergen Sie erneut. (Beachten Sie, dass Sie es nicht unbedingt zuerst in den ältesten Integrations-Branch mergen müssen. Sie können beispielsweise zuerst einen Bugfix nach next mergen, ihm etwas Testzeit geben und ihn nach maint mergen, wenn Sie wissen, dass er stabil ist.)
-
Wenn Sie feststellen, dass Sie neue Features aus einem anderen Branch benötigen, um an Ihrem Thema weiterzuarbeiten, mergen Sie den anderen Branch in Ihr Thema. (Tun Sie dies jedoch nicht "nur aus Gewohnheit", siehe unten.)
-
Wenn Sie feststellen, dass Sie von einem falschen Branch abgewichen sind und ihn "in der Zeit zurückversetzen" möchten, verwenden Sie git-rebase[1].
Beachten Sie, dass der letzte Punkt mit den beiden anderen kollidiert: Ein Thema, das bereits woanders gemergt wurde, sollte nicht neu basisiert werden. Siehe den Abschnitt über die WIEDERHERSTELLUNG NACH UPSTREAM REBASE in git-rebase[1].
Wir möchten darauf hinweisen, dass das "gewohnheitsmäßige" (regelmäßige ohne wirklichen Grund) Mergen eines Integrations-Branches in Ihre Themen - und damit auch das regelmäßige Mergen von etwas Upstream in etwas Downstream - verpönt ist.
Führen Sie keine Merges nach Downstream durch, außer aus gutem Grund: Änderungen an der Upstream-API wirken sich auf Ihren Branch aus; Ihr Branch kann nicht mehr sauber nach Upstream gemergt werden; usw.
Andernfalls enthält das Thema, zu dem gemergt wurde, plötzlich mehr als eine einzelne (gut getrennte) Änderung. Die vielen daraus resultierenden kleinen Merges werden die Historie stark verunreinigen. Jeder, der später die Historie einer Datei untersucht, muss herausfinden, ob der Merge das sich entwickelnde Thema beeinflusst hat. Ein Upstream könnte sogar versehentlich in einen "stabileren" Branch gemergt werden. Und so weiter.
Wegwerf-Integration
Wenn Sie dem letzten Absatz gefolgt sind, werden Sie nun viele kleine Topic-Branches haben und sich gelegentlich fragen, wie sie interagieren. Vielleicht funktioniert das Ergebnis des Mergens sie sogar nicht? Aber andererseits wollen wir vermeiden, sie irgendwohin "stabiles" zu mergen, da solche Merges nicht einfach rückgängig gemacht werden können.
Die Lösung ist natürlich, einen Merge zu erstellen, den wir rückgängig machen können: in einen Wegwerf-Branch mergen.
Um die Interaktion mehrerer Themen zu testen, mergen Sie sie in einen Wegwerf-Branch. Sie dürfen niemals Arbeit auf einem solchen Branch basieren!
Wenn Sie sehr klar machen, dass dieser Branch direkt nach dem Testen gelöscht wird, können Sie diesen Branch sogar veröffentlichen, zum Beispiel um den Testern die Möglichkeit zu geben, damit zu arbeiten, oder anderen Entwicklern die Möglichkeit zu geben zu sehen, ob ihre laufende Arbeit kompatibel sein wird. git.git hat einen solchen offiziellen Wegwerf-Integrations-Branch namens seen.
Branch-Management für eine Veröffentlichung
Unter der Annahme, dass Sie den oben diskutierten Merge-Ansatz verwenden, müssen Sie bei der Veröffentlichung Ihres Projekts zusätzliche Branch-Management-Arbeiten durchführen.
Eine Feature-Veröffentlichung wird vom master-Branch erstellt, da master die Commits verfolgt, die in die nächste Feature-Veröffentlichung eingehen sollen.
Der master-Branch soll eine Obermenge von maint sein. Wenn diese Bedingung nicht erfüllt ist, dann enthält maint einige Commits, die nicht in master enthalten sind. Die von diesen Commits dargestellten Korrekturen werden daher nicht in Ihre Feature-Veröffentlichung aufgenommen.
Um zu überprüfen, ob master tatsächlich eine Obermenge von maint ist, verwenden Sie git log
git log master..maint
Dieser Befehl sollte keine Commits auflisten. Andernfalls wechseln Sie zu master und mergen maint hinein.
Nun können Sie mit der Erstellung der Feature-Veröffentlichung fortfahren. Wenden Sie ein Tag auf die Spitze von master an, das die Veröffentlichungsversion angibt
git tag -s -m "Git X.Y.Z" vX.Y.Z master
Sie müssen das neue Tag an einen öffentlichen Git-Server pushen (siehe "VERTEILTE WORKFLOWS" unten). Dies macht das Tag für andere verfügbar, die Ihr Projekt verfolgen. Der Push kann auch einen Post-Update-Hook auslösen, um Release-bezogene Elemente wie das Erstellen von Release-Tarballs und vorformatierten Dokumentationsseiten durchzuführen.
Ähnlich verhält es sich bei einer Wartungsversion, maint verfolgt die zu veröffentlichenden Commits. Daher taggen und pushen Sie in den obigen Schritten einfach maint anstelle von master.
Wartungs-Branch-Management nach einer Feature-Veröffentlichung
Nach einer Feature-Veröffentlichung müssen Sie Ihre Wartungs-Branches verwalten.
Wenn Sie weiterhin Wartungs-Fixes für die vor der letzten Feature-Veröffentlichung erstellte Feature-Veröffentlichung veröffentlichen möchten, müssen Sie einen weiteren Branch erstellen, um die Commits für diese vorherige Veröffentlichung zu verfolgen.
Dazu wird der aktuelle Wartungs-Branch auf einen anderen Branch kopiert, der mit der vorherigen Versionsnummer benannt ist (z. B. maint-X.Y.(Z-1), wobei X.Y.Z die aktuelle Veröffentlichung ist).
git branch maint-X.Y.(Z-1) maint
Der maint-Branch sollte nun auf den neu veröffentlichten Code fast-forwarded werden, damit Wartungs-Fixes für die aktuelle Veröffentlichung verfolgt werden können.
-
gitcheckoutmaint -
gitmerge--ff-onlymaster
Wenn der Merge fehlschlägt, weil es sich nicht um einen Fast-Forward handelt, ist es möglich, dass einige Fixes auf maint in der Feature-Veröffentlichung übersehen wurden. Dies geschieht nicht, wenn der Inhalt der Branches wie im vorherigen Abschnitt beschrieben überprüft wurde.
Branch-Management für next und seen nach einer Feature-Veröffentlichung
Nach einer Feature-Veröffentlichung kann der Integrations-Branch next optional zurückgespult und vom Tip von master unter Verwendung der verbleibenden Themen auf next neu aufgebaut werden.
-
gitswitch-Cnextmaster -
gitmergeai/topic_in_next1 -
gitmergeai/topic_in_next2 -
…
Der Vorteil davon ist, dass die Historie von next sauber sein wird. Zum Beispiel waren einige Themen, die in next gemergt wurden, anfangs vielversprechend, erwiesen sich aber später als unerwünscht oder verfrüht. In diesem Fall wird das Thema aus next zurückgesetzt, aber die Tatsache bleibt in der Historie, dass es einmal gemergt und zurückgesetzt wurde. Durch die Neuerstellung von next erhalten andere Inkarnationen solcher Themen eine saubere Weste, um es erneut zu versuchen, und eine Feature-Veröffentlichung ist ein guter Zeitpunkt dafür.
Wenn Sie dies tun, sollten Sie eine öffentliche Ankündigung machen, die besagt, dass next zurückgespult und neu aufgebaut wurde.
Der gleiche Zurückspul- und Neuaufbauprozess kann für seen erfolgen. Eine öffentliche Ankündigung ist nicht erforderlich, da seen ein Wegwerf-Branch ist, wie oben beschrieben.
VERTEILTE WORKFLOWS
Nach dem letzten Abschnitt sollten Sie wissen, wie man Themen verwaltet. Im Allgemeinen werden Sie nicht die einzige Person sein, die am Projekt arbeitet, daher müssen Sie Ihre Arbeit teilen.
Grob gesagt gibt es zwei wichtige Workflows: Merge und Patch. Der wichtige Unterschied besteht darin, dass der Merge-Workflow die vollständige Historie, einschließlich Merges, propagieren kann, während Patches dies nicht können. Beide Workflows können parallel genutzt werden: In git.git verwenden nur Subsystem-Maintainer den Merge-Workflow, während alle anderen Patches senden.
Beachten Sie, dass die Maintainer Beschränkungen auferlegen können, wie z. B. "Signed-off-by"-Anforderungen, die für alle zur Aufnahme eingereichten Commits/Patches gelten müssen. Konsultieren Sie die Dokumentation Ihres Projekts für weitere Informationen.
Merge-Workflow
Der Merge-Workflow funktioniert, indem Branches zwischen Upstream und Downstream kopiert werden. Upstream kann Beiträge in die offizielle Historie mergen; Downstream basieren ihre Arbeit auf der offiziellen Historie.
Es gibt drei Hauptwerkzeuge, die dafür verwendet werden können
-
git-push[1] kopiert Ihre Branches in ein Remote-Repository, normalerweise in eines, das von allen beteiligten Parteien gelesen werden kann;
-
git-fetch[1], das Remote-Branches in Ihr Repository kopiert; und
-
git-pull[1], das fetch und merge in einem Schritt durchführt.
Beachten Sie den letzten Punkt. Verwenden Sie git pull nicht, es sei denn, Sie möchten tatsächlich den Remote-Branch mergen.
Änderungen herauszubekommen ist einfach
git push <remote> <branch> und sagen Sie allen, wo sie von ihnen abrufen können.
Sie müssen die Leute immer noch auf andere Weise informieren, z. B. per E-Mail. (Git stellt git-request-pull[1] zur Verfügung, um vorformatierte Pull-Anfragen an Upstream-Maintainer zu senden, um diese Aufgabe zu vereinfachen.)
Wenn Sie nur die neuesten Kopien der Integrations-Branches erhalten möchten, ist es auch einfach, auf dem neuesten Stand zu bleiben
Verwenden Sie git fetch <remote> oder git remote update, um auf dem neuesten Stand zu bleiben.
Verzweigen Sie dann einfach Ihre Topic-Branches von den stabilen Remotes, wie oben erklärt.
Wenn Sie ein Maintainer sind und die Topic-Branches anderer Leute in die Integrations-Branches mergen möchten, senden sie Ihnen in der Regel eine entsprechende Anfrage per E-Mail. Eine solche Anfrage sieht so aus:
Please pull from
<URL> <branch>
In diesem Fall kann git pull das fetch und merge in einem Schritt durchführen, wie folgt.
git pull <URL> <branch>
Gelegentlich kann der Maintainer Merge-Konflikte erhalten, wenn er versucht, Änderungen von Downstream zu ziehen. In diesem Fall kann er Downstream bitten, den Merge durchzuführen und die Konflikte selbst zu lösen (vielleicht weiß er besser, wie er sie lösen kann). Dies ist einer der seltenen Fälle, in denen Downstream von Upstream mergen sollte.
Patch-Workflow
Wenn Sie ein Mitwirkender sind, der Änderungen in Form von E-Mails an Upstream sendet, sollten Sie wie gewohnt Topic-Branches verwenden (siehe oben). Verwenden Sie dann git-format-patch[1], um die entsprechenden E-Mails zu generieren (sehr empfehlenswert gegenüber manueller Formatierung, da dies das Leben des Maintainers erleichtert).
-
gitformat-patch-Mupstream..topic, um sie in vorformatierte Patch-Dateien umzuwandeln -
gitsend-email--to=<recipient> <patches>
Siehe die Manpages git-format-patch[1] und git-send-email[1] für weitere Nutzungshinweise.
Wenn Ihnen der Maintainer mitteilt, dass Ihr Patch nicht mehr auf das aktuelle Upstream angewendet werden kann, müssen Sie Ihr Thema neu basisieren (Sie können keinen Merge verwenden, da Sie keine Merges format-patchen können)
git pull --rebase <URL> <branch>
Sie können die Konflikte dann während des Rebase beheben. Vermutlich haben Sie Ihr Thema nicht anderweitig als per E-Mail veröffentlicht, so dass das Rebasieren kein Problem darstellt.
Wenn Sie eine solche Patch-Serie erhalten (als Maintainer oder vielleicht als Leser der Mailingliste, an die sie gesendet wurde), speichern Sie die E-Mails in Dateien, erstellen Sie einen neuen Topic-Branch und verwenden Sie git am, um die Commits zu importieren.
git am < patch
Eine erwähnenswerte Funktion ist der Drei-Wege-Merge, der helfen kann, wenn Sie Konflikte erhalten: git am -3 verwendet Indexinformationen aus den Patches, um die Merge-Basis zu ermitteln. Siehe git-am[1] für weitere Optionen.
GIT
Teil der git[1] Suite