Git

Git

Versionskontrollsystem

es kann insbesondere bei folgenden Aufgaben behilflich sein:

  • Änderungen an einer Codebase mitverfolgen
  • Mit anderen Entwicklern zusammenarbeiten

Beispiele für Repositories

Commits und Branches

Commits

Ein Commit in Git ist eine Momentaufnahme einer Codebase

Die Entwicklung einer Codebase im Laufe der Zeit wird durch eine Abfolge von Commits repräsentiert

Manchmal bezeichnet man mit dem Begriff Commit auch den Übergang / die Änderungen von einer Momentaufnahme zur nächsten

Commits

Einfacher Commit-Log mit einem Branch (main):

* add footer (main)
* add company logo
* add sidebar
* add placeholder content
* initialize website

Branches

Branches erlauben das gleichzeitige / parallele Arbeiten an mehreren Aufgaben

Der Standard-Branch heißt üblicherweise main oder master

In Git ist ein Branch ein Pointer zu einem bestimmten Commit

Commits und Branches

Commit-Log mit einem aktiven Feature-Branch:

* add sidebar (main)
| * correct typo in footer (footer)
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website

Commits und Branches

Zusammenführen von Branches (via merge):

* merge branch 'footer' into main (main)
|\
| * correct typo in footer (footer)
| * add logo to footer
| * add footer with basic content
* | add sidebar
|/
* add placeholder content
* initialize website

Commits und Branches

Zusammenführen von Branches (via rebase und squash):

* add footer (main)
* add sidebar
* add placeholder content
* initialize website

Userinterfaces

Userinterfaces

  • command-line interface (Standard, umfangreiche Funktionalität)
  • GUI
    • git gui und gitk
    • ...
  • Webinterfaces / gehostete Git Repositories
    • GitHub
    • GitLab

Setup

Setup unter Windows

Installation von https://git-scm.com

Setup unter Windows

Empfehlungen:

select components: Windows Explorer integration deaktivieren (würde zusätzliche Befehle ins Rechtsklickmenü des Explorers hinzufügen)

default editor: wähle Nano als einfachen Konsolen-baiserten Texteditor

name of the initial branch: wähle "main"

line ending conversions: Checkout as-is, commit as-is - und Konfiguration der Entwicklungsumgebung auf LF

default behavior of git pull: only ever fast-forward

Konfiguration von Git

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git config --global pull.ff true

Initialisieren oder Klonen eines git Repositories

Befehle

  • git init
  • git clone

Initialisieren eines git Repositories

Initialisieren eines neuen Repositories in einem lokalen Ordner:

git init

Klonen eines git Repositories

Klonen eines öffentlichen Repositories (von GitHub):

git clone https://github.com/libgit2/libgit2

Erstellt einen neuen Ordner libgit2 mit dem aktuellen Code und der gesamten Versionsgeschichte

Aufzeichnen von Änderungen

Befehle

  • git status
  • git diff
  • git add
  • git restore
  • git commit

Befehle

git status

Gibt Informationen zu dem aktuellen Zustand des Repositories aus

Anzeigen der Änderungen seit dem letzten Commit

Status von Dateien anzeigen (hinzugefügt / verändert / gelöscht seit dem letzten Commit):

git status

Anzeigen von hinzugefügten / gelöschten Zeilen in Dateien:

git diff

Staging

Vorbereiten aller hinzugefügten / veränderten / gelöschten HTML-Dateien zum Committen (Staging von Dateien):

git add *.html

Vorbereiten aller Dateien:

git add .

Unstaging und Rückgängig machen von aktiven Änderungen

"Unstaging" von Dateien:

git restore --staged readme.txt

Verwerfen von Änderungen:

git restore readme.txt

Committen

Erstellen eines Commits mit allen Änderungen inklusive Commit-Message:

git add .
git commit -m "changing some HTML files"

Committen

Kurzversion für das direkte Committen aller Änderungen:

git commit -a -m "changing some HTML files"

Ignorieren von Dateien

Auflisten von zu ignorierenden Dateien in einer Textdatei namens .gitignore (ohne Dateiendung):

__pycache__
node_modules
.vscode

History

Befehle

  • git log
  • git show
  • git diff
  • git checkout
  • git revert

History

Auflisten bisheriger Commits:

git log
git log --oneline
git log --oneline --graph
git log --oneline --graph --all

Beispiel für Ausgabe zum zweiten Befehl:

* e84890f (HEAD -> main, origin/main, origin/HEAD) add footer
* 9eb2f53 add company logo
* 5c41c01 add sidebar
* f4f591c add placeholder content
* d6510c2 initialize website

Commit-History

Anzeigen der Änderungen zwischen Commit 19e0e64... und dessen Eltern-Commit:

git show 19e0

Anzeigen der Änderungen zwischen Commit 19e0e64... und der aktuellen Version:

git diff 19e0

kompakte Ausgabe:

git diff 19e0 --name-status

Commit-History

Zugreifen auf die Inhalte eines früheren Commits (mit id b4c906...):

git checkout b4c9

Zurück zum aktuellsten Commit des main-Branches:

git switch main

Commit-History

Rückgängig Machen des letzten Commits (mittels eines neuen Commits):

git revert HEAD

Feature Branch Workflow

Feature Branch Workflow

Workflow:

Um neue Features / Änderungen umzusetzen, erstellt man einen sogenannten Feature Branch

Der Feature Branch kann sich individuell parallel zum main Branch entwickeln

Entwickelt sich der main Branch weiter, können die Änderungen in den Feature Branch übernommen werden

Ist ein Feature komplett, können die Änderungen in den main Branch übernommen werden (nach begutachtung durch andere Entwickler)

Feature Branch Workflow

Feature Branches können oft auf einen kleinen Rahmen beschränkt sein, z.B. fix-spelling-error-in-readme

manche Feature Branches müssen großen Umfang haben, z.B. port-to-typescript

Feature Branch Workflow

Nachdem die Änderungen eines Feature Branches in den Haupt-Branch übernommen wurden, wird der Feature Branch üblicherweise gelöscht

Feature Branch Workflow

Beispiel: Entwickler arbeiten an zwei unterschiedlichen Tasks gleichzeitig:

* add sidebar (sidebar)
| * add logo to footer (footer)
| * add footer with basic content
|/
* add placeholder content (main)
* initialize website

Feature Branch Workflow

nach Vervollständigung eines Features kann es in den main-Branch eingebunden werden:

* merge branches (main)
|\
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website

alte Feature-Branches werden üblicherweise gelöscht

Feature Branch Workflow

während der Entwicklung:

  • erstelle einen neuen Feature-Branch, der von main abzweigt
  • füge bei Änderungen regelmäßig neue Commits hinzu
  • merge (oder rebase), wenn neue Commits auf dem main-Branch gemacht werden

wenn das Feature fertiggestellt ist:

  • optional: kombiniere alle Commits auf dem Branch zu einem (rebase)
  • merge in den main-Branch
  • lösche den Feature-Branch

Siehe auch

Branches erstellen und wechseln

Befehle

  • git branch foo
  • git branch foo $commitid
  • git switch foo
  • git switch -c bar
  • git switch -c bar $commitid
  • git branch

Erstellen eines Branches

git branch python-3-port

Wechseln von Branches

Wechseln zwischen python-3-port und main:

git switch python-3-port
git switch main

Wechseln von Branches

Vor dem Wechseln kann es sinnvoll sein, dass es keine aktiven Änderungen gibt

git status
git switch main

Erstellen und Wechseln in einem

git switch -c python-3-port

Erstellen und Wechseln zu einem neuen Branch

Auflisten von Branches

Auflisten von allen (lokalen) Branches:

git branch

Zusammenführen von Branches

Zusammenführen von Branches

Strategien:

  • merge: einfachste, behält alle Commits aus dem Feature Branch (erzeugt komplexe Histories)
  • squash and merge: Kombiniert alle Commits eines Feature Branches in einen Einzelnen Commit
  • rebase: komplexeste Methode, verwendet nur ausgewähle Commits

Zusammenführen von Branches via merge

Zusammenführen von Branches via merge

Beispiel für eine Commit-History (während der Feature-Entwicklung):

  * merge branches (footer)
 /|
* | add company logo (main)
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website

Zusammenführen von Branches via merge

Beispiel für eine Commit-History (wenn das Feature vollständig ist):

* merge branches (main)
|\
* | add company logo
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website

Zusammenführen von Branches via merge

Befehle zum Zusammenführen der Änderungen von main und footer (Merge von main nach footer):

git switch footer
git merge main

Merge-Konflikte

haben zwei Branches die gleiche Zeile unterschiedlich abgeändert, gibt es einen Merge-Konflikt

Merge-Konflikte

Darstellung eines Merge-Konflikts in einer Datei:

First line
Second line
<<<<<< HEAD
Thrd line!
======
Third line
>>>>>> main
Fourth line

Ein Branch hat ein Ausrufezeichen hinzugefügt, ein anderer einen Schreibfehler behoben

Merge-Konflikte Auflösen

  • Bearbeite die Datei und behalte die gewünschten Änderungen
  • Dateien mit gelösten Konflikten mittels add hinzufügen
  • git commit (ohne extra Argumente)

Löschen alter Branches

Üblicherweise werden Branches nach dem Merge gelöscht:

Löschen eines Branches, der gemerged wurde:

git branch -d footer

Löschen eines Branches, der nicht gemerged ist:

git branch -D footer

Ãœbungen

Ãœbungen

  • Erstelle und ändere eine Todo-Liste
  • Arbeite an einem bestehenden Projekt von GitHub (z.B. an der Readme-Datei)

Ãœbung: Todo-Liste

Erstelle eine Text-Datei mit Todos:

- groceries
- taxes
x gardening

Verändere die Todos mittels separater Feature Branches, z.B. "long-term todos", "new-job", "new-job-sub-items", "taxes-completed", ...

Git remote

Git remote

Hosts für Git:

  • GitHub
  • GitLab

Zusammenarbeit via GitHub

Optionen:

  • Klonen eines bestehenden Repositories von GitHub
  • Veröffentlichen eines eigenen Repositories

Klonen eines bestehenden Git Repositories

git clone https://github.com/...

Wir kopieren hierzu den Link des grünen clone or download-Buttons auf GitHub

Veröffentlichen eines neuen Git Repositories

Auf GitHub: Klicke auf das + rechts oben

Wähle nicht "Initialize this repository with a README"

Veröffentlichen eines neuen Git Repositories

Sobald das leere Repository auf GitHub existiert - folge der dort angezeigten Anleitung für ein leeres Repository

Üblicherweise verbindet man ein lokales Repository nur mit einem remote Repository - das remote Repository nennt man üblicherweise origin

git remote add origin https://github.com/...

Veröffentlichen eines neuen Branches

Zum Veröffentlichen eines Branches, der am remote Repository noch nicht bekannt ist:

git push -u origin main

kopiert die Commits des lokalen main-Branches in einen neu angelegten main-Branch im remote Repository

Veröffentlichen von Commits eines bekannten Branches

Zum Veröffentlichen von Commits eines Branches, der auf der remote-Seite schon bekannt ist:

git push

Holen neuer Commits von einem remote Branch

Holen und mergen von Commits des remote Branches, der dem aktiven Branch entspricht:

git pull

Löschen eines remote Branches

Löschen eines lokalen Branches:

git branch -d python-3-port

Löschen des zugehörigen remote Branches:

git push origin :python-3-port

Credentials speichern

git config credential.helper cache

Hierdurch speichert Git eingegebene Passwörter für 15 Minuten

Bearbeiten der Commit-History mittels rebase

Bearbeiten der Commit-History

Es ist möglich, die Commit-History zu bearbeiten - kann aber gefährlich sein

Bearbeiten der Commit-History

Beispiele für Anwendungsfälle:

  • Neustrukturierung von Commits in einem Branch, um sie klarer zu machen
  • Rückgängig machen eines Commits

Bearbeiten der Commit-History

Regeln:

  • ändere die Geschichte eines Branches nicht, von dem andere Branches abzweigen könnten (z.B. main)
  • die Geschichte einer Branches in einem eigenen Repository kann abgeändert werden

Bearbeiten der Commit-History mittels rebase

ursprünglicher Commit-Log:

  * merge branch 'main' into 'footer' (footer)
 /|
* | add company logo (main)
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website

Bearbeiten der Commit-History mittels rebase

neuer Commit-Log:

  * add footer (footer)
 /
* add company logo (main)
* add sidebar
* add placeholder content
* initialize website

Bemerkung: der main-Branch wurde nicht geändert

Bearbeiten der Commit-History mittels rebase

Befehl in Git:

git rebase -i main

Ermöglicht das Interaktive Bearbeiten des aktuellen Branches von dem Punkt, bei dem er von main abzweigt

Bearbeiten der Commit-History mittels rebase

Squashing von Commits:

Ändere alle außer dem ersten Befehle von pick auf squash

Aliases und Extras

Aliases und Extras

  • aliases: eigene Kürzel für Befehle
  • git-extras: Paket mit nützlichen Aliases und extra Befehlen

Aliases

Konfigurieren einiger Aliases:

git config --global alias.unstage 'restore --staged'
git config --global alias.show-tree 'log --graph --oneline --all'

Extras

git-extras bietet vereinfachte Befehle für häufige Aufgaben:

  • git ignore
  • git show-tree
  • git squash
  • git undo

https://github.com/tj/git-extras/blob/master/Commands.md