GIT CLI

Git installieren unter macOS

brew isntall git

Versionsverwaltungsysteme

Eine Versionsverwaltung ist ein System, das zur Erfassung von Änderungen an Dokumenten oder Dateien verwendet wird. Alle Versionen werden in einem Archiv mit Zeitstempel und Benutzerkennung gesichert und können später wiederhergestellt werden.

Tipp!

Mit man git rufst du die Manual Pages von Git auf. Dort werden die einzelnen Befehle beschrieben was diese machen.

Git-Docs

Die Docs zum Git-Cli können hier gefunden werden. Von dieser Quelle stammt der Grossteil der Informationen.


Projekt erstellen

# Erstellt ein Ordner mit dem Namen: "hello-world" in "projekte"
mkdir hello-world
# Wechselt in das Verzeichniss "hello-world"
cd hello-world

Repository anlegen

Mit dem folgenden Befehl kann ein lokales Repository erstellt werden.

git init

#Initialized empty Git repository in ~/git/projekte/hello-world/.git/

Git hat nun mit dem init Befehl ein verstecktes Verzeichnis namens “.git” angelegt.

Git Workflow

Jedes Git Repository hat drei Bäume. Ein Arbeitsverzeichnis, einen Index und einen Head
Arbeitsverzeichnis: Da sind die aktuellen Dateien des Projekts enthalten
Index: Ist die Staging-area in welches die Projekt Dateien hinzugefügt (add) werden welche für das Commit bereit sind.
Head: Head ist wo die Referenz zu vorherigen Commits existiert

git add & git commit

Wenn im Projekt neue Dateien erstellt werden, müssen diese zur Staging area hinzugefügt werden.

Wir erstellen nun in unserem Verzeichnis eine foo.txt/bar.txt Datei welches wir zu staging area hinzufügen. Danach kann mit git commit ein commit erstellt werden.

Einmal committed, kann eine Versionierung im lokalen repository stattfinden. Wir können mit Git soweit lokal arbeiten ohne ständig ‘online’ zu sein.

git add foo.txt bar.txt

bzw...

git add -A

-----

git commit --message "foo"

#[master (root-commit) 461eda0] first commit
#1 file changed, 1 insertion(+)  
#create mode 100644 readme.txt

Über Github-Desktop werden automatisch alle Dateien selektiert. Um ein(e) Datei nicht in die Staging area aufzunehmen müssen diese abgewählt werden.

Danach kann dem Commit einen Text/Beschreibung gegeben werden. Über den Button können “Commit to ”, werden die Dateien in die Staging area aufgenommen.

git-commit

Status abfragen

Mit git status können wir die staging area überprüfen:

git status

#On branch master
#Initial commit:
#Changes to be committed:
#  (use "git rm --cached <file>..." to unstage)
#
#  new file: foo.txt bar.txt

git log

Mit git log kann man die Historie eines Projektes anzeigen lassen.

git log    

#commit 3c6413c6ac1a894182161d51366f7022ce7afea8
#Author: LukasW01 <lukas@wigger.one>
#Date:   Sat Oct 1 17:28:51 2022 +0200

#    test2

#commit 987b1d90837ed537d26d27e2a7aef035b69e475c
#Author: LukasW01 <lukas@wigger.one>
#Date:   Sat Oct 1 17:21:06 2022 +0200

#    test1

Zusätzlich kann man die Commit-Historie eines bestimmten Autors anzeigen.

git log --author=<author>

In Github Desktop kann die Historie über den Tab “History” abgerufen werden die einzelnen Commits können hier eingesehen werden, inkl. die Änderungen an den Dateien.

git-log

git diff

Stellt Änderungen zwischen dem Working Tree und dem Index dar.

git diff

Im Github Desktop können die anpassungen vor einem Commit eingesehen werden

git-diff

git blame

Der git blame zeigt die Zeilen eines bestimmten Dateiinhalts mit den zugehörigen Commits und Autoren an. Als Parameter wird ein Pfad zu einem File verlangt.

git blame <path>

Im Bitbucket kann, im man im Source-Browser ist, in eine Datei gehen und über den Blame-Button herausfinden wer/wann eine Zeile im Code angepasst hat.

git-blame

git remote

Man kann den Befehl git remote add .... benutzen, um dein lokales Repository mit einem neu erstellten Remote-Repository auf GitHub oder GitLab zu verbinden.

git remote add origin  https://github.com/LukasW01/hello-world.git 

# to edit an existing remote:
git remote set-url origin  https://github.com/LukasW01/hello-world.git

Für details welches Remote-Repository git benutze, kann man den Befehl git remote -v verwenden.

git remote -v

#origin	https://github.com/LukasW01/hello-world.git (fetch)
#origin	https://github.com/LukasW01/hello-world.git (push)

git clone

Mit git clone kann man die gesamte Projekthistorie “Klonen”. Damit kann eine weitere Person am selben Projekt mitarbeiten.

git clone <repository>

#Cloning into 'hello-world'...
#remote: Enumerating objects: 121, done.
#remote: Counting objects: 100% (121/121), done.
#remote: Compressing objects: 100% (120/120), done.
#remote: Total 121 (delta 64), reused 0 (delta 0), pack-reused 0
#Receiving objects: 100% (121/121), 28.73 KiB | 1.79 MiB/s, done.
#Resolving deltas: 100% (64/64), done.

git pull - Änderungen speichern

Übernimmt Änderungen aus einem Remote-Repository in den aktuellen Branch. Wenn der aktuelle Branch hinter dem entfernten Branch liegt, dann wird standardmäßig den aktuellen Branch fast-forward, damit er mit dem Remote-Branch übereinstimmt.

git pull <remote> <branch>

#remote: Counting objects: 3, done.  
#remote: Compressing objects: 100% (3/3), done.  
#remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0  
#Unpacking objects: 100% (3/3), done.  
#From https://github.com/LukasW01/hello-world  
#2e0c3ad..d16e77c master -> origin/master  
#Updating 2e0c3ad..d16e77c  
#Fast-forward  
#HelloWorld.java | 4 ++++  
#1 file changed, 4 insertions(+)

Um änderungen von einem Remote zu erhalten muss in der Regel zuerst ein Fetch durchgeführt werden (Wird auch automatisch alle in regelmässigen abständen von Github-Desktop gemacht).

git-fetch

Dann können die änderungen aus dem Origin-Branch heruntergeladen werden.

git-pull

MIt der --rebase flag aktualisiert git das lokale Repository und wendet Commits aus dem entfernten Repository an, indem Rebase statt Merge verwendet wird.

git pull --rebase

git fetch

git fetch lädt nur neue Daten aus einem Remote-Repository herunter - es integriert keine dieser neuen Daten in die working files.

git fetch <remote>

git push - Änderungen speichern

Aktualisiert remote refs unter Verwendung local refs und sendet dabei Objekte, die zur Vervollständigung der angegebenen refs erforderlich sind.

git push -u <remote> <branch>

#Counting objects: 3, done.  
#Writing objects: 100% (3/3), 222 bytes | 0 bytes/s, done.  
#Total 3 (delta 0), reused 0 (delta 0)  
#To https://github.com/LukasW01/hello-world.git  
#* [new branch] master -> master  
#Branch master set up to track remote branch master from origin.

git merge

Um die Änderungen von einer anderen Branch zu ‘mergen’ kann der git merge Befehl verwendet werden. Mann muss sich zu dem Zeitpunkt des Merges in der Branch befinden wo die Änderungen hin sollen. Unter umständen kann es dabei zu Merge Konflikten kommen.

Die Option –-no-ff bedeutet, dass kein „Fast Forward“ gemacht wird. Das heisst, die Änderungen werden nicht einfach in den develop-Branch übernommen, auch wenn auf diesem in Zwischenzeit keine Änderungen vorgenommen wurden. Es wird also explizit ein Zusammenführen erzwungen.

git merge <branch>

Cherry-Picking in Git bedeutet, einen Commit aus einer Branch ausgewählt wird und ihn auf einen andere Branch angewendet wird.

git cherry-pick <commit-hash>

git checkout

Branch bedeutet, dass man von der Main-Branch der Entwicklung abweicht und die Arbeit fortsetzt, ohne die Main-Branch zu beeinträchtigen.

Eine neue Branch kann man folgendermassen erstellen:

git checkout -b <branch>

#Switched to a new branch 'goodBranch'

Vom ausgehenden Branch (optimal von einem aktuellen Main/Release Branch) kann über die Branch übersicht einen neuen Branch erstellt werden

git-branch

git-checkout-branch-create

Um eine Branch zu wechseln kann der git checkout befehlt mit dem folgenden Syntax verwendet werden:

git checkout master

#Switched to branch 'master'  
#Your branch is up-to-date with 'origin/master'.

Um von einem Branch zum anderen zu wechseln kann

git-checkout-main

Man kann auch von einer erstellten Branch nochmals eine neue “Feature-Branch erstellen”. D.h. man erstellt von der Branch branchA eine Feature-Branch.

			|------> FeatureA
branchA ----]
			|------> FeatureB
git checkout -b featureA branchA

#Switched to a new branch 'featureA'

Tag/Branches

Die Tags müssen separat mit Push mit der --mirror flag hochgeladen werden.

git push origin --tags

oder alles...

git push origin --mirror

#Counting objects: 1, done.
#Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
#Total 1 (delta 0), reused 0 (delta 0)
#To https://github.com/LukasW01/hello-world.git
# * [new tag]         v1.4 -> v1.4
# * [new tag]         v1.4-lw -> v1.4-lw

Wenn änderungen am Branch gemacht wurden (und diese commited wurden) müssen diese auf den Remote hochgeladen werden.

git-push

Falls jedoch ein Tag oder Branch falsch gesetzt wurde oder diese nicht mehr gebraucht werden, können diese dann mit dem delete tag/branch gemacht werden.

git push origin --delete <tagname>/<branchname>

git branch

Alle Branches in einem Projekt können mit dem git branch Befehl aufgelistet werden.

git branch

Falls Sie eine Branch nicht mehr benötigen kann diese mit der Option -d und dem Namen der Branch gelöscht werden.

git branch –d featureA

Um die Branches des Remote’s anzuzeigen kann die -r flag verwendet werden. Mit mit der -a flag werden lokale und entfernte Branches angezeigt.

git branch -r

oder alle...

git branch -a

git tag

Auch der git tag Befehl listet alle Tags in einem Projekt auf.

git tag

Git bietet die Möglichkeit, bestimmte Punkte in der Historie eines Repositorys als wichtig zu kennzeichnen. Normalerweise wird diese Funktion verwendet, um Versionspunkte zu markieren (v1.0, v2.0 usw.).

git tag -a v1.1 master -m "<message>"

....oder mit Commit-Hash

git tag -a v1.2 9fceb02 -m "<message>"

Für das löschen eines Tags entweder lokale oder im remote können folgende befehle verwendet werden:

#Löscht einen lokalen Tag.
git tag -d <tag>

#Löscht einen Tag aus dem Remote-Repository.
git push --delete <remote> <tag> 

git cherry-pick

Der cherry-pick Befehl überträgt Änderungen eines bestimmten Commits auf den aktuellen Branch.

git cherry-pick <commit>

git reset

Der reset befehlt setzt den HEAD auf den letzen Commit zurück. Bzw. falls der Commit-Hash spezifiziert wird auf diesen.

git reset --hard origin/main
#HEAD is now at 9bc39e1 goodCommit

# With Commit-Hash as parameter
git reset --hard 152ec2b