Wer ist das? • aus Castrop-Rauxel • zur Zeit Student der Angewandten Informatik (M.Sc., Universität Duisburg-Essen) • zuvor Dualer Student (IT-Center Dortmund/FH Dortmund) • Git-Nutzer seit 2011 • aktiv in der Ubuntu & Open Source Szene (seit 2010) • aktuell beruflich mehr DevOps als Software-Entwickler • Autor des Git-Buchs des mitp Verlags 1
Git-Buch • „Mein“ Git-Buch • Verlag: mitp, 2016 • Preis: 29,99€ (Buch), 25,99€ (Ebook) • Der Workshop basiert auf dem Buch • Buch basiert auf Tutorial auf meinem Blog svij.org • Keine Angst: Keine „Vorlesung“ des Buches ;) 2
Zentrale Versionsverwaltung • CVS, Subversion (svn) • Repository auf zentralen Server • Arbeitskopie auf Clients • jede Aktion am Repository nur online 11
„Projekt“ • Lernen durch einfaches Anwendungsbeispiel • Bauen einer einfachen statischen Webseite • Projekt beinhaltet ein wenig Arbeiten mit HTML-Code 17
git status $ git status Auf Branch master Initialer Commit nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen Sie "git add" zum Versionieren) 21
git status - Kein Commit - Staging-Area leer $ git status Auf Branch master Initialer Commit Unversionierte Dateien: (benutzen Sie "git add ...", um die Änderungen zum Commit vorzumerken) css/ fonts/ js/ nichts zum Commit vorgemerkt, aber es gibt unversionierte Dateien (benutzen Sie "git add" zum Versionieren) 25
git add css && git status $ git add css $ git status Auf Branch master - Initialer Commit zum Commit vorgemerkte Änderungen: (benutzen Sie "git rm --cached ..." zum Entfernen aus der Staging-Area) neue Datei: css/bootstrap-theme.css neue Datei: css/bootstrap-theme.css.map neue Datei: css/bootstrap-theme.min.css neue Datei: css/bootstrap-theme.min.css.map neue Datei: css/bootstrap.css neue Datei: css/bootstrap.css.map neue Datei: css/bootstrap.min.css neue Datei: css/bootstrap.min.css.map Unversionierte Dateien: fonts/ js/ 26
git add && git status $ git add fonts/glyphicons-halflings-regular.eot $ git status Auf Branch master Initialer Commit zum Commit vorgemerkte Änderungen: (benutzen Sie "git rm --cached ..." zum Entfernen aus der Staging-Area) neue Datei: css/bootstrap-theme.css neue Datei: css/bootstrap-theme.css.map neue Datei: css/… neue Datei: fonts/glyphicons-halflings-regular.eot Unversionierte Dateien: fonts/glyphicons-halflings-regular.svg fonts/glyphicons-halflings-regular.ttf fonts/glyphicons-halflings-regular.woff fonts/glyphicons-halflings-regular.woff2 js/ 28
Tipp Tipp: git status -s $ git status -s A css/bootstrap-theme.css A css/bootstrap-theme.css.map A css/bootstrap-theme.min.css A css/bootstrap-theme.min.css.map A css/bootstrap.css A css/bootstrap.css.map A css/bootstrap.min.css A css/bootstrap.min.css.map A fonts/glyphicons-halflings-regular.eot ?? fonts/glyphicons-halflings-regular.svg ?? fonts/glyphicons-halflings-regular.ttf ?? fonts/glyphicons-halflings-regular.woff ?? fonts/glyphicons-halflings-regular.woff2 ?? js/ 29
git add js fonts $ git add js fonts Alternativ: $ git add -A …fügt alle neuen und veränderten Dateien aus dem Arbeitsverzeichnis zur Staging-Area hinzu. 30
Nochmal: git status $ git status Auf Branch master Änderungen, die nicht zum Commit vorgemerkt sind: (benutzen Sie "git add ...", um die Änderungen zum Commit vorzumerken) (benutzen Sie "git checkout -- ...", um die Änderungen im Arbeitsverzeichnis zu verwerfen) geändert: index.html keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a") 40
Mischung aus Änderungen im Staging und im Workspace H2- unter H1-Überschrift hinzufügen: Endlich lernen wir uns kennen. Jetzt ausprobieren: $ git diff Und anschließend: $ git add index.html $ git diff Was ist der Unterschied? 45
Änderung aus Staging-Area herausnehmen $ git reset HEAD index.html Die Änderung wird hiermit aus der Staging-Area herausgenommen aber nicht gelöscht! Dies verrät ein weiteres Diff. 47
Lokale Änderungen zurücksetzen Der Checkout Subbefehl wird zum Arbeiten mit Branches verwendet, in diesem Fall werden Änderungen die nicht mindestens in der Staging-Area sind, gelöscht. $ git checkout -- index.html 48
Änderungen rückgängig machen Was man nutzt hängt davon ab, in welchem Zustand sich die Änderung befindet. Reset: • Änderungen in der Staging-Area (zuvor kennengelernt) • Commits löschen Revert: • Commits mit Revert-Commits 51
Revert $ echo "Die Zeile für den Revert" >> index.html $ git commit -am "Zeile hinzugefügt, um diese zu reverten" $ git log --oneline -2 06eac50 Zeile hinzugefügt, um diese zu reverten ef130f4 Titel und Überschrift angepasst. 53
Revert $ echo "Die Zeile für den Revert" >> index.html $ git commit -am "Zeile hinzugefügt, um diese zu reverten" $ git log --oneline -2 06eac50 Zeile hinzugefügt, um diese zu reverten ef130f4 Titel und Überschrift angepasst. $ git revert 06eac50 [master b2cb478] Revert "Zeile hinzugefügt, um diese zu reverten" 1 file changed, 1 deletion(-) $ git log --oneline -3 b2cb478 Revert "Zeile hinzugefügt, um diese zu reverten" 06eac50 Zeile hinzugefügt, um diese zu reverten ef130f4 Titel und Überschrift angepasst. 53
Reset Jetzt sollen die zuvor angelegten Commits auch aus der Historie verschwinden. Das geht (u.a.) mit Reset. Reset besitzt drei Modi mit jeweils verschiedenen Verhaltensweisen: • soft • mixed • hard 54
Soft-Reset Zum Ausprobieren wieder eine Änderung durchführen und ein Commit erzeugen! $ git reset --soft HEAD~1 Ein Soft-Reset nimmt den bzw die Commits zurück, behält die Änderungen aber im Arbeitsverzeichnis und auch in der Staging-Area bereit. 56
Hard-Reset Zum Ausprobieren wieder eine Änderung durchführen und ein Commit erzeugen! $ git reset --hard HEAD~1 Ein Hard-Reset nimmt den bzw die Commits zurück, behält weder die Änderungen noch die Commits. 57
Referenzierung von Commits Verschiedene Arten um Commit zu referenzieren: • ef130f4ad4884aaa31ec13431055cb5b3e034235 - vollständige Commit-ID • ef130f4 - kurze Commit-ID • HEAD~2 - vorletzter Commit von HEAD ausgehend • master~2 - vorletzter Commit auf master • master@{4} - viertletzter Commit vom aktuellen HEAD von master 59
Ein Blick in .git/objects nach dem Commit $ tree .git/objects .git/objects a1 85acdf314be5d33d3ec9e27965b659a5a3b4f7 a9 a5aecf429fd8a0d81fbd5fd37006bfa498d5c1 db 35c5d88e2685fe378f7feeb0afb925d4912b80 info pack 5 directories, 3 files 63
cat-file auf das neue tree Objekt $ git cat-file -p 27cc440762b0cf85979cccd13af46229d59f0818 100644 blob a9a5aecf429fd8a0d81fbd5fd37006bfa498d5c1 tmp 100644 blob f0206044e90fd5c77500ec550df0a0be6f0d0c46 tmp2 70
Allgemeines • Branch lässt sich am besten mit „Zweig“ übersetzen • „abzweigen“ vom aktuellen Entwicklungsbranch • Pflege von mehreren Entwicklungslinien • einfaches Wechseln zwischen den Branches • Arbeitsvorgang abhängig vom Entwicklungsprozess 72
Allgemeines II • Branch ist letztendlich ein Zeiger auf einen Commit • Zeiger wird bei jedem neuen Commit weitergeschoben • HEAD ist i.d.R. der aktuelle ausgecheckte Commit • head ist eine Referenz auf ein Commit. (Branch oder Tag) 73
Inhalt in content anlegen Unterhalb der Überschrift beliebigen Content einfügen, etwa vom Lorem-Ipsum-Generator auf loremipsum.de. Commit erzeugen mit den Änderungen mit der Message „Lorem-Ipsum Fülltext hinzugefügt“. 83
Das Merge 1x1 • Alles (weiterhin) Lokal • Merge-Konflikte können auftreten • Man holt sich die Änderungen aus dem anderen Branch in den aktuellen Branch herein 90
Branch löschen $ git branch -d content Branch content entfernt (war 7fbaa4c). Mit -d können gemergte Branches gelöscht werden. Mit -D können nicht gemergte Branches gelöscht werden. 94
menu nach master mergen $ git merge menu Merge branch 'menu' # Bitte geben Sie eine Commit-Beschreibung ein, um zu erklären, warum dieser # Merge erforderlich ist, insbesondere wenn es einen aktualisierten # Upstream-Branch mit einem Thema-Branch zusammenführt. # # Zeilen beginnend mit '#' werden ignoriert, und eine leere Beschreibung # bricht den Commit ab. … automatischer Merge von index.html Merge made by the 'recursive' strategy. index.html | 10 ++++++++++ 1 file changed, 10 insertions(+) 95
Erzwingen eines Merge-Konflikts Folgende Aufgaben: 1. Neuen Branch titel anlegen 2. Commit mit Änderung des Titels 3. Zurück zu master wechseln 4. Commit mit anderer Änderung des Titels 5. Mergen 6. Merge-Konflikt auflösen 98
Commit mit Änderung des Titels auf titel Title von „Hallo Git!“ auf „Hallo!“ ändern. $ git add index.html $ git commit -m "Titel für den Merge-Konflikt" [titel 6ba3d6b] Titel für den Merge-Konflikt 1 file changed, 1 insertion(+), 1 deletion(-) 100
Merge mit Merge-Konflikt $ git merge titel automatischer Merge von index.html KONFLIKT (Inhalt): Merge-Konflikt in index.html Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen Sie dann das Ergebnis. 102
Status beim offenen Merge-Konflikt $ git status Auf Branch master Sie haben nicht zusammengeführte Pfade. (beheben Sie die Konflikte und führen Sie "git commit" aus) Nicht zusammengeführte Pfade: (benutzen Sie "git add/rm ...", um die Auflösung zu markieren) von beiden geändert: index.html keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a") 103
Merge-Konflikt nach dem Auflösen $ git add index.html $ git status Auf Branch master Alle Konflikte sind behoben, aber Sie sind immer noch beim Merge. (benutzen Sie "git commit", um den Merge abzuschließen) nichts zu committen, Arbeitsverzeichnis unverändert 105
Merge-Commit nach dem Merge-Konflikt $ git commit Merge branch 'titel' # Conflicts: # index.html # # Es sieht so aus, als committen Sie einen Merge. # Falls das nicht korrekt ist, löschen Sie bitte die Datei # .git/MERGE_HEAD # und versuchen Sie es erneut. # [...] # Auf Branch master # [...] 106
Rebasing • gehört ebenfalls zum Branching-Modell von Git • beim Rebasing können ebenfalls Commits aus einem anderen Zweig übernommen werden • kein Merge-Commit • geradlinige Versionshistorie 108
Rebasing Aufgaben: 1. Gebraucht: zwei Commits auf zwei Branches 2. neuer Branch more_content anlegen 3. more_content: Verdreifachung des Lorem-Ipsum Textes 4. master: Menü um ’About me’ Link erweitert 109
Rebase master $ git checkout more_content $ git rebase master Zunächst wird der Branch zurückgespult, um Ihre Änderungen darauf neu anzuwenden ... Wende an: Verdreifachung des Lorem-Ipsum-Texts 114
Stash • eine Art Zwischenlager • Änderungen können rein- und rausgeschoben werden • häufig nützlich um zwischen Branches zu wechseln • einfacher und schneller als WIP-Commits • nur lokal 118
git stash Aufgaben: 1. eine Zeile in index.html verändern 2. beliebige Datei temp anlegen 3. beide Änderungen in den Stash schieben Wie immer hilft: git status und in diesem Fall git stash. 120
git stash Bei Änderungen: $ git stash Saved working directory and index state WIP on master: bf55e27 Social-Media Menüpunkt hinzugefügt HEAD ist jetzt bei bf55e27 Social-Media Menüpunkt hinzugefügt 121
git stash $ git add temp $ git stash Saved working directory and index state WIP on master: bf55e27 Social-Media Menüpunkt hinzugefügt HEAD ist jetzt bei bf55e27 Social-Media Menüpunkt hinzugefügt $ git status Auf Branch master nichts zu committen, Arbeitsverzeichnis unverändert 123
git stash pop $ git stash pop Auf Branch master Änderungen, die nicht zum Commit vorgemerkt sind: geändert: index.html keine Änderungen zum Commit vorgemerkt Gelöscht refs/stash@{0} (5ad2602567242ed1b3714d44a2da7db60762d5d2) 126
git clean $ mkdir x y z $ touch a b c x/x y/y z/z $ git status [...] Unversionierte Dateien: (benutzen Sie "git add ...", um die Änderungen zum Commit vorzumerken) a b c x/ y/ z/ $ git clean fatal: clean.requireForce standardmäßig auf "true" gesetzt und weder -i, -n noch -f gegeben; "clean" verweigert 127
git clean -n $ git clean -n Würde a löschen Würde b löschen Würde c löschen Würde nur die unbeobachteten Dateien, aber nicht die unbeobachteten Ordner löschen. 128
Dateitypen + Ordner ignorieren Problematischer wird das Ignorieren eines Ordners mit Ausnahme einer darin enthaltenen Datei *.dll *.so *.exe build/ !build/version.h Funktioniert so nicht! 133
Was bisher geschah… • Commits angelegt • Branches angelegt • Branches gemergt • Branches rebased • Merge-Konflikte aufgelöst Dies geschah noch alles ausschließlich lokal! 135
Erstes Remote-Repository anlegen Im Home-Verzeichnis wird ein git Ordner angelegt, wo das Remote-Repository liegen soll: $ mkdir ~/git $ git clone --bare . ~/git/meineWebseite.git Klone in Bare-Repository '/home/sujee/git/meineWebseite.git' ... Fertig. git clone --bare klont das Repository ohne Arbeitsverzeichnis. 137
Remote-Repository verknüpfen Der Subbefehl remote handhabt die Verknüpfungen zwischen lokalen und entfernten Repository. $ git remote add origin ~/git/meineWebseite.git An dieser Stelle erfolgt noch kein Datenaustausch! 138
Änderungen aus origin/master mergen Angenommen, origin/master hat neue Commits: $ git merge origin/master Achtung: Hier können Merge-Commits entstehen. 142
Branches auflisten $ git branch -a * master menu more_content titel remotes/origin/master remotes/origin/menu remotes/origin/more_content remotes/origin/titel Branches können auch ohne remotes/ ausgecheckt werden. 146
Neuer Commit auf master $ git status Auf Branch master Ihr Branch ist vor 'origin/master' um 1 Commit. (benutzen Sie "git push", um lokale Commits zu publizieren) nichts zu committen, Arbeitsverzeichnis unverändert 149
Änderungen pushen $ git push fatal: Der aktuelle Branch master hat keinen Upstream-Branch. Ohne Parameter versucht git push den aktuellen Branch auf das Remote-Repository zu schieben – allerdings nur wenn es konfiguriert wurde. 150
Branch-Management Diverse Branches sind noch vorhanden, die jedoch schon alle gemergt aber nicht mehr gebraucht werden. $ git checkout master $ git branch --merged * master menu more_content titel --merged liefert alle Branches zurück die in diesem Fall nach master gemergt wurden. 156
Informationen von Remote-Repositories anschauen $ git remote show origin * Remote-Repository origin URL zum Abholen: /home/sujee/git/meineWebseite.git URL zum Versenden: /home/sujee/git/meineWebseite.git Hauptbranch: master Remote-Branch: master gefolgt Lokaler Branch konfiguriert für 'git pull': master führt mit Remote-Branch master zusammen Lokale Referenz konfiguriert für 'git push': master versendet nach master (aktuell) 162
Neuen Klon anlegen $ cd ~ $ git clone ~/git/meineWebseite.git meineWebseite2 $ cd meineWebseite2 Frage: Welches Branches besitzt das neu geklonte Repository? 164
Remote-Repository verknüpfung löschen $ git remote rm origin Nur die Verknüpfung zum Remote-Repository wird hiermit gelöscht, sonst werden keine Daten gelöscht! 170
Remote-Repositories anlegen Aufgaben: 1. Bare Remote-Repositories origin, er, ich klonen 2. Remote-Repositories lokal verknüpfen 3. Remote-Branches fetchen 172
Fetch von allen Remote-Repositories $ git fetch Von /home/sujee/git/ich/meineWebseite * [neuer Branch] master -> origin/master $ git fetch --all Fordere an von origin Fordere an von upstream Von /home/sujee/git/meineWebseite * [neuer Branch] master -> upstream/master Fordere an von er Von /home/sujee/git/er/meineWebseite * [neuer Branch] master -> er/master 175
Vielen Dank für die Aufmerksamkeit! Fragen, Feedback und Fehler gerne per E-Mail an [email protected]. Blog: svij.org Twitter: @svijee Copyright 2017 Sujeevan Vijayakumaran 176