GIT Einführung und Best Practices

Ob Entwicklung, Test, Betrieb oder Projektmanagement – Git ist nicht nur ein Thema für Developer. Es ist ein zentrales Werkzeug, das die Zusammenarbeit im gesamten IT-Team unterstützt und absichert. Doch was macht Git eigentlich so wertvoll?

Zentraler Zugriff auf den Code

Mit Git arbeitet das ganze Team an einer gemeinsamen Codebasis. Egal ob Backend, Frontend, Testautomatisierung oder Infrastruktur-as-Code – alle Dateien liegen im selben Repository. Das sorgt für Transparenz und verhindert, dass einzelne Teammitglieder mit unterschiedlichen Versionen arbeiten. Jeder kann nachvollziehen, wie sich der Code entwickelt und welche Änderungen aktuell sind.

Nachvollziehbarkeit von Änderungen

Git protokolliert jede Änderung. Wer hat wann was geändert – und warum? Diese Informationen sind Gold wert, wenn man verstehen möchte, warum ein Fehler entstanden ist oder wie ein Feature genau implementiert wurde. Gute Commit-Nachrichten und sauber strukturierte Branches machen es möglich, die Entwicklung lückenlos nachzuvollziehen.

Sicherheit durch Versionierung

Mit Git ist jede Änderung gesichert. Man kann jederzeit auf einen früheren Stand zurückspringen – etwa wenn nach einem Deployment plötzlich ein Fehler auftritt. Git fungiert damit wie ein intelligentes Backup-System für die gesamte Codebasis. Es schützt nicht nur vor Datenverlust, sondern gibt auch Sicherheit bei Experimenten und schnellen Hotfixes.

Git Basics – Die wichtigsten Konzepte

Repository

Ein Repository ist der Speicherort für den Projektcode und dessen gesamte Versionsgeschichte. Man unterscheidet zwischen zwei Arten:

  • Das lokale Repository liegt auf dem eigenen Rechner. Hier arbeitet man direkt am Code, führt Änderungen durch und sichert diese in Form von Commits.
  • Das Remote Repository liegt auf einem Server, zum Beispiel bei GitHub oder GitLab. Es dient als zentrale Anlaufstelle für das gesamte Team. Von hier wird der Code verteilt, synchronisiert und zusammengeführt.

Ein typischer Arbeitsablauf beginnt damit, dass man ein Remote Repository einmalig klont und anschließend lokal daran arbeitet.

Commit und Push

Änderungen am Code werden in sogenannten Commits gesichert. Jeder Commit enthält eine Momentaufnahme der geänderten Dateien sowie eine Nachricht, die beschreibt, was geändert wurde. So entsteht eine nachvollziehbare Änderungshistorie.

Sobald ein oder mehrere Commits lokal erstellt wurden, kann man sie durch einen Push an das Remote Repository übertragen. Erst dann werden die Änderungen für andere sichtbar.

Pull

Während man selbst Änderungen vornimmt, arbeitet auch das Team weiter. Damit die eigene lokale Version aktuell bleibt, werden die Änderungen anderer Teammitglieder regelmäßig aus dem Remote Repository abgerufen. Dieser Vorgang heißt Pull.

Branch

Ein Branch ist ein Entwicklungszweig, in dem Änderungen isoliert vorgenommen werden können. Auf diese Weise lassen sich neue Features, Bugfixes oder Experimente entwickeln, ohne den Hauptzweig des Projekts zu beeinflussen.

Ein Projekt hat in der Regel einen Hauptbranch (z. B. main oder master), von dem aus neue Branches erstellt und später wieder integriert werden.

Merge

Wenn ein Branch fertig entwickelt wurde, sollen die Änderungen wieder in den Hauptzweig einfließen. Mit einem Merge werden die beiden Zweige zusammengeführt, wobei die komplette Entwicklungshistorie erhalten bleibt. Git erstellt dabei einen zusätzlichen Merge-Commit, der die Zusammenführung dokumentiert und die Nachvollziehbarkeit sicherstellt.

Log und History

Git speichert jede Änderung mit Zeitstempel, Autor und Nachricht. Über die Historie lässt sich jederzeit nachvollziehen, wer wann welche Änderung vorgenommen hat. Das ist besonders hilfreich, wenn man verstehen möchte, warum ein bestimmter Fehler auftritt oder wie sich ein Feature entwickelt hat.

Video mit Demo zu diesem Abschnitt.

GIT im täglichen Einsatz & Best Practices

Git Kommandozeile oder Tools

Git kann auf unterschiedliche Weise genutzt werden – je nach persönlicher Vorliebe und eingesetztem Werkzeug. Viele moderne Entwicklungsumgebungen wie IntelliJ IDEA oder Visual Studio Code haben Git bereits integriert. So lassen sich typische Aktionen wie Commit, Pull oder das Anlegen von Branches direkt aus der IDE heraus durchführen – ohne zwischen Programmen wechseln zu müssen.

Alternativ kann man Git auch direkt über die Kommandozeile bedienen. Das bietet maximale Kontrolle und hilft dabei, die Abläufe im Hintergrund besser zu verstehen. Besonders für wiederkehrende Aufgaben oder automatisierte Prozesse ist die Kommandozeile oft die bevorzugte Wahl.

Ein weiterer beliebter Weg ist die Nutzung von TortoiseGit. Dieses Tool integriert sich direkt in den Windows Explorer und macht viele Git-Funktionen über das Kontextmenü mit der rechten Maustaste zugänglich. Gerade wer häufig mit Dateien und Ordnern arbeitet, profitiert von dieser nahtlosen Einbettung in die gewohnte Arbeitsumgebung.

Bei kleinen Änderung

Pull first

Bevor man Änderungen an einem Projekt vornimmt, sollte man sich angewöhnen, zunächst einen Pull durchzuführen. Damit stellt man sicher, dass man auf dem aktuellen Stand des Remote-Repositories arbeitet und alle Änderungen der Teammitglieder berücksichtigt.

Gerade bei kleineren Anpassungen – etwa an Konfigurationsdateien, Texten oder Dokumentation – ist die Gefahr groß, dass mehrere Personen gleichzeitig dieselbe Datei bearbeiten. Ein vorheriger Pull reduziert das Risiko von Merge-Konflikten erheblich und sorgt dafür, dass die eigenen Änderungen reibungslos integriert werden können.

Diese einfache Gewohnheit spart im Alltag viel Zeit und vermeidet unnötige Unterbrechungen im Arbeitsfluss.

Review vor Commit & Push

Bevor Änderungen committet und gepusht werden, sollte man sie kurz überprüfen. Ein Blick auf die geänderten Dateien und Inhalte hilft, versehentliche Änderungen oder temporäre Code-Anpassungen zu erkennen. Dieser Schritt verbessert die Qualität und verhindert unnötige Korrekturen im Nachhinein.

Gute Commit-Message mit Ticket-Referenz

In der Teamarbeit ist eine eindeutige Ticket-Referenz in der Commit-Message besonders wichtig. Sie ermöglicht es, jede Änderung direkt einer Aufgabe oder einem Fehlerbericht zuzuordnen. Idealerweise folgt die Nachricht einem einheitlichen Format im Team – zum Beispiel: 
JIRA-123: Validation for email field added 
Ein kurzer, präziser Satz reicht meist aus, wenn er zusammen mit der Ticket-ID den Kontext klar macht.

Ein Commit – eine Änderung

Ein Commit sollte sich immer auf genau eine inhaltliche Änderung konzentrieren. Wenn man beispielsweise gleichzeitig die Texte in der Benutzeroberfläche ändert und ein neues Logging einführt, gehören diese Änderungen in getrennte Commits. So bleibt die Historie nachvollziehbar, und einzelne Änderungen lassen sich bei Bedarf gezielt zurückverfolgen oder rückgängig machen.

Revert statt Löschen

Ein Revert nimmt eine Änderung zurück, indem ein neuer Commit erzeugt wird, der genau das Gegenteil der ursprünglichen Änderung macht. Der ursprüngliche Commit bleibt in der Historie erhalten, sodass der Verlauf vollständig nachvollziehbar bleibt – es gibt also keine Löschung, sondern eine bewusste Korrektur.

Ein Revert muss nicht unbedingt einen Fehler beheben. Manchmal hat man bewusst etwas ausprobiert, das später nicht mehr benötigt wird, und möchte es daher zurücknehmen. Dabei entstehen nach einem Revert zwei Commits im Branch: der ursprüngliche Commit und der Revert-Commit.

Obwohl es grundsätzlich möglich ist, Commits zu löschen, ist dies in der Praxis eher umständlich.

Große Änderung mit feature-Branches

Bei größeren Änderungen, die umfangreiche Anpassungen oder die Entwicklung neuer Funktionen betreffen, ist es ratsam, einen Feature-Branch zu verwenden. Ein Feature-Branch ist ein separater Entwicklungszweig, der vom Hauptzweig (z. B. main oder master) abzweigt und speziell für die Entwicklung eines bestimmten Features oder einer größeren Änderung gedacht ist.

Der Vorteil von Feature-Branches liegt darin, dass man isoliert an neuen Funktionen arbeiten kann, ohne die Stabilität des Hauptzweigs zu gefährden. Änderungen im Feature-Branch werden lokal entwickelt, getestet und überprüft, bevor sie durch einen Merge oder Pull-Request in den Hauptzweig integriert werden.

Mit dieser Methode bleibt der Hauptzweig stets stabil und funktionsfähig, während das Team parallel an neuen Features oder Verbesserungen arbeitet. Feature-Branches bieten außerdem den Vorteil, dass mehrere Teammitglieder gleichzeitig an verschiedenen Features arbeiten können, ohne dass sich ihre Änderungen gegenseitig beeinflussen.


Rebase

Ein Rebase wird häufig eingesetzt, bevor ein Feature-Branch in den master- oder main-Branch gemerged wird. Ziel ist es, den Feature-Branch auf den aktuellen Stand des Hauptzweigs zu bringen, um spätere Merge-Konflikte zu vermeiden. Dabei werden die eigenen Commits so umgehängt, als wären sie auf dem aktuellen Stand von master entstanden.

Technisch gesehen verschiebt Git dabei die Commits aus dem Feature-Branch auf die aktuelle Spitze des Hauptzweigs. So entsteht eine lineare Historie, in der alle Änderungen sauber aufeinander folgen – ganz ohne zusätzlichen Merge-Commit.


Empfehlung: Merge mit Squash

Bevor ein Feature-Branch in den master- oder main-Branch gemerged wird, empfiehlt es sich, alle Commits aus dem Feature-Branch zu einem einzigen Commit zusammenzufassen – dieser Vorgang wird „Squash“ genannt. Gerade bei der Entwicklung eines Features entstehen oft viele kleine Commits, die aus Sicht der Projekt-Historie nicht einzeln relevant sind.

Ein Merge mit Squash sorgt dafür, dass im Hauptzweig nur ein klar benannter Commit auftaucht, der das gesamte Feature beschreibt. Das hält die Historie übersichtlich und hilft, die Entwicklungsschritte später leichter nachzuvollziehen.

Diese Methode ist besonders nützlich bei der Arbeit im Team, da sie Wildwuchs in der Historie vermeidet und den Überblick über eingeführte Features erleichtert.

Git Blame - wer war es?

Mit dem Git-Befehl blame kann man herausfinden, wer eine bestimmte Zeile in einer Datei zuletzt geändert hat – und in welchem Commit das passiert ist. Das ist besonders hilfreich, wenn man verstehen möchte, warum ein bestimmter Code geschrieben wurde oder wer bei Rückfragen der richtige Ansprechpartner ist.

Git Diff - was hat sich genau geändert?

Mit git diff kann man sich Unterschiede zwischen zwei Versionen von Dateien anzeigen lassen – etwa zwischen dem aktuellen Stand im Arbeitsverzeichnis und dem letzten Commit oder zwischen zwei Branches. So sieht man genau, welche Zeilen hinzugefügt, geändert oder entfernt wurden.

Tags

Tags in Git sind Markierungen, mit denen bestimmte Commits eindeutig gekennzeichnet werden – etwa für Versionen, die für den Produktivbetrieb freigegeben wurden. Ein Tag ist fest mit einem bestimmten Stand des Codes verbunden und verändert sich nicht mehr.

Tags eignen sich besonders gut zur Kennzeichnung von produktionsreifen Versionen. Anstatt separate Branches wie release oder prod zu pflegen, kann direkt ein Tag auf den Commit gesetzt werden, der in Produktion geht. So bleibt die Historie klar und nachvollziehbar: Man erkennt genau, welche Version zu welchem Zeitpunkt deployed wurde.

In vielen Projekten werden Tags nach dem Prinzip der semantischen Versionierung vergeben – zum Beispiel v1.0.5. So lässt sich schnell erkennen, ob es sich um einen neuen Funktionsumfang, ein Bugfix oder eine größere Änderung handelt.

Fazit

Git ist weit mehr als nur ein Versionierungstool – es ist ein unverzichtbares Fundament moderner Softwareentwicklung und ein Schlüsselbestandteil effektiver Teamzusammenarbeit. Git ermöglicht nicht nur die Verwaltung von Code, sondern spielt auch eine zentrale Rolle in modernen Release- und Deployment-Prozessen. Durch die enge Integration in Build- und Deployment-Pipelines können Änderungen im Git-Repository automatisch ganze Prozesse anstoßen, von der Erstellung von Builds bis hin zum Deployment in die Produktion. Dies fördert eine nahtlose und automatisierte Entwicklung und sorgt für eine effiziente, fehlerresistente Bereitstellung von Software.


Beliebte Posts aus diesem Blog

CronJobs mit Spring

Kernkonzepte von Spring: Beans und Dependency Injection

OpenID Connect mit Spring Boot 3