Eine allererste Einführung
1.0
Versionsmanagement
Wo ist die aktuelle Version?
Was ist die zuletzt lauffähige Version?
Wo ist die Implementierungsversion vom 01. April 2016?
Und welche Dokumente beziehen sich auf diese Version?
Welche Version wurde dem Kunden präsentiert?
Änderungsmanagement
Was hat sich seit letzter Woche geändert?
Wer hat diese Änderung gemacht?
Warum wurde diese Änderung gemacht?
Einfache Lösungen, die oft verwendet werden:
Austausch der Dokumente via USB-Stick / Festplatte
Austausch der Dokumente via Mail
Austausch über Netzwerkfestplatte
Zusätzlich müssen dann noch Konventionen und Regeln im Team definiert werden.
Zweck
Versionskontrollsysteme verwalten mehrere Versionen des Codes.
Erlauben es mehreren Personen gleichzeitig am selben Projekt zu arbeiten
Änderungen unterschiedlicher Personen werden teil-automatisch integriert
Erhält Historie von Änderungen
Arten
synchronisieren alle Änderungen in einem zentralen Repository (Subversion, . . . )
Keine Offline-Nutzung möglich.
können mehrere, unabhängige Repositories haben (Git, Mercurial, . . . )
Konsistenzmechanismen
System erlaubt gleichzeitiges Bearbeiten des Dokuments durch verschiedene Personen
System erkennt und integriert die Änderungen (Merging)
Evtl. funktioniert das nicht automatisch; dann muss der Konflikt manuell beseitigt werden
System verbietet gleichzeitiges Bearbeiten des Dokuments durch verschiedene Personen (Sperrprotokolle)
Beide Mechanismen haben Vor- und Nachteile
Sperren serialisiert die Arbeit
Mergen kann in seltenen Fällen komplex werden und zu Fehlern führen
Repository auf Server einrichten
Git repository einrichten (Beispielsweise über Web-Frontend wie https://github.com)
Lokale Kopie des Remote-repositories „Klonen”: git clone <repo-URL> [lokales Verzeichnis]
Repository lokal anlegen
In einem beliebigen Verzeichnis: git init
Datei neu versionieren
Dateien dem Repository hinzufügen
git add <Dateipfade>
Dateien landen dann in der sogenannten „Staging Area“.
Die Staging Area (oder Index) hält alle Änderungen, Hinzufügungen und Löschungen von Dateien, die Teil des nächsten Commits werden sollen.
gestagete Änderungen committen
git ci
Dies fügt die Änderungen dem lokalen Repository hinzu.
1commit ace47c68a2deaa6290344a5f9c2d7749d01f0efc
2Author: Michael Eichberg <mail@michael-eichberg.de>
3Date: Wed Jan 22 17:43:28 2025 +0100
45
encrypted presenter notes
67
diff --git a/renaissance/css/core/slide-view.css b/renaissance/css/core/slide-view.css
8index 21d433b..03f010a 100644
9--- a/renaissance/css/core/slide-view.css
10+++ b/renaissance/css/core/slide-view.css
11@@ -47,6 +47,12 @@
12/* The height will be computed by JavaScript depending on the mode. */
13}
1415
+
16+
17+ /* Presenter Notes */
18+ ld-presenter-note-marker[data-encrypted="true"] {
19+ display: none;
20+ }
21}
2223
...
Commits beschreiben eine atomare Änderung des Codes
Hashcode, um den Commit zu identifizieren
Autor und Zeit des Commits
Beschreibung der Änderung
Änderung als Diff: Hinzugefügte und entferne Zeilen je Datei
Zwischenspeichern von Änderungen
Aktuelle Änderungen zwischenspeichern und Working Copy resetten:
git stash
Hilfreich z. B. wenn man vergessen hat, Änderungen von Remote zu pullen.
Ein pull könnte lokale Änderungen überschreiben, mit git stash
werden diese Änderungen aber zunächst sicher beiseite gelegt.
Änderungen vom Stash in Working Copy zurückspielen:
git stash pop
Änderungen in der Working Copy zurücksetzen
git reset --hard
Setzt alle Änderungen in der Working Copy auf den letzten Commit zurück (z. B. nach einem „Fehlversuch“).
Metadaten setzen
Username und Emailadresse als Metadaten für Commits setzen:
git config user.name <name>
git config user.email <e-mail>
Git verwaltet Versionen von Dokumenten mittels Commits in Branches.
Initiales Setup - main ist aktuell auf dieser Version
main ist der aktuell ausgecheckte Branch
git branch develop
git checkout develop
git commit
von B
git commit
von B setzt den aktuellen Branch weiter
git checkout -b cveXXX-hotfix
git commit
von C
git checkout develop
Fast-forward Merge git merge cveXXX-hotfix
Sonderfälle
wenn es auf beiden Branches Änderungen gab, dann kann ein Merge ggf. fehlschlagen und muss manuell gemerged werden.
Um Änderungen auf ein remote Repository zu schieben bzw. davon zu holen muss man git push und git pull verwenden. Dabei kann es auch zu Konflikten kommen, die manuell gelöst werden müssen.
Git-Flow ist eine Konvention zur Nutzung von Branches in einer sinnvollen Art und Weise.[1]
Mindestens fünf Arten von Branches:
enthält stets die zuletzt veröffentlichte Version
enthält aktuelle Entwicklungsversion
zur Entwicklung individueller Features
zur Implementierung dringender Bugfixes
zum Vorbereiten eines Releases
(Verteilte) Workflows beschreiben, wie Personen Änderungen zwischen verteilten Repositories synchronisieren.
Hängt von Projekt und Organisationsstruktur ab
Workflows unterscheiden öffentliche und private Repositories
In den meisten Workflows gibt es ein ausgezeichnetes Repository als ground truth
Achtung!
Die Commit-Historie des blessed repository niemals verändern!
Erstellen eines neuen lokalen Repositories: git init
Lokalen Klon von entferntem Repositories anlegen: git clone <Repository-URL>
Geänderte Dateien anzeigen: git status
Zeilenweise Änderungen anzeigen: git diff (<Datei-Pfad>)
Änderungshistorie ansehen: git log
Commit ansehen: git show <Commit-Hash>
Dateien dem nächsten Commit hinzufügen: git add (--all|<Datei-Pfad>)
Commit anlegen: git commit (-m " <Beschreibung>")
Neuen Branch anlegen: git checkout -b <Branch-Name>
Aktuellen Branch wechseln: git checkout <Branch-Name>
Commits eines anderen in den aktuellen ziehen: git merge <Branch-Name>
Commits vom entfernten zum lokalen Repository holen: git fetch
Commits vom lokalen zum entfernten Repository schieben: git push
Kombination von git fetch
und git merge
: git pull
Die Datei .gitignore listet alle Arten von Dateien und Verzeichnissen auf, die von Git ignoriert werden sollen. Dies sind typischerweise alle Artefakte, die automatische generiert werden als Teil des Entwicklungsprozesses.
Kommentare beginnen mit #
Leerzeilen sind erlaubt
jede nicht-leere Zeile, die kein Kommentar ist, beschreibt ein Muster
Wildcards (*) sind erlaubt
! am Anfang negiert ein Muster
"/" separiert Verzeichnisse
Beispiel
1*.bak
2*.class
3*.jar
4target/
56
# "Editors"
7.vscode/
8.zed/
9.idea/
Eine erste Übung mit GIT
Installieren Sie Git auf Ihrem System, falls es nicht verfügbar sein sollte.
Erstellen Sie ein neues Verzeichnis und legen Sie darin ein neues lokales Repository mit Hilfe von git init
an.
Entpacken Sie die Datei https://delors.github.io/se-versionskontrolle/exercise/RPN.zip in dem Verzeichnis.
Führen Sie einen initialen Commit durch mit Hilfe von git add
und git commit
.
Compilieren Sie die Sourcen mit javac
.
Legen Sie eine .gitignore Datei an, um sicherzustellen, dass die Binärdateien nicht in das Repository gelangen.
Nutzen Sie git status
, um sich zu vergewissern, dass die Binärdateien ignoriert werden.
fügen Sie die .gitignore Datei Ihrem Repository hinzu.
Erstellen Sie einen neuen Branch mit dem Namen feature/bugfix und wechseln Sie auf den neuen Branch.
(Nutzen Sie git status, um zu verifizieren, dass Sie auf dem neuen Branch sind)
Ändern Sie die Datei RPN.java, um den Bug im Switch statement (case "* "
=> case "*"
) zu beheben.
Committen Sie die Änderungen.
Wechseln Sie zurück auf den main Branch.
Mergen Sie den Branch feature/bugfix in den main Branch mit Hilfe von git merge
.
Löschen Sie den Branch feature/bugfix mit Hilfe von git branch -d
.
Erstellen Sie einen neuen Branch develop und wechseln Sie auf diesen Branch.
Ändern Sie die Reihenfolge der Methoden pop
und peek
in der Klasse Stack
.
Committen Sie die Änderungen.
Wechseln Sie zurück auf den main Branch.
(Führen Sie noch keinen Merge durch!)
Entfernen Sie die {} Klammern um die throw new NoSuchElementException()
Anweisungen.
Committen Sie die Änderungen.
Führen Sie einen Merge von develop in main durch.
Öffnen Sie die Datei ds/Stack.java und beheben Sie den Merge-Konflikt.
Committen Sie die Änderungen.
Nutzen Sie git log --oneline --graph --all
um sich die Commit-Historie anzusehen.
Wechseln Sie zurück zum develop Branch.
Führen Sie einen Merge von main in develop durch.