Informatik/Mathematik / Software Engineering

Ziel: Vertiefung der Anwendung von Versionen in Git

Praktikumsaufgaben Teil 6 - Versionen

In den folgenden Aufgaben wird die Änderungs-/Versionsverwaltung von Git genauer betrachtet.

Git-Versionskette
Abbildung 1. Git-Versionskette

Es werden hilfreiche Konzepte zu folgenden Themen erarbeitet:

  • ältere Versionsstände untersuchen

  • Änderungen verwerfen und (temporär) wegspeichern

  • Versionen (Commits) ändern, zusammenzufassen und löschen


Hinweise zur Bearbeitung

Bearbeiten Sie die Aufgaben in Ihrem vorhandenem htwd-se-example-project-Repository oder legen Sie sich dafür ein neues Repository auf GitHub an (Siehe hierzu Praktikumsaufgaben Teil 1 - Grundlagen). Falls noch nicht geschehen, clonen Sie es als lokales Arbeitsverzeichnis auf Ihren Rechner und bearbeiten Sie in diesem die Aufgaben. Wenn nicht anders angegeben, entscheiden Sie selbst, was für eine (beispielhafte) Änderung zur Lösung der entsprechenden Aufgabe Sie an Ihrem Repository vornehmen.

Nutzen Sie die Möglichkeiten sich auf Webseiten wie der offiziellen Git Dokumentation oder anderen Ressourcen über die verwendeten git-Kommandos und -Konzepte zu informieren.

Linkliste zu hilfreichen Webseiten und Videos

In den Aufgaben gibt es ebenfalls aufklappbare Hinweise. Diese beinhalten die benötigten git-Kommandos mit erklärenden Anmerkungen.

Je nach verwendetem git-Client oder IDE sind die Kommandos über entsprechenden Menüpunkte und Schaltflächen zu erreichen. Es ist Ihnen freigestellt, ob Sie einen grafischen Client/IDE oder das Terminal verwenden.

Terminal in Visual Studio Code

Über das Hauptmenü: View  Terminal kann innerhalb von VS Code ein Terminal geöffnet werde.

Terminal unter Windows

PowerShell, git-Bash, Eingabeaufforderung (cmd), …​

Terminal unter Linux, macOS

XTerm, Konsole, Terminal.app, …​

Hinweise zum Praktikum in den Windows-Laboren

Aufgrund der nicht gespeicherten Nutzer-Profile in den Windows-Laboren, sind zu jedem Praktikumsbeginn folgende Schritte durchzuführen:

Schritte zur Vorbereitung des Praktikums
  1. Git-Konfiguration C:\Users\<username>\.gitconfig wiederherstellen oder anpassen:

    per Editor in der .gitconfig
    [user]
    	name = Vorname Nachname
    	email = s00000@htw-dresden.de
    [safe]
        directory = *
    [http]
    	proxy = http://www-cache.htw-dresden.de:3128
    oder per PowerShell und Git-Kommandos
    > git config --global user.name "Vorname Nachname"
    > git config --global user.email s00000@informatik.htw-dresden.de
    > git config --global --add safe.directory *
    > git config --global http.proxy http://www-cache.htw-dresden.de:3128
  2. Visual Studio Code: Anpassen der AsciiDoc-Einstellungen:

    • Asciidoc > Preview: Use Editor Style: (deaktiviert)

    • Asciidoc > Extensions: Enable Kroki: (aktiviert)

  3. GitHub Login mit gespeichertem oder neuem Personal Access Token über die PowerShell bekanntgeben:

    Repository vorhanden
    > U:
    > cd path/to/repository/<repo-name>/
    > git pull
    Authentifizierung ...
    Repository nicht vorhanden (Home-/SAMBA-Laufwerk)
    > U:
    > cd path/to/repository/
    > git clone https://github.com/.../<repo-name>
    Authentifizierung ...
    Repository nicht vorhanden (TEMP-Laufwerk)
    > T:
    > git clone https://github.com/.../<repo-name>
    Authentifizierung ...


1. Änderungen und Versionen verwalten

Die folgenden Aufgaben behandeln Möglichkeiten zum Umgang mit Änderungen und Versionen (Commits) im lokalen Arbeitsverzeichnis.

  • Änderung …​ (noch) nicht versionierte Änderung im lokalen Arbeitsverzeichnis

  • Version …​ versionierte Änderung (Commit) im lokalen Arbeitsverzeichnis

Aufgabe 1.1 - Versionen untersuchen

Untersuchen Sie in Ihrem lokalen Repository einen älteren Projektstand (Version) indem Sie sich die Unterschiede (diff) zwischen Versionen oder neueren Änderungen anzeigen lassen und direkt zu früheren Versionen in Ihrem Projekt springen (checkout). Kehren Sie anschließend zum aktuellen Stand zurück.

Hinweise: diff
$ git diff (1)
$ git diff <file> (2)

$ git diff --cached (3)

$ git diff <commit-id> (4)
$ git diff <commit-id> HEAD (5)
$ git diff <commit-id-1> <commit-id-2> (6)
1 zeigt Unterschied der letzten Version (HEAD) zum lokalen Arbeitsstand
2 mit der zusätzlichen Angabe <file> kann gezielt eine Datei oder ein Verzeichnis verglichen werden
3 mit --cached werden die vorgemerkten Änderungen gegenüber HEAD oder einer angegebenen Version verglichen
4 zeigt Unterschied der Version <commit-id> zum lokalen Arbeitsstand
5 zeigt Unterschied der Version <commit-id> zur letzten Version HEAD
6 zeigt Unterschied von Version <commit-id-1> (älter) zur Version <commit-id-2> (neuer)
Hinweise: checkout
…​
$ git log --oneline (1)
$ git checkout <old_commit_id> (2)
$ git switch main (3)
1 Versionshistorie (commits) anzeigen, die Option --oneline erlaubt eine Anzeige mit weniger Details auf einer Zeile pro Commit
2 vergangenen Projektstand laden
3 Neuere Alternativ zu git checkout <branch>. Zu aktuellem Projektstand (main-Branch) zurückkehren. Zwischenzeitliche Commits auf den vergangenen Projektstand werden verworfen.
In der unteren Statusleiste (links) in VS Code oder über das git-Kommando git branch sieht man den aktuellen Branch, bspw. main. Seit Oktober 2020 verwenden alle auf GitHub neu erstellten Repository main anstelle von master als Standard-Branch (Quelle).

Aufgabe 1.2 - Änderung wegspeichern

Nehmen Sie in Ihrem Repository eine lokale Änderung vor und speichern Sie diese temporär mit stash weg. Schauen Sie sich Ihren lokalen Arbeitsstand an. Stellen Sie anschließend Ihre weggespeicherte Änderung wieder her und nehmen Sie diese als neue Version auf.

Hinweise: stash
…​
$ git stash (1) (2)
$ git stash save "Arbeitsstand X"
$ git stash -u
$ git stash -S
$ git stash -k

$ git stash pop (3)
$ git stash apply (4)
$ git stash drop (5)

$ git stash list (6)
stash@{0}: WIP on main: ...
stash@{1}: WIP on main: ...
stash@{2}: On main: Arbeitsstand X

$ git stash show (7)
$ git stash show -p (8)
1 Änderungen an unter Versionskontrolle stehenden Dateien und im INDEX (staged) befindliche Änderungen werden aus dem Arbeitsverzeichnis temporär weggespeichert
2 Varianten:
  • save "…​" …​ benennt den erzeugten Stash für eine bessere Unterscheidung

  • -u …​ speichert zusätzlich untracked neue bzw. noch nicht unter Versionskontrolle stehende Dateien weg

  • -S …​ nur staged im INDEX befindliche Änderungen werden aus dem Arbeitsverzeichnis temporär weggespeichert

  • -k …​ nur unstaged nicht im INDEX befindliche Änderungen werden aus dem Arbeitsverzeichnis temporär weggespeichert

3 pop …​ stellt die weggespeicherte Änderung wieder her und entfernt den zugehörigen Stash
4 apply …​ stellt die weggespeicherte Änderung wieder her und behält den zugehörigen Stash (nützlich, wenn die Änderung noch an anderer Stelle (bspw. anderer Branch) gebraucht wird)
5 drop …​ entfernt den Stash mit den enthaltenen Änderungen
6 list …​ Liste der vorhandenen Stashes
7 show …​ zeigt Kurzform der Änderungen im Stash gegenüber der aktuellen Version
8 show -p …​ zeigt auch inhaltliche Änderungen (Patch-Form)
Hat man mehrere Stashs, wird bei pop, apply und drop der zuletzt angelegte genommen. Man kann auch den gewünschten Stash mit bspw. git stash pop stash@{1} angegeben. Der neueste ist stash@{0} (default), der nächst ältere stash@{1} und so weiter.

Aufgabe 1.3 - Änderung verwerfen

Nehmen Sie in Ihrem Repository eine lokale Änderung vor und verwerfen Sie diese anschließend, ohne eine neue Version zu erstellen.

Hinweise: checkout, restore, reset, clean
…​
$ git checkout -- <file(s)> (1)
$ git restore -- <file(s)> (2)
$ git reset --hard (3)
$ git clean -df (4)
1 Setzt lokale Änderungen einer oder mehrerer unter Versionskontrolle stehender Dateien auf die letzte Version zurück. Ein . statt <file(s)> nimmt alle lokalen Änderungen.
2 Neuere alternative Variante gegenüber checkout.
3 Alternative Möglichkeit zu git checkout . bzw. git restore .. Ein --hard veranlasst bei einem git reset auch den Workspace, also die lokalen (geänderten) Dateien, zurückzusetzen.
4 Entfernt alle lokalen nicht unter Versionskontrolle stehenden Dateien. (git-clean Dokumentation, -n Testlauf, -i interaktiv, -d beachte auch entsprechende Verzeichnisse, -f ignoriere Löschwarnung)

Aufgabe 1.4 - Version verwerfen

  1. Nehmen Sie in Ihrem Repository eine Änderung als neue lokale Version auf. Schauen Sie sich die Versionshistorie an und nehmen Sie die eben gemachte Version mit reset zurück.

    Hinweise: reset
    …​
    $ git add .
    $ git commit -m "..."
    $ git log --oneline
    $ git reset --hard <commit_id> (1) (2)
    1 Setzt den aktuellen Stand des Repository auf die angegeben Version (Commit-ID) zurück. Mit der Option --hard wird auch das lokale Arbeitsverzeichnis zurückgesetzt.
    2 Die Commit-ID kann relative HEAD~1 oder absolut a2a33s23 angegeben werden. Alle davon ausgehenden neueren Version werden verworfen.
    Die Verwendung von reset ist nur für lokale, private und noch nicht veröffentlichte Versionen (Commits) geeignet. Denn das Verändern der Repository-Historie führt, im Gegensatz zu revert, zu Problemen mit anderen Nutzern, da die Versionskette nicht mehr synchron ist.
  2. Nehmen Sie in Ihrem Repository eine weitere Änderung als neue lokale Version auf. Schauen Sie sich die Versionshistorie an und nehmen Sie die eben gemachte Version mit revert zurück.

    Hinweise: revert
    …​
    $ git add .
    $ git commit -m "..."
    $ git log --oneline
    $ git revert <commit_id> (1)
    1 Nimmt die Änderung der angegebenen Version zurück und erzeugt eine neue Version (ohne die Änderung der zurückgenommenen Version) im Repository. Die Versionshistorie bleibt inklusive der zurückgenommen Version erhalten.
    Die Verwendung von revert erhält, gegenüber reset, die Versionskette und ist konsistent zu entfernten, öffentlichen und geteilten Repositories.


2. Versionen ändern und zusammenfassen

Das Ändern (commit --amend) und das Zusammenfassen (rebase -i) von Versionen zu einer neuen Version verändert die Commit-ID(s) und die Versionshistorie, ähnlich wie bei reset, des Repository. Es ist nur für lokale, private Repository und noch nicht veröffentlichte Versionen empfohlen, um unterschiedliche Versionsketten mit anderen Nutzern zu vermeiden.

Falls der oder die ursprünglichen Commits schon an ein remote-Repository gepusht wurde, muss der überschriebene Commit noch einmal mit git push --force oder besser git push --force-with-lease gepusht werden. (obere Warnung beachten!)

Hinweise: Force-Push mit VS Code

In VS Code ist über das Git-Menü standardmäßig kein Force-Push möglich und man kann nur über das integrierte Terminal ein git push --force auszuführen.

Über die Einstellungen von VS Code: Settings  Extensions  Git kann die Option Allow Force Push aktiviert werden. Danach sind im Git-Menü …​  Pull, Push  entsprechende Push (Force) Einträge vorhanden.

Aufgabe 2.1 - letzte Version ändern

  1. Nehmen Sie in Ihrem Repository eine Änderung als neue lokale Version auf und schauen Sie sich die Versionshistorie an.

  2. Ändern Sie mit commit --amend die Commit-Message des eben erstellten letzten Commits. Alternativ nehmen Sie vorher eine lokale Änderung vor, welche mit in die Änderung des letzten Commits einfließen soll.

Hinweise: commit --amend
…​
$ ...
$ git add .
$ git commit -m "... Message ..."
$ git log --oneline
$ ...
$ git add . (1)
$ git commit --amend -m "... (neue) Message ..." (2)
$ git log --oneline
1 optional: Aufnahme der vergessenen/zusätzlichen Änderungen.
2 Mit der Option --amend wird der letzten Commit mit dem aktuellen Commit überschrieben. Dies ist eine gute Möglichkeit, um Fehler in der Commit-Message zu korrigieren oder vergessene Änderungen oder Dateien aufzunehmen.

Aufgabe 2.2 - Versionen zusammenfassen

  1. Nehmen Sie in Ihr Repository drei neue Versionen (Commits) auf.

  2. Fassen Sie mit rebase -i die letzten drei Commits zu einem neuen Commit zusammen.

Hinweise: rebase -i
…​
$ git log --oneline
00af044 (HEAD -> main) Fix typo in <object>
0af0043 Update <object>
af00042 Add new <object>
f000041 Fixup #11 <object>
...

//$ git rebase -i f000041
$ git rebase -i HEAD~3 (1)
pick af00042 Add new <object>
f    0af0043 Update <object> (2)
f    00af044 Fix typo in <object> (2)

$ git log --oneline
f000045 (HEAD -> main) Add new <object>
...
1 Alle neueren Commits nach der angegebenen Commit-ID können jetzt einzeln bearbeitet (siehe Tabelle) werden. Der älteste Commit steht oben.
2 Die beiden Nachfolge-Commits (00af044, 0af0043) werden mit f (fixup) statt pick markiert, um in den vorhergehenden Commit (af00042) aufgenommen zu werden.
Kommando Beschreibung

p, pick

Commit verwenden

r, reword

Commit verwenden und Commit-Message ändern

s, sqash

Commit und Commit-Message in vorherigen Commit aufnehmen

f, fixup

Commit ohne Commit-Message in vorherigen Commit aufnehmen

Ist bei Ihnen im Terminal für Git der Editor vi(m) eingestellt, können Sie mit i in den Bearbeitungsmodus wechseln und nach der Änderung mit esc und der Eingabe von :wq speichern und den Editor schließen.

Seitenübersicht