Das Hauptwerkzeug zur Quellcodeverwaltung für das FreeCAD-Projekt ist Git, das in den meisten Betriebssystemen einfach über einen Paketmanager oder direkt von der Website von Git installiert werden kann. Es wird empfohlen, sich mit Git vertraut zu machen, bevor man direkt mit dem FreeCAD-Quellcode arbeitet. Auf der Seite Git documentation findet man das Referenzhandbuch sowie das Pro Git book (beide engl.), um zu lernen, wie das System im Allgemeinen genutzt wird. Das vorliegende Dokument konzentriert sich auf die Verwendung von Git für die FreeCAD-Entwicklung. Die Zusammenstellung von FreeCAD ist unter Kompilieren beschrieben.
Während Git in erster Linie eine Terminal-Anwendung ist, gibt es viele grafische Anwendungen, die die Arbeit mit Branches (Zweigen), das Anwenden von Patches und das Senden von Pull-Requests an einen Main-Branch (Hauptzweig) erleichtern. Beispiele dafür sind git-gui (hilft beim Staging und bei Commits, kann gitk starten), gitk (zeigt die Commmit-Historie an, die erste grafische Benutzeroberfläche, die entwickelt wurde),gitg (Gnome),qgit (Qt), tig (Ncurses), git-cola und GitKraken (proprietär). Eine kurze Einführung in dieses Werkzeug findet man unter Entwicklung von FreeCAD mit GitKraken.
Hinweis: Wenn einem davon schwindelig wird, gibt es eine sehr gute nicht-technische Serie über die Verwendung von Git und Github mit dem Titel 'Git und Github für Dichter'.
Jeder kann auf den FreeCAD-Quellcode zugreifen und eine Kopie davon bekommen, aber nur die FreeCAD-Projektmanager haben Schreibzugriff darauf. Man kann eine Kopie des Codes erhalten, ihn studieren und nach Belieben ändern, aber wenn man möchte, dass die Änderungen in den offiziellen Quellcode aufgenommen werden, musst man einen „Pull-Request“ gegen das Main-Repository durchführen, damit die Änderungen von den Verwaltern überprüft werden können. Diese Art der Entwicklung ist bekannt als der Dictator and Lieutenants Workflow (engl. wörtlich etwa „Diktator und Leutnants-Arbeitsablauf“), da die Kern-Entwickler (Diktatoren) und betrauten Entwickler (Leutnante) den Code filtern, der von unabhängigen Entwicklern und Benutzern eingereicht wird.
Wenn die Quellcode-Änderungen signifikant sind, empfehlen wir, sie im Pull-Request-Abschnitt des FreeCAD-Forums zu erklären.
Typischer Arbeitsablauf zur Entwicklung von Code für FreeCAD; jeder kann den Code aus dem Haupt-Repository beziehen, aber die Hauptentwickler haben das exklusive Recht, Eingaben anderer Entwickler zu überprüfen und zusammenzuführen.
Der FreeCAD-Quellcode wird in Github bereitgestellt, https://github.com/FreeCAD/FreeCAD
Um Code beitragen zu können, wird ein GitHub-Konto benötigt.
In der Vergangenheit wurde der Quellcode in einem SVN-Repository bereitgestellt, https://free-cad.svn.sourceforge.net/svnroot/free-cad. Dieses wurde am 10. Oktober 2011 mit commit 120ca87015 nach GitHub verschoben.
Entwickler sollten Code in ihr persönliches Repository mit ihrem GitHub-Benutzernamen eintragen. Wenn dieser nicht bereits global gesetzt ist, kann er lokal für das aktuelle Git-Repository wie folgt gesetzt werden:
git config user.name "YOUR_NAME"
git config user.email GITHUB_USERNAME@users.noreply.github.com
Wobei „YOUR_NAME“ den vollständigen Namen oder Spitznamen darstellt, der zur Identifizierung des Autors eines bestimmten Beitrags verwendet wird, und GITHUB_USERNAME den Namen des Accounts auf GitHub angibt.
Man lese Was ist der Unterschied zwischen Origin und Upstream auf GitHub? (Stackoverflow), um den Unterschied zwischen origin und upstream im Zusammenhang mit Git zu verstehen. In diesem Abschnitt wird erklärt, wie die richtigen Repositorys für die Entwicklung eingerichtet werden.
Im Wesentlichen:
origin ist der persönliche Fork des offiziellen FreeCAD-Projektarchivs, also https://github.com/GITHUB_USERNAME/FreeCADupstream ist das offizielle FreeCAD-Repository, d. h. https://github.com/FreeCAD/FreeCADDiese Unterscheidung ist wichtig, da man den Code zunächst in der eigenen Kopie des Repositorys schreiben sollte, bevor man diese Änderungen in das offizielle Repository überträgt.
Basierend auf den obigen Ausführungen gibt es zwei Möglichkeiten, die Git-Entwicklungsumgebung einzurichten:
Wir empfehlen die erste Methode, weil sie einen Schritt schneller ist.
Zuerst wird das FreeCAD-Repository in GitHub geforkt, dann klont man diesen persönlichen Fork auf dem Computer und legt schließlich das upstream-Repository fest.
https://github.com/FreeCAD/FreeCADhttps://github.com/GITHUB_USERNAME/FreeCADfreecad-source erstellt.git clone https://github.com/GITHUB_USERNAME/FreeCAD.git freecad-source
upstream-Repository fest.cd freecad-source
git remote add upstream https://github.com/FreeCAD/FreeCAD.git
git remote -v überprüfen; die Ausgabe sollte in etwa so aussehenorigin https://github.com/GITHUB_USERNAME/FreeCAD.git (fetch)
origin https://github.com/GITHUB_USERNAME/FreeCAD.git (push)
upstream https://github.com/FreeCAD/FreeCAD.git (fetch)
upstream https://github.com/FreeCAD/FreeCAD.git (push)
Zuerst wird das FreeCAD-Repository in GitHub geforkt, jedoch wird das ursprüngliche FreeCAD-Repository auf den lokalen Rechner geklont und dann die Remotes über das Terminal geändert.
https://github.com/FreeCAD/FreeCADhttps://github.com/GITHUB_USERNAME/FreeCADfreecad-source erstellt.git clone https://github.com/FreeCAD/FreeCAD.git freecad-source
origin festgelegt.cd freecad-source
git remote add origin https://github.com/GITHUB_USERNAME/FreeCAD.git
upstream-Repository eingerichtet.git remote add upstream https://github.com/FreeCAD/FreeCAD.git
git remote -v bestätigen; die Ausgabe sollte ähnlich wie diese seinorigin https://github.com/GITHUB_USERNAME/FreeCAD.git (fetch)
origin https://github.com/GITHUB_USERNAME/FreeCAD.git (push)
upstream https://github.com/FreeCAD/FreeCAD.git (fetch)
upstream https://github.com/FreeCAD/FreeCAD.git (push)
Wenn das Remote-Repository aus irgendeinem Grund zwar existiert, aber auf die falsche Adresse verweist, kann die Situation durch Umbenennen des Namens des Remote-Repository behoben werden. Beispielsweise sollte origin auf den persönlichen Fork zeigen; wenn er auf das ursprüngliche FreeCAD-Repository zeigt, wird der Name dieses Remote-Repository in upstream geändert und das origin-Repository manuell hinzugefügt.
git remote rename origin upstream
git remote add origin https://github.com/GITHUB_USERNAME/FreeCAD.git
git remote -v
Es können auch weitere Informationen mit dem Schlüsselwort show angezeigt werden.
git remote show origin
git remote show upstream
Generischer Arbeitsablauf zur Entwicklung von Code für FreeCAD unter Verwendung von git; das Main-Repository wird online geforked und auf einen Offline-Computer geklont (0); neue Branches (1) werden verwendet, um lokale Änderungen und Ergänzungen des Codes zu übergeben (2); die Forks werden auf den neuesten Online-Code zurückgeführt (3), und dann zum Remote-Repository verschoben (pushed) (4); dann wird ein Pull-Request erstellt, um den Code in das Main-Repository einzufügen (5). Dann wird der persönliche Klon mit dem neuen Main-Code aktualisiert (a); dieser aktualisierte Main-Code wird ebenfalls an das Remote-Repository (b) geschickt, um denselben Code sowohl online als auch offline zu haben.
Anstatt an der Main-Version des Codes zu arbeiten, empfiehlt die bewährte Methode mit Git die Erstellung eines neuen Branches, wann immer man an einer neuen Funktion arbeiten möchte. Branches sind kostengünstig, sie kopieren nicht den gesamten Quellcode-Baum, sondern erzeugen lediglich einen Zeitpunkt, an dem Code geschrieben wird; daher helfen Branches dabei, die laufende Arbeit vom Hauptcode getrennt zu halten.
Die Verwendung eines neuen Branchs erfolgt in zwei Schritten: Zuerst wird der Branch erstellt, und dann wird zu ihm gewechselt:
git branch myNewBranch
git checkout myNewBranch
Alternativ können beide Schritte mit einer einzigen Anweisung ausgeführt werden:
git checkout -b myNewBranch
Jetzt können die Branches mit checkout geändert werden, wann immer daran gearbeitet werden muss. Um die Branches in dem Projekt und dem aktuellen Branch zu sehen, wird die Operation branch allein verwendet oder -v oder -vv für weitere Informationen hinzugefügt:
git branch
git branch -vv
Nachdem Änderungen vorgenommen wurden und diese Änderungen übertragen wurden, wird die Operation log mit den folgenden Optionen verwendet, um die Branches zu visualisieren
git log --oneline --decorate --graph --all
Sobald man sich in einem neuen Branch befindet, bearbeitet man die gewünschten Quelldateien mit einem Texteditor. Um zu sehen, welche Dateien geändert wurden, verwendet man die Operationen status und diff; wenn man mit den Änderungen zufrieden ist, wird die Änderungen mit der Operation commit gespeichert:
git status
git diff
git commit -a
Anders als bei SVN muss man ausdrücklich angeben, welche Dateien übergeben werden; mit der Option -a werden alle geänderten Dateien gespeichert. Der voreingestellte Texteditor, z. B. nano oder vim, wird zum Verfassen einer commit-Nachricht geöffnet.
Alternativ fügt man die Mitteilung dem commit hinzu:
git commit -a -m "Fix the bug in the clone function."
Werden neue Dateien oder Verzeichnisse erstellt, muss zuerst die Aktion add ausgeführt werden, die sie zum lokalen Repository hinzufügt, bevor die Änderungen übergeben werden.
git add path
git commit -a
Wobei path eine beliebige Datei oder ein beliebiges Verzeichnis sein kann.
Man sollte versuchen, in kleinen Schritten zu arbeiten, d. h. häufig Commits durchzuführen, nachdem man eine kleine Ergänzung in dem Code vorgenommen hat. Wenn man die Änderungen nicht in einem Satz zusammenfassen kann, ist es wahrscheinlich schon zu lange her, dass man einen Commit durchgeführt hat.
Bei größeren Änderungen ist es wichtig, dass man hilfreiche und nützliche Beschreibungen der Arbeit bereitstellt. FreeCAD hat ein Format übernommen, das im Buch Pro Git erwähnt wird und aus einer kurzen Nachricht und einem längeren beschreibenden Absatz besteht.
Kurze Zusammenfassung der Änderungen (maximal 50 Zeichen)
Falls erforderlich, fügt man einen ausführlicheren Erläuterungstext
hinzu. Man beschränkt sich dabei auf etwa 72 Zeichen. In manchen
Kontexten wird die erste Zeile als Betreff einer E-Mail und der Rest
des Textes als Hauptteil behandelt. Die Leerzeile zwischen der
Zusammenfassung und dem Hauptteil ist entscheidend (es sei denn,
man lässt den Hauptteil ganz weg); Werkzeuge wie rebase können
verwirrt werden, wenn man beides zusammen ausführt.
Weitere Absätze folgen nach Leerzeilen.
- Aufzählungspunkte sind auch in Ordnung.
- Typischerweise wird für den Aufzählungspunkt ein Bindestrich oder
Sternchen verwendet, dem ein einzelnes Leerzeichen vorangestellt
ist, mit Leerzeilen dazwischen, aber die Konventionen variieren hier.
Wenn in einem Branch viele verwandte Arbeiten ausgeführt werden, sollten viele kleine Commits vorgenommen werden (siehe einen Beitrag im Forum). Wenn diese Änderungen in den Main-Branch eingefügt werden sollen, sollten folgende Befehle ausgeführt werden:
git log main..myNewBranch
um die einzelnen Commit-Nachrichten zu sehen. Es kann eine Nachricht von hoher Qualität geschrieben werden, wenn ein Merge durchgeführt wird.
Wenn mit dem Hauptzweig zusammengeführt wird, wird die Option --squash verwendet und ein Commit mit der Qualitäts-Commit-Meldung durchgeführt. So kann sehr großzügig mit den Commits umgegangen werden und die Commit-Nachricht detailliert gestaltet werden, ohne zu viele unterschiedliche Beschreibungen zu verwenden.
Squashing bezeichnet den Vorgang, bei dem mehrere aufeinanderfolgende Commits zu einem einzigen zusammengefasst werden. Dies kann sinnvoll sein, wenn man viele kleine Commits vorgenommen hat, die man als einen einzigen Commit präsentieren möchte, beispielsweise wenn man eine einzelne Variable geändert, Rechtschreibfehler korrigiert und die Abstände im Code angepasst hat. Man sollte nur kleine Commits zu einer einzigen Datei zusammenfassen; größere Änderungen am Code, die sich über mehrere Dateien erstrecken, sollten die vollständige Commit-Historie enthalten.
Mit git log --oneline können viele Commits nacheinander angezeigt werden, wobei der neueste Commit ganz oben steht. In diesem Beispiel werden ausgehend von „Feature A“ viele Commits vorgenommen, um „Feature B“ zu implementieren. Wir möchten alle Commits, die zu „Feature B“ gehören, zu einem einzigen zusammenfassen.
871adb OK, feature B is fully implemented
1c3317 Whoops, it is not ready yet...
87871a I'm almost ready!
643d0e Code cleanup
af2581 Fix this and that
4e9baa Good implementation
d94e78 Prepare the module for feature B
6394da Feature A
Den Befehl rebase wird mit der Option --interactive oder -i verwendet, um verschiedene Commits auszuwählen und zusammenzufassen. Den Hash des Commits unmittelbar vor dem ersten verwenden, den man zusammenfassen möchte, in diesem Fall den, der „Feature A” entspricht.
git rebase -i 6394da
(Tipp: Wenn man weiß, wie viele Commits bearbeiten werden sollen, kann man git rebase -i HEAD~n verwenden, um die letzten n Commits zu bearbeiten.)
Der Befehlszeilen-Editor, wie nano oder vim, wird geöffnet und zeigt erneut die Commits an, wobei nun der ältere Commit oben steht. Vor jedem Commit wird das Wort pick angezeigt. Das Wort pick löschen und stattdessen das Wort squash oder nur den Buchstaben s schreiben, mit Ausnahme des ersten Eintrags; dieser Commit ist der älteste, sodass alle zukünftigen Commits darin zusammengefasst werden.
pick d94e78 Prepare the module for feature B
s 4e9baa Good implementation
s af2581 Fix this and that
s 643d0e Code cleanup
s 87871a I'm almost ready!
s 1c3317 Whoops, it is not ready yet...
s 871adb OK, feature B is fully implemented
Die Datei speichern und den Editor schließen.
Der Editor wird erneut geöffnet. Jetzt kann man eine längere Nachricht hinzufügen, die alle Änderungen so beschreibt, als wären sie ein einziger Commit. Die Datei speichern und den Editor erneut schließen. Damit sind diese Commits zu einem einzigen Commit mit der verfassten neuen Commit-Nachricht zusammengefasst.
git log --oneline kann erneut verwendet werden, um den neuen Commit-Verlauf anzuzeigen. In diesem Fall wird nur ein einziger Commit für „Feature B“ angezeigt, und zwar über dem unveränderten Commit für „Feature A“.
c83d67 OK, feature B is fully implemented now, with proper module setup, and clean code.
6394da Feature A
Wenn man für FreeCAD programmiert, bitten wir darum, jede Commit-Meldung mit dem Modul zu beginnen, das davon betroffen ist. Eine Commit-Meldung für eine Änderung am Sketcher könnte beispielsweise lauten:
Sketcher: gerade Linien etwas krümmen Gerade Linien sind irgendwie hässlich, daher fügt dieser Commit ihnen ein wenig Krümmung hinzu, damit sie optisch ansprechender sind. Sie funkeln auch ein wenig und ändern mit der Zeit ihre Farbe. Behebt Fehler #1234.
Der Pull Request lässt sich leichter überprüfen und schneller zusammenführen, wenn man darauf achtet, die Commits vor dem Einreichen mit Rebase zu strukturieren und zu beschreiben.
Die lokalen Branches auf dem Computer werden nicht automatisch mit den Remote-Servern synchronisiert, die man als origin oder upstream angegeben hat (siehe Remote-Repositorys); Man muss die Branches explizit auf die Remote-Server übertragen, für die man Schreibzugriff haben muss. Sobald man dies getan hat, werden die Branches öffentlich und können von anderen Entwicklern überprüft werden.
Für FreeCAD sollte man den lokalen Zweig in das Remote-Repository origin übertragen, d. h. https://github.com/GITHUB_USERNAME/FreeCAD. Man muss bei jedem Push den Benutzernamen und das Passwort eingeben, es sei denn, man hat Credential Caching eingerichtet. Weitere Informationen sind unter Commits an ein Remote-Repository übertragen zu finden.
git push origin myNewBranch
Wenn man mit einem einzelnen Branch arbeitet, muss man möglicherweise mehrmals interaktiv Rebase, Squash und Fix Commits durchführen. In diesem Fall ist der Branch-Verlauf nicht einfach und man kann ihn nicht in das Remote-Repository pushen. Möglicherweise erhält man eine Meldung wie die folgende, die besagt, dass ein „Fast-Forward”-Push nicht möglich ist.
error: failed to push some refs to 'https://github.com/USER/FreeCAD.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Um den Branch endgültig in das Remote-Repository zu übertragen, muss man einen „Force Push“ durchführen. Dadurch wird der Remote-Branch vollständig mit dem aktuellen Branch überschrieben, den man offline hat.
git push -f origin myNewBranch
Der reguläre Entwickler hat keinen Schreibzugriff auf das upstream-Repository https://github.com/FreeCAD/FreeCAD, daher sollte man niemals Code auf diesen Remote-Server übertragen.
Während man am eigenen Branch arbeitet, entwickelt sich der offizielle FreeCAD-Code durch Commits anderer Entwickler weiter und weicht somit zunehmend von dem Code ab, den man in seinem persönlichen Fork hat.
.-----A origin/myNewBranch
/
-----o-----------Z FreeCAD upstream/main
Wenn man bereit ist, den Branch mit dem Haupt-Repository von FreeCAD zusammenzuführen, muss man daher die eigene Kopie des Repositorys „rebasen”, damit sie so nah wie möglich am offiziellen Repository ist. Weitere Informationen sind unter Git Branching – Rebasing zu finden.
git checkout myNewBranch
git pull --rebase upstream main
Dadurch wird der Code aus dem main-Branch des upstream-Repositorys (der offiziellen FreeCAD-Quelle) heruntergeladen und mit dem aktuellen Branch (myNewBranch) zusammengeführt, sodass die Änderungen über dem neuesten offiziellen Code erscheinen. Wenn niemand dieselben Dateien wie man selbst geändert hat, wird die Zusammenführung ohne Probleme gelingen. Wenn einige Dateien gleichzeitig von verschiedenen Personen geändert wurden, kann es zu einem Konflikt kommen, der gelöst werden muss.
.-----A' origin/myNewBranch
/
-----o-----------Z FreeCAD upstream/main
Zusammenfassend lässt sich sagen, dass man sich im entsprechenden Branch befindet, den Upstream-Code rebasen und dann mit dem Push fortfahren muss.
git checkout myNewBranch
git pull --rebase upstream main
git push origin myNewBranch
Der Befehl pull entspricht einem Befehl fetch, gefolgt von einem Befehl merge. Wenn die Option --rebase verwendet wird, wird anstelle eines einfachen Befehls merge der Befehl rebase ausgeführt.
git pull upstream
git fetch upstream
git merge FETCH_HEAD
git pull --rebase upstream main
git fetch upstream
git rebase main
Nachdem die Änderungen lokal committet, den Branch aus dem Upstream-Repository rebased und den Branch online gepusht wurden, kann man einen „Pull Request“ initiieren. Ein Pull Request teilt den Administratoren des offiziellen FreeCAD-Repositorys mit, dass man den neuen Code in dem Branch mit dem offiziellen Code zusammenführen möchte.
Zusammenfassend sieht der Entwicklungsprozess wie folgt aus:
git rebase -i HEAD~n (wobei n die Gesamtzahl der Commits ist), um die Commits zu einer logischen Gruppe mit guten Commit-Meldungen zusammenzufassen (jede Meldung sollte mit dem Namen des Moduls beginnen, auf das sie sich bezieht, z. B. „Sketcher: gerade Linien etwas krümmen“).Sobald man den Code in das origin-Repository https://github.com/GITHUB_USERNAME/FreeCAD übertragen hat, bietet einem GitHub die Möglichkeit, einen Vergleich durchzuführen und einen Pull-Request für das upstream-Repository zu erstellen. Durch Klicken auf Compare & pull request öffnet sich eine Oberfläche, in der man auswählen kann, welches Repository die „Basis” und das Ziel der Zusammenführung ist und welches der „Head” mit dem zusätzlichen Code ist. Das System führt eine schnelle Überprüfung durch und teilt mit, ob es Konflikte mit den von einem geänderten Dateien gibt. Wenn man an Dateien gearbeitet hat, die niemand anderes geändert hat, kann der Branch problemlos zusammengeführt werden.
GitHub zeigt einen Texteditor an, in dem man eine Nachricht mit einer Dokumentation der Änderungen verfassen kann: Dieser Editor ist bereits mit einer Willkommensnachricht (die man löschen kann), einer Checkliste (die man durchgehen sollte) und einer Erinnerung versehen, die Änderung im Wiki zu dokumentieren, sobald sie akzeptiert wurde. Um die Checkliste zu verwenden, geht man nacheinander alle Punkte durch und ändert [ ] in [X], um anzuzeigen, dass man diesen Schritt durchgeführt hat. GitHub zeigt auch die Anzahl der Commits im Branch, die Anzahl der geänderten Dateien und eine Ansicht mit den Unterschieden zwischen „base” und „head” an, sodass jeder sofort die beabsichtigten Änderungen sehen kann. Diese noch einmal auf Dinge wie versehentlich hinzugefügte Leerzeilen oder umfangreiche Formatierungsänderungen überprüfen, die die IDE hinter dem Rücken vorgenommen hat.
base repository: FreeCAD/FreeCAD base: main <---- head repository: GITHUB_USERNAME/FreeCAD compare: myNewBranch
Able to merge. These branches can be automatically merged.
Auf Pull-Anfrage erstellen klicken, um fortzufahren. Es erscheint eine Meldung, dass einige Überprüfungen am Code durchgeführt werden muss. Dabei handelt es sich um ein System, das FreeCAD automatisch kompiliert und die Unit-Tests ausführt. Wenn die Tests erfolgreich sind, hat die Pull-Anfrage eine bessere Chance, in den Hauptcode integriert zu werden, andernfalls wird ein Bericht erstellt, in dem die aufgetretenen Fehler aufgeführt sind. Siehe FreeCAD-Pull-Anfragen.
Some checks haven’t completed yet * continuous-integration/travis-ci/pr Pending — The Travis CI build is in progress |Required|
Wenn die Tests erfolgreich sind, wird eine Meldung wie die folgende angezeigt
Alle Prüfungen wurden bestanden.
* continuous-integration/travis-ci/pr — The Travis CI build passed |Required|
Dieser Zweig hat keine Konflikte mit dem Basis-Zweig. Nur diejenigen mit Schreibzugriff auf dieses Repository können Pull-Requests zusammenführen.
Jetzt muss man warten, bis die Administratoren den Branch zusammenführen. Man wird benachrichtigt, sobald dies geschehen ist.
Pull request successfully merged and closed
You’re all set — the GITHUB_USERNAME:myNewBranch branch can be safely deleted.
If you wish, you can also delete your fork of FreeCAD/FreeCAD.
Wenn man möchte, kann man den gerade zusammengeführten Zweig oder sogar den gesamten FreeCAD-Fork löschen, da der eigene Code bereits am Ende des Hauptzweigs enthalten ist.
-----o-----------Z----A' FreeCAD upstream/main
Hinweis: Man Kann während man auf die Genehmigung der Zusammenführung wartet, weiter an demselben Zweig arbeiten (git commit -a). Wenn man erneut git push ausführt, wird ein zweiter Zusammenführungs-Commit in derselben Pull-Anfrage in die Warteschlange gestellt und ein weiterer automatisierter Test durchgeführt. Das heißt, solange die Zusammenführungen noch nicht von den Administratoren genehmigt wurden, kann man weiterhin Änderungen an dem origin-Repository vornehmen, wodurch diese Commits in derselben Pull-Anforderung an das upstream-Repository in die Warteschlange gestellt werden. Bei kleinen Änderungen ist es oft wünschenswert, viele einzelne Commits mit einer einzigen Pull-Anforderung in die Warteschlange zu stellen. Für umfangreiche Ergänzungen zum Quellcode sollte man einen weiteren Branch erstellen, die Funktionen dort entwickeln und dann einen separaten Pull-Request für diesen Branch einreichen.
Die Pull-Request-Schnittstelle kann immer dann verwendet werden, wenn man Code aus den eigenen Repositorys an ein anderes Repository in GitHub übermitteln möchte. Man kann sie auch verwenden, um Code in die umgekehrte Richtung zusammenzuführen, d. h. von den Branches anderer Personen zu dem eigenen oder sogar zwischen den eigenen Branches. Im letzten Fall kann man die Zusammenführungen sofort selbst genehmigen, da man selbst der Eigentümer der Branches ist.
base repository: SomeProject/Some_Software base: main <---- head repository: GITHUB_USERNAME/Some_Software compare: add_new_functions
base repository: GITHUB_USERNAME/FreeCAD base: myNewBranch <---- head repository: FreeCAD/FreeCAD compare: main
base repository: GITHUB_USERNAME/FreeCAD base: myNewBranch <---- head repository: GITHUB_USERNAME/FreeCAD compare: fix-many-bugs-branch
Sobald man FreeCAD geforkt hat, existiert das persönliche Repository unabhängig vom Original. Wenn das ursprüngliche Repository neue Commits enthält, informiert GitHub einen darüber, dass das persönliche Repository hinsichtlich der Anzahl der Commits hinterherhinkt:
This branch is 5 commits behind FreeCAD:main.
In ähnlicher Weise informiert GitHub einen, wenn man einen Entwicklungszweig mit neuem Code erstellt hat, dass dieser Zweig in der Anzahl der Commits voraus ist, d. h., dieser Zweig enthält Änderungen, die noch nicht in das offizielle FreeCAD-Repository übernommen wurden:
This branch is 3 commits ahead of FreeCAD:main.
Während der Entwicklung sind beide Fälle möglich, da der eigene Branch möglicherweise keine Commits anderer Entwickler enthält, aber neue Commits von einem enthält:
This branch is 2 commits ahead, 14 commits behind FreeCAD:main.
Bei der Entwicklung von Code wird empfohlen, den Zweig, an dem man gerade arbeitet, neu zu rebasen, da der Zweig dadurch immer vor dem FreeCAD-Hauptcode bleibt.
Was den ursprünglichen main-Zweig betrifft, so wird dieser niemals automatisch von GitHub aktualisiert; dies muss man selbst tun. Zum main-Zweig wechseln, dann pull von upstream ausführen (wodurch fetch und merge ausgeführt werden) und diesen aktualisierten main-Zweig dann in das Remote-Repository origin übertragen.
git checkout main
git pull upstream main
git push origin main
Nachdem dies erledigt ist, teilt GitHub mit, dass man mit dem upstream-Repository synchronisiert ist.
This branch is even with FreeCAD:main.
Nachdem der main nun auf dem neuesten Stand ist, kann man zu diesem wechseln und den anderen Zweig löschen, den man zuvor zur Entwicklung einer Funktion verwendet hat.
git checkout main
git branch -d myNewBranch
Um den Branch im Remote-Repository origin zu löschen, kann man den Befehl push verwenden. Normalerweise pusht man einen lokalen Zweig; dadurch wird ein Remote-Zweig mit dem gleichen Namen wie der lokale Zweig erstellt.
git push origin myNewBranch
Wenn jedoch die Notation local_name:remote_name verwendet wird, wird der lokale Zweig im Remote-Repository unter einem anderen Namen erstellt:
git push origin myNewBranch:someRemoteBranch
Daher kannst du den entfernte Fernzweig löschen, indem du einen leeren lokale Zweig schiebst:
git push origin :myNewBranch
git push origin :someRemoteBranch
Da man nun nur noch über ein aktuelles main verfügt, kann man einen neuen Zweig erstellen und die Schritte zum Ändern von Dateien, Committen, Pushen, Einreichen eines Pull-Request, Zusammenführen und Aktualisieren wiederholen.
git checkout main
git checkout -b anotherBranch
Wenn man den bereits benutzerdefinierten Branch nicht löschen möchte, kann man eine Aktualisierung erzwingen, sodass er mit dem aktualisierten main übereinstimmt. Anschließend kann man damit tun, was man möchte, einschließlich weiterer Commits hinzufügen und ihn in das Remote-Repository origin pushen.
git checkout myNewBranch
git reset --hard main
git push -f origin myNewBranch
Ein solches hartes Zurücksetzen eines Branches ist in der Regel nicht erforderlich. In den meisten Fällen sollten man die Reihenfolge befolgen: Einen neuen Branch erstellen, die Änderungen committen, diese Änderungen pushen, den Zweig mergen und ihn anschließend löschen.
Einige praktische Werkzeuge, die einem bei der Suche helfen:
git ls-files verwenden, um das Repository nach Dateien zu durchsuchen, deren Dateiname eine bestimmte Zeichenfolge enthält. Das folgende Beispiel gibt alle Dateien zurück, deren Dateiname die Zeichenfolge 'dxf' enthält.
git ls-files *dxf*
git grep verwenden, um das Repository nach Dateien zu durchsuchen, die eine bestimmte Zeichenfolge enthalten. Das folgende Beispiel gibt alle Instanzen der Dateien zurück, die die Zeichenfolge 'dxf' enthalten.
git grep dxf
Das Zusammenführen von Branches mit git merge oder das Rebasing des Branches mit git rebase führt gelegentlich zu Konflikten, da Dateien möglicherweise gleichzeitig von einem anderen Autor geändert wurden. In diesem Fall sollte man sich die Änderungen beider Seiten, die des anderen Autors und die eigenen, ansehen und dann entscheiden, wie man beide Änderungssätze bestmöglich einarbeiten kann. Dies ist in der Regel ein manueller Prozess, der nicht automatisiert werden kann. Der Programmierer muss den Code verstehen und entscheiden, welcher Code verschoben, umgeschrieben oder entfernt werden muss, um den Konflikt zu lösen.
Sobald ein Konflikt auftritt, kann eine Meldung wie diese erscheinen.
CONFLICT (content): Merge conflict in src/Mod/source_code.py
error: Failed to merge in the changes.
Patch failed at 1234 Some commit message when editing source_code.py
Wenn ein spezielles Diff-Tool für Git installiert und konfiguriert ist, beispielsweise Gnome's Meld, kann der Konflikt mithilfe der Operation mergetool untersucht und gelöst werden.
git mergetool
Das Meld-Tool zeigt normalerweise drei Spalten an: Die beiden seitlichen Spalten zeigen die beiden in Konflikt stehenden Dateien an, während die mittlere Spalte den neuen Code anzeigt, der schließlich gespeichert und committet wird. Daher sollte diese mittlere Spalte so bearbeitet werden, dass sie den Code beider seitlichen Spalten integriert. Sobald der Konflikt gelöst und der neue Quellcode (die mittlere Spalte) gespeichert ist, kann das Meld-Tool geschlossen werden. Dann kann der Vorgang merge oder rebase fortgesetzt werden.
git merge --continue
git rebase --continue
Weitere Informationen zum Zusammenführen und Lösen von Konflikten finden Sie unter:
git merge.
Den Verlauf einer einzelnen Datei anhand verschiedener Commits mit dem Befehl log überprüfen:
git log --patch path
Wobei path ein beliebiges Verzeichnis oder eine beliebige Datei sein kann. Anstelle von --patch können auch die Kurzformen -p oder -u verwendet werden.
Die Änderungen zwischen zwei Zweigen mit den Operationen log und diff unter Angabe der Namen der Zweige überprüfen:
git log main..myBranch
git diff main..myBranch
Der Befehl log zeigt die Commits an, während diff die tatsächlichen Änderungen in den Dateien anzeigt.
Wenn man versehentlich Änderungen an einer Datei oder einem Verzeichnis vorgenommen hat, möchte man diese Änderungen möglicherweise vollständig rückgängig machen, um den vorherigen Zustand des Quellcodes wiederherzustellen.
Dies kann schnell mit der Operation checkout durchgeführt werden:
git checkout path
git checkout .
Dadurch wird path (eine Datei oder ein Verzeichnis) in den Zustand am Anfang des Zweigs zurückgesetzt, wobei nicht festgeschriebene Änderungen verworfen werden. Wenn path der einzelne Punkt . ist, werden alle Dateien im aktuellen Verzeichnis wiederhergestellt.
Wenn man versehentlich Dateien und Verzeichnisse hinzugefügt hat, kann man den Befehl clean verwenden:
git clean -df
Dadurch werden alle Dateien und Verzeichnisse (-df) gelöscht, die nicht vom Repository verfolgt werden, d. h. diejenigen, die zuvor nicht mit dem Befehl add hinzugefügt wurden.
Um das Repository vollständig zurückzusetzen und alle nicht festgeschriebenen Änderungen zu verlieren, verwendet man den Befehl reset:
git fetch
git reset --hard FETCH_HEAD
Wobei FETCH_HEAD die Spitze des upstream-Repositorys ist. Es kann auch ein anderer Commit verwendet werden.
Der Befehl revert macht ebenfalls Änderungen rückgängig. Allerdings fügt dieser Befehl dazu einen weiteren Commit zur Historie hinzu, was in vielen Fällen nicht erwünscht ist.
Wenn man viele Branches in das upstream-Repository übertragen hat, möchten man diese Branches möglicherweise aus dem lokalen System entfernen, da sie bereits zusammengeführt wurden. Der Zweig im Online-Repository origin kann unmittelbar nach dem Zusammenführen gelöscht werden. Anschließend kann man die lokalen Verweise auf diesen Zweig entfernen, indem man die Optionen --prune oder prune für die Operationen fetch und remote verwenden.
git fetch --prune origin
git remote prune origin
Schließlich kannst du die Zweige lokal löschen
git branch -D myBranch
Es empfiehlt sich außerdem, nach einer Weile eine Garbage Collection durchzuführen, indem man den Befehl gc verwendet. Dadurch werden unnötige Dateien bereinigt und lokale Dateirevisionen komprimiert, um die lokale Festplattennutzung des Repositorys zu optimieren.
git gc
Obwohl Git Ihnen dir erlaubt, verschiedene Code Zweige mit git merge zusammenzuführen (in deinem Computer) oder einer Pull Anfrage (Fernrepositorium) gibt es Zeiten, in denen es wünschenswert sein kann, einen traditionellen "Patch" zu erstellen, der als Anhang per Email verschickt werden kann. Der folgende Arbeitsablauf erklärt, wie dies zu tun ist.
git branch -v
git checkout myBranch
git format-patch für den Hauptzweig und verwendet die Option --stdout, um das Ergebnis an die Standardausgabe umzuleiten. Dann die Standardausgabe in eine Datei umleiten, die der Einfachheit halber über dem Quellcodeverzeichnis erstellt wird.git format-patch main --stdout > ../myCode.patch
git format-patch HEAD^
git format-patch HEAD~1
Die Anzahl der Zirkumflex-Zeichen ^ oder die Zahl 1 geben die Anzahl der zu berücksichtigenden Commits an, d. h. ^^^ oder ~3 erstellt drei Patches für drei Commits.
git format-patch HEAD^
Dadurch wird ein Patch oder eine Reihe von Patches mit der folgenden Namenskonvention erstellt
XXXX-commit-message.patch
wobei XXXX eine Zahl zwischen 0000 und 9999 ist und die Commit-Nachricht den größten Teil des Dateinamens ausmacht, zum Beispiel
0001-fix-ViewProjMatrix-getProjectionMatrix.patch
Git kann Patches oder Diffs zusammenführen. Weitere Informationen zu diesem Vorgang findet man unter Patches mit Git anwenden.
Wenn du die Patch Datei bereits in deinem System hast, wende sie einfach an.
git apply myCode.patch
Man kann curl verwenden, um einen Patch von einer Website herunterzuladen, und ihn dann über git anwenden.
curl -O https://some.website.org/code/myCode.patch
git apply myCode.patch
.diff oder .patch am Ende der URL eines GitHub-Commits, Pull-Requests oder Vergleichsansicht hinzufügen, damit die Website die Nur-Text-Ansicht dieser Seite anzeigt.
https://github.com/FreeCAD/FreeCAD/commit/c476589652a0f67b544735740e20ff702e8d0621https://github.com/FreeCAD/FreeCAD/commit/c476589652a0f67b544735740e20ff702e8d0621.diffhttps://github.com/FreeCAD/FreeCAD/commit/c476589652a0f67b544735740e20ff702e8d0621.patchMan kann curl auf einen bestimmten Commit-Patch im Repository verweisen und ihn direkt an git weiterleiten, um den Patch anzuwenden.
curl https://github.com/FreeCAD/FreeCAD/commit/c476589652a0f67b544735740e20ff702e8d0621.patch | git apply -
Wenn man einen Patch anwendet, werden einige Dateien geändert. Diese Änderungen sind jedoch erst dann dauerhaft, wenn man die Änderungen festschreibt. Wenn man einen Patch rückgängig machen möchte, befolgen man daher die folgenden Anweisungen.
Dadurch werden die vorgenommenen Änderungen rückgängig gemacht, sofern noch Zugriff auf die ursprüngliche Patch-Datei besteht.
git apply -R myCode.patch
Alternativ werden dadurch nicht festgeschriebene Änderungen an dem Zweig entfernt.
git checkout -f
Angenommen, man arbeiten an einem Branch und nimmt einige Änderungen an der Quelle vor, die außerhalb des Umfangs des aktuellen Branches liegen. Mit anderen Worten: Diese Änderungen wären besser in einem anderen Branch als dem aktuellen aufgehoben. Mit dem Befehl git stash kann man diese nicht festgeschriebenen lokalen Änderungen vorübergehend speichern.
git stash
Wenn man diese Commits in Zukunft verwenden möchte, kann man die Commits aus dem Zwischenspeicher (Stash) in den Arbeitszweig „herausholen“.
git stash pop
Wenn man feststellt, dass einem die gespeicherten Commits nicht mehr gefallen, kann man die Commits vollständig aus dem Stash löschen.
git stash drop
Man kann mehrere Stash-Commits mit
git stash list
Weitere Informationen findet man unter Nützliche Tricks, die man vielleicht noch nicht über Git Stash weiß.
GitHub-Pull-Anfragen lokal überprüfen
Die Blame-Funktion auf GitHub ist nützlich, um herauszufinden, welcher Commit jede einzelne Codezeile eingeführt oder zuletzt geändert hat. Um sie zu aktivieren, wechselt man beim Anzeigen einer Datei von der Registerkarte Code zur Registerkarte Blame oder wählt eine bestimmte Zeile aus (auf deren Nummer klicken), die Taste ... drücken und View git blame wählen. Weitere Informationen zur Blame-Funktion findet man in diesem Forumbeitrag. Der zugehörige Git-Befehl ist hier dokumentiert.
git bisect ist eine Methode, um den spezifischen Commit zu finden, der einen Fehler verursacht hat.
Es müssen zwei Commits gefunden werden:
abcd) vor dem Ausfall des Systems.efgh) nach dem Ausfall des Systems.Dann Folgendes über das Terminal eingeben:
git bisect start
git bisect good abcd
git bisect bad efgh
Ergebnis: git checkt den Mittelpunkt zwischen den beiden Commits aus.
Der nächste Schritt besteht darin, den Code zu erstellen und zu testen. Wenn das System funktioniert, fährt man mit der Eingabe von folgendem Befehl fort:
git bisect good
Den vorherigen Schritt wiederholen, indem man den Code erstellt und testet.
Wenn das System defekt ist, gibt man Folgendes ein:
git bisect bad
Die vorherigen Schritte wiederholen und dabei je nach Ergebnis der Tests good oder bad anwenden.
Schließlich wird git mitteilen, dass wxyz der erste fehlerhafte Commit ist.
Um den bisect-Prozess zu beenden, gibt man schließlich Folgendes ein:
git bisect reset
Hinweis: git bisect dauert sehr lange, wenn gute und schlechte Ergebnisse weit auseinander liegen.
Im Gegensatz zu Subversion, das für seine Revisionen eine fortlaufende Nummer verwendet, erzeugt Git bei jedem Commit SHA-1-Hashwerte. Ein Hashwert ist eine lange alphanumerische Zeichenfolge, die wie folgt aussieht
9b3ffef570596e184006287434fba54a4b03ccc3
Um die neueste Revisionsnummer eines bestimmten Branches zu ermitteln, verwendet man den Befehl rev-list mit der Option --count. Gibt den Namen des Branches, des Remote-Repositorys, des Tags oder eines speziellen Zeigers wie HEAD an, um den letzten Commit in diesem bestimmten Objekt anzugeben.
git rev-list --count main
git rev-list --count HEAD
git rev-list --count origin
Oder man durchsucht das Repository auf GitHub und liest die Anzahl der Commits, die in dem jeweiligen Branch gemeldet werden.
Da es sich bei dem Hash um eine alphanumerische Zeichenfolge handelt, ist es nicht sehr sinnvoll, zu entscheiden, ob ein bestimmter Commit älter oder neuer als ein anderer Hash ist. Um die Revisionsnummer eines bestimmten Hashs zu ermitteln, verwendet man erneut die Operation rev-list. Als Eingabe kann der vollständige Hash oder ein eindeutiger Teil-Hash verwendet werden, wobei in der Regel die ersten 7 Ziffern ausreichen.
git rev-list --count ab1520b872821414c6ce4a15fb85d471ac2a2b03
git rev-list --count 9948ee4
Wenn wir die Commit-Nummer haben, beispielsweise 15000, und den entsprechenden Hash finden möchten, müssen wir die Anzahl der Commits seit diesem Zeitpunkt bis zum letzten Commit (HEAD) berechnen. Zunächst muss die neueste Commit-Nummer abgerufen werden.
git rev-list --count HEAD
17465
Dann subtrahiert man den gewünschten Commit.
17465 - 15000 = 2465
Dann den Befehl log verwenden, um alle Commits und Hashes anzuzeigen. Die Option --skip überspringt die von uns berechneten Unterschiede zwischen den Commits, sodass wir direkt zu dem gesuchten Hash gelangen.
git log --skip=2465
commit 44c2f19e380e76b567d114a6360519d66f7a9e24
Da das Protokoll möglicherweise zwei nahe beieinander liegende Commits anzeigt, überprüfen, ob es sich um die richtige Commit-Nummer handelt. Wenn sie um eins abweicht, einfach den nächsten Commit in der Reihenfolge wählen (vor oder nach) und erneut überprüfen.
git rev-list --count 44c2f19e38
15000
commit in commits ändern, um eine Liste anzuzeigen.
Die Versionsnummer, die mit dem Std Über Werkzeug angezeigt wird, ist in src/Build/Version.h definiert, was zur Kompilierzeit erstellt wird, wenn das Werkzeug cmake ausgeführt wird. Lies Versionsnummer aus der Git Quelle extrahieren für weitere Informationen.
Mehrere Mitarbeiter des FreeCAD Projekts haben ihre eigenen Git Repositorien, in denen sie ihre Arbeit aufbauen oder neue Ideen ausprobieren, bevor sie bereit sind, in den offiziellen Quellcode aufgenommen zu werden. Vielleicht möchtest du ihre Quellen bekommen, um ihren Code selbst zu testen, wenn sie eine Pull Anfrage stellen.
Verwende den Befehl git fern Befehl, um diese anderen Repositorien hinzuzufügen, so dass du deren Code holen und abrufen kannst.
git checkout main
git remote add OTHER_USER OTHER_URL
git fetch OTHER_USER
git checkout -b OTHER_BRANCH OTHER_USER/OTHER_BRANCH
Lass uns zum Beispiel Bernds Fernrepositorium hinzufügen:
git remote add bernd http://github.com/berndhahnebach/FreeCAD_bhb
Der git holen Befehl lädt die Referenzen von diesem Fernrepositorium herunter.
git fetch bernd
Liste alle Zweige in deinem eigenen Repositorium und die von deinen hinzugefügten Fernen auf. Bernds Zweige werden als Fern/bernd/<Zweigname> angezeigt.
git branch -a
Lass uns nun eine zusammenfassende Liste der letzten 10 Commits von bernds femdev Zweig ansehen.
git log -10 --oneline remotes/bernd/femdev
Jetzt können wir den gewünschte Zweig zur Inspektion herausfinden.
git checkout remotes/bernd/femdev
Dann können wir einen lokalen Zweig erstellen, der auf dem entfernten Zweig basiert. Diesen lokalen Zweig können wir modifizieren und unseren eigenen Code hinzufügen.
git checkout -b local_branch_name /remotes/bernd/femdev
Du kannst den git rebase des neu erhaltenen Zweigs auf den upstream/main Zweig umstellen, um sicherzustellen, dass er den neuesten Code verwendet. Wenn es Konflikte gibt, müssen diese an diesem Punkt gelöst werden.
git pull --rebase upstream main
Der neue Zweig ist bereit, modifiziert und kompiliert zu werden, wie in Kompilieren beschrieben.
Besuche die Entwicklungsabteilung des FreeCAD Forums, um mehr über die Entwicklung zu erfahren.
git.