git intim - jug saxony day · 2016-01-23 · git intim jug saxony day 02.10.2015 sven oppermann...
TRANSCRIPT
Eigenschaften eines DVCS
Infrastruktur
Intern
In Aktion
Besonderheiten
Eigenschaften eines DVCSDVCS = Distributed Version Control System
Gerichteter Azyklischer Graph (DAG)
A B F G H I
C D E
J K
Jede Kopie eines Projektes, ist ein
vollwertiges Projekt.
Offline arbeiten möglich
Operationen sind extrem schnell
Netzwerkkommunikation nur beim Abgleich
DVCS Commit != CVCS Commit
Lokaler Commit
eindeutig identifizierbar
Snapshot Speicherung (GIT)
Branching und Merging sehr einfach
flexible Branchingmodelle
„wer wars?“ funktioniert
Lang laufende Branches sind kein Problem
Sonstiges:
Infrastruktur
$ ls -A1
.git/
pom.xml
src/
Das Repository Konfiguration
Hooks
Index
Objectstore
Referenzen
$ ls -A1
.git/
pom.xml
src/
Der Workspace Hier wird
„gearbeitet“
Workspace Index
(pre-commit)
Staging Area
Repository
Hat einen oder mehrere Eltern
eindeutig identifizierbar über
SHA1 (40 Zeichen)
Unveränderbar
Der COMMIT
A B F G H I
J
K‘
C D E
K
Der TAG
A B F G H I
J K
C D E
v1.0 v2.0
Markierung eines Standes
kann nicht verändert werden (~Commit)
Der BRANCH
A B F G H I
J K
C D E
v1.0 v2.0
master master Referenz
Veränderbar
Der REMOTE-BRANCH
A B F G H I
J K
C D E
origin/master
Eigener Namensraum
spiegelt den letzten bekannten Stand wieder
master
L
origin/master
Der HEAD
A B F G H I
J K
C D E
master
HEAD
Zeigt auf den aktuell ausgecheckten Stand
Wird vom nächsten Commit der Parent
Intern
$ ls .git
config
hooks
index
objects
HEAD
refs
Das Repository□ Konfiguration□ Hooks
□ Index
□ Objectstore
□ Referenzen
$ ls .git
config
hooks
index
objects
HEAD
refs
Das Repository□ Konfiguration
□ Hooks□ Index
□ Objectstore
□ Referenzen
$ ls .git
config
hooks
index
objects
HEAD
refs
Das Repository□ Konfiguration
□ Hooks
□ Index□ Objectstore
□ ReferenzenWorkspace
Index
Repository
$ ls .git
config
hooks
index
objects
HEAD
refs
Das Repository□ Konfiguration
□ Hooks
□ Index
□ Objectstore□ Referenzen
Key – Value Store
Hash Table
Der Objectstore
.git/objects/
89/38d6b70b1c502275d8b31bef7f7f9bf922d4ab
content
SHA18938d6b70b1c502275d8b31bef7f7f9bf922d4ab
zlib deflate compressed1001010101010111101..
type + ´ ´ + size + \0
content
.git
|- objects
| |- 89
| | |-38d6b70b1c5022...
KEY VALUE
$ git cat-file –p 8938d6
package de.geewhiz.demo;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
Der Objectstore
tree
commit tag
blob
Der Objectstore - VALUE
blobDer Objectstore –
Arbeitsverzeichnis
blob: 431a48…
blob: 8938d6…
Objectstore
demo
src
main
java
pom.xml
App.java
blobDer Objectstore –
Arbeitsverzeichnisblob 178\0
blob: 8938d6…
package de.geewhiz.demo;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
demo
src
main
java
pom.xml
App.java
Der Objectstore –
Arbeitsverzeichnis Objectstore
blob: 431a48…
tree
tree: c84e99…
tree: 1de782…
blob: 8938d6…
tree: eeef21…tree 118\0
100644 blob 431a48… pom.xml
040000 tree 1de782… src
demo
src
main
java
pom.xml
App.java
Der Objectstore –
Arbeitsverzeichnis Objectstore
commit
commit 203\0
tree c84e999ac503722dbfe4fbd3f0fe34f52d5fd972
author Sven Oppermann <[email protected]> 1442487756 +0200
committer Sven Oppermann <[email protected]> 1442487756 +0200
created demo project
commit: 6eb258…
blob: 431a48…
tree: c84e99…demo
pom.xml
…
Der Objectstore –
Arbeitsverzeichnis Objectstore
commit
commit 250\0
tree ...
parent ...
author Sven Oppermann <[email protected]> 1442487756 +0200
committer Sven Oppermann <[email protected]> 1442487756 +0200
second commit
commit: ……
blob: 431a48…
tree: c84e99…demo
pom.xml
…
Der Objectstore – tag
commit: 6eb258…
blob: 431a48…
tree: c84e99…
Arbeitsverzeichnis Objectstoretag 141\0object 6eb258a2e7effc4e60628d655489f419ab8aba31
type commit
tag v1.0
tagger Sven Oppermann <[email protected]> 1442836249 +0200
v1.0
tag: 5d9c31…
demo
pom.xml
…
Der Objectstore
blob tree
committag
tree
committag
blob
Der Objectstore
Unveränderbar !
Der Objectstore
blob blob
tree blob tree
blobtree tree
tree tree
commit commit
blob
Der Objectstore
blob blob
tree blob tree
tree tree blobblob
tree tree tree
commit commit commit
blob
Der Objectstore
blob blob
tree blob tree
blob treetree blob
tree tree tree
commit commit
…
commit
… …
$ ls .git
config
hooks
index
objects
HEAD
refs
Das Repository□ Konfiguration
□ Hooks
□ Index
□ Objectstore
□ Referenzen
.git
|- …
|- HEAD
|- refs
| |- heads
| | |- master
| |- remotes
| | |- origin
| | | |- master
| |- tags
| | |- v1.0
Die Referenzen
Die Referenzen
$ cat .git/refs/heads/master6eb258a2e7effc4e60628d655489f419ab8aba31
.git
|- …
|- HEAD
|- refs
| |- heads
| | |- master
Die Referenzen
$ cat .git/HEADref: refs/heads/master
.git
|- …
|- HEAD
|- refs
| |- heads
| | |- master
In Aktion
$ mkdir demo
$ cd demo
$ git init
$ …creating the demo project…
$ git add –all
$ git commit -m „initial setup“
commit
blob blob
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master […]
tree
df212
master
HEAD
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [df212…]
$ git branch F-189
commit
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [df212…]
df212
F-189
master
HEAD
$ git checkout F-189
commitdf212
.git
|- HEAD
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [df212…]
F-189
master
HEAD
|- HEAD [ref: refs/heads/F-189]
.git
|- HEAD [ref: refs/heads/F-189]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
$ … Implementierung …
$ git add --all
$ git commit –m „#F-189: step1“
df212
master
F-189
HEAD
e12fd
$ git checkout -b H-47 master
.git
|- HEAD [ref: refs/heads/F-189]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
| | |- H-47 [df212…]
df212
git branch H-47 master
master
e12fd
H-47F-189
HEAD
$ git checkout -b H-47 master
.git
|- HEAD [ref: refs/heads/H-47]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
| | |- H-47 [df212…]
git branch H-47 master
git checkout H-47
master
e12fd
H-47F-189
HEAD
df212
$ … Implementierung …
$ git add --all
.git
|- HEAD [ref: refs/heads/H-47]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
| | |- H-47 [df212…]
df212
master
e12fd
H-47F-189
HEAD
.git
|- HEAD [ref: refs/heads/H-47]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
| | |- H-47 [h3f12…]
$ git commit -m „#H-47: fixed“
df212
master
e12fd
h3f12
F-189
H-47
HEAD
.git
|- HEAD
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [e12fd…]
| | |- H-47 [h3f12…]
$ git checkout F-189
df212
master
e12fd
h3f12
F-189
H-47
HEAD
|- HEAD [ref: refs/heads/F-189]
.git
|- HEAD [ref: refs/heads/F-189]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [1d172…]
| | |- H-47 [h3f12…]
$ … Implementierung …
$ git commit -am „#F-189: step2“
df212
e12fd
h3f12
masterH-47
1d172
F-189
HEAD
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [df212…]
| | |- F-189 [1d172…]
| | |- H-47 [h3f12…]
$ git checkout master
df212
master
e12fd
h3f12
H-47
1d172
HEAD
F-189
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [h3f12…]
| | |- F-189 [1d172…]
| | |- H-47 [h3f12…]
$ git checkout master
$ git merge H-47
df212
fast-forward merge
h3f12
e12fd
master H-47
1d172
HEAD
F-189
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [h3f12…]
| | |- F-189 [1d172…]
| | |- H-47 [h3f12…]
$ git merge F-189
df212
3-Wege Merge
e12fd
h3f12
1d172
master H-47
F-189
HEAD
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [f1f1e…]
| | |- F-189 [1d172…]
| | |- H-47 [h3f12…]
$ git merge F-189
df212
e12fd
h3f12
1d172
H-47
F-189
f1f1e
master
HEAD
.git
|- HEAD [ref: refs/heads/master]
|- refs
| |- heads
| | |- master [f1f1e…]
$ git branch -d H-47
$ git branch -d F-189
df212
e12fd
h3f12
1d172
f1f1e
master
HEAD
Sven
Franz
Blessed Repo
b1
$
$
b2
master
Sven
Franz
Blessed Repo
$ git clone …/demo.git
$ git clone …/demo.git
b1
b1
b1
b2
b2
b2
origin/master
master
master
origin/master
master
Sven
Franz
Blessed Repo
$
$ git commit …
b1
b1
b1
b2
b2
b2
master
master
origin/master
origin/master
s1
master
Sven
Franz
Blessed Repo
$
$ git commit …
$ git commit …
b1
b1
b1
b2
b2
b2
master
master
origin/master
origin/master
s1 s2
master
Sven
Franz
Blessed Repo
$ git commit …
$ git commit …
$
b1
b1
b1
b2
b2
b2
master
origin/master
origin/master
s1
f1
s2
f2
master
master
Sven
Franz
Blessed Repo
$ git push
$
b1
b1
b1
b2
b2
b2
master
origin/master
origin/master
s1
f1
s2
f2
master
master
Sven
Franz
Blessed Repo
$ git push
$
b1
b1
b1
b2
b2
b2
master
origin/master
origin/master
s1
f1
s2
f2
master
master
Sven
Franz
Blessed Repo
$ git push
$
b1
b1
b1
b2
b2
b2
master
origin/master
origin/master
s1
f1 f2
master
s2
master
Sven
Franz
Blessed Repo
$ git push
… SUCCESS …
$
b1
b1
b1
b2
b2
b2
s1
f1
f1
s2
f2
f2
master
origin/master
master
master
origin/master
Sven
Franz
Blessed Repo
$
$ git push
… REJECTED, plz PULL …
b1
b1
b1
b2
b2
b2
origin/master
s1
f1
f1
s2
f2
f2
master
origin/master
master
master
Franz
Sven
Blessed Repo
$
$ git fetch
b1
b1
b1
b2
b2
b2
f1
s1
f1
f1
f2
s2
f2
f2
origin/master
master
origin/master master
master
Franz
Sven
Blessed Repo
$
$ git fetch
$ git merge origin/masterb1
b1
b1
b2
b2
b2
f1
s1
f1
f1
f2
s2
f2
origin/master
master
origin/master
f2
master
m1
master
Franz
origin/master
Sven
Blessed Repo
origin/master
$ git pull
$
b1
b1
b1
b2
b2
b2
f1
s1
f1
f1
f2
s2
f2
m1
f2
master
master
master
Franz
Sven
Blessed Repo
$ git push
$
b1
b1
b1
b2
b2
b2
f1
s1
f1
f1
f2
s2
f2
f2
origin/master
master
masterorigin/master
m1
master
Franz
Sven
Blessed Repo
$ git push
… SUCCESS …
$
b1
b1
b1
b2
b2
b2
f1
s1
f1
f1
s1
f2
s2
f2
f2
s2
origin/master
master
m1
master
m1
master
origin/master
Besonderheiten
CHERRY-PICK
A B E F G H
C D
master
bugfix
$
CHERRY-PICK
A B E F G H
C D
bugfix
master
$
CHERRY-PICK
A B E F G H
C D
bugfix
H‘
master
$ git checkout bugfix
$ git cherry-pick H
REBASE
$
A B C
W
origin/master
X
f-186
REBASE
$ git fetch
A B C
W
origin/master
D E
X
f-186
REBASE
$ git fetch
$ git merge origin/master
A B C
W X
f-186
D E
Y
origin/master
REBASE
$ git fetch
$ git rebase origin/master
A B C
W X
f-186
D E
origin/master
REBASE
$ git fetch
$ git rebase origin/master
A B C
W X
f-186D E
origin/master
REBASE
$ git fetch
$ git rebase origin/master
A B C
W X
f-186
D E
W‘
origin/master
REBASE
$ git fetch
$ git rebase origin/master
A B C
W X
f-186
D E
W‘ X‘
origin/master
REBASE
$
A B
S
C D
M1 M2
merge rebase
A B
S
C D
S‘ S‘‘
BISECT
$
A B F G H I
C D E
J K
master
HEAD
v1.0
BISECT
$
A B F G H I
C D E
J K
master
HEAD
v1.0
BISECT
$ git bisect start HEAD v1.0
A B F G H I
C D E
J K
master
HEAD
v1.0
BISECT
$ … TEST …
A B F G H I
C D E
J K
masterHEADv1.0
BISECT
$ … TEST …
$ git bisect good
A B F G H I
C D E
J K
masterv1.0 HEAD
BISECT
$ … TEST …
$ git bisect bad
A B F G H I
C D E
J K
masterv1.0
HEAD
BISECT
$ …
D is the first bad commit
A B F G H I
C D E
J K
masterv1.0
HEAD
BISECT
$ git bisect reset
A B F G H I
C D E
J K
masterv1.0
HEAD
BISECT
$ git bisect start HEAD v1.0
$ git bisect run ~/test.sh
A B F G H I
C D E
J K
masterv1.0
HEAD
MERGETREIBER
A B D E G
C F
master
v1.0
v2.0 v2.1
$ git merge v2.1
… SUCCESS …
https://github.com/cecom/pomutils
<version>
2.1
</version>
<version>
master
</version>
Zeig mir was drin ist…
$ git lg ^master v2.1I – (tag: v1.0) commit msg (5 minutes ago Sven)
A B D E G
C F
master
v1.0
v2.0 v2.1
H
I
J
Zeig mir was drin ist…
$ git lg v1.0..v2.0C – commit msg (17 minutes ago Sven)
F – (tag: v2.0) commit msg (14 minutes ago Sven)
A B D E G
C F
master
v1.0
v2.0 v2.1
H
I
J
Link
Zeig mir wo es drin ist…
$ git branch --contains Fmaster
A B D E G
C F
master
v1.0
v2.0 v2.1
H
I
J
Zeig mir wo es drin ist…
$ git tag --contains Fv2.0
v2.1
A B D E G
C F
master
v1.0
v2.0 v2.1
H
I
J
ENDE
My ~/.gitconfig[core]
editor = 'C:/Users/sveno/Dropbox/tools/notepad++6.8.2.bin/notepad++.exe' -multiInst -nosession -noPluginquotepath = offpreloadindex = truefscache = trueautocrlf=true
[merge]tool = merge-p4mergekeepBackup = falsekeepTemporaries = falserenormalize = truerenamelimit = 10000
[mergetool]prompt = false
[mergetool "merge-p4merge"]cmd = "C:/Users/sveno/Dropbox/tools/Perforce/p4merge.exe" -dw -tw 4 -C \"utf8\" "$BASE" "$LOCAL" "$REMOTE" "$MERGED"keepTemporaries = falsetrustExitCode = falsekeepBackup = false
[diff]tool = diff-p4mergealgorithm = patience
[difftool "diff-p4merge"]prompt = false#if you diff a file which is new or deleted, we have to create an empty file, otherwise the tool does not startcmd = "if [ \"$LOCAL\" == \"/dev/null\" ] ; then EMPTY=\"true\"; echo. 2>$TMP/empty; LOCAL=$TMP/empty; fi; if [ \"$REMOTE\" == \"/dev/null\" ] ; then EMPTY=\"true\"; echo. 2>$TMP/empty; REMOTE=$TMP/empty; fi; \
C:/Users/sveno/Dropbox/tools/Perforce/p4merge.exe -dw -tw 4 -C \"utf8\" \"$LOCAL\" \"$REMOTE\"; if [ \"$EMPTY\" == \"true\" ] ; then rm $TMP/empty; fi;"[rerere]
enabled = true[color]
ui = auto[push]
default = simple[i18n]
commitencoding = utf-8logoutputencoding = utf-8
…
My ~/.gitconfig…[alias]
#show the last 10 branches, orderedb = for-each-ref --count=10 --sort=-committerdate refs/heads/ --format='%(refname:short)'
#status infos = status -sb
#log output but pretty printed on one linelg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbrev-commit --date=relative
#dont show the commits, only show the files that i have changed on top of my remote branchdt = "!sh -c \"if [ -z \"$(git currentremote)\" ] ; then \
echo "Branch ist nicht richtig konfiguriert!" ; \else \
git diff-tree -r --name-status \$(if [ \"$(git currentremote)\" != '.' ] ; then \
echo "$(git currentremote)/" ; \fi)$(git currentmergebranch)..HEAD ; \
fi\""
#print the current remote branch, used in other commandscurrentremotebranch = "!sh -c \"git config branch.$(git currentbranch).remote\""
#print the current branch, used in other commandscurrentbranch = rev-parse --abbrev-ref HEAD
#print the current remote, used in other commandscurrentremote = "!sh -c \"if [ $# -eq 0 ] ; then \
git config branch.$(git currentbranch).remote; \else \
git config branch.$1.remote; \fi\"„
My ~/.gitconfig…
#print the current merge branch, used in other commandscurrentmergebranch = "!sh -c \"if [ $# -eq 0 ] ; then \
git config branch.$(git currentbranch).merge | sed -e 's#^refs/heads/##'; \else \
git config branch.$1.merge | sed -e 's#^refs/heads/##'; \fi\""
#show all commits and files that i changed and are on top of my remote branchlgb = "!sh -c \"if [ -z \"$(git currentremote)\" ] ; then \
echo "Branch ist nicht richtig konfiguriert!" ; \else \git log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' \
--abbrev-commit --date=relative --no-merges --name-status \$( \
if [ \"$(git currentremote)\" != '.' ] ; then \echo "$(git currentremote)/" ; \
fi\)$(git currentmergebranch)..HEAD ; \
fi\""
#push to gerritpg = "!sh -c \"if [ -z \"$(git currentremote)\" ] ; then \
echo "Branch ist nicht richtig konfiguriert!" ; \else \
git push $(git currentremote) HEAD:refs/for/$(git currentmergebranch) ; \fi; \""
A SHORT NOTE ABOUT SHA-1 (http://git-scm.com/book/ch6-1.html#A-SHORT-NOTE-ABOUT-SHA-1)
A lot of people become concerned at some point that they will, by random happenstance, have two objects
in their repository that hash to the same SHA-1 value. What then?
If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your
repository, Git will see the previous object already in your Git database and assume it was already written. If
you try to check out that object again at some point, you’ll always get the data of the first object.
However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160
bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about
2^80 (the formula for determining collision probability is p = (n(n-1)/2) * (1/2^160)). 2^80 is 1.2 x 10^24 or 1
million billion billion. That’s 1,200 times the number of grains of sand on the earth.
Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on
Earth were programming, and every second, each one was producing code that was the equivalent of the
entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5
years until that repository contained enough objects to have a 50% probability of a single SHA-1 object
collision. A higher probability exists that every member of your programming team will be attacked and killed
by wolves in unrelated incidents on the same night.
Der Objectstore – SHA1