Git-Workflow für C++-Entwickler: Vom Chaos zur Ordnung

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Git-Workflow für C++-Entwickler: Wenn Commits die Nerven retten

\n\n

Haben Sie schon einmal einen halben Tag mit dem Zusammenführen von Branches in einem C++-Projekt verbracht, nur damit der Compiler Ihnen 500 Fehler ausspuckt, weil jemand versehentlich Ihre Header-Datei überschrieben hat? Kommt Ihnen das bekannt vor? Wenn ja – dieser Artikel ist für Sie. Wenn nein – sind Sie entweder ein Genie oder haben noch nie in einem Team mit mehr als zwei Personen gearbeitet.

\n\n

C++ ist an sich schon eine komplexe Sprache. Da haben Sie die manuelle Speicherverwaltung, Templates und den Präprozessor, der sein eigenes Leben führt. Wenn dann noch Chaos in Git hinzukommt, wird das Projekt zur Hölle. Aber es gibt eine gute Nachricht: Ein richtiger Git-Workflow kann Ihr C++-Projekt von einem „Sumpf“ in ein „Schweizer Uhrwerk“ verwandeln. Lassen Sie uns herausfinden, wie das funktioniert.

\n\n

Warum brauchen C++-Projekte einen besonderen Ansatz für Git?

\n\n

C++ unterscheidet sich von Python oder JavaScript. Wir haben keinen Interpreter, der Ihnen ein überflüssiges Komma verzeiht. Wir haben einen Compiler, der aufgrund einer falschen Reihenfolge von Includes einen Fehler ausgeben kann. Und dann gibt es noch Binärdateien, die Gigabytes wiegen, und Bibliotheken, deren Build stundenlang dauert.

\n\n

Daher funktionieren Standardansätze wie „alles in master committen und losrennen“ hier nicht. In C++-Projekten muss ein Git-Workflow drei Kernaufgaben lösen:

\n\n
    \n
  • Minimierung von Konflikten in Header-Dateien – .h-Dateien ändern sich häufig, und ihr Merge ist eine Qual.
  • \n
  • Versionskontrolle von binären Abhängigkeiten – Bibliotheken, die für verschiedene Plattformen gebaut wurden, sollten nicht durcheinandergeraten.
  • \n
  • Automatisierung von Build und Tests – CI muss überprüfen, dass Ihr Code kompiliert, und nicht nur „irgendwie funktioniert“.
  • \n
\n\n

Und ja, wir werden über echten C++-Code sprechen. Kein Blabla.

\n\n

Das Branching-Modell wählen: Git Flow oder etwas Einfacheres?

\n\n

Für C++-Projekte empfehle ich Git Flow mit kleinen Anpassungen. Warum? Weil C++-Projekte in der Regel langlebig sind, mit Releases, die wochenlang vorbereitet werden. Sie brauchen einen stabilen develop-Branch, feature-Branches für neue Funktionen und release-Branches zur Vorbereitung auf ein Release.

\n\n

Aber wenn Sie ein kleines Projekt oder eine Bibliothek machen – verwenden Sie GitHub Flow (ein main-Branch + feature-Branches). Hauptsache, Sie mergen nicht in main ohne Code-Review und CI.

\n\n

Branch-Struktur für ein C++-Projekt

\n\n
main          — stabiler Code, nur Releases\ndevelop       — Integrationsbranch\nfeature/*     — neue Funktionen (z. B. feature/logger-refactoring)\nrelease/*     — Release-Vorbereitung (release/v2.1.0)\nhotfix/*      — dringende Fehlerbehebungen (hotfix/crash-on-exit)\n
\n\n

Ein Beispiel aus der Praxis: Sie schreiben eine Bibliothek zur Arbeit mit JSON. Sie müssen Unterstützung für Streaming-Parsing hinzufügen. Erstellen Sie einen Branch feature/stream-parsing, arbeiten Sie dort, und wenn alles fertig ist, machen Sie einen Pull Request in develop.

\n\n

Arbeiten mit Commits: Wie man kein „Chaos“ bekommt

\n\n

In C++ ist es entscheidend, dass jeder Commit kompilierbar ist. Warum? Denn wenn Sie kaputten Code committen und dann Mittagspause machen, könnte Ihr Kollege einen Rebase durchführen und einen Kompilierungsfehler erhalten. Und Sie sind schuld.

\n\n

Regel: git commit erst, nachdem der Code fehlerfrei gebaut wurde. Auch wenn es „noch nicht fertig, aber muss gespeichert werden“ ist – committen Sie nicht. Verwenden Sie git stash.

\n\n

Beispiel für einen schlechten Commit

\n\n
// Datei: parser.cpp\n// Commit: "angefangen, Parser zu machen"\n#include "parser.h"\n// TODO: fertigschreiben\n
\n\n

Ein solcher Commit wird nicht kompilieren, weil in parser.h möglicherweise eine Funktion deklariert ist, die nicht implementiert ist. Machen Sie das nicht.

\n\n

Beispiel für einen guten Commit

\n\n
// Datei: parser.cpp\n// Commit: "Basisklasse Parser mit virtueller Methode parse() hinzugefügt"\n#include "parser.h"\n\nclass JsonParser : public Parser {\npublic:\n    JsonResult parse(const std::string& input) override {\n        // Basisimplementierung\n        return JsonResult{};\n    }\n};                

Blogs

Buchempfehlungen