Das Git Tutorial – Die Git Grundlagen
Mit diesem Git Tutorial / Git Grundlagen werden Sie zum Git Profi!
Wir haben uns entschieden, einen mehrteiligen Blog zum Thema Git zu schreiben, beginnend bei den Git Grundlagen. Außerdem sind folgende Themen entstanden:
- Einführung in die Welt von Git
- Arbeiten mit Git und SAPUI5 Entwicklung mit Git
Sollten Sie Fragen zum Thema Git haben, hinterlassen Sie ganz einfach eine Nachricht!
In diesem Blog werden wir uns mit dem Thema Git beschäftigen und damit, warum das Arbeiten mit Git oder mit einem ähnlichen Tool für Entwickler fast schon unumgänglich ist.
Zielsetzung
Unser Ziel ist es, dass Sie nach diesem Git Tutorial die unten stehende Grafik interpretieren und Ihre Entwicklungen mit Git optimieren können.

Wichtig
Seitdem GitHub die Namenskonventionen umgestellt hat, heißt der Strang, der automatisch angelegt wird, nicht mehr „master“ bzw. „origin/master“, sondern „main“ und „origin/main“.
Inhaltsverzeichnis
Begrifflichkeiten:
- Repository
- Branch
- Commit
- Staging Area
Funktionen:
- Push
- Clone
- Fetch
- Merge
- Pull
- Best practice
- Rebase
- Reset (Hard Reset & Mixed Reset)
Über den Autor

Daniel Krancz
SAP-Consultant / Software-Developer
Ich bin SAP-Berater und -Entwickler im SAPUI5/Fiori- und OData-Umfeld. Seit 2019 bin ich offiziell als externer Trainer bei SAP gelistet und halte Kurse (UX, S4, …) über SAP-Webentwicklungen und Cloud-Implementierungen im In- und Ausland. Seit 2021 bin ich SAP Press Autor beim Rheinwerk Verlag im Bereich SAP Mobile.
Welche Begriffe sind im Git Umfeld üblich?
Bei unserem Git Tutorial erklären wir die wichtigsten Begrifflichkeiten und gängigsten Funktionen im Git-Umfeld. Mehr über die Git Grundlagen erfährt ihr hier:
Repository
Ein Repository kann mit einem einfachen Verzeichnis verglichen werden, in welchem weitere Verzeichnisse und Dateien abgelegt werden können. Ein Repository beinhaltet normalerweise ein Projekt bzw. ein Programm.
Es gibt eine Unterscheidung zwischen einem Remote (am Server oder in der Cloud) und einem Local (in der IDE) Repository.

Branch
Ein Repository beinhaltet mindestens einen Entwicklungsstrang, kann aber auch in mehrere Entwicklungsstränge unterteilt werden. Diese Stränge nennt man Branches.
Branches benutzt man entweder um Systemlandschaften (z.B. DEV, QAS und PRD) oder Feature-Entwicklungen (z.B. eine neue Funktionalität für Kunden) abzubilden. Die Unterteilung in den Landschaften ist üblicherweise am Remote Repository vertreten.
Je nachdem wo die Branches liegen, redet man von Remote und Local Branches.

Wenn man ein Remote Repository erstellt, so wird automatisch auch der erste Branch mit dem Namen „origin/master“ angelegt. Bei einem Local Repository heißt der erste Branch nur „master“.
Commit
Einen Commit kann man mit einem Snapshot, sprich mit einer Momentaufnahme, vergleichen. Diese Momentaufnahme beinhaltet die gesamten Änderungen seit dem letzten Commit. Diese Commits werden mit bestimmten Daten (Description, ID, Author, Timestamp, …) versehen und abgespeichert.
Ein Commit ist somit die kleinste „Einheit“ im Git-Umfeld.

Staging Area
In der Staging Area befinden sich alle Files, die seit dem letzten Commit editiert wurden. Das heißt, die Staging Area ist ein Ort für das Zwischenspeichern der Änderungen. Zusätzlich kann man auswählen, welche Änderungen aus der Staging Area man beim nächsten Commit mitnehmen möchte.
So könnte man X Änderungen aus der Staging Area auf Y Commits aufteilen und so einen sauberen Entwicklungsstrang abbilden.
Welche Funktionen gibt es im Git Umfeld?
Natürlich gehören zu den Git Grunlagen die Git Funktionen, anbei gehen wir auf die gängigsten Funktionen ein, mit der man Repositories und Branches manipulieren kann. Wir werden uns nur die wichtigsten anschauen (Push, Fetch, Merge, Pull, Clone, Rebase), aber es gibt noch um einiges mehr (Cherry-Pick, Stashing, …).
Push
Wenn man in der IDE entwickelt und irgendwann einen Stand hat, den man mit anderen Entwicklern teilen möchte, dann muss man den letzten Commit mit einem Push in das Remote Repository bringen.
Da das Remote Repository am Anfang leer ist, kann der erste Entwickler, der z.B. das Rahmenprojekt aufgesetzt hat, seine Entwicklungen ohne Rücksicht pushen:

Später sollte vor jedem Push gecheckt werden, ob sich am Remote Repository etwas geändert hat. Wie das funktioniert, erfahren Sie weiter unten.
Clone
Es kann nur einen ersten bzw. initialen Push geben. Wenn also sich am Remote Repository bereits Daten befinden, dann muss ich das Ganze in meine lokale Umgebung bekommen.
Das funktioniert mit einem Clone:

Fetch
Mit einem Fetch kann ich die Änderungen, die seit meinem letzten Fetch gemacht wurden, in die lokale Umgebung laden. Einfacher ausgedrückt: Wir schauen nach, ob andere Entwickler was Neues gemacht haben.

Merge
Nur nachschauen, ob andere Entwickler etwas gemacht haben, reicht noch nicht ganz aus. Wir müssen die Datenstände zusammenführen und diesen Vorgang nennt man Merge.
Wir haben vorhin, als wir über Branches geredet haben, etwas verschwiegen. Die Namen für Branches sind nichts anderes wie Pointer bzw. Zeiger. Ein Zeiger auf den aktuellen Commit, sprich auf den letzten Snapshot.
Was bei einem Merge technisch passiert ist ganz einfach: Der Zeiger von meinem altem Commit, wird auf den neuen Commit gesetzt, welchen wir uns mit einem Fetch geladen haben. Dabei wird geschaut, ob sich Änderungen überschneiden. Wenn sich Änderungen überschneiden, gibt es Konflikte.

Auf Konflikte wird man immer hingewiesen und der Entwickler, der die Zusammenführung macht, kann entscheiden, welche Code-Passagen die Aktuellen sind. Ein Merge wird in einem eigenen Commit protokolliert.
Pull
Man sieht jetzt schon, dass man Fetch und Merge oft brauchen wird. Das haben sich auch die Entwickler von Git gedacht und deswegen die Funktion Pull ins Leben gerufen.
Pull führt zuerst einen Fetch und dann automatisch einen Merge aus:

Zu diesem Git Tutorial gehört natürlich auch Best practice
Einmalig:
- Clone or Initial Commit and Push
- wenn ich der erste bin = Push
- App vom Remote Repository clonen
Wiederkehrend:
- Fetch: schauen ob sich was getan hat
- Merge: den Zeiger auf die aktuelle Version verschieben und die Datenstände zusammenführen (auf eventuelle Konflikte reagieren)
- Push: die aktuelle Version mit anderen Entwicklern teilen
- Pull: schauen ob sich was getan hat, den Zeiger auf die aktuelle Version verschieben und die Datenstände zusammenführen (auf eventuelle Konflikte reagieren)
- Push: die aktuelle Version mit anderen Entwicklern teilen
Wir kennen jetzt viele Begriffe und kennen auch schon die wichtigsten Funktionalitäten. Jetzt gehen wir nochmal auf die Branches ein und bringen all das Wissen mit, was wir gelernt haben.
Wir haben gesagt, dass auch am Remote Repository Branches erstellt werden können (z.B. P,Q,D), aber auch am Local Repository (z.B. Features).
Gehen wir von folgendem Beispiel aus: Es existiert bereits ein Repository und da wir jetzt auch im Entwicklerteam sind, können wir vom Remote Repository vom Entwicklungsbranch die aktuellen Stände clonen.

Wir machen sicherheitshalber einen Local Feature Branch wo wir einige Entwicklungen und auch Commits machen. Nach einigen Entwicklungstagen sind wir fertig und mergen lokal unsere Features mit dem lokalen Master.

Bevor wir unsere Änderungen mit anderen teilen können, müssen wir checken, ob andere Entwickler auch zwischenzeitlich gepusht haben und führen einen Fetch und danach Merge bzw. einen Pull aus.

Nachdem wir uns mit bei dem Git Tutorial mit einigen Konflikten beschäftigen durften, können wir nun endlich unsere Änderungen pushen und mit anderen Entwicklern teilen.
Unser Administrator nimmt nach eigenem Ermessen die Datenstände und macht einen Merge zwischen D und Q und signalisiert somit dem Testteam, dass sie testen können.
Wenn die Tests abgeschlossen sind, dann kann der Administrator zwischen Q und P einen Merge durchführen. Der P-Branch wird dann entweder exportiert oder der Administrator deployed ihn direkt auf das Kundensystem und der Kunde hat nun eine neue Version der Applikation.

Rebase
Wenn wir uns die obenstehende Grafik genauer anschauen, dann werden wir erkennen, dass durch einen Merge immer ein „unnötiger“ Commit entsteht.
Durch Rebase können wir auch dieses – oft von Entwicklern empfundene – Designproblem lösen und einen sauberen Entwicklungsstrang ohne „Merge-Commits“ aufbauen.
Nehmen wir an, wir haben lokal einen Feature Branch gemacht. Dort haben wir fleißig entwickelt und möchten jetzt unsere Änderungen wieder auf den Master Branch bekommen:

Wenn wir jetzt ein Rebase von unserem Feature auf den Master Branch machen, dann schauen unsere Commits wie folgt aus:

Nichtsdestotrotz müssen wir an dieser Stelle noch einen Merge machen, da passiert aber wiederum nichts anderes, als das der Zeiger von dem alten Commit auf den neuesten Commit bewegt wird, jedoch mit dem Unterschied, dass wir an dieser Stelle keinen zusätzlichen Commit für das Mergen erzeugen:

Jetzt schaut unser Master Branch sauber aus, wir haben einen sauberen Entwicklungsstrang und ein Außenstehender würde meinen, dass wir keinen Feature Branch – sprich keinen weiteren Branch – für die Entwicklung verwendet haben.
Git Grundlagen: Rebase mit Konflikten
Wenn es zu einem Konflikt kommt, so wird das nicht, wie bei einem Merge, in einem extra Commit verpackt, sondern die zwei Commits, die von den Änderungen betroffen sind, werden entweder fusioniert oder einer von den beiden Commits gewinnt. Entscheidungsträger ist hier wiederum der Entwickler, der gerade einen Rebase vornimmt.
Reset
Viele „Git-Neulinge“ verwechseln Reset mit Rebase. Oft glaubt man, dass Rebase irgendetwas mit dem Zurücksetzen der Änderungen zu tun hat, was aber nicht stimmt.
Mit Reset hat man zwei Möglichkeiten um das Zurücksetzen der Daten bzw. den Änderungen bis zu einem, in der Vergangenheit liegenden, bestimmten Commit zu erreichen:
Hard Reset
Gehen wir davon aus, dass wir einen Feature Branch eröffnet haben und dem Feature, welches ein Change Request vom Kunden war, eine Absage erteilt wird. Wir wissen schon, dass wir an einem weiteren Feature arbeiten werden, welches aber nichts mit unserem bisherigen Feature Entwicklungen zu tun hat.

In diesem Fall werden wir einen Hard Reset machen. Die bisherigen Entwicklungen am Feature Branch werden verworfen und der Feature Branch wird mit dem ausgewählten Branch, in unserem Fall dem Master Branch, gemerged um wieder auf dem gleichen Datenstand zu sein:

Mixed Reset
Bei einem Mixed Reset schaut das ganze fast gleich aus, mit dem Unterschied, dass wir nicht alles verwerfen, sondern einige Änderungen, die sich in der Staging Area befinden, mitgenommen werden können.
Möchten Sie noch mehr über Git erfahren, dann haben wir hier noch das eine oder andere Git Tutorial:
Sind Sie auf der Suche nach SAP Cloud Consulting oder ganz allgemein SAP Beratung in Österreich, Deutschland oder der Schweiz? Dann sind Sie bei uns genau richtig! Wir bringen Sie sicher in die Cloud – we deliver !
Verlieren Sie keine Zeit - kontaktieren Sie uns jetzt
Zögern Sie nicht uns zu kontaktieren. Mit Fragen zum SAP Cloud Connector, zur SAP BTP, zur SAP Cloud Platform, zur SAP CPI, zur SAP Integration Suite und anderen innovativen Themen sind Sie bei uns genau an der richtigen Adresse!