OSMC 2010 | Monitoring mit Shinken by Gerhard Laußer
Git class german / english
1. git isn’t sh*t
It’s your friend
An introduction in a lot of slides
Kevin Read
2. Schedule
• Why? ◀
• GitHub
• Local git Repository
• Collaborating
• First aid
3. Why version stuff
• In the “good” old days:
• Pre-SVN: We send files via mail or sneakernet. If two people
change the same file, we’re f***ed.
• Post-SVN: “Please don’t update live, I committed unfinished
changes”
• We want versioning, but it is either complicated (SVN branches) or
incomplete (CVS, SVN without branches)
4. git Workshop
Where will it end us?
• The goal is for you to understand the basic principles of git and to
be fluent in its use.
• This might be boring for you with git experience. But you guys
might appreciate in-depth technical stuff that is marked with ☃
• Commands are shown for the command line and SourceTree (get it
now)
• So, git ready!
5. git Workshop
Prerequisites
• Get a git client:
• Mac users:
• Sourcetree
(www.sourcetreeapp.com)
• Xcode or git from Homebrew
• Linux users:
• sudo apt-get install git-cli
• Windows:
• Sourcetree (www.sourcetreeapp.com)
For linux / CLI:
# git config --global user.name ‘FIRST NAME’
# git config --global user.email ‘YOU@cliqz.com’
6. Schedule
• Why? ✔
• GitHub ◀
• Local git Repository
• Collaborating
• First aid
7. About GitHub
• GitHub is a company that offers commercial version control and
associated services
• Projects can be private (for internal code) or public (for open source)
• We have an enterprise account and all code lives in private
repositories
• Eleni can create new projects for us
• Typically only the owner has full access to a project
8. GitHub
Issue tracker
• GitHub also offers other services
like an issue tracker or a Wiki
• We use one central issue tracker
for all of our projects. It can be
found at https://github.com/cliqz/
bug-tracker/issues
• When you find a bug, do a quick
search to see if it’s already known
• If not, create a report and include
the following:
• What were you trying to do
when the issue appeared
• What was the expected
outcome
• What happened instead
• Is it reproducible?
9. GitHub
Forking projects
• The model we use is the pull & fork model
• When Cliqzer “kevin-cliqz” wants to change a project called “cookies”
owned by “luician-cliqz”, he forks it
• The original project would be at http://github.com/cliqz/cookies, the fork at
http://github.com/kevin-cliqz/cookies
• kevin-cliqz can’t change the original project, but can do whatever he likes
with his fork
• Once he has made changes to his fork, he can tell lucian-cliqz to review and
merge them in the original by issuing a pull request
10. Github
Forking projects
• So lets start by forking a small
sample project
• Go to github.com/kevin-cliqz/
playground and fork it.
• You will now have a forked
repository at github.com/
YOURNAMEHERE/playground
• This is your own fork. You have full
access to it, all other cliqzers can
only read it.
11. Schedule
• Why? ✔
• GitHub ✔
• Local git Repository ◀
• Collaborating
• First aid
12. Local Repositories
Cloning repositories
• Now we need to clone this repository
completely.
• This makes an _exact_ copy of the
repository
• Later on we learn how to apply changes
we make to one copy to its other clones
• On the CLI do git clone URL, and in
SourceTree
• Important: It makes sense to have
one folder called “git” where you
create all clones
13. Local Repositories
What is it?
• A repository records all changes
made to everything in one folder
• So all files, folders, and files in
folders :)
• This folder is called working copy
• ☃ Within the working copy you will
find the repository itself within the
hidden folder “.git”
Working
copy
Repository
14. Local Repository
Yeah, but what is it?
• Internally, repositories are snapshots of
past contents of the working copy
➡ We can reset the working copy into any
of these snapshots of history - time
machine style
• Repositories never “forget”, they always
grow
• This also means they can use up quite
a lot of space
• (☃ Strictly speaking you can change
history - but please don’t)
☃ Fun fact: Each snapshot is
exactly that - it contains the
complete state. Files that weren’t
changed from the last commit are
reduplicated by using hard links.
15. NB: In case you wondered
that this sounds familiar…
Yes, this is also how Apples
Time Machine works and
uses the same mechanics
internally.
16. Local Repository
Untracked files
• Now lets create a file “cliqz.txt” and
write something awesome there.
• With git status we can see the state
of both the repository and the
working copy.
• We can see the new file under
“Untracked files” on the CLI and in
SourceTree as marked with
➡ This means that the new file lies
within the working copy but has not
been added to the repository.
17. Local Repository
Staging changes
• Changes to the working copy can
be added to the “Staging Area” with
git add.
• The staging area is the sum of all
changes that will become the next
snapshot in time after a “commit”.
• git status will now show that the new
files is in the staging area
(“Changes to be committed”)
☃ The Staging Area (oder
“Index”) is a Blob in .git/index
18. Local Repository
Create commits
• So add all changes that will create
one coherent snapshot in time
(called a “revision”) to the staging
area.
• You can add as many files at any
time you want.
• Using git commit the content of the
staging area becomes a commit.
• Each commit has a description
that we can use later to remember
what it was all about.
19. Local Repository
Timeline
• The time line (git log) now shows the
first commit.
• Now its time for a few further
changes to the Repo:
• Lets create a second file called
“github.txt” and stage it.
• Lets also add a few lines to
“cliqz.txt” and also stage this.
• Now commit both changes.
20. Local Repository
So whats in a commit?
• Each revision has these attributes on top of the description:
• A unique identifier called SHA1 (its actually a checksum)
• Author: Name and e-mail
• Time and date of creation
• List of files that were changed in this commit
☃ The SHA1 really is formed
from the diff itself
21. Local Repository
Working copy and time travel
• Using the SHA1 of a revision you
can turn your working copy into its
state of the repository
• This process is called a Checkout
and can be achieved with git
checkout.
• In ST you double click on a
revision
• You can’t easily change this
resurrected revision (its
complicated)!
22. Local Repository
Branches
• We might all work on different tasks
(“Hey can you fix this quickly?”)
• So we need different lines of
development (“heads” or
“branches”)
• Each repository initially has a
branch called “master”. It’s the
parent of all branches.
• Every time you start working on a
feature that won’t be finished in a day
it’s a good idea to create a branch
23. Local Repository
Branches, Tags
• The working copy can be switched between branches at any time provided
that you don’t have uncommitted files that would be changed by the branch
switch
• It’s always a good idea to check which branch is active before you start
working!
• It is also possible to bring changes you make to one branch onto another at a
later time, but it’s a little bit of work.
• Tags are labels you can attach to a certain commit (not to a branch)
24. Local Repository
Zusammenfassung
• Repositories save snapshots in time
(“revisions”) of a folder (“working
directory”) with all its contents.
• Changes to these contents can be
“staged” at any time. All staged
changes are “committed” together with
a comment and form a new revision.
• You can have different “branches” of
development and switch between them.
• The working directory can be turned
into any revision or branch.
25. Schedule
• Why? ✔
• GitHub ✔
• Local git Repository ✔
• Collaborating ◀
• First aid
26. Collaborating
Pushing and pulling
• Up to now we only looked at working with a repository on your own
computer (and yes, using git can make sense here too).
• But the main reason to use a version control system is to easily work
on the same set of files in a team without overwriting changes other
people made.
• We can “push” the changes we make to others
• And we can “pull” the changes other team members have made
to the files
28. Repositories teilen
Eigenes Repository zu Server
• Anwendungsfall: Eigenes Repo, mit
dem bisher nur lokal gearbeitet
wurde mit anderen teilen.
• Wenn man dazu das eigene
Notebook nicht immer angeschaltet
lassen will braucht man einen Server
:)
• Dafür richtet ein Admin ein komplett
leeres Repo ein.
• Dort kann man dann das gesamte
Repo rein schieben
• Für den Workshop haben wir für
jeden ein leeres Repo auf Martins
Notebook angelegt.
• Die URL dieses Repos ist ssh://
repo@IP/repo/USERNAME.git, also
für Kevin ssh://repo@IP/repo/
kread.git
• Schreibt euch diese URL erstmal
auf :)
29. Repositories teilen
Remotes
• Wenn wir unser Repo jetzt in ein leeres
Repo auf Martins Notebook pushen
wollen müssen wir besagtes Notebook
erstmal als “Remote” anlegen.
• Ein Remote ist ein “befreundetes”
Repository, mit dem wir Commits
teilen. Remotes haben einen Namen
und eine URL
• Legen wir ein Remote namens
“notebook” mit der URL von vorhin an
31. Repositories teilen
Push
• Ein Push sorgt dafür, dass der Branch im Ziel-Repository (fremdes) auf den
selben Commit zeigt wie der gleiche Branch im Quell-Repository (eures).
• Dazu werden alle Commits kopiert, die nötig sind, damit die Timeline auf
beiden Repos gleich ist.
• Wenn das Ziel-Repo leer ist wird also einfach alles kopiert.
• Wenn das Ziel-Repo schon Commits hat schaut git nach dem frühesten
Commit, den beide gemeinsam haben und kopiert Commits ab da.
• ☃ Fortgeschrittene User können mit einem Push alle möglichen
abgefahrenen Sachen machen, etwa merges :D
32. Repositories teilen
Push
• Kopieren wir also unseren Branch
“master” in das leere Repo des
Remotes “notebook”
• Das Häkchen bei “Track” (bzw. das
“-u”) bedeutet, dass die Branches in
beiden Repos sich merken, dass sie
nach dem Push identisch sind.
• Das spart etwas Handarbeit beim
Pullen später, sonst müsste man
beim pull immer angeben, aus
welchem Remote und Branch
gepulled wird.
33. Repositories teilen
Push
• Nach dem Push sehen wir, dass jetzt
ein neuer Branch namens “notebook/
master” existiert.
• Das ist die Kopie unseres Master-
Branches auf diesem Remote.
• Mit der Zeit werden beide Branches
etwas auseinander laufen. Lets do this!
• Dazu machen wir einen weiteren
Commit in unseren Master.
• ST bzw git status zeigt an, dass
unser Branch vor dem Remote ist
Pushed nun die neue Änderung
zum Remote
34. Repositories teilen
Klonen
• In den meisten Fällen liegt ein Repository schon irgendwo auf einem
Server
• In diesem Fall wollen wir dieses Repo auf unseren Rechner klonen
• Ein Klon kopiert alle Commits, Branches und Tags
• Gleichzeitig legt er ein neues Remote namens “origin” an, das auf
das ursprüngliche Repo auf dem Server zeigt. Damit kann man
schnell Sachen dort hin pushen.
35. Repositories teilen
Unser erster Klon
• Holt euch von eurem linken
Nachbarn die URL seines Repos
und klont dieses in einen Ordner
auf eurer Platte.
• Mit ST auf File/New
• Nun legt hier eine Datei namens
“hallo.txt” mit einem freundlichen
Gruß an und committet diese.
• Und dann an das Remote
pushen :)
36. Repositories teilen
Zusammenfassung
• Repositories können ganze
Branches in andere Repositories
schieben.
• Ein bestehendes Repository kann
über das Netzwerk / Internet
komplett geklont werden.
• Jedes Repo ist dabei ein
vollständiges Repo mit Branches
und Arbeitskopie.
• Mit jedem Repo kann komplett
unabhängig gearbeitet werden!
38. Fremde Änderungen einpflegen
Konfliktpotential
• Ihr habt das Repo vom linken Nachbarn auf Martins Notebook
verändert und eure Änderungen gepushed.
• Wenn euer linker Nachbar zwischenzeitlich keine Commits gemacht
hat kann er euren Commit sehr einfach bei sich einspielen.
• Hat er jedoch zwischenzeitlich auch Änderungen gemacht kann es zu
Konflikten kommen.
• Selbst ohne Konflikte gibt es zwei unterschiedliche Timelines. Es gibt
verschiedene Strategien, wie diese wieder zusammen geführt
werden können.
39. Fremde Änderungen einpflegen
Konfliktpotential
• Nehmen wir den einfachen Fall.
• Auf eurem eigenen Repo aktualisieren
wir jetzt nun unsere Information über
alle Branches auf unserem Remote.
• Zur Erinnerung: Euer Remote ist auf
Martins Notebook, das euer rechter
Nachbar gerade geändert hat.
• ST macht das von selbst, auf der
Konsole genügt git fetch und dann git
status
40. Fremde Änderungen einpflegen
Commits holen
• git weiss jetzt, dass der master-
Branch auf remote aktueller ist als
der eigene “master”.
• Wenn wir diese Commits auch bei
uns haben möchten, brauchen wir
git pull
• ☃ Ein git merge genügt nicht, da
ein git pull mehr ist als ein git
fetch; git merge (zB wenn in
einem Commit nur ein Branch auf
einen andere SHA1 zeigt)
41. Fremde Änderungen einpflegen
Fast-Forward!
• Das Ergebnis ist, dass “master” und
“notebook/master” wieder auf den gleichen
Commit zeigen - wir sind up-to-date.
• Dies ging jetzt nur so einfach, weil
zwischenzeitlich nichts am eigenen Repo
geändert wurde. “master” hier ist also ein
Vorfahre von “master” auf notebook.
• git kann daher einen “Fast Forward”-
Merge machen, also einfach die
neueren Commits vor den eigenen rein
kopieren.
• Schauen wir uns einen komplexeren Fall
an.
42. Fremde Änderungen einpflegen
Echtes Szenario #1
• Bittet euren rechten Nachbarn (der also
euer Repo geklont hat) eine Änderung an
der hallo.txt zu machen.
• Ihr macht gleichzeitig eine Änderung an
der wiegsagt.txt.
• Ihr committed beide eure Änderung.
• Nachbar pusht, ihr macht einen Fetch.
• Ihr seht in ST, dass jetzt zwei Heads
existieren.
• Wenn ihr jetzt pulled, müssen beide
Linien zusammen geführt werden.
43. Fremde Änderungen einpflegen
Echtes Szenario #1
• Mit einem git pull oder dem Pull-Befehl
in ST werden die Linien zusammen
geführt.
• Dazu wird ein so genannter “Merge
Commit” angelegt. Dieser hat nicht
einen Vorgänger in der Timeline,
sondern gleich zwei.
• Auf der Kommandozeile wird man
auch nach der Commit-Message
gefragt.
• Pushed diesen Merge Commit und
euren eigenen zurück auf notebook
44. Fremde Änderungen einpflegen
Merge Commits
• Merge Commits haben ihre
Daseinsberechtigung.
• Wenn man zwei echte Branches
zusammen führt ist es vorteilhaft
wenn man sieht was hier passiert
ist.
• Aber bei der gemeinsamen Arbeit
an einem Branch machen sie nur
das Lesen der Historie schwerer.
• Stattdessen haben wir uns alle auf
rebase geeinigt.
Das Beispiel oben ist krass,
aber sowas kann passieren!
45. Fremde Änderungen einpflegen
Echtes Szenario #1 mit Rebase
• Also nochmal ran. Euer Nachbar soll
noch einmal die Datei hallo.txt
verändern, committen und pushen.
• Ihr verändert die wiegsagt.txt und
committed, dann ein Pull, aber
diesmal mit Rebase.
• In ST gibt es dafür eine
Checkbox, auf der
Kommandozeile mit git pull -r
• What just happened?
46. Fremde Änderungen einpflegen
Echtes Szenario #1 mit Rebase
• Rebase sucht genauso wie pull bzw. merge
den neuesten Commit, den beide branches
gemein haben.
• Von diesem ausgehend werden die Commits,
die auf das eigene Repo gemacht wurden
entfernt und in eine Zwischenablage gelegt.
• Nun werden die Commits vom Quell-Repo
eingespielt.
• Danach alle Commits aus der Zwischenablage.
• Nachteil: Die Historie wurde geändert. Merke:
Kein rebase nach push!
• ☃ Frage: Warum?
47. Fremde Änderungen einpflegen
Probleme beim Zusammenführen
• Unabhängig davon, ob merge oder
rebase verwendet wird, kann es
beim Zusammenführen Probleme
geben.
• Wenn in beiden Repos dieselben
Stellen in den gleichen Dateien
verändert wurden, weiß git nicht,
welche Änderung jetzt die richtige
ist.
• Dann kommt der schöne,
heißgeliebte Konflikt-Dialog.
48. Fremde Änderungen einpflegen
Echtes Szenario #2
• Verursachen wir also einen Konflikt.
• Dein Nachbar soll die Datei
“wiegsagt.txt” öffnen und ganz unten
eine Zeile hinzufügen, committen
und pushen.
• Du fügst auch eine Zeile hinzu und
committest.
• Wenn du jetzt pullst, wird es einen
Konflikt geben, da git nicht weiß
welche hinzugefügte Zeile korrekt
ist.
49. Fremde Änderungen einpflegen
Soft Skill : Konflikte
• Dateien mit Konflikten werden in ST mit
Ausrufezeichen versehen und in git
status extra hervorgehoben.
• Der Konflikt muss jetzt von einem
Menschen von Hand behoben werden.
Dazu gleich mehr.
• So lange der Konflikt nicht behoben ist
kann nicht wirklich committed, gepulled
oder sonstwas werden.
• Konflikte beim rebasen verhalten sich
etwas anders, aber nicht
grundlegend.
50. Fremde Änderungen einpflegen
Einfache Konfliktlösung
• ST bietet euch einfach die
Möglichkeit, den Konflikt in einer
Datei zu beheben:
• Ihr könnt eure Änderungen oder
die Änderungen vom Quell-Repo
komplett zu verwerfen.
• Dies betrifft nur die Änderungen,
die im Konflikt sind, alle anderen
veränderten Zeilen der Commits
sind ok.
• Wird eher selten benötigt.
51. Fremde Änderungen einpflegen
Händische Konfliktlösung
• Die meisten Konflikte sind komplexer und müssen in
der Datei selbst bearbeitet werden.
• Öffnet die Datei wiegsagt.txt in eurem Editor.
• Der Teil zwischen “===“ und “<<<“ ist üblicher
weise die Textstelle, so wie so vom Fremd-Repo
kommt.
• Von “===“ bis “>>>” die Textstelle, die von euren
Commits stammt.
• An den Klammern stehen jeweils die Commits, die
den Konflikt verursacht haben
• Bei rebase steht statt Fremd-Commit “HEAD” (☃
weiß wer warum?)
<<<<<<< HEAD
Zum Konflikt von Martin
=======
Zum Konflikt von Kevin
>>>>>>> Von Kevin
Fremd-Textstelle
Eigene Textstelle
52. Fremde Änderungen einpflegen
Händische Konfliktlösung
• Entscheidet euch für eine der beiden
Textstellen und entfernt die andere.
• Oder: Kombiniert beide!
• Wenn ihr euch nicht sicher seid was
los ist, sprecht mit dem Autor der
konfliktverursachenden Änderungen!!!!
• Wichtig: Die Zeilen mit <<<, >>> und ===
müssen mit entfernt werden.
• Das Ergebnis kann als konfliktfrei markiert
werden.
<<<<<<< HEAD
Zum Konflikt von Kevin und
Martin
=======
Zum Konflikt von Kevin
>>>>>>> Von Kevin
53. Fremde Änderungen einpflegen
Nach dem Konflikt
• Fügt nun die von euch bereinigte
Datei ganz normal zur Staging Area
und drückt in ST auf Commit
• Auf der Kommandozeile git add
gefolgt von git rebase —continue
(falls ihr gerade rebased) oder git
commit
• Ihr könnt in ST auch per Rechtsklick
als resolved markieren, das entfernt
schon mal die Markierung
• Danach natürlich brav pushen.
54. Fremde Änderungen einpflegen
Zusammenfassung
• Es gibt verschiedene Möglichkeiten um
Commits in anderen Repos in euer
Repo zu bringen.
• Rebase ist im Allgemeinen euer Freund,
solange ihr nicht einen großen Feature-
Branch mergen wollt.
• Konflikte von Hand beheben ist schnell
gelernt. Ruhig bleiben und tief
durchatmen. Im Ernstfall Fat Boy treten.
• Bei seltsamen Konflikten im Log
herausfinden wer Schuld ist und
lieber nachfragen.
56. Erste Hilfe
Was tun wenns brennt?
• Manchmal geht auf einmal nichts mehr (“es geht einfach nicht”), und
git verweigert commit, pull, oder push.
• Oft gibt es dazu auch eine hilfreiche Fehlermeldung (“Du musst erst
pullen bevor du pushen kannst”, “du kannst nicht rebasen wenn du
uncommittete Änderungen hast”, …)
• Manchmal scheint aber auch einfach alles im Arsch zu sein.
• Erste Regel des git-Clubs: Nicht pushen wenn kaputt!!!
• Zweite Regel: Keine Panik. Vielleicht helfen euch diese Faustregeln.
57. Erste Hilfe
Warum git manchmal nicht pullen mag
• Git hat als oberste Faustregel, dass
keine Änderungen verloren gehen
dürfen.
• Daher mag git auch keine
uncommitteten Änderungen
überschreiben oder Commits pullen, die
eure lokale Historie zerballern würden.
• Daher Faustregel: Wenn nicht alles
sauber committed ist, könnt ihr nicht
pullen und erst recht nicht rebasen.
• Committed, nicht gepushed!
• Am einfachsten und saubersten ist
es, wenn ihr nur Dateien verändert,
die zum aktuellen Task gehören und
danach alle diese Dateien am Stück
committed.
• Wenn ihr Dateien geändert habt die
nicht zum aktuellen Task gehören,
aber die Änderungen sind wichtig,
dann einfach zwei Commits machen
:)
• Wenn auch das nicht geht -> Stash.
58. Erste Hilfe
Stash it!
• Der Stash (englisch für Beutelager)
ist ein geheimes Versteck für
Änderungen, die ihr zur Zeit nicht
committen könnt.
• Ihr legt immer alle uncommitteten
Änderungen in den Stash und gebt
der Sache einen Namen.
• Danach ist die Arbeitskopie
sauber und ihr könnt pullen etc.
• Probiert es aus: wiegsagt.txt ändern,
dann git stash save oder in ST
59. Erste Hilfe
Stash it!
• Mit git stash list seht ihr, was sich
alles in eurem geheimen Hort
befindet, bzw bei ST in der linken
Leiste.
• Ihr könnt ein Paket an Änderungen zu
einem späteren Zeitpunkt aus dem
Stash holen und auf den aktuellen
Branch anwenden. Der Stash-Eintrag
wird dabei auf Wunsche gelöscht (git
stash pop)
• Danach normal weiter arbeiten und
committen.
☃ git stash pop vs apply
60. Erste Hilfe
Fiese Fremdeinflüsse
• Bei Problemen beim Pullen hilft es oft
zu schauen, wie die Remotes
aussehen, also die Repos, die
“befreundet” sind.
• Wo ist euer Branch aktuell in der
Timeline? Wo derselbe Branch im
Remote? Ist HEAD irgendwo seltsam
unterwegs?
• Wenn das alles nichts hilft und ihr
euch sicher seid, dass ihr keine nicht
gepushten Commits habt, dann hilft
die Radikalkur.
61. Erste Hilfe
Radikalkur
• Die Radikalkur sorgt dafür, dass ein
Branch im Repo gestutzt wird.
• Die Spitze des Branch wird auf
einen bestimmten Commit oder
Branch gesetzt, und alles dahinter
wird verworfen.
• Am häufigsten wird damit das
eigene Repo auf den gleichen Stand
wie ein Remote gebracht:
• git reset —hard REMOTE/
BRANCH
62. Erste Hilfe
Zusammenfassung
• git verhindert fast immer, dass
Änderungen verloren gehen.
• Das sieht dann manchmal so aus,
als ob es euch hasst und ärgern
will.
• Wenn nix mehr geht: stachen
• Wenn gar nix mehr geht: git reset
• Im Zweifelsfall lieber fragen bei
Problemen. Nie pushen!
63. git is shit?
No, git is it!
• Wenn man einige Zeit mit git
gespielt hat ist alles nicht mehr so
seltsam.
• Ein gute grafische App hilft enorm.
• Wenn ein Problem dort seltsam
aussieht hilft manchmal auch ein git
status auf der Kommandozeile.
• Ich hoffe, ihr habt was gelernt.
• Viel Spaß, wie gsagt!