ZSL RSKA Fachbereich Informatik Fortbildung Einführung in GitCamp

# GIT auf der Konsole
Author: Dirk Zechnall

Dirk Zechnall dirk.zechnall@semgym-karlsruhe.de

## Grundlegende Konfiguration

    $ git config --global user.name "Max Mustermann"
    $ git config --global user.email max@example.org

Bevor mit git gearbeitet werden kann, sollten Name und Mailadresse festgelegt werden.
Dazu sind in einer Shell die obenstehenden Kommandos auszuführen.

## Ansicht auf GitCamp

Änderungen auf GitCamp werden nun mit username und email angezeigt.

## Lokales Repo initialisieren

In dem Verzeichnis, welches versioniert werden soll, kann mit dem Befehl `git init` ein lokales Repo initialisiert werden.

    tagebuch$ git init

    Initialized empty Git repository in /tagebuch/.git/

## Initialisierung

## Änderungen im Verzeichnis

Nun steht das Verzeichnis `tagebuch` unter Versionskontrolle. Das lokale Git-Repository befindet sich im Unterverzeichnis `.git`.

    tagebuch$ ls -la

    total 52
    drwxr-xr-x 1 xxx 197121 0 Oct 9 14:19 ./
    drwxr-xr-x 1 xxx 197121 0 Oct 9 14:18 ../
    drwxr-xr-x 1 xxx 197121 0 Oct 9 14:19 .git/

## Das .git-Verzeichnis

Hier sind neben allen versionierten Dateien auch die Konfigurationen abgelegt.

    tagebuch$ cd .git
    tagebuch/.git$ ls -l

    insgesamt 44
    ...
    -rw-rw-r--  1 xxx   92 Feb 12 08:25 config
    -rw-rw-r--  1 xxx   73 Feb 12 08:25 description
    -rw-rw-r--  1 xxx    0 Feb 12 08:35 FETCH_HEAD
    -rw-rw-r--  1 xxx   21 Feb 12 08:25 HEAD
    drwxrwxr-x  2 xxx 4096 Feb 12 08:25 hooks
    -rw-rw-r--  1 xxx  406 Feb 12 08:39 index
    ...

## Repository Status anzeigen lassen

Das Verzeichnis tagebuch ist jetzt ein "git-Repository" - es wird von git "beobachtet". Mit dem Befehl `git status` kann der aktuelle Status des "Repos" angezeigt werden.

    tagebuch$ git status

    On branch main
    No commits yet
    Nothing to commit
    (create/copy files and use "git add" to track)

## Der Git-Workflow

Um den git-Workflow zu verstehen, müssen drei Begriffe unterschieden werden: Das Arbeitsverzeichnis ("Working Directory"), die Staging Area ("Index") und das eigentliche Repository ("Snapshot").

## Der Git-Workflow

## Zuerst Stagen …​

Eine Datei wird dem Working Directory hinzugefügt.

## Zuerst Stagen …​

`git status` zeigt "Untracked Files".

    tagebuch$ git status

    On branch main
    No commits yet
    Untracked files: (use "git add <file>..." to stage)
        aufstehen.txt

## Zuerst Stagen …​

`git add aufstehen.txt` fügt die Datei `aufstehen.txt` zum Index hinzu → Staging Area.

    tagebuch$ git add aufstehen.txt
    tagebuch$ git status

    On branch main
    No commits yet
    Changes to be committed:
    (use "git rm --cached <file>..." to unstage)
        new file: aufstehen.txt

## Zuerst Stagen …​

## …​ dann Commiten

Wenn man mit den im Index vorgemerkten Änderungen zufrieden ist, kann mit `git commit` ein "Commit" durchgeführt werden. Dadurch wird ein Snapshot mit einer eindeutigen ID erstellt und die Staging Area geleert. Jeder Snapshot lässt sich zu jedem Zeitpunkt wieder herstellen.

## …​ dann Commiten

Mit dem Befehl `git commit -m "Erster Commit: aufstehen.txt"` wird ein Commit mit einer Commit-Message angelegt (Parameter `-m`).

    tagebuch$ git commit -m "Erster Commit: aufstehen.txt"

    [main (root-commit) 9eefa56] Erster Commit: aufstehen.txt
    1 file changed, 1 insertion(+)
        create mode 100644 aufstehen.txt

## …​ dann Commiten

Nun ist der Working-Tree wieder sauber.

    tagebuch$ git status

    On branch main
    nothing to commit, working tree clean

## Git-Workflow - Übersicht

## Arbeitsaufträge

1. Halten Sie in der Datei `fruehstueck.txt` fest, was es zum Frühstück gab.

2. Kontrollieren Sie mit `git status`, dass die Datei jetzt existiert, sie jedoch noch nicht unter Versionskontrolle steht.

3. Fügen Sie die Datei `fruehstueck.txt` mit dem Befehl `git add` `fruehstueck.txt` zum Index hinzu.

4. Erstellen Sie einen Commit für das Frühstück. Vergessen Sie die Commit-Message nach der `Option -m` nicht.

5. Überprüfen Sie mit `git status` den Zustand des Repositorys erneut.

## Aktueller Stand

## Übersicht über Commits

Ein Commit kann also wie im Bild dargestellt als Archivbox betrachtet werden, in dem jeweils der Zustand aller versionierten Dateien festgehalten ist. Ein Commit wird durch einen hexadezimalen "Hashwert" identifiziert, das ist gewissermaßen die eindeutige Nummer eines Commits, z.B. 2f40bf7.

## Git log

Mit dem Befehl `git log` können die Commits aufgelistet werden.

    tagebuch$ git log

    commit 2f40bf7011e453259db21014979353003262df (HEAD -> main)
    Author: Max Mustermann <max.mustermann@zsl-rska.de>
    Date: Wed Oct 9 14:35:50 2024 +0200
    Frühstück in Datei 'fruehstueck.txt' hinzugefügt

    commit 9eefa5687ebae993ce7ca0f597159418f1d7cd
    Author: Max Mustermann <max.mustermann@zsl-rska.de>
    Date: Wed Oct 9 14:31:24 2024 +0200
    Erster Commit: 'aufstehen.txt' angelegt

## Aktueller Working Tree

Man sieht, dass die Commit-Hashes sehr lange sind. Für die Identifizierung eines Commits reichen jedoch die ersten 7 Stellen des Hashes aus.

## Arbeitsaufträge

1. Fügen Sie dem Tagebuch den Eintrag `mittagessen.txt` als Datei hinzu, zunächst ohne diese zu versionieren.

2. Ändern Sie die Datei `fruehstueck.txt` und schreiben Sie zusätzlich Schokolade in die Datei.

3. Überprüfen Sie mit `git status` den Zustand des Repositorys.

4. Fügen Sie mit `git add fruehstueck.txt` die Datei `fruehstueck.txt` zum Index hinzu.

5. Erstellen Sie einen Commit. Vergessen Sie die Commit-Message nach der Option `-m` nicht.

6. Stagen Sie ebenfalls die neue Datei `mittagessen.txt` mit `git add mittagessen.txt`.

## Veränderungen

    tagebuch$ git status

    On branch main
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes)
        modified: fruehstueck.txt

    Untracked files:
    (use "git add <file>..." to include in commit)
        mittagessen.txt

    no changes added to commit
        (use "git add" and/or "git commit -a")

## Frühstück stagen

    tagebuch$ git add fruehstueck.txt

    tagebuch$ git status

    On branch main
    Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
        modified: fruehstueck.txt

    Untracked files:
    (use "git add <file>..." to include in commit)
        mittagessen.txt

## Frühstück committen

    tagebuch$ git commit -m "fruehstueck.txt geändert"

    [main 1c669a2] fruehstueck.txt geändert
    1 file changed, 2 insertions(+), 1 deletion(-)

    tagebuch$ git status

    On branch main
    Untracked files:
    (use "git add <file>..." to include in commit)
        mittagessen.txt

    nothing added to commit but untracked files present
        (use "git add" to track)

## Mittagessen stagen

    tagebuch$ git add mittagessen.txt

    tagebuch$ git commit -m "Mittagessen hinzugefügt"

    [main 311cb29] Mittagessen hinzugefügt
    1 file changed, 1 insertion(+)
    create mode 100644 mittagessen.txt

    $ git status

    On branch main
    nothing to commit, working tree clean

## Aktueller Stand

## Versionshistorie

## Zeitreise

| Man sollte nur dann zu einem älteren Stand der Dateien zurückkehren, wenn das Arbeitsverzeichnis keine nicht committeten Änderungen beinhaltet. ("Sauberes Arbeitsverzeichnis")

    tagebuch$ git status

    On branch main
    nothing to commit, working tree clean

## Zurück gehen

Mit dem Befehl `git checkout <Commit-Hash>` kann man das Arbeitsverzeichnis in den Zustand des angegebenen Commits zurückzuversetzen. Es reicht dabei aus, die ersten 7 Zeichen des Hashwertes, z.B. 2f40bf7, anzugeben.

## Hashwert ermitteln

Mit `git log` kann man den Hashwert eines Commits ermitteln.

    tagebuch$ git log

    commit 311cb296f5c7099ed88cfa6336c089eb03ddbb35 (HEAD -> main)
    ...
    commit 2f40bf7011e453259db1621014979353003262df
    Author: Max Mustermann <max.mustermann@zsl-rska.de>
    Date: Wed Oct 9 14:35:50 2024 +0200
        Frühstück in Datei 'fruehstueck.txt' hinzugefügt
    ...

## Zurück gehen

Mit `git checkout <Commit-Hash>` stellt man den angegebenen Zustand wieder her.

    tagebuch$ git checkout 2f40bf7

    Note: switching to '2f40bf7'.
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by switching back to a branch.

    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -c with the switch command. Example:
        git switch -c <new-branch-name>

    Or undo this operation with: git switch -

    HEAD is now at 2f40bf7 Frühstück in Datei 'fruehstueck.txt' hinzugefügt

## Neuer Status

    tagebuch$ git status

    HEAD detached at 2f40bf7
    nothing to commit, working tree clean

## Arbeitsaufträge

1. Emitteln Sie mit `git log` einen Commit-Hash (die ersten 7 Ziffern) zu dem Sie zurückkehren möchten.

2. Kehren Sie mit `git checkout <Commit-Hash>` zu diesem Commit zurück.

3. Betrachten Sie mit `git status` den Zustand des Repositorys.

4. Überprüfen Sie in Ihrem Arbeitsverzeichnis die Dateien und deren Inhalte.

5. Betrachten Sie mit `git log` die Versionshistorie.

6. (`git log --all` zeigt alle Commits. Probieren Sie das aus.)

## Vergangenheit

## Der Working-Tree

Neben dem HEAD gibt es nun einen weiteren Zeiger `main`, der auf den aktuellen Stand der Arbeit zeigt. Visualisieren Sie diesen sogenannten `Detached Head` mit `gitk`.

    tagebuch$ gitk

## gitk-Visualisierung

## Weitere Aufträge

1. Bearbeiten Sie das Kapitel "4.3.4 Manipulation der Vergangenheit" im Skript.

2. Bearbeiten Sie das Kapitel "4.3.2. Änderungen zwischen Commits ansehen" im Skript.

## Zusammenfassung

## Historie

## Status Unstaged

## Unstaged Close-Up

## Status Staged

## Staged Close-Up

## Git Cheatsheet

    // Credentials für 90 Minuten zwischenspeichern
    $ git config --global credential.helper
        "cache --timeout=5400"

    // Alias 'git lg' für 'git log' mit schlichter Formatierung
    $ git config --global alias.lg "log --graph --pretty=format:
     '%Cred%h%Creset-%C(yellow)%d%Creset %s %Cgreen(%cr) %Creset'
     --abbrev-commit"