diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index 506c4c35..e91eee92 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -1,119 +1,82 @@ [[_contributing_project]] -=== An einem Projekt mitarbeiten +=== In einem Projekt mitwirken (((contributing))) -Die größte Schwierigkeit bei der Beschreibung der Mitarbeit an einem Projekt besteht darin, dass es eine große Anzahl von Variationen gibt, wie dies geschehen kann. -Da Git sehr flexibel ist, bietet es den Menschen viele Möglichkeiten der Zusammenarbeit, und es ist problematisch zu beschreiben, wie Sie mitarbeiten sollten, da jedes Projekt ein bisschen anders ist. -Einige der variablen Größen dabei sind die Anzahl der aktiven Mitarbeiter, der gewählte Arbeitsablauf, Ihre Zugriffsrechte und möglicherweise eine externe Methode der Mitarbeit. - -Die erste variable Größe ist die Anzahl der aktiven Mitarbeiter - wie viele Nutzer steuern aktiv Code zu diesem Projekt bei und wie häufig? -In vielen Fällen gibt es zwei oder drei Entwickler mit ein paar Commits pro Tag, oder auch weniger bei irgendwie ruhenden Projekten. -Bei größeren Firmen oder Projekten kann die Anzahl der Entwickler in die Tausende reichen mit hunderten oder tausenden eingehenden Commits pro Tag. -Das ist deshalb von Bedeutung, da Sie mit einer wachsenden Anzahl von Entwicklern auch sicherstellen müssen, dass sich der Code problemlos anwenden lässt und leicht zusammengeführt werden kann. -Änderungen, die Sie übermitteln, können sich als überflüssig oder dysfunktional erweisen durch Beiträge, die inzwischen eingefügt wurden, während Sie noch an ihren Änderungen arbeiteten oder darauf warteten, dass diese geprüft oder angewendet werden. -Wie können Sie Ihren Code permanent auf dem neusten Stand halten und dafür sorgen, dass Ihre Commits gültig sind? - -Die nächste Variable ist der für das Projekt verwendete Arbeitsablauf. -Ist es ein zentralisierter Arbeitsablauf, in dem jeder Entwickler die gleichen Schreibrechte auf die Hauptentwicklungslinie hat? -Gibt es bei dem Projekt einen Projektbetreiber oder Integrationsmanager, der alle Patches prüft? -Werden die Patches durch eine bestimmte Gruppe oder öffentlich, z. B. durch die Community, geprüft? -Sind Sie selbst an diesem Prozess beteiligt? -Gibt es ein Leutnant-System und müssen Sie Ihre Arbeit zunächst an einen solchen übermitteln? - -Eine weiteres Thema sind ihre Commit-Zugriffsrechte. -Der erforderliche Arbeitsablauf, um Änderungen zu einem Projekt beizusteuern, ist ein ganz anderer, wenn Sie über Schreibrechte verfügen, als wenn das nicht der Fall ist. -Und wenn Sie keine Schreibrechte haben, in welcher Form müssen Sie ihre Änderungen bei diesem Projekt vorzugsweise übermitteln? -Gibt es dafür überhaupt eine Richtlinie? -Wie umfangreich sind die Änderungen, die Sie jeweils beisteuern? -Und wie häufig tun Sie das? - -All diese Aspekte haben Einfluss darauf, wie Sie effektiv an einem Projekt mitarbeiten können und welche Arbeitsabläufe bevorzugt werden oder verfügbar für Sie sind. -Wir werden verschiedene Aspekte davon in einer Reihe von Fallbeispielen betrachten, wobei wir mit simplen Beispielen anfangen und später komplexere Szenarios besprechen. Sie sollten in der Lage sein, anhand dieser Beispiele die spezifischen Arbeitsabläufe zu erstellen, die Sie in der Praxis benötigen. +Die Hauptschwierigkeit bei der Beschreibung, wie man an einem Projekt mitwirkt, sind die zahlreichen Varianten, wie man das machen könnte. Da Git sehr flexibel ist, können die Personen auf viele Arten zusammenarbeiten. Es ist nicht einfach zu beschreiben, wie Sie dazu beitragen sollen, da jedes Projekt ein wenig anders ist. Einige der wichtigen Unbekannten sind die Anzahl der aktiven Mitwirkenden, der ausgewählte Workflow, Ihre Zugriffsberechtigung und möglicherweise auch die Methode, wie externe Beiträge verwaltet werden sollen. + +Die erste Unbekannte ist die Anzahl der aktiven Mitwirkenden - wie viele Benutzer tragen aktiv Code zu diesem Projekt bei und wie oft? In vielen Fällen haben Sie zwei oder drei Entwickler mit ein paar Commits pro Tag oder möglicherweise weniger für etwas untätigere Projekte. Bei größeren Unternehmen oder Projekten kann die Anzahl der Entwickler in die Tausende gehen, wobei jeden Tag Hunderte oder Tausende von Commits getätigt werden können. Dies ist wichtig, da mit der Anzahl der Entwickler auch die Anzahl der zu lösenden Problemen steigt um ihren Code weiterhin ordnungsgemäß auszuführen oder um ihn einfach nur zusammenzuführen. Von Ihnen übermittelte Änderungen können durch Arbeiten, die während Ihrer Arbeit oder während Ihrer Änderungen genehmigt oder eingearbeitet wurden, veraltet sein oder schwer beschädigt werden. Wie können Sie Ihren Code konsistent auf dem neuesten Stand und Ihre Commits gültig halten? + +Die nächste Unbekannte ist der für das Projekt verwendete Workflow. Ist er zentralisiert, wobei jeder Entwickler den gleichen Schreibzugriff auf die Haupt Codelinie hat? Verfügt das Projekt über einen Betreuer oder Integrationsmanager, der alle Patches überprüft? Sind alle Patches von Fachleuten geprüft und genehmigt? Sind Sie in diesen Prozess involviert? Ist ein Leutnant System vorhanden und müssen Sie Ihre Arbeit zuerst bei Ihnen einreichen? + +Die nächste Unbekannte ist Ihr Zugriffsberechtigung. Der Workflow, der erforderlich ist, um zu einem Projekt beizutragen, unterscheidet sich erheblich, wenn Sie Schreibzugriff auf das Projekt haben, von dem, wenn Sie diesen nicht haben. Wenn Sie keinen Schreibzugriff haben, wie bevorzugt das Projekt die Annahme von beigetragener Arbeit? Gibt es überhaupt eine Strategie? Wie viel Arbeit steuern Sie auf einen Schlag bei? Wie oft tragen Sie etwas bei? + +All diese Fragen können sich darauf auswirken, wie Sie effektiv zu einem Projekt beitragen und welche Workflows bevorzugt oder überhaupt für sie verfügbar sind. Wir werden jeden dieser Aspekte in einer Reihe von Anwendungsfällen behandeln und von einfach zu komplex wechseln. Sie sollten in der Lage sein, anhand dieser Beispiele die spezifischen Workflows zu konstruieren, die Sie in der Praxis benötigen. [[_commit_guidelines]] -==== Richtlinien für Commits +==== Richtlinien zur Zusammenführung (Commit) -Bevor wir damit beginnen, spezifische Anwendungsfälle zu betrachten, hier noch eine kurze Anmerkung zu Commit-Nachrichten. -Ein gute Richtlinie für das Erzeugen von Commits zu haben und sich daran zu halten, macht die Arbeit mit Git und die Zusammenarbeit mit anderen um vieles leichter. -Das Git-Projekt stellt ein Dokument bereit, welches eine Reihe von guten Tipps für das Erzeugen von Commits zum Übermitteln von Patches beinhaltet. Sie können die Tipps in der Datei `Documentation/SubmittingPatches` im Git-Quellcode nachlesen. +Bevor wir uns mit den spezifischen Anwendungsfällen befassen, finden Sie hier einen kurzen Hinweis zu Commit-Nachrichten. Ein guter Leitfaden zum Erstellen von Commits und das Befolgen desselbigen, erleichtert die Arbeit mit Git und die Zusammenarbeit mit anderen erheblich. Das Git-Projekt selber enthält ein Dokument, in dem einige nützliche Tipps zum Erstellen von Commits für die Übermittlung von Patches aufgeführt sind. Sie finden diese Tipps im Git-Quellcode in der Datei `Documentation/SubmittingPatches`. (((git commands, diff, check))) -Als Erstes wollen Sie keinerlei Leerzeichenfehler übermitteln. -Git bietet eine einfache Möglichkeit, dies zu überprüfen - bevor Sie einen Commit vornehmen, führen Sie die Anweisung `git diff --check` aus, welche mögliche Leerzeichenfehler erkennt und für Sie auflistet. +Ihre Einsendungen sollten keine Leerzeichenfehler enthalten. Git bietet eine einfache Möglichkeit, dies zu überprüfen. Führen Sie vor dem Commit `git diff --check` aus, um mögliche Leerzeichenfehler zu identifizieren und diese für Sie aufzulisten. .Ausgabe von `git diff --check`. image::images/git-diff-check.png[Ausgabe von `git diff --check`.] -Wenn Sie diese Anweisung vor einem Commit ausführen, können Sie erkennen, ob Sie dabei sind, Leerzeichenfehler zu übermitteln, welche andere Entwickler verärgern könnten. +Wenn Sie diesen Befehl vor dem committen ausführen, können Sie feststellen, ob Leerzeichen Probleme auftreten, die andere Entwickler stören könnten. -Als Nächstes, versuchen Sie, aus jedem Commit einen logisch getrennten Satz von Änderungen zu machen. -Wenn Sie können, versuchen Sie, Ihre Änderungen leicht verdaulich zu machen - arbeiten Sie nicht ein ganzes Wochenende an fünf verschiedenen Themen und übermitteln Sie dann all diese Änderungen in einem massiven Commit am Montag. -Auch wenn Sie am Wochenende keine Commits durchführen, nutzen Sie am Montag die Staging Area, um Ihre Änderungen aufzuteilen in wenigstens einen Commit für jeden Teilaspekt mit jeweils einer sinnvollen Nachricht. -Wenn einige der Änderungen die selbe Datei modifizieren, benutzen Sie die Anweisung `git add --patch`, um Dateien partiell zur Staging Area hinzuzufügen (detailiert dargestellt im Abschnitt <<_interactive_staging>>). -Der Schnappschuss vom Projekt an der Spitze des Branches ist der Selbe, ob Sie einen oder fünf Commits durchgeführt haben, solange nur all die Änderungen irgendwann hinzugefügt werden. Versuchen Sie also, die Dinge zu vereinfachen für Ihre Entwicklerkollegen, die Ihre Änderungen begutachten müssen. +Versuchen Sie als Nächstes, für jeden Commit einen logisch separierten Änderungssatz festzulegen. Wenn möglich, versuchen Sie Ihre Änderungen gut verdaulich zu machen. Codieren Sie nicht ein ganzes Wochenende lang fünf verschiedene Themen und übermitteln Sie diese dann am Montag als ein einziges Commit. Auch wenn Sie am Wochenende keinen Commit durchführen, teilen Sie Ihre Arbeit am Montag in der Staging-Area in mindestens einen Commit pro Problem mit einer nützlichen Nachricht pro Commit auf. Wenn einige der Änderungen dieselbe Datei ändern, versuchen Sie `git add --patch` zu verwenden, um Dateien teilweise zu stagen (ausführlich beschrieben in <>). Der Projektschnappschuss an der Spitze des Branches ist identisch, unabhängig davon, ob Sie einen oder fünf Commits ausführen, solange alle Änderungen zu einem bestimmten Zeitpunkt hinzugefügt werden. Versuchen Sie daher, den Kollegen, die Ihre Änderungen überprüfen müssen, die Arbeit zu erleichtern. -Dieser Ansatz macht es außerdem einfacher, einen Satz von Änderungen zu entfernen oder rückgängig zu machen, falls das später nötig wäre. -<<_rewriting_history>> beschreibt eine Reihe nützlicher Git-Tricks zum Umschreiben des Verlaufs oder um interaktiv Dateien zur Staging Area hinzuzufügen. Verwenden Sie diese Werkzeuge, um einen sauberen und leicht verständlichen Verlauf aufzubauen, bevor Sie Ihre Arbeit jemand anderem schicken. +Dieser Ansatz erleichtert auch das Abholen oder Zurücksetzen eines der Änderungssätze, wenn Sie es später benötigen. <> beschreibt eine Reihe nützlicher Git-Tricks zum Umschreiben des Verlaufs und zum interaktiven stagen von Dateien. Verwenden Sie diese Tools, um einen sauberen und verständlichen Verlauf zu erstellen, bevor Sie die Arbeit an eine andere Person senden. -Ein weitere Sache, die Sie nicht vergessen sollten, ist die Commit-Nachricht. -Wenn man sich angewöhnt, aussagekräftige und hochwertige Commit-Nachrichten zu schreiben, ist die Benutzung von Git viel einfacher und es erleichtert die Zusammenarbeit. -In der Regel sollte Ihre Commit-Nachricht mit einer einzelnen Zeile anfangen, die nicht länger als 50 Zeichen sein sollte und die Änderungen kurz und bündig beschreibt, gefolgt von einer leeren Zeile, welcher eine ausführlichere Beschreibung der Änderungen folgt. -Das Git-Projekt fordert, dass die detailliertere Erklärung Ihre Motivation für die Änderungen beinhaltet und deren Implementierung dem vorhergehenden Verhalten gegenüberstellt. Das ist eine gute Richtlinie, an die man sich halten sollte. -Es empfiehlt sich außerdem, die Gegenwartsform des Imperativ in diesen Nachrichten zu benutzen. Mit anderen Worten, verwenden Sie Anweisungen. Anstatt „Ich habe Test hinzugefügt für“ oder „Tests hinzufügend für“ benutzen Sie „Füge Tests hinzu für“. -Hier ist ein https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[Muster, welches ursprünglich von Tim Pope stammt]: +Als letztes darf die Commit-Nachricht nicht vergessen werden. Macht man es sich zur Gewohnheit, qualitativ hochwertige Commit-Nachrichten zu erstellen, erleichtert dies die Verwendung und die Zusammenarbeit mit Git erheblich. In der Regel sollten Ihre Nachrichten mit einer einzelnen Zeile beginnen, die nicht länger als 50 Zeichen ist. Diese sollte ihre Änderungen kurz beschreiben. Darauf folgen eine leere Zeile und eine ausführliche Erläuterung. Für das Git-Projekt ist es erforderlich, dass die ausführliche Erläuterung Ihre Motivation für die Änderung enthält. Außerdem sollte das Ergebnis ihre Implementierung mit dem vorherigen Verhalten des Projekts verglichen wird. Dies ist eine gute Richtlinie, die befolgt werden sollte. +Schreiben Sie Ihre Commit-Nachricht im Imperativ: "Behebe das Problem" und nicht "Problem wurde behoben". +Hier ist eine https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[E-Mail-Vorlage, die ursprünglich von Tim Pope geschrieben wurde]: [source,text] ---- -Kurze (50 Zeichen oder weniger) Zusammenfassung der Änderungen +Kurzfassung der Änderung (50 Zeichen oder weniger) -Detailliert erklärender Text, wenn nötig. Beschränken Sie diesen auf -ca. 72 Zeichen. In Abhängigkeit vom Kontext wird die erste Zeile -manchmal wie die Betreff-Zeile einer E-Mail behandelt und der übrige -Text wie der Textkörper der Nachricht. Die leere Zeile, welche die -Zusammenfassung vom Text trennt, ist kritisch (außer Sie lassen den Text -komplett weg); Werkzeuge wie Rebase können durcheinander kommen, wenn -Sie beide gleichzeitig verwenden. +Gegebenenfalls ausführlicher, erläuternder Text. Pro Zeile etwa 72 +Zeichen. In einigen Kontexten wird die erste Zeile wie der Betreff einer +E-Mail gehandelt und der Rest des Textes als Textkörper. Die Leerzeile, +welche die Zusammenfassung vom Text trennt ist von entscheidender Bedeutung +(es sei denn, Sie lassen den Textkörper ganz weg). Werkzeuge wie rebase +können durcheinander kommen, wenn Sie diese Trennung nicht einhalten. -Weitere Absätze folgen jeweils nach leeren Zeilen. +Schreiben Sie Ihre Commit-Nachricht im Imperativ: "Behebe das Problem" und +nicht "Problem wurde behoben". Diese Konvention stimmt mit den durch +`git merge` und `git revert` generierten Commit-Nachrichten überein. -. Aufzählungspunkte kann man auch verwenden +Weitere Absätze folgen nach Leerzeilen. -* Typischer Weise nutzt man Bindestriche oder Sternchen - als Aufzählungszeichen, denen ein einzelnes Leerzeichen - vorangestellt wird, die einzelnen Punkte werden durch - leere Zeilen getrennt, die Konventionen variieren hier +- Aufzählungszeichen sind auch in Ordnung - einen hängenden Einzug benutzen ----- - -Wenn alle Ihre Commit-Nachrichten so aussehen, werden die Dinge für Sie und die Entwickler, mit denen Sie zusammenarbeiten, viel einfacher sein. -Das Git-Projekt selbst hat wohl-formatierte Commit-Nachrichten – führen Sie mal die Anweisung `git log --no-merges` aus, um zu sehen, wie ein angenehm formatierter Commit-Verlauf eines Projektes aussieht. +- In der Regel wird für das Aufzählungszeichen ein Bindestrich oder ein + Sternchen verwendet, gefolgt von einem Leerzeichen. Zwischen den einzelnen + Aufzählungen werden Leerzeilen eingefügt. Diese Konventionen variieren + jedoch. -In den folgenden Beispielen und fast überall in diesem Buch finden Sie der Kürze halber keine angenehm formatierten Meldungen wie diese. Stattdessen wird die Anweisung `git commit` zusammen mit der Option `-m` verwendet. -Also folgen Sie meinen Worten und nicht meinem Beispiel. +- Verwenden Sie einen hängenden Einzug +---- +Wenn alle ihre Commit-Nachrichten diesem Modell folgen, wird es für Sie und die Entwickler, mit denen Sie zusammenarbeiten, viel einfacher. Das Git-Projekt selber enthält gut formatierte Commit-Meldungen. Versuchen Sie, `git log --no-merges` auszuführen, um zu sehen, wie ein gut formatierter Commit-Verlauf des Projekts aussieht. [NOTE] -.Mach es wie wir sagen, nicht wie wir es tun. +.Tun sie das, was wir sagen und nicht das, was wir tun. ==== -Der Kürze halber haben viele der Beispiele in diesem Buch keine gut formatierten Commit-Nachrichten wie diese. Stattdessen verwenden wir einfach die Option `-m`, um `-m` auszuführen. +Der Kürze halber haben viele der Beispiele in diesem Buch keine gut formatierten Commit-Nachrichten. Stattdessen verwenden wir einfach die Option `-m`, um `git commit` auszuführen. -Kurz, mach es wie wir sagen, nicht wie wir es tun. +Kurz gesagt, tun Sie was wir sagen und nicht was wir tun. ==== [[_private_team]] -==== Privates kleines Team +==== Kleine, private Teams (((contributing, private small team))) -Das einfachste Szenario, dem Sie sehr wahrscheinlich begegnen werden, ist ein vertrauliches Projekt mit einem oder zwei Entwicklern. -„Private“ in diesem Zusammenhang bedeutet „closed source“ - nicht öffentlich zugänglich für die Außenwelt. -Sie und die anderen Entwickler haben alle Schreibzugriff auf das Repository. +Das einfachste Setup, auf das Sie wahrscheinlich stoßen werden, ist ein privates Projekt mit einem oder zwei anderen Entwicklern. Privat bedeutet in diesem Zusammenhang "closed source" - es ist für die Außenwelt nicht zugänglich. Sie und die anderen Entwickler haben alle Schreibzugriff (Push-Zugriff) auf das Repository. -Sie können sich in diesem Umfeld an einen Arbeitsablauf halten, den Sie genauso auch bei Subversion oder einem anderen zentralisierten System verwenden könnten. -Sie genießen dann immer noch die Vorteile von Dingen, wie Commits offline durchführen zu können und erheblich einfacher Branches anzulegen und zusammenzuführen, der Arbeitsablauf kann sehr ähnlich sein. Der Hauptunterschied ist, dass das Zusammenführen eher auf der Client-Seite stattfindet als auf dem Server beim Durchführen eines Commits. -Lassen Sie uns betrachten, wie es aussehen könnte, wenn zwei Entwickler damit beginnen, an einem gemeinsamen Repository zu arbeiten. -Der erste Entwickler, John, klont das Repository, nimmt eine Änderung vor und führt lokal einen Commit durch. -(Die Protokoll-Nachrichten wurden in diesen Beispielen durch `...` ersetzt, um das Ganze etwas zu kürzen.) +In dieser Umgebung können Sie einem Workflow folgen, der dem ähnelt, den Sie mit Subversion oder einem anderen zentralisierten System ausführen würden. Sie haben immer noch die Vorteile von Dingen wie Offline-Commit und ein wesentlich einfacheres Verzweigen (Branching) und Zusammenführen (Merging) Model, aber der Workflow kann sehr ähnlich sein. Der Hauptunterschied besteht darin, dass Merging zur Commit Zeit clientseitig stattfindet und nicht auf dem Server. Mal sehen, wie es aussehen könnte, wenn zwei Entwickler beginnen, mit einem gemeinsam genutzten Repository zusammenzuarbeiten. Der erste Entwickler, John, klont das Repository, nimmt eine Änderung vor und commitet es lokal. (Die Protokollnachrichten wurden in diesen Beispielen durch `...` ersetzt, um sie etwas zu verkürzen.) [source,console] ---- @@ -128,7 +91,7 @@ $ git commit -am 'remove invalid default value' 1 files changed, 1 insertions(+), 1 deletions(-) ---- -Die zweite Entwicklerin, Jessica, tut dasselbe. Sie klont das Repository, ändert etwas und führt einen Commit durch. +Der zweite Entwickler, Jessica, macht dasselbe -- sie klont das Repository und commitet eine Änderung: [source,console] ---- @@ -143,7 +106,7 @@ $ git commit -am 'add reset task' 1 files changed, 1 insertions(+), 0 deletions(-) ---- -Nun lädt Jessica ihre Arbeit auf den Server hoch: +Nun pusht Jessica ihre Änderungen zum Server. Das funktioniert problemlos: [source,console] ---- @@ -154,12 +117,9 @@ To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master ---- -Die letzte Zeile der obigen Ausgabe zeigt eine nützliche Rückmeldung aus aus der Push-Operation. -Das Ausgangsformat ist `.. fromref -> toref`, wobei `oldref` die alte Referenz bedeutet, `newref` die neue Referenz bedeutet, `fromref` der Name der zu verschiebenden lokalen Referenz ist und `toref` der Name der zu aktualisierenden Fernreferenz ist. -Sie werden ähnliche Ausgaben wie diese unten in den Diskussionsrunden sehen, so dass eine grundlegende Vorstellung der Bedeutung hilft, die verschiedenen Zustände der Repositorien zu verstehen. -Weitere Details finden Sie in der Dokumentation zu https://git-scm.com/docs/git-push[git-push]. +Die letzte Zeile der obigen Ausgabe zeigt eine nützliche Rückmeldung der Push Operation. Das Grundformat ist ` .. fromref -> toref`, wobei `oldref` die alte Referenz bedeutet, `newref` die neue Referenz bedeutet, `fromref` der Name der lokalen Referenz ist, die übertragen wird, und `toref` ist der Name der entfernten Referenz, die aktualisiert werden soll. Eine ähnliche Ausgabe finden Sie weiter unten in den Diskussionen. Wenn Sie also ein grundlegendes Verständnis der Bedeutung dieser Angaben haben, dann können Sie die verschiedenen Zustände der Repositorys besser verstehen. Weitere Informationen dazu finden Sie in der Dokumentation für https://git-scm.com/docs/git-push[git-push]. -In Fortsetzung dieses Beispiels nimmt John kurz darauf einige Änderungen vor, überträgt sie in sein lokales Repository und versucht, sie auf den gleichen Server zu verschieben: +Wenn wir mit diesem Beispiel fortfahren, nimmt John einige Änderungen vor, schreibt sie in sein lokales Repository und versucht, sie auf denselben Server zu übertragen: [source,console] ---- @@ -170,12 +130,9 @@ To john@githost:simplegit.git error: failed to push some refs to 'john@githost:simplegit.git' ---- -John ist es nicht gestattet, seine Änderungen hochzuladen, weil Jessica vorher _ihre_ hochgeladen hat. -Dies zu verstehen, ist besonders wichtig, wenn Sie dem Umgang mit Subversion gewöhnt sind, weil Sie bemerkt haben werden, dass die beiden Entwickler nicht die gleiche Datei bearbeitet haben. -Obwohl Subversion automatisch das Zusammenführen auf dem Server durchführt, wenn zwei verschiedene Dateien bearbeitet werden, müssen Sie die Commits bei Git _zuerst_ lokal zusammenführen. -Anders ausgedrückt: John muss erst Jessicas Änderungen abholen und lokal mit seinen zusammenführen, bevor ihm das Hochladen gestattet wird. +In diesem Fall scheitert Johns Push an Jessicas früherem Push mit _ihren_ Änderungen. Dies ist wichtig zu verstehen, wenn Sie an Subversion gewöhnt sind. Wie Sie sicherlich bemerkt haben, haben die beiden Entwickler nicht dieselbe Datei bearbeitet. Obwohl Subversion eine solche Zusammenführung automatisch auf dem Server durchführt, wenn verschiedene Dateien bearbeitet werden, müssen Sie bei Git die Commits _zuerst_ lokal zusammenführen. Mit anderen Worten, John muss zuerst Jessicas Änderungen abrufen und in seinem lokalen Repository zusammenführen, bevor er wiederrum seine Push-Vorgänge ausführen kann. -Als ersten Schritt ruft John Jessicas Arbeit ab (dies ruft nur Jessicas Vorgängerarbeit ab, er verbindet sie noch nicht mit Johns Arbeit): +Als ersten Schritt holt John, Jessicas Änderungen (dies holt nur Jessicas Änderungen, es mergt sie noch nicht mit Johns Änderungen): [source,console] ---- @@ -187,10 +144,10 @@ From john@githost:simplegit Zu diesem Zeitpunkt sieht Johns lokales Repository ungefähr so aus: -.Johns abzweigender Verlauf. -image::images/small-team-1.png[John's divergent history.] +.Johns abweichender Verlauf. +image::images/small-team-1.png[Johns abweichender Verlauf.] -Jetzt kann John Jessicas Arbeit, die er abgerufen hat, mit seiner eigenen lokalen Arbeit zusammenführen: +Jetzt kann John, Jessicas abgeholte Änderungen, zu seiner eigenen lokalen Änderungen zusammenführen: [source,console] ---- @@ -200,12 +157,12 @@ Merge made by the 'recursive' strategy. 1 files changed, 1 insertions(+), 0 deletions(-) ---- -Das Zusammenführen läuft problemlos - Johns Commit-Verlauf sieht jetzt so aus: +Solange diese lokale Zusammenführung reibungslos verläuft, sieht der aktualisierte Verlauf von John nun folgendermaßen aus: -.Johns Repository nach dem Zusammenführen mit `origin/master`. -image::images/small-team-2.png[John's repository after merging `origin/master`.] +.Johns Repository nach der Zusammenführung `origin/master`. +image::images/small-team-2.png[Johns Repository nach der Zusammenführung `origin/master`.] -Jetzt kann John seinen Code überprüfen, um sicherzustellen, dass dieser immer noch ordnungsgemäß funktioniert, und dann kann er seine neue, zusammengeführte Arbeit auf den Server hochladen: +Zu diesem Zeitpunkt möchte John möglicherweise diesen neuen Code testen, um sicherzustellen, dass sich keine der Arbeiten von Jessica auf seine auswirkt. Solange alles in Ordnung scheint, kann er die neu zusammengeführten Änderungen schließlich auf den Server übertragen: [source,console] ---- @@ -215,18 +172,17 @@ To john@githost:simplegit.git fbff5bc..72bbc59 master -> master ---- -Schließlich sieht Johns Commit-Verlauf so aus: +Am Ende sieht Johns Commit-Verlauf so aus: -.Johns Verlauf nach dem Hochladen auf den `origin`-Server. -image::images/small-team-3.png[John's history after pushing to the `origin` server.] +.Johns Verlauf nach pushen zum `origin` server. +image::images/small-team-3.png[Johns Verlauf nach pushen zum `origin` server.] -Jesicca hat in der Zwischenzeit an einem neuen Branch gearbeitet. Sie hat einen Branch namens `issue54` erzeugt und auf diesem Branch drei Commits durchgeführt. -Noch hat sie Johns Änderungen nicht vom Server abgeholt, sodass ihr Commit-Verlauf jetzt so aussieht: +In der Zwischenzeit hat Jessica einen neuen Branch mit dem Namen `issue54` erstellt und drei Commits auf diesem Branch vorgenommen. Sie hat Johns Änderungen noch nicht abgerufen, daher sieht ihr Commit-Verlauf folgendermaßen aus: -.Jessicas Branches. -image::images/small-team-4.png[Jessica's topic branch.] +.Jessicas topic branch. +image::images/small-team-4.png[Jessicas topic branch.] -Plötzlich erfährt Jessica, dass John neue Arbeit auf den Server geschoben hat und sie will sich das ansehen. Deshalb muss sie alle neuen Inhalte vom Server abrufen über die sie noch nicht verfügt: +Nun erfährt Jessica, dass John einige neue Arbeiten auf den Server gepusht hat und sie möchte sich diese ansehen. Sie kann alle neuen Inhalte von dem Server abrufen über die sie noch nicht verfügt: [source,console] ---- @@ -237,14 +193,12 @@ From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master ---- -Das lädt alle Änderungen herunter, die John in der Zwischenzeit hochgeladen hat. -Jessicas Verlauf sieht nun so aus: +Dies zieht die Arbeit runter (Pull), die John in der Zwischenzeit gepusht hat. Jessicas Verlauf sieht jetzt so aus: -.Jessicas Verlauf nach dem Abholen von Johns Änderungen. -image::images/small-team-5.png[Jessica's history after fetching John's changes.] +.Jessicas Verlauf nach dem ziehen von Johns Änderungen. +image::images/small-team-5.png[Jessicas Verlauf nach dem ziehen von Johns Änderungen.] -Jessica denkt, dass ihr Branch fertig ist, aber sie möchte wissen, welchen Teil von Johns abgerufenen Arbeiten sie in ihre Arbeit einbinden muss, damit sie ihrerseits hochladen kann. -Sie führt die Anweisung `git log` aus, um es herauszufinden: +Jessica denkt, dass ihr Themen Branch nun fertig ist. Sie möchte jedoch wissen, welchen Teil von Johns abgerufenen Arbeiten sie in ihre Arbeit einbinden muss, damit sie pushen kann. Sie führt "git log" aus, um das herauszufinden: [source,console] ---- @@ -256,15 +210,13 @@ Date: Fri May 29 16:01:27 2009 -0700 remove invalid default value ---- -Bei der Syntax `issue54..origin/master` handelt es sich um einen log-Filter, der Git anweist, nur die Commits aufzulisten, welche auf dem letzteren Branch durchgeführt wurden (in diesem Fall `origin/master`) und die sich nicht auf dem ersten Branch befinden (in diesem Fall `issue54`). -Wir werden diese Syntax detailliert in <> erläutern. +Die Syntax `issue54..origin/master` ist ein Logfilter, der Git auffordert, nur die Commits anzuzeigen, die sich im letzterem Branch befinden (in diesem Fall `origin/master`) und nicht im ersten Branch (in diesem Fall `issue54`). Wir werden diese Syntax in <> genauer erläutern. -Fürs Erste können wir an der Ausgabe erkennen, dass es einen einzelnen Commit von John gibt, den Jessica noch nicht bei sich eingefügt hat. -Dieser einzelne Commit modifiziert ihre lokalen Änderungen, wenn sie ihren Branch mit `origin/master` zusammenführt. +Aus der obigen Ausgabe können wir sehen, dass es einen einzigen Commit gibt, den John gemacht hat, welchen Jessica nicht in ihre lokale Arbeit eingebunden hat. Wenn sie `origin/master` zusammenführt, ist dies der einzige Commit, der ihre lokale Arbeit verändert. -Jetzt kann Jessica ihren "issue54"-Branch mit ihrem `master`-Branch zusammenführen, danach Johns Arbeit (`origin/master`) mit ihrem `master`-Branch zusammenführen und dann das Ganze auf den Server hochladen. +Jetzt kann Jessica ihre Arbeit in ihrem Master Branch zusammenführen, Johns Arbeit (`origin/master`) in ihrem `master`-Branch zusammenführen und dann wieder auf den Server pushen. -Zuerst wechselt sie zu ihrem `master`-Branch, um alle diese Änderungen zu integrieren: +Als erstes wechselt Jessica (nachdem sie alle Änderungen in ihrem Themen Branch `issue54` commitet hat) zurück zu ihrem Master Branch, um die Integration all dieser Arbeiten vorzubereiten: [source,console] ---- @@ -273,9 +225,7 @@ Switched to branch 'master' Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. ---- -Sie kann entweder `origin/master` oder `issue54` zuerst integrieren, da sie beide "stromaufwärts" angeordnet sind, spielt die Reihefolge keine Rolle. -Der Snapshot am Ende sollte identisch sein, egal, welche Reihenfolge sie wählt, nur der Verlauf wird ein wenig anders sein. -Sie entscheidet sich dafür, `issue54` zuerst einfließen zu lassen. +Jessica kann entweder `origin/master` oder `issue54` mit ihrem lokalem `master` zusammenführen - beide sind ihrem `master` vorgelagert. Daher spielt die Reihenfolge keine Rolle. Der finale Schnappschuss sollte unabhängig von der gewählten Reihenfolge identisch sein. Nur der Verlauf wird anders sein. Sie beschließt, zuerst den Branch `issue54` zusammenzuführen: [source,console] ---- @@ -287,8 +237,7 @@ Fast forward 2 files changed, 6 insertions(+), 1 deletions(-) ---- -Es treten keine Probleme auf; wie Sie sehen können, war es ein einfacher "Fast-Forward". -Jessica vervollständigt nun den lokalen Merge-Prozess, indem sie Johns früher geholte Arbeit zusammenführt, die im Branch `origin/master` liegt: +Es treten keine Probleme auf. Wie Sie sehen, handelte es sich um eine einfache Schnellvorlauf (Fast-Forward) Zusammenführung. Jessica schließt nun den lokalen Zusammenführungsprozess ab, indem sie Johns zuvor abgerufene Arbeit zusammenführt, die sich im Zweig `origin/master` befindet: [source,console] ---- @@ -299,12 +248,12 @@ Merge made by the 'recursive' strategy. 1 files changed, 1 insertions(+), 1 deletions(-) ---- -Alles lässt sich sauber zusammenführen und Jessicas Verlauf sieht jetzt so aus: +Alles kann sauber zusammengeführt werden. Jessicas Verlauf sieht nun so aus: -.Jessicas Verlauf nach dem Zusammenführen mit Johns Änderungen. -image::images/small-team-6.png[Jessica's history after merging John's changes.] +.Jessicas Verlauf nach Zusammenführung mit Johns Änderungen. +image::images/small-team-6.png[Jessicas Verlauf nach Zusammenführung mit Johns Änderungen.] -Jetzt ist `origin/master` von Jessicas `master`-Branch aus erreichbar, sodass sie in der Lage sein sollte, erfolgreich hochladen zu können (vorausgesetzt, John hat nicht inzwischen schon wieder etwas hochgeladen): +Jetzt ist `origin/master` über Jessicas `master`-Branch erreichbar, sodass sie erfolgreich pushen kann (vorausgesetzt, John hat in der Zwischenzeit keine weiteren Änderungen gepusht): [source,console] ---- @@ -314,32 +263,25 @@ To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master ---- -Jeder Entwickler hat einige Commits durchgeführt und jeweils die Arbeiten des anderen mit den eigenen zusammengeführt. +Jeder Entwickler hat ein paar Mal committet und die Arbeit des anderen erfolgreich zusammengeführt. + +.Jessicas Verlauf nach pushen aller Änderungen auf den Server. +image::images/small-team-7.png[Jessicas Verlauf nach pushen aller Änderungen auf den Server.] -.Jessicas Verlauf nach dem Hochladen aller Änderungen auf den Server. -image::images/small-team-7.png[Jessica's history after pushing all changes back to the server.] +Das ist einer der einfachsten Workflows. Sie arbeiten eine Weile (in der Regel in einem Themen Branch) und führen diese Arbeiten in Ihrem Branch `master` zusammen, sobald sie für die Integration bereit sind. Wenn Sie diese Arbeit teilen möchten, rufen Sie Ihren `master` von `origin/master` ab und führen ihn zusammen, falls er sich geändert hat. Anschließend pushen sie ihn in den `master` Branch auf dem Server. Die allgemeine Reihenfolge sieht in etwa so aus: -Das ist einer der einfachsten Arbeitsabläufe. -Sie arbeiten eine Weile, gewöhnlich an einem Themenbranch, und führen diesen mit ihrem master-Branch zusammen, wenn dieser soweit fertig ist, dass er integriert werden kann. -Wenn Sie diese Arbeit mit anderen teilen wollen, führen Sie die Änderungen mit ihrem eigenen `master`-Branch zusammen, holen eventuelle Änderungen vom Branch `origin/master` ab und führen diese mit ihren `master`-Branch zusammen, und schließlich laden sie alles auf den `master`-Branch auf den Server hoch. -Der generelle Ablauf sieht ungefähr so aus: +. Allgemeine Abfolge von Ereignissen für einen einfachen Git-Workflow mit mehreren Entwicklern. +image::images/small-team-flow.png[Allgemeine Abfolge von Ereignissen für einen einfachen Git-Workflow mit mehreren Entwicklern.] -.Genereller Ablauf von Ereignissen für einen einfachen Arbeitsablauf mit mehreren Entwicklern. -image::images/small-team-flow.png[General sequence of events for a simple multiple-developer Git workflow.] -==== Geführte private Teams +==== Geführtes und geschlossenes Team (((contributing, private managed team))) -In diesem Szenario werden Sie die Funktionen von Mitarbeitern in einem größeren, nicht öffentlich arbeitenden Team betrachten. -Sie werden erfahren, wie Sie in einem Umfeld arbeiten können, wo in kleinen Gruppen an der Entwicklung einzelner Features gearbeitet wird und dann diese team-basierten Beiträge durch einen anderen Beteiligten integriert werden. +In diesem Szenario sehen Sie sich die Rollen der Mitwirkenden in einer größeren, geschlossenen Gruppe an. Sie lernen, wie Sie in einer Umgebung arbeiten, in der kleine Gruppen an Features zusammenarbeiten. Anschließend werden diese teambasierten Beiträge von einer anderen Partei integriert. -Sagen wir, John und Jessica arbeiten gerade zusammen an einem Feature, während Jessica und Josie gerade an einem zweiten arbeiten. -Das Unternehmen benutzt in diesem Fall einen Typ des Arbeitsablaufs mit Integrationsmanager, bei dem die Arbeit der individuellen Gruppen nur durch bestimmte Mitarbeiter integriert wird und der `master`-Branch des Haupt-Repositorys auch nur durch eben diese Mitarbeiter aktualisiert werden kann. -Die ganze Arbeit wird in diesem Szenario auf team-basierten Branches ausgeführt und später von den Integrationsmanagern zusammengeführt. +Nehmen wir an, John und Jessica arbeiten gemeinsam an einem Feature (nennen wir dieses `FeatureA`), während Jessica und Josie, ein dritter Entwickler, an einem zweiten Feature arbeiten (sagen wir `FeatureB`). In diesem Fall verwendet das Unternehmen eine Art Integration-Manager-Workflow. Bei diesem kann die Arbeit der einzelnen Gruppen nur von bestimmten Beteiligten integriert werden. Der Master-Branch des Haupt Repositorys kann nur von diesen Beteiligten aktualisiert werden kann. In diesem Szenario werden alle Arbeiten in teambasierten Branches ausgeführt und später von den Integratoren zusammengeführt. -Lassen Sie uns Jessicas Arbeitsablauf betrachten, wie sie in diesem Umfeld parallel mit zwei verschiedenen Entwicklern an ihren beiden Features arbeitet. -Vorausgesetzt, sie hat ihr Repository bereits geklont, entscheidet sie sich, zuerst an `featureA` zu arbeiten. -Sie erzeugt einen neuen Branch für das Feature und arbeitet etwas daran: +Folgen wir Jessicas Workflow, während sie an ihren beiden Features tätig ist und parallel mit zwei verschiedenen Entwicklern in dieser Umgebung arbeitet. Wir nehmen an, sie hat ihr Repository bereits geklont. Zuerst beschließt sie an `featureA` zu arbeiten. Sie erstellt einen neuen Branch für das Feature und führt dort einige Änderungen aus: [source,console] ---- @@ -352,8 +294,7 @@ $ git commit -am 'add limit to log function' 1 files changed, 1 insertions(+), 1 deletions(-) ---- -An diesem Punkt muss sie den Stand ihrer Arbeiten John mitteilen, also lädt sie ihre Commits von `featureA`-Branch auf den Server hoch. -Jessica hat keine Schreibrechte auf dem `master`-Branch - den haben nur die Integrationsmanager - also muss sie auf einen anderen Branch hochladen, um mit John zusammenarbeiten zu können. +Zu diesem Zeitpunkt muss sie ihre Arbeit mit John teilen, also pusht sie ihre `featureA` Branch Commits auf den Server. Jessica hat keinen Push-Zugriff auf den `master` Branch, nur die Integratoren haben das. Sie muss daher auf einen anderen Branch pushen, um mit John zusammenzuarbeiten: [source,console] ---- @@ -363,9 +304,7 @@ To jessica@githost:simplegit.git * [new branch] featureA -> featureA ---- -Jessica sendet John eine E-Mail, um ihm mitzuteilen, dass einige Änderungen auf einen neuen Branch namens `featureA` hochgeladen hat und er nun einen Blick darauf werfen kann. -Während sie auf ein Feedback von John wartet, entscheidet sich Jessica, mit der Arbeit an `featureB` zu beginnen - diesmal gemeinsam mit Josie. -Am Anfang legt sie einen neuen Feature-Branch an, basierend auf dem `master`-Branch, welcher sich auf dem Server befindet (`origin/master`): +Jessica schickt John eine E-Mail, um ihm mitzuteilen, dass sie einige Arbeiten in einen Branch mit dem Namen `featureA` gepusht hat. Er kann sie sich jetzt ansehen. Während sie auf Rückmeldung von John wartet, beschließt Jessica, mit Josie an `featureB` zu arbeiten. Zunächst startet sie einen neuen Feature-Branch, der auf dem `master` Branch des Servers basiert: [source,console] ---- @@ -375,7 +314,7 @@ $ git checkout -b featureB origin/master Switched to a new branch 'featureB' ---- -Jetzt führt Jessica eine Reihe von Commits auf dem `featureB`-Branch durch: +Jetzt macht Jessica ein paar Commits auf dem Branch `featureB`: [source,console] ---- @@ -389,14 +328,12 @@ $ git commit -am 'add ls-files' 1 files changed, 5 insertions(+), 0 deletions(-) ---- -Jessicas Repository sieht jetzt so aus: +Jessicas Repository sieht nun folgendermaßen aus: -.Jessicas ursprünglicher Commit-Verlauf. -image::images/managed-team-1.png[Jessica's initial commit history.] +.Jessicas initialer Commit Verlauf. +image::images/managed-team-1.png[Jessicas initialer Commit Verlauf.] -Jessica könnte ihre Arbeit jetzt hochladen, aber sie bekommt eine E-Mail von Josie, in der diese mitteilt, dass bereits ein Branch namens `featureBee` hochgeladen wurde, welcher einige erste Änderungen beinhaltet. -Jessica muss also erst diese Änderungen mit ihren eigenen Änderungen zusammenführen, bevor sie selbst etwas hochladen kann. -Sie kann Josies Änderungen mit `git fetch` herunterladen: +Sie ist bereit, ihre Arbeit zu pushen, erhält jedoch eine E-Mail von Josie, dass ein Branch mit einigen anfänglichen `featureB` Aufgaben bereits als `featureBee` Branch auf den Server übertragen wurde. Jessica muss diese Änderungen mit ihren eigenen zusammenführen, bevor sie ihre Arbeit auf den Server übertragen kann. Jessica holt sich zuerst Josies Änderungen mit `git fetch`: [source,console] ---- @@ -406,7 +343,7 @@ From jessica@githost:simplegit * [new branch] featureBee -> origin/featureBee ---- -Angenommen, Jessica befindet sich noch in ihrem ausgecheckten `featureB` Branch und kann nun Josies Arbeit mit `git merge` in diesen Zweig einbinden: +Angenommen Jessica befindet sich noch in ihrem ausgecheckten `featureB` Branch. Dann kann sie nun Josies Arbeit mit `git merge` in diesen Branch zusammenführen: [source,console] ---- @@ -417,8 +354,7 @@ Merge made by the 'recursive' strategy. 1 files changed, 4 insertions(+), 0 deletions(-) ---- -Jetzt möchte Jessica alle zusammengeführten featureB-Arbeiten zurück auf den Server schieben, aber sie will nicht sie einfach ihren eigenen featureB-Zweig hochschieben. -Da Josie bereits einen Upstream-FeatureBee-Zweig gestartet hat, will Jessica zu diesem Branch hochladen, indem sie folgenden Befehl ausführt: +Zu diesem Zeitpunkt möchte Jessica die gesamte zusammengeführte Arbeit an `featureB` zurück auf den Server übertragen. Jedoch möchte sie nicht einfach ihren eigenen Branch `featureB` übertragen. Da Josie bereits einen Upstream Branch `featureBee` gestartet hat, möchte Jessica auf diesen Zweig pushen, was sie auch folgendermaßen tut: [source,console] ---- @@ -428,12 +364,9 @@ To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee ---- -Das bezeichnet man als _refspec_. -Siehe <> für eine ausführlichere Beschreibung der Git „refspecs“ und den unterschiedlichen Möglichkeiten, die Sie damit haben. -Beachten Sie auch das `-u` Flag, eine Abkürzung für `--set-upstream`, das die Branches für später leichtere Pushs und Pulls konfiguriert. +Dies wird als _refspec_ bezeichnet. Unter <> finden Sie eine detailliertere Beschreibung der Git-Refspecs und der verschiedenen Dinge, die Sie damit ausführen können. Beachten Sie auch die `-u` Option. Dies ist die Abkürzung für `--set-upstream`, mit der die Branches so konfiguriert werden, dass sie später leichter gepusht und gepullt werden können. -Als Nächstes sendet John eine E-Mail an Jessica, um sie zu informieren, dass er einige Änderungen auf den `featureA`-Branch hochgeladen hat, und sie bittet, diese zu überprüfen. -Wieder Sie führt die Anweisung `git fetch` aus, um diese Änderungen herunter zu laden: +Plötzlich erhält Jessica eine E-Mail von John, der ihr mitteilt, dass er einige Änderungen am Branch `featureA` vorgenommen hat, an dem sie zusammenarbeiten. Er bittet Jessica, sie sich anzusehen. Wieder führt Jessica ein einfaches `git fetch` durch, um _alle_ neue Inhalte vom Server abzurufen, einschließlich (natürlich) Johns neuester Arbeit: [source,console] ---- @@ -443,7 +376,7 @@ From jessica@githost:simplegit 3300904..aad881d featureA -> origin/featureA ---- -Jessica kann sich das Protokoll von Johns neuer Arbeit anzeigen lassen indem sie den Inhalt des neu abgerufenen Branch `featureA` mit ihrer lokalen Kopie des gleichen Zweiges vergleicht: +Jessica kann sich Johns neue Arbeit ansehen, indem sie den Inhalt des neu abgerufenen Branches `featureA` mit ihrer lokalen Kopie desselben Branches vergleicht: [source,console] ---- @@ -455,7 +388,7 @@ Date: Fri May 29 19:57:33 2009 -0700 changed log output to 30 from 25 ---- -Wenn ihr Johns neue Arbeit gefällt, kann sie sie mit ihrem lokalen Branch `featureA` verschmelzen: +Wenn Jessica gefällt, was sie sieht, kann sie Johns neue Arbeit in ihrer lokalen `featureA` Branch zusammenführen: [source,console] ---- @@ -468,7 +401,7 @@ Fast forward 1 files changed, 9 insertions(+), 1 deletions(-) ---- -Schließlich möchte Jessica möglicherweise ein paar geringfügige Änderungen an dem gesamten zusammengeführten Inhalt vornehmen. Sie kann diese Änderungen vornehmen, sie in ihren lokalen Zweig 'featureA' übertragen und das Endergebnis zurück auf den Server übertragen: +Schließlich möchte Jessica noch ein paar geringfügige Änderungen an dem gesamten, zusammengeführten Inhalt vornehmen. Sie kann diese Änderungen vornehmen, sie in ihren lokalen Branch `featureA` comitten und das Endergebnis zurück auf den Server pushen. [source,console] ---- @@ -481,36 +414,28 @@ To jessica@githost:simplegit.git 3300904..774b3ed featureA -> featureA ---- -Jessicas Commit-Verlauf sieht jetzt ungefähr so aus: +Jessicas commit Verlauf sieht nun in etwa so aus: -.Jessicas Verlauf nach dem Commit auf den Feature-Branch. -image::images/managed-team-2.png[Jessica's history after committing on a feature branch.] +.Jessicas Verlauf nach committen auf einem Feature Branch. +image::images/managed-team-2.png[Jessicas Verlauf nach committen auf einem Feature Branch.] -Irgendwann informieren Jessica, Josie und John die Integratoren, dass die Zweige `featureA` und `featureBee` auf dem Server für die Integration in die Hauptlinie bereit sind. -Nachdem die Integratoren diese Branches in der Hauptlinie zusammengeführt haben, wird beim Abrufen das neue Merge-Commit beendet, sodass der Verlauf wie folgt aussieht: +Irgendwann informieren Jessica, Josie und John die Integratoren, dass die Branches `featureA` und `featureBee` auf dem Server für die Integration in die Hauptlinie bereit sind. Nachdem die Integratoren diese Branches in der Hauptlinie zusammengeführt haben, holt ein Abruf den neuen Zusammenführungs-Commit ab, sodass der Verlauf wie folgt aussieht: -.Jessicas Verlauf nach dem Zusammenführen mit ihren beiden Themenbranches. -image::images/managed-team-3.png[Jessica's history after merging both her topic branches.] +.Jessicas Verlauf nach Zusammenführung ihrer beiden Themen Branches. +image::images/managed-team-3.png[Jessicas Verlauf nach Zusammenführung ihrer beiden Themen Branches.] -Viele Teams wechseln zu Git, weil es damit möglich ist, dass mehrere Teams parallel arbeiten können und die verschiedenen Entwicklungslinien erst später im Prozess zusammengeführt werden. -Ein riesiger Vorteil von Git besteht darin, dass man in kleinen Untergruppen eines Teams über entfernte Branches zusammenarbeiten kann, ohne notwendigerweise das gesamte Team zu involvieren oder zu behindern. -Die Reihenfolge bei dem Arbeitsablauf, den Sie gesehen haben, ist ungefähr folgende: +Viele Gruppen wechseln zu Git, da mehrere Teams parallel arbeiten können und die verschiedenen Arbeitsbereiche zu einem späteren Zeitpunkt zusammengeführt werden können. Die Fähigkeit kleinerer Untergruppen eines Teams, über entfernte Niederlassungen zusammenzuarbeiten ohne das gesamte Team einbeziehen oder behindern zu müssen, ist ein großer Vorteil von Git. Die Vorgehensweise für den Workflow, den Sie hier gesehen haben, sieht in etwa so aus: -.Grundlegende Reihenfolge des Arbeitsablaufs bei einem geführten Team. -image::images/managed-team-flow.png[Basic sequence of this managed-team workflow.] +.Grundlegende Vorgehensweise für den geführten Team Workflow. +image::images/managed-team-flow.png[Grundlegende Vorgehensweise für den geführten Team Workflow.] [[_public_project]] -==== Verteiltes öffentliches Projekt +==== Abgespaltene (Forked), öffentliche Projekte (((contributing, public small project))) -An einem öffentlichen Projekt mitzuarbeiten, ist ein wenig anders. -Da Sie keine Berechtigungen haben, die Branches des Projektes direkt zu aktualisieren, müssen Sie die Änderungen auf andere Art und Weise zu den Projektbetreibern bekommen. -Dieses erste Beispiel beschreibt die Mitarbeit mittels "Forking" auf Git-Hosting-Servern, welche einfaches "Forking" unterstützen. -Viele Hosting-Websites unterstützen dies (einschließlich GitHub, BitBucket, Google Code repo.or.cz und andere), und viele Projektbetreiber erwarten diese Art der Mitarbeit. -Der nächste Abschnitt handelt von Projekten, welche die Abgabe von Patches via E-Mail bevorzugt akzeptieren. +An öffentlichen Projekten mitzuwirken ist ein wenig anders. Da Sie nicht die Berechtigung haben, Branches im Projekt direkt zu aktualisieren, müssen Sie ihre Arbeit auf andere Weise an die Betreuer weiterleiten. In diesem ersten Beispiel wird beschrieben, wie Sie auf Git Hosts, die einfaches forken unterstützen, via forking mitwirken können. Viele Hosting-Sites unterstützen dies (einschließlich GitHub, BitBucket, repo.or.cz und andere) und viele Projektbetreuer erwarten diesen Beitragsstil. Der nächste Abschnitt befasst sich mit Projekten, die bereitgestellte Patches bevorzugt per E-Mail akzeptieren. -Zunächst werden Sie vermutlich das Hauptrepository klonen wollen, einen Themenbranch anlegen für den Patch oder die Serie von Patches, die Sie beisteuern möchten, und dann darin arbeiten. -Die Reihenfolge sieht dann in etwa so aus: +Zunächst möchten Sie wahrscheinlich das Haupt-Repository klonen, einen Branch für den Patch oder die Patch Serien erstellen, die Sie beitragen möchten, und dort Ihre Arbeit erledigen. Der Prozess sieht im Grunde so aus: [source,console] ---- @@ -525,23 +450,19 @@ $ git commit [NOTE] ==== -Sie können `rebase -i` verwenden, um Ihre Arbeit auf einen einzelnen Commit zu reduzieren oder die Arbeit in den Commits neu anzuordnen damit der Patch für den Maintainer einfacher zu überprüfen ist – siehe <> für weitere Informationen über interaktives Rebasing. +Sie können `rebase -i` verwenden, um Ihre Arbeit auf ein einzelnes Commit zu reduzieren. Sie können auch die Änderungen in den Commits neu anordnen, damit der Betreuer den Patch einfacher überprüfen kann - siehe <> für weitere Informationen zum interaktiven Rebasing. ==== -Wenn Sie mit der Arbeit an ihrem Branch fertig sind und Sie ihren Beitrag den Projektbetreibern zur Verfügung stellen wollen, gehen Sie auf die Projektseite und klicken auf den „Fork“ Button, um Ihren eigenen Fork des Projektes anzulegen, in den Sie dann schreiben können. -Anschließend müssen Sie diese Repository-URL als neue Remote-Adresse Ihres lokalen Repositorys hinzufügen. Nennen wir es in diesem Beispiel `myfork`: +Wenn Ihre Arbeit am Branch abgeschlossen ist und Sie bereit sind, sie an die Betreuer weiterzuleiten, wechseln Sie zur ursprünglichen Projektseite. Dort klicken Sie auf die Schaltfläche `Fork`, um Ihren eigenen schreibbaren Fork des Projekts zu erstellen. Anschließend müssen Sie diese Repository-URL als neue Remote-Adresse Ihres lokalen Repositorys hinzufügen. Nennen wir es in diesem Beispiel `myfork`: [source,console] ---- $ git remote add myfork ---- -Dann müssen Sie Ihre Änderungen dorthin hochladen. -Es ist am einfachsten, den Themenbranch, an dem Sie arbeiten, in Ihr Forked-Repository hochzuladen, anstatt diese Arbeit in Ihrem Master-Zweig zusammenzuführen und dorthin zu verschieben. -Der Grund dafür ist, dass Sie Ihren `master` Branch nicht zurücksetzen müssen, wenn Ihre Arbeit nicht angenommen oder ausgewählt wurde (die Git-Operation `cherry-pick` zum Auswählen einzelner Commits wird in <> ausführlicher behandelt). -Wenn die Projektbetreiber Ihre Änderungen übernehmen, ob mit `merge`, `rebase` oder `cherry-pick`, werden Sie diese schließlich sowieso zurückbekommen mittels `git pull` von deren Repository. +Anschließend müssen Sie Ihre neue Arbeit in dieses Repository pushen. Es ist am einfachsten, den Branch, an dem Sie arbeiten, in Ihr geforktes Repository zu pushen, anstatt diese Arbeit in Ihrem Master-Branch zusammenzuführen und diesen zu pushen. Der Grund dafür ist, dass Sie Ihren Master-Branch nicht zurückspulen müssen, wenn Ihre Arbeit nicht akzeptiert oder teilweise ausgewählt (cherry-pick) wurde (die Git-Operation zum `cherry-pick` wird ausführlicher in <> behandelt). Wenn die Betreuer Ihre Arbeit `mergen`, `rebasen` oder `cherry-picken`, erhalten Sie ihre Arbeit sowieso zurück, wenn Sie aus dem Repository der Betreuer pullen. -Auf jeden Fall können Sie Ihre Arbeit voranbringen mit: +Auf jedem Fall können Sie Ihre Arbeit pushen mit: [source,console] ---- @@ -549,11 +470,9 @@ $ git push -u myfork featureA ---- (((git commands, request-pull))) -Sobald Ihre Arbeit auf Ihren Fork des Repository verschoben wurde, müssen Sie die Maintainer des ursprünglichen Projekts darüber informieren, dass Sie Arbeit haben, die Sie zusammenführen möchten. -Das wird oft als _pull request_ bezeichnet, und Sie generieren eine solche Anforderung typischerweise entweder über die Website – GitHub hat einen eigenen „Pull-Request“ Mechanismus, den wir im < durchgehen werden – oder Sie können den Befehl `git request-pull` ausführen und die nachfolgende Ausgabe manuell per E-Mail an den Projektbetreuer senden. +Sobald Ihre Arbeit an Ihren Fork des Repositorys gepusht wurde, müssen Sie den Betreuern des ursprünglichen Projekts mitteilen, dass Sie Änderungen haben, die sie zusammenführen möchten. Dies wird oft als _Pull Request_ bezeichnet. Sie generieren eine solche Anfrage entweder über die Website - GitHub hat einen eigenen Pull-Request-Mechanismus, den wir in <> behandeln werden, oder Sie können den Befehl `git request-pull` ausführen und die nachfolgende Ausgabe manuell per E-Mail an den Projektbetreuer senden. -Die Anweisung `git request-pull` verwendet den Ausgangsbranch, für den Ihre Änderungen bestimmt sind, und die URL des Git-Repositorys, von dem Ihre Änderungen heruntergeladen werden sollen, und gibt eine Zusammenfassung aller Änderungen aus, um deren Übernahme Sie bitten. -Wenn Jessica z.B. einen pull request an John schicken will, und sie zwei Commits auf dem gerade hochgeladenen Themenbranch durchgeführt hat, kann sie diese Anweisung ausführen: +Der Befehl `git request-pull` verwendet den Basis Branch, in den Ihr Themen Branch gepullt werden soll. Außerdem wird die Git-Repository-URL angegeben aus dem er gepullt werden solle. Er erstellt damit eine Zusammenfassung aller Änderungen, die Sie pullen möchten. Wenn bspw. Jessica an John eine Pull Request senden möchte und sie zwei Commits für den Themen Branch ausgeführt hat, den sie gerade gepusht hat, kann sie Folgendes ausführen: [source,console] ---- @@ -574,11 +493,9 @@ Jessica Smith (2): 1 files changed, 9 insertions(+), 1 deletions(-) ---- -Diese Meldung kann an den Betreuer gesendet werden – sie teilt ihm mit, woher die Arbeit stammt, fasst die Commits zusammen und gibt an, von wo die neue Arbeit geholt werden soll. +Diese Ausgabe kann an den Betreuer gesendet werden. Sie teilt ihm mit, von wo die Arbeit gebranched wurde, fasst die Commits zusammen und identifiziert, von wo die neue Arbeit abgerufen werden soll. -Bei einem Projekt, für das Sie nicht der Betreuer sind, ist es im Allgemeinen einfacher, einen Branch wie `master` zu haben, welcher immer dem `origin/master` Branch folgt, und Ihre eigenen Änderungen in Themenbranches vorzunehmen, die Sie leicht verwerfen können, wenn diese nicht akzeptiert werden. -Wenn Sie Schwerpunkte Ihrer Arbeit in Themenbranches unterteilen, können Sie diese außerdem recht leicht auf den letzten Stand des Hauptrepositorys rebasen, falls das Hauptrepository in der Zwischenzeit weiter entwickelt wurde und Ihre Commits sich nicht mehr sauber anwenden lassen. -Wollen Sie beispielsweise Änderungen zu einem weiteren Thema dem Projekt beisteuern, dann arbeiten Sie nicht weiter auf dem Themenbranch, den Sie gerade hochgeladen haben - sondern beginnen Sie von vorn vom `master` Branch des Hauptrepositorys: +Bei einem Projekt, für das Sie nicht der Betreuer sind, ist es im Allgemeinen einfacher, einen Branch wie `master` zu haben, der immer `origin/master` verfolgt. Ihre Arbeit können Sie dann in Themen Branches erledigen, die Sie einfach verwerfen können, wenn ihre Änderungen abgelehnt werden. Durch das Isolieren von Änderungen in Themen Branches wird es für Sie auch einfacher, Ihre Arbeit neu zu strukturieren. falls sich das Haupt-Repositorys in der Zwischenzeit weiter bewegt hat und Ihre Commits nicht mehr sauber angewendet werden können. Wenn Sie beispielsweise ein zweites Thema an das Projekt senden möchten, arbeiten Sie nicht weiter an dem Branch, den Sie gerade gepusht haben. Beginnen Sie erneut im `master` Branch des Haupt-Repositorys: [source,console] ---- @@ -591,13 +508,13 @@ $ git request-pull origin/master myfork $ git fetch origin ---- -Jedes Ihrer Themen befindet sich jetzt in einer Art Silo – ähnlich einer Patch Queue – sodass Sie diese neu schreiben, rebasen und ändern können, ohne dass die Branches sich gegemseitig stören oder voneinander abhängen: +Jetzt ist jedes Ihrer Themen in einem Silo enthalten, ähnlich wie bei einer Patch-Warteschlange. Dieses können Sie umarbeiten, zurücksetzen oder ändern, ohne dass die Themen sich gegenseitig stören oder voneinander abhängig sind. -.Ursprünglicher Commit-Verlauf bei der Arbeit an `featureB`. -image::images/public-small-1.png[Initial commit history with `featureB` work.] +.Initialer commit Verlauf mit `featureB` Änderungen. +image::images/public-small-1.png[Initialer commit Verlauf mit `featureB` Änderungen.] -Nehmen wir an, der Projektbetreiber hat eine Menge von anderen Patches übernommen und versucht, Ihren ersten Branch einfließen zu lassen, aber dieser lässt sich nicht mehr sauber anwenden. -In diesem Fall können Sie Ihre Änderungen auf dem letzten Stand des `origin/master` Branch mittels Rebase hinzufügen, die Konflikte für den Projektbetreiber beheben und Ihre Arbeit erneut einreichen: +Nehmen wir an, der Projektbetreuer hat eine Reihe weiterer Patches gepullt und Ihren ersten Branch ausprobiert, der jedoch nicht mehr ordnungsgemäß zusammengeführt werden kann. +In diesem Fall können Sie versuchen, diesen Branch auf `origin/master' zu reorganisieren, die Konflikte für den Betreuer zu lösen und Ihre Änderungen erneut zu übermitteln: [source,console] ---- @@ -606,18 +523,15 @@ $ git rebase origin/master $ git push -f myfork featureA ---- -Das schreibt Ihren Commit-Verlauf neu, sodass dieser jetzt so aussieht <>. +Dadurch wird Ihr Verlauf so umgeschrieben, dass er jetzt folgendermaßen aussieht <>. [[psp_b]] -.Commit-Verlauf nach dem Rebase von `featureA`. -image::images/public-small-2.png[Commit history after `featureA` work.] +.Commit Verlauf nach `featureA` Änderungen. +image::images/public-small-2.png[Commit Verlauf nach `featureA` Änderungen.] -Da Sie den Branch mittels Rebase hinzugefügt haben, müssen Sie die Anweisung `git push` mit der Option `-f` verwenden, um den `featureA`-Branch auf dem Server mit einem Commit ersetzen zu können, der nicht vom gegenwärtig letzten Commit des entfernten Branches abstammt. -Eine Alternative dazu wäre, diese neuen Änderungen in einen anderen Branch auf dem Server hochzuladen (vielleicht namens `featureAv2`). +Da Sie den Branch reorganisiert haben, müssen Sie das `-f` für Ihren Push-Befehl angeben, um den `featureA` Branch auf dem Server mit einen Commit ersetzen zu können, der kein Nachfolger von diesem ist. Eine Alternative wäre, diese neue Arbeit in einen anderen Branch auf dem Server zu pushen (beispielsweise als `featureAv2`). -Schauen wir uns noch ein weiteres mögliches Szenario an: der Projektbetreiber hat sich Ihre Arbeit in Ihrem zweiten Branch angesehen und mag das Konzept, aber er bittet Sie, noch ein Detail an der Implementierung zu ändern. -Sie werden die Gelegenheit außerdem nutzen, um Ihre Änderungen zu verschieben, damit diese auf dem aktuellen `master` Branch des Projektes basieren. -Sie legen dazu ausgehend vom aktuellen `origin/master` Branch einen neuen Branch an, führen Ihre Änderungen aus `featureB` damit zusammen, lösen dabei jegliche Konflikte, erledigen die gewünschte Änderung an der Implementierung und laden das Ganze als neuen Branch hoch: +Schauen wir uns ein weiteres mögliches Szenario an: Der Betreuer hat sich die Arbeit in Ihrem zweiten Branch angesehen und mag ihr Konzept, möchte aber, dass Sie ein Implementierungsdetail ändern. Sie nutzen diese Gelegenheit, um ihre Arbeit zusätzlich aus dem aktuellen Master-Branches des Projekts zu verlagern. Sie starten einen neuen Branch, der auf den aktuellen Branch `origin/master` basiert und fassen die Änderungen an `featureB` dort zusammen. Anschließend lösen sie etwaige Konflikte, machen die Implementierungsänderungen und pushen diese Arbeiten als neuen Branch: (((git commands, merge, squash))) [source,console] @@ -629,25 +543,20 @@ $ git commit $ git push myfork featureBv2 ---- -Die Option `--squash` fasst alle Änderungen des einfließenden Branches (featureB) zusammen und komprimiert sie in ein Change-Set, das den Zustand des Repositorys erzeugt, als ob ein echter Merge stattgefunden hätte, ohne tatsächlich einen Merge Commit zu machen. -Das bedeutet, dass Ihr zukünftiger Commit nur einen Elternteil hat und Ihnen ermöglicht, sämtliche Änderungen aus einem anderen Branch zu übernehmen und dann weitere Änderungen vorzunehmen, bevor Sie einen neuen Commit aufzeichnen. -Die Option `--no-commit` weist Git außerdem an, nicht automatisch einen Commit anzulegen. +Mit der Option `--squash` wird die gesamte Arbeit an dem zusammengeführten Branch in einen Änderungssatz gedrückt. Dadurch wird ein Repository-Status erzeugt, als ob eine echte Zusammenführung stattgefunden hätte, ohne dass tatsächlich ein Merge-Commit durchgeführt wurde. Dies bedeutet, dass Ihr zukünftiger Commit nur einen übergeordneten Vorgänger hat. Das erlaubt ihnen alle Änderungen aus einem anderen Branch einzuführen und weitere Änderungen vorzunehmen, bevor Sie den neuen Commit aufnehmen. Auch die Option `--no-commit` kann nützlich sein, um den Merge-Commit im Falle des Standard-Merge-Prozesses zu verzögern. -Jetzt können Sie dem Projektbetreiber eine Nachricht schicken, dass Sie die gewünschten Änderungen vorgenommen haben und dass er Ihre Änderungen in Ihrem `featureBv2`-Branch finden kann. +Nun können Sie den Betreuer darüber informieren, dass Sie die angeforderten Änderungen vorgenommen haben und dass er diese Änderungen in Ihrem Branch `featureBv2` findet. -.Commit-Verlauf nach den Änderungen an `featureBv2`. -image::images/public-small-3.png[Commit history after `featureBv2` work.] +.Commit Verlauf nach getaner `featureBv2` Arbeit. +image::images/public-small-3.png[Commit Verlauf nach getaner `featureBv2` Arbeit.] [[_project_over_email]] -==== Öffentliches Projekt via E-Mail +==== Öffentliche Projekte via Email (((contributing, public large project))) -Viele Projekte haben festgelegte Verfahren, um Patches entgegenzunehmen – Sie werden sich mit den jeweiligen Regeln vertraut machen müssen, da diese bei jedem Projekt unterschiedlich sein werden. -Da es etliche ältere, große Projekte gibt, welche Patches über eine Mailingliste der Entwickler entgegennehmen, werden wir auf dieses Beispiel als Nächstes eingehen. +Viele Projekte haben fest definierte Prozesse, um Änderungen anzunehmen. Sie müssen die spezifischen Regeln dieser Projekte kennen, da sie sich oft unterscheiden. Da es viele alte und große Projekte gibt, die Änderungen über eine Entwickler-Mailingliste akzeptieren, werden wir jetzt solch ein Beispiel durchgehen. -Der Arbeitsablauf ist ähnlich dem im vorherigen Anwendungsfall – Sie erzeugen Themenbranches für jede Patchserie, an der Sie arbeiten. -Der Unterschied besteht dann darin, wie Sie die Änderungen an das Projekt übermitteln. -Anstatt das Projekt zu forken und Änderungen in Ihren Fork hochzuladen, erzeugen Sie E-Mail-Versionen von jeder Ihrer Commit-Folgen und senden diese an die Mailingliste der Entwickler. +Der Workflow ähnelt dem vorherigen Anwendungsfall: Sie erstellen Themen Branches für jede Patch Serie, an der Sie arbeiten. Der Unterschied besteht darin, wie Sie diese an das Projekt senden. Anstatt das Projekt zu forken und auf Ihre eigene beschreibbare Version zu pushen, generieren Sie E-Mail-Versionen jeder Commit-Serie und senden sie per E-Mail an die Entwickler-Mailingliste: [source,console] ---- @@ -659,9 +568,7 @@ $ git commit ---- (((git commands, format-patch))) -Jetzt haben Sie zwei Commits, die Sie an die Mailingliste schicken wollen. -Sie verwenden die Anweisung `git format-patch`, um die Dateien im mbox-Format zu erzeugen, die Sie per E-Mail an die Mailingliste schicken können - diese Anweisung macht aus jedem Commit eine E-Mail-Nachricht, wobei die erste Zeile der Commit-Nachricht zum Betreff der E-Mail wird und der Rest der Commit-Nachricht sowie der Patch des Commits selbst wird zum Text der E-Mail. -Das Schöne daran ist, dass bei der Anwendung eines Patches von einer mit `format-patch` erzeugten E-Mail alle Commit-Informationen ordnungsgemäß erhalten bleiben. +Jetzt haben Sie zwei Commits, die Sie an die Mailingliste senden könnten. Sie verwenden `git format-patch`, um die mbox-formatierten Dateien zu generieren, die Sie anschließend per E-Mail an die Mailingliste senden. Dabei wird jedes Commit in eine E-Mail-Nachricht umgewandelt. Die erste Zeile der Commit-Nachricht wird als Betreff verwendet. Der Rest der Commit-Nachricht plus den Patch, den der Commit einführt wird als Mail-Körper verwendet. Der Vorteil daran ist, dass durch das Anwenden eines Patches aus einer mit `format-patch` erstellten E-Mail alle Commit-Informationen ordnungsgemäß erhalten bleiben. [source,console] ---- @@ -670,9 +577,7 @@ $ git format-patch -M origin/master 0002-changed-log-output-to-30-from-25.patch ---- -Die Anweisung `git format-patch` zeigt Ihnen die Namen der Patch-Dateien an, die er erzeugt hat. -Die Option `-M` weist Git an, nach umbenannten Dateien Ausschau zu halten. -Die Dateien sehen dann so aus: +Der Befehl `format-patch` gibt die Namen der von ihm erstellten Patch-Dateien aus. Die `-M` Option weist Git an, nach Umbenennungen zu suchen. Die Dateien sehen am Ende folgendermaßen aus: [source,console] ---- @@ -705,22 +610,17 @@ index 76f47bc..f9815f1 100644 2.1.0 ---- -Sie können diese Patch-Dateien auch bearbeiten, um weitere Informationen für die Mailingliste hinzuzufügen, die nicht in der Commit-Nachricht erscheinen sollen. -Wenn Sie Text zwischen der `---` Zeile und dem Anfang des Patches (der Zeile `diff --git`) hinzufügen, dann können die Entwickler diesen lesen, bei der Anwendung des Patches wird er aber ausgeschlossen. +Sie können diese Patch-Dateien auch bearbeiten, um weitere Informationen für die E-Mail-Liste hinzuzufügen, die nicht in der Commit-Nachricht angezeigt werden sollen. Wenn Sie Text zwischen der Zeile `---` und dem Beginn des Patches (der Zeile `diff --git`) einfügen, können die Entwickler diesen Text lesen. Der Inhalt wird jedoch vom Patch-Vorgang ignoriert. -Um das jetzt an eine Mailingliste zu schicken, können Sie die Datei entweder in Ihrem E-Mail Programm einfügen oder sie über ein Befehlszeilen-Programm direkt verschicken. -Das Einfügen des Textes verursacht oft Formatierungsprobleme – insbesondere mit „smarten“ E-Mail-Clients, welche Zeilenumbrüche und Leerzeichen nicht adäquat erhalten. -Glücklicherweise bietet Git ein Tool, das Ihnen hilft, ordnungsgemäß formatierte Patches über IMAP zu verschicken, was einfacher für Sie sein könnte. -Wir werden demonstrieren, wie man Patches über Gmail verschickt, welches der E-Mail-Client ist, mit dem wir uns am besten auskennen; Sie können detaillierte Anleitungen für eine Reihe von E-Mail-Programme am Ende der schon erwähnten Datei `Documentation/SubmittingPatches` im Git Quellcode nachlesen. +Um dies per E-Mail an eine Mailingliste zu senden, können Sie die Datei entweder an eine Mail anhängen oder über ein Befehlszeilenprogramm senden. Das Einfügen von Text führt häufig zu Formatierungsproblemen, insbesondere bei "intelligenten" Clients, bei denen Zeilenumbrüche und andere Leerzeichen nicht ordnungsgemäß beibehalten werden. Glücklicherweise bietet Git ein Tool, mit dem Sie ordnungsgemäß formatierte Patches über IMAP senden können, was für Sie möglicherweise einfacher ist. Wir zeigen Ihnen, wie Sie einen Patch über Google Mail senden. Dies ist der E-Mail-Agent, den wir am besten kennen. Detaillierte Anweisungen für eine Reihe von Mail-Programmen finden Sie am Ende der oben genannten Datei `Documentation/SubmittingPatches` im Git-Quellcode. (((git commands, config)))(((email))) -Zunächst müssen Sie den Abschnitt IMAP in Ihrer `~/.gitconfig` Datei einrichten. -Sie können jeden Wert separat mit einer Reihe von `git config` Anweisungen eingeben oder die Datei öffnen und die Werte manuell eingeben, am Ende sollte Ihre config-Datei in etwa so aussehen: +Zuerst müssen Sie den Abschnitt imap in Ihrer `~/.gitconfig` Datei einrichten. Sie können jeden Wert separat mit einer Reihe von `git config` Befehlen festlegen oder manuell hinzufügen. Am Ende sollte Ihre Konfigurationsdatei ungefähr so aussehen: [source,ini] ---- [imap] - folder = "[Gmail]/Drafts" + folder = "[Gmail]/Entwürfe" host = imaps://imap.gmail.com user = user@gmail.com pass = YX]8g76G_2^sFbd @@ -728,8 +628,7 @@ Sie können jeden Wert separat mit einer Reihe von `git config` Anweisungen eing sslverify = false ---- -Wenn Ihr IMAP-Server kein SSL verwendet, sind die letzten beiden Zeilen wahrscheinlich nicht nötig und der Host-Wert müsste `imap://` statt `imaps://` lauten. -Wenn Sie diese Einstellungen vorgenommen haben, können Sie `git send-email` verwenden, um die Patches im Entwurfsordner des angegebenen IMAP-Servers zu platzieren: +Wenn Ihr IMAP-Server kein SSL verwendet, sind die letzten beiden Zeilen wahrscheinlich nicht erforderlich. Der Hostwert lautet dann `imap://` anstelle von `imaps://`. Wenn dies eingerichtet ist, können Sie `git imap-send` verwenden, um die Patch-Reihe im Ordner `Entwürfe` des angegebenen IMAP-Servers abzulegen: [source,console] ---- @@ -741,10 +640,9 @@ sending 2 messages 100% (2/2) done ---- -At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you're sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. +Zu diesem Zeitpunkt sollten Sie in der Lage sein, in Ihren Entwurfsordner zu wechseln und dort das Feld An der generierten Email in die Mailinglist-Adresse zu ändern, an die Sie den Patch senden wollen. Möglicherweise wollen sie auch den Betreuer oder die Person in Kopie nehmen, die für diesen Abschnitt verantwortlich ist. Anschließend können sie die Mail versenden. -You can also send the patches through an SMTP server. -As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: +Sie können die Patches auch über einen SMTP-Server senden. Wie zuvor können Sie jeden Wert separat mit einer Reihe von `git config` Befehlen festlegen oder manuell im Abschnitt sendemail in Ihrer `~/.gitconfig` Datei hinzufügen: [source,ini] ---- @@ -755,7 +653,7 @@ As before, you can set each value separately with a series of `git config` comma smtpserverport = 587 ---- -After this is done, you can use `git send-email` to send your patches: +Danach können Sie Ihre Patches mit `git send-email` versenden: [source,console] ---- @@ -768,7 +666,7 @@ Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y ---- -Git gibt dann für jeden Patch, den Sie versenden, ein paar Log-Informationen aus, die in etwa so aussehen: +Git gibt anschließend für jeden Patch, den Sie senden, eine Reihe von Protokollinformationen aus, die in etwa so aussehen: [source,text] ---- @@ -790,6 +688,4 @@ Result: OK ==== Zusammenfassung -Dieser Abschnitt hat eine Reihe von gebräuchlichen Arbeitsabläufen behandelt, die für jeweils sehr verschiedene Arten von Projekten üblich sind und denen Du vermutlich begegnen wirst. Wir haben außerdem ein paar neue Tools vorgestellt, die dabei hilfreich sind, diese Workflows umzusetzen. -Als nächstes werden wir auf die andere Seite dieser Medaille eingehen: wie Sie selbst ein Git Projekt betreiben können. -Sie werden erfahren, wie Sie als „wohlwollender Diktator“ oder als Integrationsmanager arbeiten können. +In diesem Abschnitt wurden eine Reihe gängiger Workflows für den Umgang mit verschiedenen Arten von Git-Projekten behandelt. Außerdem wurden einige neue Tools vorgestellt, die Sie bei der Verwaltung dieser Prozesse unterstützen. Als Nächstes erfahren Sie, wie Sie auf der anderen Seite arbeiten: als Verwalter (Maintainer) eines Git-Projektes. Sie lernen, wie man sich als wohlwollender Diktator oder Integrationsmanager verhält. \ No newline at end of file diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index c0a96f4f..51e9ce4d 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -1,90 +1,63 @@ -=== Verteilter Arbeitsablauf +=== Verteilte Workflows (((workflows))) -Im Gegensatz zu CVCSs (Centralized Version Control Systems) können Sie dank der verteilten Struktur von Git die Zusammenarbeit von Entwicklern in Projekten wesentlich flexibler gestalten. -In zentralisierten Systemen fungieren alle Entwickler als gleichwertige Netzknoten, die mehr oder weniger in der gleichen Art und Weise an einem zentralen Hub arbeiten. -In Git dagegen ist jeder Entwickler potentiell beides – Netzknoten und zentraler Hub, d.h. jeder Entwickler kann sowohl Code zu anderen Repositories beitragen als auch selbst ein öffentliches Repository unterhalten, auf welchem wiederum andere Ihre Arbeit aufbauen und an dem sie mitarbeiten können. -Das eröffnet eine Fülle von möglichen Arbeitsabläufen (engl. Workflows) für Ihr Projekt, weshalb wir einige gängige Verfahren behandeln werden, die diese Flexibilität nutzen. -Wir werden auf die Stärken und möglichen Schwächen der einzelnen Entwürfe eingehen; Sie können einen einzelnen davon auswählen, um ihn zu nutzen, oder Sie können die Funktionalitäten von allen miteinander kombinieren. +Im Gegensatz zu CVCSs (Centralized Version Control Systems - Zentrale Versionsverwaltungs Systeme) können Sie dank der verteilten Struktur von Git die Zusammenarbeit von Entwicklern in Projekten wesentlich flexibler gestalten. In zentralisierten Systemen ist jeder Entwickler ein Knoten, der mehr oder weniger gleichermaßen mit einem zentralen System arbeitet. +In Git ist jedoch jeder Entwickler möglicherweise sowohl ein Knoten als auch ein zentrales System. Das heißt, jeder Entwickler kann sowohl Code für andere Repositorys bereitstellen als auch ein öffentliches Repository verwalten, auf dem andere ihre Arbeit aufbauen und zu dem sie beitragen können. Dies bietet eine Vielzahl von Workflow Möglichkeiten für Ihr Projekt und/oder Ihrem Team, sodass wir einige gängige Paradigmen behandeln, welche die Vorteile dieser Flexibilität nutzen. Wir werden die Stärken und möglichen Schwächen der einzelnen Designs untersuchen. Sie können ein einzelnes Design auswählen oder Eigenschaften aus diesen kombinieren. -==== Zentralisierter Arbeitsablauf +==== Zentralisierter Workflow (((workflows, centralized))) -In einem zentralisierten System gibt es im Allgemeinen ein einziges Modell für die Zusammenarbeit – der zentralisierte Workflow. -Ein zentraler Hub (oder _Repository_) kann Code von anderen akzeptieren und übernehmen, und alle Beteiligten synchronisieren ihre Arbeit damit. -Eine Reihe von Entwicklern sind Netzknoten – Abnehmer von diesem Hub – und synchronisieren ihre Arbeit mit diesem einen, zentralen Punkt. +In zentralisierten Systemen gibt es im Allgemeinen ein einziges Kollaborationsmodell - den zentralisierten Workflow. Ein zentraler Hub oder _Repository_ kann Code akzeptieren und jeder synchronisiert seine Arbeit mit ihm. Eine Reihe von Entwicklern sind Knoten - Nutzer dieses Hubs - und synchronisieren ihre Arbeit mit diesem zentralisierten Standort. .Zentralisierter Workflow. -image::images/centralized_workflow.png[Zentralisierter Arbeitsablauf.] +image::images/centralized_workflow.png[Zentralisierter Workflow.] -Das bedeutet, wenn zwei Entwickler ein Repository vom zentralen Knotenpunkt klonen und beide lokal Änderungen vornehmen, dann kann der Entwickler, welcher als erster seine Änderungen ins zentrale Repository hochladen möchte, dies ohne Probleme tun. -Der zweite Entwickler muss jedoch zunächst die Änderungen des ersten Entwicklers bei sich einfließen lassen, bevor er seine eigenen Änderungen hochladen kann, damit er die Änderungen des ersten Entwicklers nicht überschreibt. -Dieses Prinzip gilt sowohl für Git als auch für Subversion(((Subversion))) (oder irgendein anderes CVCS). Das Konzept funktioniert bei Git perfekt. +Dies bedeutet, wenn zwei Entwickler vom Hub klonen und beide Änderungen vornehmen, der erste Entwickler, der die Änderungen zurückgespielt hat, dies problemlos tun kann. Der zweite Entwickler muss die Arbeit des ersten Entwicklers zusammenführen (mergen), bevor seine Änderungen aufgenommen werden können, damit die Änderungen des ersten Entwicklers nicht überschrieben werden. Dieses Konzept ist in Git genauso wahr wie in Subversion(((Subversion))) (oder ein anderes beliebiges CVCS), und dieses Modell funktioniert in Git wunderbar. -Wenn Sie in Ihrer Firma oder in Ihrem Team bereits mit einem zentralisierten Arbeitsablauf vertraut sind, können Sie einfach so weitermachen und diesen Arbeitsablauf mit Git realisieren. -Richten Sie einfach ein einziges Repository ein und geben Sie jedem in Ihrem Team Schreibzugriff („push access“). Git sorgt dann dafür, dass niemand die Arbeit von anderen überschreiben kann. +Wenn Sie bereits mit einem zentralisierten Workflow in Ihrem Unternehmen oder Team vertraut sind, können Sie diesen Workflow problemlos mit Git weiterverwenden. Richten Sie einfach ein einziges Repository ein und gewähren Sie allen Mitgliedern Ihres Teams Schreib-Zugriff (push). Git lässt nicht zu, dass Benutzer sich gegenseitig überschreiben. -Angenommen, John und Jessica beginnen gleichzeitig mit der Arbeit. -John beendet seine Änderungen und lädt diese auf den Server hoch. -Dann versucht Jessica, ihre Änderungen hochzuladen, aber der Server weist diese zurück. -Ihr wird mitgeteilt, dass sie versucht hat „non-fast-forward“ Änderungen hochzuladen und dass sie das erst dann durchführen kann, wenn sie zuvor vorhandene andere Änderungen geholt und zusammengeführt hat. -Viele Anwender mögen diesen Arbeitsablauf, weil sie mit dem bewährten Modell bereits vertraut sind und es bequem ist. +Sagen wir, John und Jessica fangen beide zur gleichen Zeit an zu arbeiten. John beendet seine Änderung und pusht sie zum Server. Dann versucht Jessica, ihre Änderungen zu pushen, aber der Server lehnt sie ab. Ihr wird gesagt, dass sie versucht, Änderungen 'non-fast-forward' zu pushen, und dass sie dies erst tun kann, wenn sie sie bestehende Änderungen abgeholt (gefetched) und mit ihrer lokalen Kopie vereint (gemergt) hat. Dieser Workflow ist für viele Menschen sehr ansprechend, weil er ein Paradigma ist, mit dem viele bereits bekannt und vertraut sind. -Das gilt nicht nur für kleine Teams. -Mit dem Branching-Modell von Git ist es Hunderten von Entwicklern möglich, an einem einzelnen Projekt, über Dutzende von Branches, gleichzeitig erfolgreich zu arbeiten. +Diese Vorgehensweise ist nicht auf kleine Teams beschränkt. Mit dem Branching Model von Git ist es Hunderten von Entwicklern möglich, ein einzelnes Projekt über Dutzende von Branches gleichzeitig erfolgreich zu bearbeiten. [[_integration_manager]] -==== Arbeitsablauf mit Integrationsmanager +==== Integration-Manager Workflow (((workflows, integration manager))) -Da Git es Ihnen ermöglicht, mehrere Remote-Repositorys zu betreiben, ist ein Workflow möglich, bei dem jeder Entwickler Schreibzugriff auf sein eigenes öffentliches Repository und Lesezugriff auf alle anderen hat. -Dieses Szenario beinhaltet häufig ein eigens dafür eingerichtetes Repository, welches das „offizielle“ Projekt darstellt. -Um Änderungen zu einem solchen Projekt beizusteuern, können Sie Ihren eigenen öffentlichen Klon des Projektes anlegen und Ihre Änderungen dorthin hochladen. -Anschließend können Sie den Betreiber des Haupt-Repositories bitten, Ihre Änderungen in sein Repository zu übernehmen. -Der Betreiber kann dann Ihr Repository als ein entferntes Repository auf seinem Rechner hinzufügen, Ihre Änderungen lokal testen, diese in einen seiner Branches einfließen lassen und dann in sein öffentliches Repository hochladen. -Dieser Prozess läuft wie folgt ab (siehe <>): - -1. Der Projektbetreiber lädt in sein öffentliches Repository hoch. -2. Ein Mitwirkender klont dieses Repository und nimmt Änderungen vor. -3. Der Beitragende lädt diese in sein eigenes öffentliches Repository hoch. -4. Der Beitragende schickt dem Betreiber eine E-Mail und bittet darum, die Änderungen zu übernehmen. -5. Der Betreuer fügt das Repository des Beitragenden als ein Remote-Repository hinzu und führt die Änderungen lokal zusammen. -6. Der Betreuer lädt die zusammengeführten Änderungen in das Haupt-Repository hoch. + +Da Sie in Git über mehrere Remote-Repositorys verfügen können, ist ein Workflow möglich, bei dem jeder Entwickler Schreibzugriff auf sein eigenes, öffentliches Repository und Lesezugriff auf die Repositorys aller anderen Entwickler hat. Dieses Szenario enthält häufig ein anerkanntes Repository, das das "offizielle" Projekt darstellt. Um zu diesem Projekt beizutragen, erstellen Sie Ihren eigenen öffentlichen Klon des Projekts und pushen Ihre Änderungen darauf. Anschließend können Sie eine Anforderung an den Betreuer des Hauptprojekts senden, um Ihre Änderungen zu übernehmen (Pull Request). Der Betreuer kann dann Ihr Repository als Remote hinzufügen, Ihre Änderungen lokal testen, sie in ihrem Branch mergen und in ihr Repository zurück pushen. +Der Prozess funktioniert wie folgt (siehe <>): + +1. Die Projekt Betreuer pushen zu ihrem eigenen, öffentlichen Repository. +2. Ein Mitwirkender klont dieses Repository und nimmt Änderungen vor. +3. Der Mitwirkende pusht auf seine eigene öffentliche Kopie. +4. Der Mitwirkende sendet dem Betreuer eine E-Mail mit der Aufforderung, Änderungen zu übernehmen (Pull Request). +5. Der Betreuer fügt das Repository des Mitwirkenden als Remote hinzu und merged es lokal zusammen. +6. Der Betreuer pusht die zusammengeführten Änderungen an das Hauptrepository. [[wfdiag_b]] -.Arbeitsablauf mit Integrationsmanager. -image::images/integration-manager.png[Arbeitsablauf mit Integrationsmanager.] +.Integration-Manager Workflow. +image::images/integration-manager.png[Integration-Manager Workflow.] (((forking))) -Das ist ein sehr verbreiteter Workflow bei hub-basierten Werkzeugen wie GitHub oder GitLab, wo es sehr einfach ist, ein Projekt zu „forken“ und Ihre Änderungen in Ihren eigenen Fork hochzuladen, wo jeder sie sehen kann. -Einer der Hauptvorteile dieser Vorgehensweise ist, dass Sie an Ihrem Fork weiterarbeiten können und der Betreiber des Haupt-Repositorys Ihre Änderungen jederzeit übernehmen kann. -Mitarbieter müssen nicht darauf warten, dass der Betreiber ihre Änderungen einarbeitet – jeder Beteiligte kann in seinem eigenen Tempo arbeiten. +Dies ist ein sehr häufiger Workflow mit Hub-basierten Tools wie GitHub oder GitLab, bei dem es einfach ist, ein Projekt zu forken und Ihre Änderungen in Ihren fork zu pushen, damit jeder sie sehen kann. Einer der Hauptvorteile dieses Ansatzes besteht darin, dass Sie weiterarbeiten können und der Verwalter des Haupt-Repositorys Ihre Änderungen jederzeit übernehmen kann. Die Mitwirkenden müssen nicht warten, bis das Projekt ihre Änderungen übernommen hat - jede Partei kann in ihrem eigenen Tempo arbeiten. -==== Arbeitsablauf mit Diktator und Leutnants +==== Diktator und Leutnants Workflow (((workflows, dictator and lieutenants))) -Dies ist eine Variante eines Arbeitsablaufs mit vielen Repositories. -Sie wird normalerweise bei sehr großen Projekten mit hunderten von Mitarbeitern verwendet; ein bekanntes Beispiel ist der Linux Kernel. -Verschiedene Integrationsmanager sind zuständig für bestimmte Teile des Repositorys; sie werden _Leutnants_ genannt. -Alle Leutnants haben wiederum einen Integrationsmanager, der als der wohlwollende Diktator (benevolent dictator) bezeichnet wird. -Der wohlwollende Diktator pusht von seinem Verzeichnis zu einem Referenz-Repository, aus dem alle Beteiligten ihre eigenen Repositories aktualisieren müssen. -Dieser Prozess funktioniert wie folgt (siehe <>): - -1. Normale Entwickler arbeiten an ihren Themenbranches und fügen Ihre Arbeit an der Spitze des `master` Branch mittels Rebase ein. - Der `master` Branch ist der des Referenz-Repositorys, in das der Diktator pusht. -2. Die Leutnants führen die Themenbranches der Entwickler mit ihren `master` Branches zusammen. -3. Der Diktator führt die `master`-Branches der Leutnants mit seinem eigenen `master`-Branch zusammen. -4. Der Diktator lädt seinen `master`-Branch ins Referenz-Repository hoch, damit die anderen Entwickler darauf einen Rebase durchführen können. +Dies ist eine Variante eines Workflows mit mehreren Repositorys. Er wird im Allgemeinen von großen Projekten mit Hunderten von Mitarbeitern verwendet. Ein berühmtes Beispiel ist der Linux-Kernel. Verschiedene Integrationsmanager sind für bestimmte Teile des Repositorys verantwortlich. Sie heißen _Leutnante_. Alle Leutnante haben einen Integrationsmanager, den wohlwollenden Diktator. Der wohlwollende Diktator pusht von seinem Verzeichnis in ein Referenz-Repository, aus dem alle Mitarbeiter pullen müssen. Der Prozess funktioniert wie folgt (siehe <>): + +1. Entwickler arbeiten regelmäßig an ihrem Topic Branch und reorganisieren (rebasen) ihre Arbeit auf `master`. Der `Master`-Branch ist der des Referenz-Repositorys, in das der Diktator pusht. +2. Die Leutnants fassen die Topic Branches der Entwickler zu ihrem `Master`-Branch zusammen. +3. Der Diktator merged die `Master`-Branch der Leutnants in den `Master`-Branch des Diktators zusammen. +4. Schließlich pusht der Diktator diesen `Master` -Branch in das Referenz-Repository, damit die anderen Entwickler darauf rebasen können. [[wfdiag_c]] -.Arbeitsablauf mit wohlwollendem Diktator. -image::images/benevolent-dictator.png[Arbeitsablauf mit wohlwollendem Diktator.] +.Wohlwollender Diktator Workflow. +image::images/benevolent-dictator.png[Wohlwollender Diktator Workflow.] -Diese Art Arbeitsablauf ist nicht weit verbreitet, kann aber bei sehr großen Projekten oder in stark hierarchischen Umgebungen sehr nützlich sein. -Er ermöglicht es dem Projektleiter (dem Diktator), Arbeit in großem Umfang zu delegieren und große Teilbereiche von Code an verschiedenen Punkten einzusammeln, bevor diese integriert werden. +Diese Art von Workflow ist nicht üblich, kann jedoch in sehr großen Projekten oder in sehr hierarchischen Umgebungen hilfreich sein. Es ermöglicht dem Projektleiter (dem Diktator), einen Großteil der Arbeit zu delegieren und große Teilmengen von Code an mehreren Stellen zu sammeln, bevor sie integriert werden. -==== Zusammenfassung Arbeitsabläufe +==== Zusammenfassung -Dies sind einige häufig verwendete Arbeitsabläufe, die mit verteilten Systemen wie Git möglich sind, aber Sie können sehen, dass viele Variationen möglich sind, um genau zu Ihrem speziellen Arbeitsablauf in der realen Welt zu passen. -Jetzt, da Sie (hoffentlich) bestimmen können, welche Kombination von Arbeitsabläufen bei Ihnen funktionieren würde, werden wir einige spezifischere Beispiele davon betrachten, wie man die Hauptaufgaben durchführen kann, welche die unterschliedliche Abläufe ausmachen. -Im nächsten Abschnitt erfahren Sie etwas über gängige Formen der Mitarbeit an einem Projekt. +Dies sind einige häufig verwendete Workflows, die mit einem verteilten System wie Git möglich sind. Allerdings sind auch viele Variationen möglich, um Ihren eigenen Arbeitsabläufen gerecht zu werden. Nachdem Sie (hoffentlich) bestimmen können, welche Workflow-Kombination für Sie geeignet ist, werden wir einige spezifischere Beispiele für die Ausführung der Hauptfunktionen behandeln, aus denen die verschiedenen Abläufe bestehen. Im nächsten Abschnitt erfahren Sie mehr über einige gängige Muster, um zu einem Projekt etwas beizutragen. \ No newline at end of file