Wolf-Dieter Fink
GIT
Versionsverwaltung in der Praxis Mitwirken an der JBoss Entwicklung
mit GITHUB
GIT Versionsverwaltung in der Praxis
• GIT ist lokal
• GIT ist verteilt
• Wie geht das ?
GIT lokal
• Das gesamte Repository mit Historie wird im .git Verzeichnis abgelegt
• Aktionen wie commit, branch etc. sind lokale Kommandos
• Lokale Kommandos haben keine
Auswirkung auf andere Repositories
solange nicht explizit gewünscht
GIT
generelles Konzept
• GIT basiert auf einem Objektmodell
• Elemente des Repositories sind Objekte
– Dateien
– Verzeichnisse – Commits
• Jedes Objekt erhält eine eindeutige
SHA-1 prüfsumme
GIT
generelles Konzept
• Ein Repository ist ein gerichteter Graph
• Der Top-Level commit oder eine Tag referenz ist der Einstiegspunkt
• Ein branch ist nur ein verschiebbarer Tag
• Dateien sind namenlose Objekte
eine Datei mit gleichem Namen existiert nur als ein Objekt und wird zwei mal referenziert
• Alles wird referenziert mittels SHA-1
GIT
generelles Konzept
• Dreiteilung
– Working Tree
lokales Verzeichnis mit Dateien – Index
Vorbereitete Änderungen die mittles add oder remove hinzugefügt wurden
– Repository
alle persistenten Änderungen
GIT
Dreifaltigkeit
• Alle Änderungen im Dateisystem wirken sich auf den WorkingTree aus.
– Diese Änderungen werden bei einem commit nicht dem Repository hinzugefügt
• add, remove bewirken das die Änderungen zum Index hinzugefügt werden
– Nachträgliche Änderungen am workingTree wirken sich nicht auf den Index aus ohne erneuten add
• Commit persistiert die Änderungen im Index im Repository
– Der Index ist danach wieder leer
GIT Praxis
• Die Ideale Welt
commit “Feature #3”
commit “Bugfix Production Problem”
commit “Feature #2”
commit “Feature #1”
• Die Reale Welt
commit “Vergessene Datei für Feature#3”
commit “Kleine Korrektur für Feature #2”
commit “Feature #3”
commit “Bugfix Production Problem”
commit “Vergessene Abhängigkeit für Feature #2”
commit “Schreibfehler in Message Feature #1 gefixed”
commit “Feature #2”
commit “Feature #1”
Git
Praxis
• Schnell noch was an den letzten commit hängen
– git add <meine fehlende Datei>
– git commit --amend
• Mittels Interaktivem Rebase
– git rebase -i HEAD~8
– git rebase -i d48be64a6
Git
Praxis (rebase)
• Wann ist rebase sinnvoll
– Bereinigen der lokalen Entwicklung
– Integrieren der Änderungen vom 'master' – Transplantieren von zusammen gehörigen
commits
Git
Praxis (rebase)
• Fertige Features nicht mit rebase integrieren da der Zeitpunkt der Integration verloren geht (merge nutzen)
• Während der Entwicklung häufig rebase nutzen
• Logische Einheiten auf verschiedenen
Branches entwickeln und ggf. Mittels rebase verschmelzen.
GIT verzweigt
• Jede (noch so kleine) in sich abgeschlossene Entwicklung sollte in einem branch stattfinden
• Ein branch sollte sooft wie möglich (mit rebase) auf den aktuellen Stand gebracht werden
• Kleine commits erleichtern die Arbeit und Fehlersuche mit bisect und blame
• Verwenden von namespaces erleichtern den Überblick
• Zum testen von Integrationen einen Throw-away-branch erzeugen
• Vor dem merge eines branch sollten die commits sinnvoll
zusammengefasst werden solange der branch nicht 'öffentlich' war
vom Umgang mit branches
Git verteilt
• Zentrale oder 'Blessed' repositories
– Sind 'Bare' repositories ohne WorkingTree – Können im Filesystem oder per Protokoll
erreicht werden
– Hierachien sind möglich
GIT verteilt (Commandos)
• git clone
– erzeugt eine komplette Kopie
• git remote
– Fügt weitere remote referenzen hinzu
• git pull || fetch
– Läd Commits und Referenzen aus einem Remote
• git push
– fügt Commits und Referenzen zu einem Remote hinzu
GIT verteilt
Erzeugen eines 'Bare' Repository
git init –bare –shared=0777 <path>
git remote add origin <path>
git push –all origin
Damit wird ein Bare-Repository im lokalen Filesystem erzeugt, durch die Angabe von
--shared werden die Zugriffrechte entsprechend gesetzt.
Das erzeugte Repository kann wie jedes Remote Repository verwendet werden.
GIT verteilt
typische Repository URL's
• Erzeugen einer Kopie mittels git clone
– ssh://wfink@code.engineering.redhat.com/ironjacamar.git – git@github.com:wfink/jboss-as.git
– git@github.com:jbossas/jboss-as.git – gitosis@server:ejb21.git
– /usr/mount/git/ejb/ejb21.git
GIT verteilt
synchronisieren von Repositories
• Laden der Änderungen vom Remote
– git fetch origin
– git merge origin/master – git pull origin master
– git pull --rebase origin master
GIT verteilt
synchronisieren von Repositories
origin
master
3d81b5 a25919 3033fa
master
origin/master
a25919 bf87b6
3d81b5
master
origin/master
bare bare-clone-pull1+
3d81b5 a25919
3033fa bf87b6
e08440
nach 'pull'
GIT verteilt
synchronisieren von Repositories
origin
master
3d81b5 a25919 3033fa
master
origin/master
a25919 bf87b6
3d81b5
master
origin/master
bare bare-clone-pull1+
3d81b5 a25919
3033fa
1887b6
nach 'pull --rebase'
GIT verteilt
synchronisieren von Repositories
• Übertragen der eigenen Änderungen git push origin master
• Das ist nur möglich wenn der aktuelle commit ein Nachfahre ist
• !
wurde nachträglich mit rebase oder amend der graph verändert können commits verloren gehen oder Dopplungen auftretenGIT verteilt
Dreiecks Beziehungen
• Your branch is ahead of 'origin/master' by 5 commits Im lokalen branch wurden commits hinzugefügt
• Your branch is behind 'oring/master' by 7 commits, and can be fast- forwarded
Der remote branch enthält 7 commits die lokal nicht verfügbar sind, es sind keine lokalen Änderungen gemacht worden
• Your branch and 'origin/master' have diverged, and have 2 and 3 different commit(s) each , respectively
Der remote branch enthält 2 commits die lokal nicht vorhanden sind.
Der lokale branch enthält 3 commits die remote nicht vorhanden sind.
GIT verteilt
• Es können beliebig viele remote repositories referenziert werden mit 'remote add URL'
• Commits und Dateien können anhand des SHA1 Keys eindeutig identifiziert werden. Dies verhindert unnötige Dopplungen
• Da alle Informationen im lokalen Clone enthalten sind ist keine permanente Verbindung erforderlich
• Unterstützung von Integration-Manager Workflow
• Mehrstufiger, verteilter, hierarchischer Workflow
Diktator - Subsystem-Maintainer möglich in großen Projekten
GIT verteilt
Eigenes repository von upstream aktualisieren
1.Aktualisieren des lokalen clone
git pull –rebase upstream master
2.Aktualisieren des remote clone
git push [origin master]
3.Aktualisieren von tags
git fetch --tags upstream git push --tags
GIT verteilt
Änderungen integrieren
• Änderungen aus anderen Repositories können einfach über einen 'remote'
übernommen werden
git remote add aDeveloper <git URL>
git fetch aDeveloper git cherry-pick SHA-1
• Beim merge wird der so integrierte
commit erkannt
GIT Praktisch
Nützliche Kommandos oder
Arbeitsschritte
GIT Praktisch
• Mit git notes <commit> kann eine Information an einen commit
angehangen werden ohne dass sich
der SHA-1 ändert
GIT Praktisch
• Den/die letzte(n) commits löschen
– git reset –hard HEAD~1
Damit werden die letzten ~x commits aus dem Graphen entfernt, die Änderungen sind in allen drei Bereichen wirksam
– git reset HEAD~1
Der letzte commit wird aus dem Repository und dem Index entfernt. Der Arbeitsbereich bleibt erhalten. (So wie vor add)
GIT Praktisch
mach mal eben ...
• Mal eben einen Fehler beheben?
Alle aktuellen Änderungen 'parken'
– git stash
– Alle Änderungen am Workingtree und Index werden gesichert
– Mehrfaches stashing möglich – pop auch in anderen branches
GIT Praktisch
Hilfe ich hab was gelöscht
• Git löscht nicht, nur die Referenz wird entfernt
– git branch -D myBranch
• Die Referenz kann mit Kenntnis des commit SHA-1 wieder hergestellt
werden
– git branch myBranch <SHA-1>
GIT Praktisch
Wer hat's erfunden
• Das Kommando sucht das auftreten von Codesegmenten
– git blame -L<startLine>,<endLine> <datei>
• -M nützlich zum auffinden von Verschiebungen
• -C zum auffinden von Code duplikaten
GIT
Wo ist der Fehler eingebaut worden?
• Manuell den letzten Stand ermitteln
git bisect start
git bisect bad 4d563e #fehlerhaft
git bisect good 563efd #hier geht es noch
• GIT checked einen Stand aus
git bisect good|bad|skip
• Abbrechen mittels
git bisect reset
GIT
Wo ist der Fehler eingebaut worden?
• Es geht auch automatisch
git bisect run myCommand
• GIT prüft anhand des return wertes
0 => good 125 => skip
<>0 => bad
GIT Praktisch
• Keine Angst vor Experimenten
– Der aktuelle Stand, gleich welches Repository, kann einfach durch kopieren gesichert werden
– Bei direkten File-Referenzen zu remotes müssen diese ggf.
angepasst werden
GIT Praktisch
Hilfe mein branch läßt sich nicht aktualisieren
• schlägt ein git rebase mal fehl ...
– master oder anderen quell-branch auf den gewünschten Stand bringen
– neuen Branch erzeugen
git checkout -b neu <master>
– eigene commits aus branch übernehmen
git cherry-pick abcd...def
– orginal branch löschen oder umbenennen
git branch -D my
git branch -m my my_save
– neuen branch umbenennen
git branch -m neu my
Git Praktisch
Noch Fragen ?
GIT
Quellen und Literatur
• Git – Verteilte Versionsverwaltung
OpenSource Press ISBN978-3-941841-42-0
• Github Hilfe
https://help.github.com/
• Git
http://git-scm.com/documentation
• WildFly
https://community.jboss.org/wiki/HackingOnWildFly