git internals

53
git internals dbyrne 23andMe

Upload: dennis-byrne

Post on 12-Apr-2017

334 views

Category:

Software


2 download

TRANSCRIPT

Page 1: git internals

git internals

dbyrne23andMe

Page 2: git internals

agenda

1.data ... in two commits

a. blobs

b. trees

c. commits

2.algorithms ... in six commitsa. commit

b. branch

c. merge

d. reset

e. rebase

Page 3: git internals

objects

commits

trees

blobs

Page 4: git internals

objects, blobs

$ git init objects_example

$ cd objects_example

$ echo "puts 'hello world'" > foo.rb

$ git add foo.rb

$ strings .git/index | grep hello

$ strings .git/index | grep foo.rb

foo.rb

Page 5: git internals

objects, blobs$ find .git/objects -type file

.git/objects/aa/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

$ git cat-file -t aaaa # what type of object is this?

blob

$ git cat-file -p aaaa # print the object

puts 'hello world'

Page 6: git internals

objects, blobs$ echo "puts 'hello world'" > bar.rb

$ git add bar.rb

$ strings .git/index | grep bar.rb

bar.rb

$ find .git/objects -type file # no new blob

.git/objects/aa/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Page 7: git internals

objects

$ git commit -m 'commit msg #1'

$ find .git/objects -type file

.git/objects/aa/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

.git/objects/bb/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

.git/objects/cc/cccccccccccccccccccccccccccccccccccccc

Page 8: git internals

objects, trees$ git cat-file -t bbbb

tree

$ git cat-file -p bbbb

100644 blob aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bar.rb

100644 blob aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa foo.rb

Page 9: git internals

objects, commits$ git cat-file -t cccc

commit

$ git cat-file -p cccc

tree bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

author dbyrne <[email protected]> 1474171822 -0700

committer dbyrne <[email protected]> 1474171822 -0700

commit msg #1

Page 10: git internals

c

a

b

foo.rb bar.rb

Page 11: git internals

objects

$ mkdir dir

$ echo "puts 'hello world'" > dir/baz.rb

$ git add dir/baz.rb

$ git commit -m 'commit msg #2'

Page 12: git internals

objects$ find .git/objects -type file

.git/objects/aa/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

.git/objects/bb/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

.git/objects/cc/cccccccccccccccccccccccccccccccccccccc

.git/objects/dd/dddddddddddddddddddddddddddddddddddddd <- new

.git/objects/ee/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee <- new

.git/objects/ff/ffffffffffffffffffffffffffffffffffffff <- new

Page 13: git internals

objects$ git cat-file -p HEAD^{commit} # same as ffff

tree eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

parent cccccccccccccccccccccccccccccccccccccccc

author dbyrne <[email protected]> 1474172113 -0700

committer dbyrne <[email protected]> 1474172113 -0700

commit msg #2

Page 14: git internals

objects

$ git cat-file -p HEAD^{tree} # same as eeee

100644 blob aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bar.rb

040000 tree dddddddddddddddddddddddddddddddddddddddd dir

100644 blob aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa foo.rb

Page 15: git internals

objects$ git cat-file -t dddd

tree

$ git cat-file -p dddd

100644 blob aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa baz.rb

Page 16: git internals

c

a

b /

f

e /

d /dir

foo.rb

bar.rb

baz.rb

foo.rb bar.rb

Page 17: git internals

objectsthere are three types of objects: blobs, trees & commits

blobs represent files

blobs are created with the add, not the commit command

blobs are snapshots, not deltas or patches

the add command records snapshots every time

a file can be both “staged” and “modified”

trees represent directories

trees point to blobs and/or trees

commits point to trees and most likely each other

a SHA can be abbreviated with a minimum of four chars

Page 18: git internals

refs$ ls .git/HEAD

.git/HEAD <- important

$ tree .git/refs/

├── heads <- important

│ └── master

├── remotes

├── stash

└── tags

Page 19: git internals

git commit$ git init refs_example

$ cd refs_example

$ echo "print 'commit #1'" > spam.py

$ git add spam.py

$ git commit -m 'commit msg #1'

[master (root-commit) 1111111] commit msg #1

Page 20: git internals

git commit$ ls .git/objects/11

11111111111111111111111111111111111111

$ cat .git/refs/heads/master

1111111111111111111111111111111111111111

$ cat .git/HEAD

ref: refs/heads/master

Page 21: git internals

git commit

1111

master

HEAD

Page 22: git internals

top to bottom

5HEAD

branch

commit

tree

blob

Page 23: git internals

git commit$ echo "print 'commit #2'" >> spam.py

$ git commit -am 'commit msg #2'

[master 2222222] commit msg #2

$ cat .git/HEAD

ref: refs/heads/master

Page 24: git internals

git commit

1111

master

HEAD2222

Page 25: git internals

git commit$ git show-ref master --abbrev

2222222 refs/heads/master

$ git cat-file -p 2222 | grep parent

parent 1111111111111111111111111111111111111111

Page 26: git internals

git branch$ git branch feature_branch

$ ls .git/refs/heads/

feature_branch

master

$ git show-ref --abbrev

2222222 refs/heads/feature_branch

2222222 refs/heads/master

Page 27: git internals

git branch

1111

master

HEAD2222

feature_branch

Page 28: git internals

git checkout$ cat .git/HEAD

ref: refs/heads/master <- before

$ git checkout feature_branch

$ cat .git/HEAD

ref: refs/heads/feature_branch <- after

Page 29: git internals

git checkout

1111

master

HEAD2222

feature_branch

Page 30: git internals

working on a branch$ echo "print 'commit #3'" > eggs.py

$ git add eggs.py

$ git commit -m 'commit msg #3'

[feature_branch 3333333] commit msg #3

$ git show-ref --abbrev

3333333 refs/heads/feature_branch

2222222 refs/heads/master

Page 31: git internals

working on a branch

1111

master

HEAD2222

feature_branch

3333

Page 32: git internals

divergence$ git checkout master

$ echo "print 'commit #4'" > spam.py

$ git commit -am 'commit msg #4'

[master 4444444] commit msg #4

Page 33: git internals

divergence

1111

master

HEAD2222

feature_branch

3333

4444

Page 34: git internals

git merge$ git merge --no-edit feature_branch

Merge made by the 'recursive' strategy. <- important

eggs.py | 1 +

1 file changed, 1 insertion($)

create mode 100644 eggs.py

Page 35: git internals

git merge

1111

master

HEAD2222

feature_branch

3333

4444

5555

Page 36: git internals

git lol$ git log --graph --oneline --decorate

* 5555555 (HEAD -> master) Merge branch 'feature_branch'

|\

| * 3333333 (feature_branch) commit msg #3

* | 4444444 commit msg #4

|/

* 2222222 commit msg #2

* 1111111 commit msg #1

Page 37: git internals

git merge$ git show-ref master --abbrev

5555555 refs/heads/master

$ git cat-file -p 5555 | grep parent

parent 4444444444444444444444444444444444444444 <- master

parent 3333333333333333333333333333333333333333 <- fe. br.

Page 38: git internals

merge vs. rebase

record of what

actually happened

vs. story of how your

project was made

Page 39: git internals

git reset (to a commit)

change index? change working dir? working dir safe?

git reset --soft SHA Yes No

git reset --mixed SHA No Yes

git reset --hard SHA Yes Yes

Page 40: git internals

git reset$ git show-ref --abbrev

3333333 refs/heads/feature_branch

5555555 refs/heads/master

$ git reset --hard HEAD^

HEAD is now at 4444444 commit msg #4

$ git show-ref --abbrev

3333333 refs/heads/feature_branch

4444444 refs/heads/master

Page 41: git internals

git reset

1111

master

HEAD2222

3333

4444

5555

feature_branch

Page 42: git internals

feature_branch

git reset, simplified

1111

master

HEAD2222

3333

4444

Page 43: git internals

git rebase$ git show-ref feature_branch --abbrev

3333333 refs/heads/feature_branch

$ git checkout feature_branch

$ git rebase master

First, rewinding head to replay your work on top of it...

Applying: commit msg #3

$ git show-ref feature_branch --abbrev

6666666 refs/heads/feature_branch

Page 44: git internals

git rebase

1111

master

HEAD2222

feature_branch

3333

4444

6666

Page 45: git internals

git rebase, simplified

1111

master

HEAD2222

feature_branch

4444 6666

Page 46: git internals

git merge - fast forward$ git checkout master

$ git merge feature_branch

Updating 4444444..6666666

Fast-forward <- important

eggs.py | 1 $

1 file changed, 1 insertion($)

create mode 100644 eggs.py

Page 47: git internals

git merge - fast forward

1111

master

HEAD2222

feature_branch

4444 6666

Page 48: git internals

git merge - fast forward$ git show-ref --abbrev

6666666 refs/heads/feature_branch

6666666 refs/heads/master

$ ls

eggs.py

spam.py

Page 49: git internals

git reflog$ git reflog

6666666 HEAD@{0}: merge feature_branch: Fast-forward

...6666666 HEAD@{3}: rebase: commit msg #3...4444444 HEAD@{6}: reset: moving to HEAD^

5555555 HEAD@{7}: merge feature_branch: Merge made by the 'recursive' strategy....

Page 50: git internals

git fsck$ echo "lost?" >> spam.py && git add spam.py

$ echo "no" >> spam.py && git add spam.py

$ git fsck --unreachable

unreachable blob 7777777777777777777777777777777777777777

$ git cat-file -p 7777

print 'commit #4'

lost?

Page 51: git internals

git gc$ git fsck --unreachable

unreachable blob 7777777777777777777777777777777777777777

$ git gc --prune=all

$ git fsck --unreachable

$ git cat-file -p 7777

fatal: Not a valid object name 7777

Page 52: git internals

detached head state$ git checkout 5555555

<(HEAD detached at 5555555)> $ cat .git/HEAD

5555555555555555555555555555555555555555

<(HEAD detached at 5555555)> $ # look around, even do work

$ git checkout -b nostalgia

$ git branch

feature_branch master* nostalgia

Page 53: git internals

trends