- Dokumentation von Veränderung von Dateien über der Zeit
- Wiederherstellbarkeit früherer Versionen
⇒ „If you skrew things up […], you can easily recover“ – pro Git - Simpelste Form der Versionskontrolle: Kopiere über Zwischenversionen von Dateien in ein „Backup“-Verzeichnis
- z. B. CVS, Subversion, Perforce
- ein zentrales Repository, Clients checken Dateien von dort aus und commiten nach dort
- Jeder weiß, was jeder gerade tut
- Administratoren können kontrolieren, wer was darf und wer was nicht
- Single Point of Failure
- Verbindung zum zentralen Server ist zwingend notwendig
- z. B. Git, Mercurial, Bazaar
- Clients checken Dateien nicht aus, sondern spiegeln das gesamte Repository
- Linux-Kernel wurde bis 2002 mit Patchdateien via E-Mail versionskontrolliert
- ab 2002: proprietäres DVCS BitKeeper
- 2005: Anspannung der Beziehung zwischen Linux-Community und BitKeeper-Entwickler ⇒ Linus Torvald entwickelt als Wochenendprojekt Git als Alternative
- Anforderungen:
- Geschwindigkeit
- Einfaches Design
- Unterstützung nicht-linearer Entwicklung
- komplett verteilt
- Unterstützung sehr großer Projekte
- Snapshots, keine Diffs
- (fast) alle Operationen sind lokal (Ausnahme:
fetch
undpush
und Erweiterungen) - Checksummen-basiertes speichern (SHA1-Summen sind Objekt-ID)
- nur Hinzufügen von Daten erlaubt
- Dateien können 3 Zustände in einem Git-Repository haben:
- commited: Datei in Datenbak gespeichert
- verändert: Datei verändert, aber noch nicht commited
- staged: veränderte Datei, die zum commiten markiert wurde
- ⇒ Drei Hauptsektionen eines Git-Projekts:
- Git-Verzeichnis
- Arbeits-Verzeichnis
- Staging-Area
-
git.git war ursprünglich nur als Toolkit für Versionskontrollsysteme gedacht
⇒ Viele Low-Level-Befehle, die aneinaneder gekettet benutzerfreundliche Befehle ergeben -
Plumbing: Low-Level-Befehle
git cat-file git hash-object git update-index git write-tree ...
-
Porcelain: benutzerfreundlichere Befehle
git checkout git commit git remote ...
- Alles in einem Git-Repository ist ein Objekt (
.git/objects
) - Objekte werden durch eine eindeutige ID (ihre SHA1-Checksumme) identifiziert
- Vier Arten von Objekte:
- Blob: Abbild des Inhalts einer Datei
- Tree: zeigt auf Menge von Blob- und anderen Tree-Objekten (äquivalent zu Verzeichnis in Dateisystemen) und benennt sie (= Dateinamen)
- Commit: zeigt auf ein Tree-Objekt, mindestens ein Eltern-Commit-Objekt und hat Eigenschaften wie Autor, Commiter, Commit-Nachricht und Zeitstempel
- Tag: zeigt auf Objekt und Eigenschaften wie Tagger, Zeitstempel und Tag-Nachricht
- Obvious flaw is obvious: 160-Bit-Hashes sind schwer zu merken
⇒ Referenzen - Dateien im
.git/refs
-Verzeichnis mit einem Hashwert oderref: refs/...
als Inhalt)- Branches (
refs/heads/<name>
) - Der aktuelle Kopf (
refs/HEAD
) - leichtgewichtige Tags (
refs/tags/<name>
) - entfernte Repositories (
refs/remotes/<repo_name>/<branchname>
)
- Branches (
- Unterschied zu Referenzen und Tag-Objekten (annotierte Tags): Referenzen können verschoben werden
- „implizite“ Referenzen:
- short SHA, RefLog-Kurznamen (s. reflog), Vorfahren-Schreibweise (
HEAD^[n]
undHEAT~[n]
), Ranges (<commit>..<commit>
,<commit>...<commit>
)
- short SHA, RefLog-Kurznamen (s. reflog), Vorfahren-Schreibweise (
.git/objects/pack
?[0-9]{2}/
-Objekte sind so genannte loose objects- Snapshots werden mit der Zeit sehr groß (besonders bei großen Dateien)
git gc
komprimiert mit Delta- und zlib-Komprimierung- Speichert Ergebnisse in
pack-*.idx
(ein Index der komprimierten Objekte) undpack-*.pack
(die komprimierten Objekte) - Half-byte orientierte Bytedateien in network order
- Konfiguration geschieht mit
git config
- Manipulation von 3 verschiedenen Dateien:
/etc/gitconfig
: Systemweite Konfiguration (--system
)$HOME/.gitconfig
: globale Konfiguration (--global
)$REPO_PATH/.git/config
: repo-spezifische Konfiguration
- Dinge die vorm ersten Einsatz (global) konfiguriert werden sollten:
- Identität:
user.name
unduser.email
- Editor:
core.editor
- Diff-Editor:
merge.tool
- Identität:
- Nice to have:
-
Farbe:
git config --global color.ui true
-
Password caching:
git config --global credential.helper 'cache --timeout=3600'
-
Aliases:
git config --global alias.ci commit
-
Trailing Spaces entfernen:
git config --global core.whitespace trailing-space git config --global apply.whitespace fix
-
-
Repository lokal erstellen
git init git init --bare
-
entferntes Repository herunterladen
git clone <url> [dir]
- Git unterstützt mehrere Protokolle
- lokales Dateisystem:
git clone <path>
- HTTP/HTTPS (The dumb protocol):
git clone http[s]://<host>/<path>
- Git-Protocol (unauthentifiziert):
git clone git://<host>/<path>
- SSH (authentifiziert):
git clone [<username>@]<host>:<path>
- lokales Dateisystem:
- Git unterstützt mehrere Protokolle
- leere Zeilen und Zeilen die mit
#
: ignoriert - Standard glob-Pattern (wie in UNIX-Shells)
/
am Ende: Verzeichnis!
am Zeilenanfang: Negation des Patterns
- Commit-Nachrichten: Betreff und (optionalen) Körper
- Länge des Betreff: optimal ≤50 Zeichen, maximal ≤72 Zeichen
- Inhalt des Betreff: kurze Beschreibung der Änderung
- Policy: Imperative Formulierung ohne Punkt: „Add method to apply commits“
- nach Betreff: Leerzeile
- Länge des Körpers: beliebig
- Inhalt des Körpers: genauere Beschreibung des Patches und Begründung
- Manipulation der Ausgabe mit
git log --pretty=format:<format string>
Option Beschreibung der Ausgabe %H Commit-Hash %h Abgekürzter Commit-Hash %T Tree-Hash %t Abgekürzter Tree-Hash %P Eltern-Hashes %p Abgekürzte Eltern-Hashes %an Name des Autors %ae E-Mailadresse des Autors %ad Datum des Authors (Format folgt der „–date=“-Option) %ar relatives Datum des Authors %cn Name des Committers %ce E-Mailadresse des Committers %cd Datum des Committers %cr relatives Datum des Committers %s Betreff der Commit-Nachricht … *(s. git help log)*
-
Idee: Abspaltung von Hauptentwicklungspfad, ohne diese zu stören
⇒ Ziel: mögliche Wiedervereinigung -
in den meisten VCSs: sehr teuer
-
in Git: Commit-History ist by-design ein DAG
-
„Killer-Feature“ (leichtgewichtig, schnell, …)
⇒ Branch-basierte Workflows
-
stabiler master-Branch
-
mehrere kurzlebige Feature-Branches
-
Entwicklungs-Branch zum einmergen der Feature-Branches und für Stabilitätstest
-
git.git hat z. B. noch proposed und proposed update (pu)
- Format der Namen:
{remote}/{branch}
git pull {remote} {branch}
≙git fetch {remote} {branch} && git merge {remote}/{branch}
- Remote branch mit aktuellem Branch
aktualisieren mit
git push {remote} {branch}
- Tracking branches:
- lokale Branches die einem Remote Branch folgen
- neuer lokaler:
git checkout -b {local branch} {remote}/{branch}
- bestehende (ab 1.6.2):
git checkout --track {remote}/{branch}
git push {remote} :{branch}
löscht remote branch
Do not do:
- bereits gepushte commits rebasen (or people will hate you)
git reflog
: Log aller lokalenHEAD
- und Branch-Referenzengit add -i
: interaktives Stagengit stash
: momentan nicht benötigte Änderungen auf einem Stack ablegen- Rewriting History (nur lokale Commits!!!!!):
git commit --amend
: aktuelle Index zum letzten Commit + Message änderngit rebase -i <commit>
: bearbeiten aller Commits in<commit>..HEAD
-Range:- neu anordnen, bearbeiten, zusammenführen, ...
git filter-branch
: bearbeiten von Details in gesamter History:- E-Mail-Adressen in Commits ändern, Dateien löschen, ...
git blame
: wer hat wann welche Zeile geschrieben?git bisect
: Binärsuche nach bugeinführenden Commitsgit submodules
: binde andere Git-Projekte als Unterordner ein
.gitattributs
: pfadspezifische Regeln für Befehle.git/hooks
: Skripte die bei bestimmten Git-events ausgeführt werdengit svn
: Benutze Subversion-Repositories mit Gitgit fast-import
: Portiere Repositories anderer VCS nach Git
- Pro Git, Scott Chacon
- Manpages (
git help [<command>]
oderman git [<command>]
) - All pictures are from Scott Chacon's Pro Git and under CC BY-NC-SA 3.0 License
- This presentation is published a under CC BY-NC-SA 3.0 License