Versionsverwaltungssystem (VCS - version control systems) git
¶
Ein Versionsverwaltungssystem (VCS) wie Git hat mehrere Hauptaufgaben, die es erleichtern, den Entwicklungsprozess von Softwareprojekten zu organisieren und zu verwalten.
Aufgaben eines VCS:¶
- Versionskontrolle - Protokollieren von Änderungen
- Erfassen und speicheren von Änderungen an Quellcode (Textdateien) oder anderen Dateien. So kann man auf frühere Versionen des Codes zuzugreifen, Änderungen vergleichen und nachvollziehen, wer wann welche Änderungen vorgenommen hat.
- Archivierung und Wiederherstellung von alten Ständen einzelner Dateien.
- Kollaboratives Arbeiten: Koordinierung des gemeinsamen Zugriffs von mehreren Entwicklern auf die Dateien.
- Verzweigungen (Branching) und Merging: Mehrere Entwicklungszweige parallel pflegen und zusammenführen können.
Wichtige Begriffe¶
- Versionsdatenbank, bei git Repository genannt: Ein Repository (kurz: Repo) in der Kontext von Versionsverwaltungssystemen wie Git ist ein Speicherort, in dem alle Dateien, Verzeichnisse und die zugehörige Versionsgeschichte eines Projekts gespeichert sind. Ein Repository kann auf einem lokalen Computer oder auf einem entfernten Server gehostet werden. Es dient als (zentrale) Datenbank für alle Änderungen, die im Laufe der Zeit am Projekt vorgenommen wurden.
- Commit: Ein Commit ist eine grundlegende Aktion in Git und anderen Versionsverwaltungssystemen. Ein Commit repräsentiert eine einzelne, zusammenhängende Änderung am Code oder eine Gruppe von Änderungen, die als zusammengehörig betrachtet werden. Wenn Sie einen Commit erstellen, speichern Sie effektiv den aktuellen Stand Ihres Codes im Repository.
Repositories, Branches und Tags¶
Ein Repository enthält typischerweise folgende Elemente:
- Dateien und Verzeichnisse: Die eigentlichen Dateien und Ordner des Projekts, die im Repository gespeichert sind.
- Versionsgeschichte: Die Aufzeichnung aller Änderungen, die im Laufe der Zeit am Code vorgenommen wurden. Dies umfasst Informationen wie wer die Änderung vorgenommen hat, wann dies geschah und eine Beschreibung der Änderung.
- Branches: Verzweigungen im Code, die es ermöglichen, unabhängig voneinander an verschiedenen Features oder Bugfixes zu arbeiten.
- Tags: Markierungen, die bestimmte Commits als wichtige Meilensteine kennzeichnen, wie zum Beispiel Veröffentlichungen oder Versionen.
Branches¶
Ein Branch, auch als Zweig bezeichnet, ist eine Abspaltung oder Verzweigung von einem Hauptentwicklungszweig (bei git als "Main" bezeichnet). Diese Verzweigung ermöglicht es, verschiedene Versionen des Codes parallel weiterzuentwickeln. Jeder Branch repräsentiert eine separate Linie der Entwicklung, die unabhängig von anderen Änderungen gemacht werden kann.
Einige wichtige Konzepte rund um Branches sind:
Erstellen von Branches: Entwickler können Branches erstellen, um an neuen Funktionen, Bugfixes oder anderen Änderungen zu arbeiten, ohne den Hauptcode zu beeinflussen. Zum Beispiel kann ein Branch für die Entwicklung einer neuen Softwareversion oder für die Anpassung an unterschiedliche Betriebssysteme erstellt werden.
Merging (Verschmelzen): Nachdem Änderungen in einem Branch getestet und als stabil befunden wurden, können sie wieder in den Hauptentwicklungszweig (Trunk oder Main) integriert werden. Dieser Prozess wird als Merging bezeichnet. Es ermöglicht, die in einem Branch vorgenommenen Änderungen in den Hauptcode zu integrieren, um eine konsistente und fortlaufende Entwicklung sicherzustellen.
Tags: Ein bestimmter Stand eines Branches oder des Hauptentwicklungszweigs kann mit einem Tag gekennzeichnet werden. Ein Tag ist eine Bezeichnung, die es erleichtert, zu einem bestimmten Zeitpunkt in der Versionsgeschichte zurückzukehren, beispielsweise für Veröffentlichungen oder wichtige Meilensteine.
Fork: Wenn ein Zweig in einer neuen, unabhängigen Versionsverwaltung erstellt wird, spricht man von einem Fork. Ein Fork erstellt eine Kopie des gesamten Projekts, und Entwickler können unabhängig davon Änderungen vornehmen. Forks sind häufig in Open-Source-Projekten zu finden, wenn externe Beiträge gemacht werden sollen.
Zusammengefasst ermöglicht die Verwendung von Branches in einem Versionsverwaltungssystem wie Git eine organisierte und parallele Entwicklung, wodurch Teams gleichzeitig an verschiedenen Funktionen arbeiten können, ohne sich gegenseitig zu beeinflussen. Merging ermöglicht es dann, diese Änderungen wieder in den Hauptcode zu integrieren.
Das Erstellen von Branches in Git im Vergleich zu z.B. SVN bietet mehrere Vorteile, die sich aus der dezentralen und flexiblen Natur von Git ergeben. Außerdem sind Brachnes in git leichtgewichtig, d.h. es sind Referenzen/Zeiger, die wenig Speicherplatz benötigen.
Snapshot¶
In Bezug auf Versionsverwaltungssysteme wie Git wird der Begriff "Snapshot" oft verwendet, um einen bestimmten, festen Zustand der Daten oder des Codes zu einem bestimmten Zeitpunkt zu beschreiben. Es ermöglicht eine klare Referenzierung und Wiederherstellung zu diesem Zeitpunkt, falls erforderlich.
Centralized Version Control System vs Decentralized Version Control System¶
Repositories bei git: lokal vs. remote¶
- Lokales Repository: Dies ist das Repository, das sich auf dem lokalen Computer eines Entwicklers befindet. Hier werden alle Änderungen, Commits und Verzweigungen gespeichert. Jeder Entwickler kann auf seinem lokalen System arbeiten und Änderungen vornehmen, ohne dass diese sofort mit anderen geteilt werden müssen.
- Remote Repository: Dies ist das Repository, das auf einem entfernten Server gehostet wird. Es dient als zentrale Anlaufstelle für die Zusammenarbeit im Team. Entwickler können Änderungen von ihren lokalen Repositories auf das Remote Repository hochladen, und umgekehrt können sie Änderungen von anderen Teammitgliedern herunterladen.
In einem Distributed Version Control System (DVCS) hat jeder Entwickler ein lokales Repository, das mittels der Operationen pull
and push
mit dem Remote-Repository synchronisiert wird:
git pull
git push
Commits¶
Ein Commit in Git besteht aus den folgenden Elementen:
- Einzigartige Kennung (Commit-ID oder SHA-1-Hash): Jeder Commit wird durch eine eindeutige Zeichenfolge identifiziert, die durch einen kryptografischen Hash-Algorithmus erzeugt wird. Diese Kennung ermöglicht es, den Commit eindeutig zu identifizieren.
- Autor und Zeitstempel: Der Name des Autors (die Person, die den Commit erstellt hat) und der Zeitpunkt des Commits sind ebenfalls Teil der Commit-Informationen.
- Commit-Nachricht: Eine kurze, aussagekräftige Beschreibung der vorgenommenen Änderungen. Die Commit-Nachricht sollte klar und präzise sein, um anderen Entwicklern zu helfen, den Zweck des Commits zu verstehen.
- Änderungen am Code (inkrementelle Änderung): Der eigentliche Unterschied zwischen dem vorherigen Zustand des Codes und dem aktuellen Zustand, den der Commit repräsentiert. Dies können hinzugefügte, gelöschte oder modifizierte Dateien und Codezeilen sein.
- ID des Parent-Commits
git commit -m "Commit Message
'
Commits die verschiedene Zweige vereinen, werden als Merge-Commits bezeichnet.
Commit-Trees¶
Der Begriff "Commit-Tree" bezieht sich auf die Struktur in einem Versionsverwaltungssystem wie Git, die die Historie der Commits und deren Beziehungen zueinander darstellt. Der Commit-Tree bildet die Verzweigungen, Merges und die chronologische Reihenfolge der Commits ab.
In einem Commit-Tree wird jeder Commit als ein Knoten (Node) betrachtet, und die Kanten (Edges) zwischen den Knoten repräsentieren die Eltern-Kind-Beziehung zwischen aufeinanderfolgenden Commits. Jeder Commit speichert einen Verweis auf seinen Eltern-Commit, und dieser Verweis bildet die Historie der Code-Änderungen ab.
Beispiel eines Commit-Trees:
Knoten im Graphen repräsentieren Commits, und Pfeile stellen die Eltern-Kind-Beziehung zwischen Commits dar (Pfeile zeigen von Eltern zu Kindern). Die HEAD-Commits von drei Branches (develop, feature-1 und feature-2) sind mit einem orangefarbenen Rahmen hervorgehoben.
Abbildung aus Automatic feedback and assessment of team-coding assignments in a DevOps context
HEAD¶
In Git ist der "HEAD" ein spezieller Zeiger (Pointer), der auf den neuesten Commit im aktuellen Branch zeigt. Der HEAD gibt somit an, welcher Commit momentan im Arbeitsverzeichnis und im Staging-Bereich aktiv ist.
Im Kontext von Commit-Trees können wir uns die Struktur wie einen Baum vorstellen, bei dem jeder Knoten einen Commit repräsentiert. Der HEAD-Zeiger zeigt auf den Spitzenknoten (englisch: "tip") des aktuellen Branches. Dieser Spitzenknoten ist der aktuelle Stand des Codes im Arbeitsverzeichnis.
Es gibt verschiedene Situationen, in denen sich der HEAD-Zeiger ändern kann:
- Normaler Zustand: Der HEAD zeigt auf den neuesten Commit im aktuellen Branch.
- Nach einem Commit: Wenn ein neuer Commit gemacht wird, wird der HEAD auf den neuen Commit verschoben.
- Nach einem Branch-Wechsel: Wenn zu einem anderen Branch gewechselt wird (zum Beispiel mit git checkout oder git switch), wird der HEAD auf den Spitzenknoten dieses Branches umgeschaltet.
- Nach einem Merge oder einer Rebase-Operation: Wenn Merging oder Rebasen durchgeführt wird, bewegt sich der HEAD entsprechend zum Abschluss der Operation.
In der Git-Befehlszeile können Sie den aktuellen HEAD-Zeiger mit dem Befehl git log
oder git show
anzeigen. Der HEAD-Zeiger ist wichtig, um zu wissen, auf welchem Commit Sie sich gerade befinden, und um zu verstehen, welcher Code gerade im Arbeitsverzeichnis aktiv ist.
git Workflows¶
Ein Git-Workflow bezieht sich auf einen Satz von Richtlinien und Praktiken, die von Softwareentwicklerteams festgelegt werden, um effizient mit Git zusammenzuarbeiten. Es definiert, wie verschiedene Aufgaben und Prozesse im Zusammenhang mit Versionskontrolle, Branching, Merging und anderen Git-Funktionen durchgeführt werden sollen. Der Workflow hilft dabei, den Entwicklungsprozess zu organisieren, Klarheit zu schaffen und Konsistenz im Team zu gewährleisten.
Es gibt verschiedene Git-Workflows, die auf die Bedürfnisse und die Struktur des Entwicklungsteams zugeschnitten sind. Einige der bekanntesten sind:
Einige bewährte Praktiken (best practices) im Zusammenhang mit Git-Workflows sind:
- Aussagekräftige Commit-Nachrichten: Verfassen Sie klare, präzise und aussagekräftige Commit-Nachrichten, um die Absicht jeder Änderung zu dokumentieren.
- Regelmäßige Merges: Integrieren Sie Änderungen regelmäßig, um Konflikte zu minimieren und eine ständige Integration zu fördern.
- Branch-Namenskonventionen: Verwenden Sie konsistente Namenskonventionen für Branches, um die Identifikation und das Verständnis zu erleichtern.
- Kleine, häufige Commits: Teilen Sie größere Aufgaben in kleinere Teile auf und committen Sie häufig, um die Versionshistorie übersichtlich zu halten.
- Review-Prozesse: Implementieren Sie Code-Reviews, um die Qualität des Codes zu verbessern und ein besseres Verständnis für den Code im Team zu fördern.
- Automatisierte Tests: Integrieren Sie automatisierte Tests, um sicherzustellen, dass Änderungen keine neuen Fehler einführen.
- Verwendung von Tags: Markieren Sie wichtige Meilensteine oder Veröffentlichungen mit Tags, um leicht auf bestimmte Versionen zurückkehren zu können.
Die Auswahl des geeigneten Git-Workflows hängt von den Anforderungen des Projekts und den Präferenzen des Entwicklungsteams ab. Es ist wichtig, dass das gewählte Workflow-Modell gut dokumentiert und von allen Teammitgliedern verstanden wird.
Literatur hierzu, siehe z.B.: A unifying framework for the systematic analysis of Git workflows, Information and Software Technology, Volume 145, May 2022, 106811
Continuous Integration, Continuous Delivery (CD) und Continuous Deployment (CD)¶
Continuous Integration (CI): CI bezieht sich auf den Praxisansatz, bei dem Entwickler regelmäßig ihre Codeänderungen in einem gemeinsamen Repository integrieren. Jede Integration führt zu automatischen Builds und Tests, um sicherzustellen, dass der Codebasis stabil bleibt. CI hilft, Konflikte frühzeitig zu erkennen und die Qualität des Codes während der Entwicklung aufrechtzuerhalten.
Continuous Delivery (CD): CD ist eine Erweiterung von CI und bezieht sich darauf, automatisierte Prozesse zu haben, die sicherstellen, dass die Anwendung zu jedem Zeitpunkt bereit für eine Veröffentlichung ist. Nach einem erfolgreichen CI-Prozess durchläuft die Anwendung automatisierte Tests und wird möglicherweise in eine Produktionsähnliche Umgebung bereitgestellt. Der Code kann jedoch manuell oder durch eine Geschäftsentscheidung in die Produktionsumgebung überführt werden.
Continuous Deployment (CD): CD geht einen Schritt weiter als Continuous Delivery, indem es den gesamten Prozess automatisiert und den Code automatisch in die Produktionsumgebung überführt, wenn alle Tests erfolgreich bestanden wurden. Dies bedeutet, dass jede erfolgreiche Code-Änderung direkt in Produktion gehen kann, ohne manuelles Eingreifen. Continuous Deployment ist besonders in agilen Umgebungen nützlich, da es dazu beiträgt, schnellere Iterationen und kontinuierliche Verbesserungen zu ermöglichen.
Insgesamt helfen CI, CD und CD, den Entwicklungsprozess zu automatisieren, die Qualität des Codes sicherzustellen und die Bereitstellung von Software effizienter und zuverlässiger zu gestalten. Diese Praktiken sind integraler Bestandteil von DevOps und agilen Entwicklungsansätzen.
GitLab¶
GitLab ist eine webbasierte Plattform für die Versionsverwaltung von Quellcode und das Zusammenarbeiten an Softwareprojekten. Es bietet eine umfassende Lösung für den gesamten Entwicklungslebenszyklus, einschließlich Versionskontrolle, CI/CD (Continuous Integration/Continuous Deployment), Projektmanagement, Code-Reviews, Issue-Tracking, Container-Registry und vieles mehr.
Hier sind einige der Hauptmerkmale von GitLab:
Git-Repository-Hosting: GitLab bietet einen sicheren Ort zur Speicherung und Verwaltung von Git-Repositories. Entwickler können ihre Projekte auf GitLab hosten und von überall auf der Welt darauf zugreifen.
CI/CD-Pipelines: GitLab integriert CI/CD direkt in die Plattform. Benutzer können automatisierte Build- und Test-Pipelines konfigurieren, um sicherzustellen, dass Codeänderungen stabil sind, bevor sie in Produktionsumgebungen bereitgestellt werden.
Projektmanagement: GitLab enthält Tools für das Projektmanagement, darunter Issue-Tracking, Kanban-Boards, Meilensteine und Zeitverfolgung. Diese Funktionen erleichtern die Organisation und Verfolgung von Aufgaben und Projekten.
Code-Reviews: Durch integrierte Code-Review-Funktionen können Entwickler zusammenarbeiten und Änderungen am Code überprüfen. Kommentare und Diskussionen können direkt im Kontext des Codes hinterlassen werden.
Wiki und Dokumentation: GitLab ermöglicht es, Wikis für Projekte zu erstellen und zu pflegen. Entwickler können auch Dokumentation direkt im Repository speichern, um die Projektinformationen zentral zu halten.
Container-Registry: GitLab enthält eine Container-Registry, um Docker-Images für Anwendungen zu hosten. Dies ist besonders nützlich in Umgebungen, die Container-Orchestrierung verwenden.
Security-Features: GitLab bietet integrierte Sicherheitsfunktionen, um Sicherheitslücken und Schwachstellen im Code zu erkennen. Dies umfasst statische Code-Analyse, Dependency-Scanning und mehr.
GitLab ist als Open-Source-Community-Edition (CE) verfügbar, und es gibt auch eine Enterprise Edition (EE) mit zusätzlichen Funktionen und Support für Unternehmensumgebungen. Die Plattform wird sowohl als gehosteter Dienst (GitLab.com) als auch als selbst gehostete Instanz bereitgestellt, sodass Entwickler die Wahl haben, wie sie GitLab nutzen möchten.
So hat die HTW Berlin beispielweise eine selbst gehostete Instanz, die von den Studis der HTW Berlin genutzt werden kann:
Aufgaben¶
- Arbeiten Sie das Buch Pro Git oder ein git-Tutorial Ihrer Wahl durch.
- Erzeugen Sie ein neues git-Projekt auf dem Server der HTW und richten Sie legen Sie einen ssh-Key dort ab, um
einfacher mit dem remote repository zu arbeiten (keine Passworteingabe nötig): https://docs.gitlab.com/ee/user/ssh.html
- Teilen Sie das Projekt mit Partner_innen
Literatur¶
- Buch Pro Git (Deutsche Version) online unter https://git-scm.com/book/de/v2