Benutzer-Werkzeuge

Webseiten-Werkzeuge


developing:git

GIT

GIT kennenlernen, Spickzettel für Einsteiger.

BegriffBedeutung
RepositoryEine für das jeweilige Projekt eigene Git-DB (in Filesystem des Projektes), die durch GIT intern verwaltet wird.
Der Entwickler kommt mit dieser DB eigentlich nicht in Berührung.
Working TreeDas Projekt-Verzeichnis, in dem sich alle zum Projekt gehörende QuellCode-Files befinden (samt Unterverzeichnisse).
Commit Veränderungen am Working Tree, sprich an den QuellCode-Files, werden detailliert in den Commits festgehalten.
HEAD Eine symbolische Referenz auf den neuesten Commit im aktuellen Branch.
Index Der Index ist eine Zwischenstufe zwischen Working Tree und Repository.
Im Index werden (i.d.R. mehrere) Files für einen späteren Commit vorbereitet.
Tag Tags sind symbolische Namen für (schwer zu merkende) SHA-1-Summen.
Branch Eine Abzweigung in der Entwicklung.
:!: Tipp zur Benennung von Branches:
Es sorgt für mehr Übersicht, wenn man den Namen eines Arbeits-Branches aus 3 Teilen zusammenfasst, getrennt durch ein "/"-Zeichen, nach dem Schema "KindOfBranch/User/Topic".
Einige Beispiele: "feature/juergen/Task-12345.GUI-Erweiterung_XY" oder "bugfix/oliver/Task-54321.Falsche_Berechnung_XYZ".
master Default-Branch eines Repositories. (Kann/darf umbenannt/gelöscht werden.)
Es wird empfohlen, die laufende Entwicklung in (mindestens) einem separaten Branch zu führen, der i.d.R. "develop" benannt wird.
Noch besser, auch den "develop"-Branch in die weiteren Feaure- und Bugfix-Branches für die Dauer der jeweiligen Implementierungen abzuzweigen und danach wieder in den "develop"-Branch zu mergen.

Installation

FIXME Client-Installation (für lokale Entwicklung / lokale Repositories)

FIXME Installation auf dem Server (für remote-Repositories)

Konfiguration

GIT-Einstellungen und deren Ursprung anzeigen lassen:

~/prj> git config --list --show-origin

Oder einfach die Einstellungen anzeigen lassen:

~/prj> git config --list

Eigene Identität in der GIT-Konfiguration hinterlegen (die GIT-Commits speichern diese Informationen in den Commits unveränderlich ab):

~/prj> git config --global user.name "Vorname Nachname"
~/prj> git config --global user.email "vorname.nachname@domain.tld"
# Oder so:
~/prj> git config --global user.email vorname.nachname@domain.tld

Durch die Option "--global" werden diese Angaben für die gesamte GIT-Installation gelten.
Ohne diese Option gelten die Angaben nur für das jeweilige Projekt (z.B. falls man für einige Projekte abweichende Namen und eMail-Adresse verwenden möchte).

Folgender Befehl definiert, wonach EOLs (Line-Endings) beim checkout konvertiert werden:

# EOL - mögliche Werte: lf, crlf, native
~/prj> git config --global core.eol lf

:!: Die Git-Konfiguration wird im File "~/.gitconfig" (globale Konfig) bzw. ".git/config" (für das jeweilige Repository) gespeichert.
Falls ein Parameter in beiden Files vorhanden ist (global und im Repository), dann hat der Parameter aus der Repository-Konfig Vorrang.
Falls ein Git-Parameter in keinem der beiden Files vorhanden ist, wird ein für den jeweiligen Parameter festgelegter default-Wert verwendet.

Liste aller gesetzten Einstellungen:

~/prj> git config -l

:!: Mit den Kommandos "git config -e" bzw. "git config --global -e" lassen sich die beiden Konfigurationsdateien in einem Editor ändern.

SSH-Zugriff für das remote Repository konfigurieren

Um nicht jedes mal beim Datenaustausch zwischen dem remote und dem lokalen Repository den Benutzernamen und das Passwort eingeben zu müssen, ist es ratsam, einen SSH-Key dafür zu verwenden.

Einen SSH-Key erzeugen:

~/prj> ssh-keygen -t rsa -b 2048 -C "Eine_aussagekräftige_Schlüsselbezeichnung"

Bei der Frage nach dem FileNamen, unter dem das Schlüssel-Paar gespeichert werden soll, kann man den Standardnamen "id_rsa" übernehmen, besser aber einen für den Zweck passenden Namen anzugeben. Wenn das Schlüssel-Paar für GitLab gedacht ist, könnte man es z.B. als "id_rsa_gitlab" benennen.
:!: Die Passphrase lässt man am besten leer, damit der Datenaustausch zwischen dem remote und dem lokalen Repository quasi automatisch stattfindet, ohne dass man jederzeit die Passphrase eingeben muss. Da dieses Schlüssel-Paar ausschließlich für die Kommunikation mit dem remote-Repository zuständig ist, ist das Sicherheitsrisiko vertretbar.

Der neu erstellte Schlüssel soll dem SSH-Agenten hinzugefügt werden:

~/prj> ssh-add ~/.ssh/id_rsa_gitlab

Der SSH-Agent muss noch wissen, bei welchem Host der o.g. Schlüssel zum Einsatz kommen soll. Dafür ist das File "~/.ssh/config" zuständig:

Host gitlab.com
  HostName gitlab.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_rsa_gitlab

Nicht vergessen, die Zugriffsrechte auf beide Files auf das Nötigste zu reduzieren:

~/prj> chmod 400 ~/.ssh/id_rsa_gitlab
~/prj> chmod 600 ~/.ssh/config

Damit das lokale Git mit dem remote-Repository über das SSH-Protokoll kommuniziert, muss noch sichergestellt werden, dass in der Git-Konfiguration (".git/config") die URL für das [remote "origin"] auf das SSH-Protokoll (und nicht auf z.B. "HTTPS") eingestellt ist. Die allgemeine Syntax lautet:

ssh://[username@]repositoryhost.tld[:port]/pfad/zum/repository.git

:!: Es gibt dabei manche Stolperfallen! Einige Git-Hoster verlangen als UserNamen nicht den korrekten UserNamen des Repository-Besitzers, sondern einen bestimmten Namen. Zum Beispiel GitLab erwartet an dieser Stelle den Namen git:

ssh://git@gitlab.com/pfad/zum/repository.git

Und natürlich nicht vergessen, den public-Key (in dem o.g. Beispiel das File "~/.ssh/id_rsa_gitlab.pub") bei dem remote-Repository einzutragen.

Lokale und remote Repository

:?: Lokales Repository erstellen → nach Remote (z.B. GitHub/GitLab) übertragen.

Schritt Vorgehen
Ein neues Repository erstellen. Repository-Name beispielsweise "git_sample":
~/prj> git init git_sample

FIXME

:?: Das Repository Remote (z.B. in GitHub/GitLab) erstellen → von dort in die lokale Umgebung klonen.

Schritt Vorgehen
Repository von Remote nach Lokal klonen. Repository beispielsweise "git_sample":
~/prj> git clone git://gitlab.com/juser-name/git_sample.git

Dabei wird der Ordner "git_sample" erstellt.

Oder das Gleiche per SSH-Protokoll:

~/prj> git clone ssh://git@gitlab.com/juser-name/git_sample.git


Falls der Ordner anders heißen soll als das Repository, den Ordner-Namen (hier als Beispiel "mein_git_sample") mitgeben:

~/prj> git clone git://gitlab.com/juser-name/git_sample.git mein_git_sample_ordner
Lokal wird das remote Repository default-mäßig als origin benannt.
~/prj> cd git_sample
~/prj/git_sample> git remote
origin
"origin" umbenennen. Der default-Name "origin" läßt sich umbenennen, hier z.B. in "gitlab":
~/prj/git_sample> git remote rename origin gitlab
~/prj/git_sample> git remote
gitlab
…oder gleich beim Klonen die Option --origin mitgeben:
~/prj> git clone --origin gitlab git://gitlab.com/juser-name/git_sample.git

FIXME

Beispiele für Kommandos und häufige Aufgaben

Versionierung

Kommando¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Bedeutung
git status Zeigt den aktuellen Stand des (lokalen) Repositorys an (im aktuell aktiven Branch).
git add FileName.Ext Die Datei FileName.Ext wird dem Git-Index (für einen späteren Commit) hinzugefügt.
git add -u
git add --update
Alle Änderungen (an allen Dateien) in einem Rutsch in den Index übernehmen.
git add --patch FileName.Ext
git add -p FileName.Ext
git add -p
Commits schrittweise (interaktiv) erstellen.
Interaktive Optionen:
y (yes) - übernimmt den aktuellen Hunk in den Index;
n (no) - übernimmt den aktuellen Hunk nicht;
q (quit)- übernimmt weder den aktuellen Hunk noch einen der folgenden;
a (all) - übernimmt den aktuellen Hunk und alle, die ihm folgen (in der aktuellen Datei);
s (split) - versucht, den aktuellen Hunk zu teilen;
e (edit) - editiert den aktuellen Hunk.
git diff

git diff --staged
Zeigt Änderungen an den Quelltexten, die durch einen Commit in das Repository einfließen würden.

Ohne Parameter "--staged" werden Änderungen angezeigt, die sich noch im "Working Tree" befinden,
mit dem Parameter "--staged" - die, die sich (durch "git add") bereits in der "Staging Area" (im Index) befinden (Unterschiede zwischen Index und HEAD).
git diff --word-diff Statt der entfernten und hinzugefügten Zeilen zeigt diese Variante die Ausgabe mit einer entsprechenden Syntax sowie farblich kodiert die hinzugekommenen (grün) und entfernten (rot) Wörter.
git reset
git reset HEAD
git reset -p
FIXME
"git reset" bewirkt das Gegenteil davon, was "git add" gemacht hat.
"git reset HEAD" setzt den Index zurück.
"git reset -p" tut es interaktiv (analog zu "git add -p").
git commit Ohne Argumente fasst Git alle Files, die sich im Index befinden, zu einem Commit zusammen und öffnet einen Editor, in dem man die (teils bereits vorausgefüllte) Commit-Message erstellen kann.
git commit -m "Commit-Message" Alle Dateien aus dem Git-Index werden zusammengefasst und in einem in sich abgeschlossenen Daten-Block, dem s.g. Commit, festgehalten.
Alle Commits sind miteinander verkettet - dadurch sind sämtliche Änderungen an den QuellTexten nachvollziehbar.
git commit --amend
FIXME
Damit kann man den aktuellen Commit noch geringfügig verändern. (Dadurch ändert sich konsequenterweise auch die Commit-ID.)
Es startet automatisch auch ein Editor, so dass man auch noch die Commit-Message bearbeiten kann.
git fetch
git fetch origin
Lädt Commits aus dem remote-Repository, die dem lokalen Repository voraus sind, in das lokale Repository herunter. ()
git merge
git merge origin/master
Commits, die mit dem vorherigen "git fetch" herunter geladen wurden, werden mit dem lokalen Repository gemerged. ()
Mit der Angabe "origin/master" legt man fest, in welchen Branch die Commits gemerged werden sollen.
git pull
git pull origin master
Macht das gleiche wie "git fetch" und "git merge" zusammen, nur in einem Rutsch. ( + )
git push
git push origin master
Lädt Commits aus dem lokalen Repository in das remote-Repository hoch. Das ist das Gegenstück zu "git fetch" bzw. "git pull". ()
git push origin ein_neuer_branch
git branch -u origin/ein_neuer_branch
Lädt man Commits aus dem neuen Branch hoch, den es in dem remote-Repository noch nicht gibt,…
…muss dieser in der Upstream-Konfiguration vermerkt werden.
git push -u origin ein_neuer_branch Das Gleiche wie oben, nur in einem Rutsch.

FIXME git stash - S.119-124

FIXME git notes - S.125-126

FIXME Revert - S.64-65

Versionshistorie

Kommando Bedeutung
git show
git show HEAD
git show master

git show Commit-ID

Beispiele mit Commit-ID:
git show 3363115a
git show 3363115ad35db647f088f064b57b10d6b9670298
Infos zu einem bestimmten Commit einsehen.
Ohne Parameter wird der aktuellste Commit angezeigt.

Es werden alle relevanten Infos über einen Commit angezeigt:
- Commit-ID
- Autor
- Datum/Uhrzeit des Commits
- Commit-Nachricht
- Zusammenfassung der Veränderungen im Unified-Diff-Format.
git log
git log -n

Beispiele:
git log -4
git log -1 Commit-ID
Mehrere Commits (als Liste) in einem Rutsch einsehen.
Die Ausgabe von Commits auf die letzten "n" Stück begrenzen.


Zeigt nur die letzten 4 Commits.
Zeigt einen einzelnen Commit mit der "Commit-ID".
git log --after='Datum'
git log --since='Datum'
git log --before='Datum'
git log --until='Datum'

Beispiele:
git log --since='yesterday'
git log --since='2021-10-04'
git log --since='2021-09-01' --until='2021-09-05'
Zeigt nur die Commits ab dem Datum an.
Parameter --since ist ein Synonym für --after.
Zeigt nur die Commits vor dem Datum an.
Parameter --until ist ein Synonym für --before.
git log -- Filename.Ext *.Ext Ordnername/ Es werden nur die Commits angezeigt, die die angegebenen Dateien betreffen.
:!: Zwischen dem Doppelstrich "--" und der Liste der Dateinamen ist eine Leerstelle.
git log --author='Max Mustermann'
git log --committer='Fritz Meier'
Es werden Commits angezeigt, die den Max Mustermann als Author haben.
Es werden Commits angezeigt, die den Fritz Meier als Committer haben.
:!: Die beiden Namen müssen nicht vollständig angegeben werden. Nur ein Teil des Namens reicht auch.
git log --grep=Suchmuster
git log -i --grep=Suchmuster
Es werden Commits angezeigt, in denen das Suchmuster innerhalb der Commit-Nachricht vorkommt.
Durch den Parameter "-i" wird die Groß-/Kleinschreibung ignoriert.
gitk
gitk --all
Gitk ist ein GUI für die graphische Darstellung des aktuellen Branches.
Mit der Option "--all" werden alle Branches in einem Graphen dargestellt.
Gitk akzeptiert im wesentlichen die gleichen Optionen wie "git log".

FIXME Wie findet man heraus, von welchem Branch wurde der aktuelle (bzw. jeder beliebige) Branch abgeleitet? (Ohne graphische Branches-Übersicht.)

Suche

Kommando¯¯¯¯¯¯¯¯ Bedeutung
git grep Suchmuster Git-eigenes "grep"-Kommando, dass alle gängigen Optionen von dem GNU-grep unterstützt, sucht jedoch innerhalb der von Git verwalteten Dateien und wesentlich schneller als das "Original" ist.

Fileoperationen

Kommando Bedeutung
git rm FileName.Ext
git rm -r FileName.Ext
git rm -f FileName.Ext
Datei löschen.
Funktioniert wie die reguläre Unix-Kommando, darüber hinaus jedoch modifiziert den Git-Index.
Mit der Option "-r" - rekursiv, mit der Option "-f" - ohne Rückfrage.
git mv FileName.Ext
git mv -r FileName.Ext
git mv -f FileName.Ext
Datei verschieben/umbenennen.
Funktioniert wie die reguläre Unix-Kommando, darüber hinaus jedoch modifiziert den Git-Index.
Mit der Option "-r" - rekursiv, mit der Option "-f" (force) - ohne Rückfrage.

Branches

Kommando Bedeutung
git branch
git branch -v
Listet alle Branches auf (nur die Namen).
Mit der Option "-v" werden zusätzlich die Commit-IDs und die 1. Zeile aus der Commit-Message angezeigt.
git branch BranchName
git branch BranchName Commit-ID
Erstellt aus dem aktuellen Branch einen neuen Branch mit dem Namen "BranchName".
FIXME
git branch -m NeuerBranchName
git branch -m AlterBranchName NeuerBranchName
Der aktuelle Branch wird zu "NeuerBranchName" umbenannt.
Der Branch mit dem Namen "AlterBranchName" wird zu "NeuerBranchName" umbenannt.
:!: Die Umbenennung funktioniert nur wenn kein Branch mit dem Namen "NeuerBranchName" bereits existiert.
git branch -d BranchName Löscht den Branch "BranchName". Man kann auch mehrere Branches gleichzeitig angeben.
git checkout BranchName
git checkout -b NeuerBranch
Wechselt von dem aktuellen Branch zu dem Branch "BranchName".
Zuerst erstellt einen neuen Branch "NeuerBranch" und dann wechselt zu ihm.
git merge BranchName Übernimmt Änderungen von dem Branch "BranchName" in den aktuellen Branch (also in den "HEAD").
git branch -r Alle verfügbaren remote-Branches anzeigen. Ein ähnliches Ergebnis, jedoch mit mehr Infos:
git remote show origin
git branch -a Alle verfügbaren Branches anzeigen - remote und die lokalen.

FIXME mergetool - S.81-82

FIXME Tags - S.55-61

Remotes

Kommando¯¯¯¯¯¯¯¯¯¯ Bedeutung
git remote show
git remote show origin
Die Zusammenfassung des Remotes anzeigen lassen. Durch die Option "-n" wird die Abfrage bei dem Remote unterdrückt (es wird nur die lokal vorhandene Zusammenfassung angezeigt).

Stand: 13.05.2023

EOF

developing/git.txt · Zuletzt geändert: 2023/05/13 22:40 von Jürgen Kreick

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki