Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
at                                                        with  Matthew  McCullough
GitGraphs, Hashes, and Compression, Oh...
@matthewmccull
matthew@github.com
github.com/training
GIT - the stupid content tracker
"git" can mean anything, depending on your mood.
* random three-letter combination that i...
2005
git
Architecture
Hashes
centralized VCSs use sequential revision numbers
Git uses a SHA-1 hash
40 hex characters
(20 bytes)
9AB223D28B1AA46EF1780B22F304982E39872C34
9AB223D28B1AA46EF1780B22F304982E39872C34
<html>
<body>
<p>This is a test</p>
<img src="http://ai.com/icon.gif">
</body>
</...
<html>
<body>
<p>This is a test</p>
<img src="http://ai.com/icon.gif">
</body>
</html>
9AB223D28B1AA46EF1780B22F304982E398...
Hashed Content
Git commits without Git
# Green field project
$ git init newproject
$ cd newproject
# ...start coding
.git
!"" COMMIT_EDITMSG
!"" HEAD
!"" MERGE_RR
!"" config
!"" description
!"" hooks
#   !"" pre-commit.sample
#   $"" updat...
$ printf "blob 12000Hello Worldn" | shasum
Architecture
Hash Shortcuts
use as little of it as is unique
9AB223D28B1AA46EF
1780B22F304982E39
872C34
a certain commit
9AB22F
a certain commit
git rev-parse 9AB22F
expand the commit ref
Architecture
Storage
Typical SCMs use delta storage
CVS / Subversion / darcs / Mercurial
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
Δ Δ
Δ
Δ ΔΔΔ
Checkin
Checkin Checkin
Checkin
Checkin
Checkin
Checkin
Checkin
Checkin
Checkin
Checkin
Delta storage gets slower as the h...
Directed Acyclic Graph
Copy of the entire tree per checkin
cp -r srcfolder srcfolder.prev
Why?
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
hard link to existing identical blobs
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File Cß
zlib deflates each blob at commit
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
zlib deflates the entire repo
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
v1 v2 v3 v4
File A
File B
File C
File A
File B File B
File C
v5
File A
File BFile B
File A File A
File C File C File C
2100 MBbecame
205 MB
Act I
Architecture
Hash relationships
‣Blob
‣Tree
‣Commit
‣Tag
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
tree
tree: 7e8b1 web
blob: 9ab16 index.html
a10b3
tree
blob: 8d162 logo.jpg
blob: 51d22 draw.js
7e8b1commit
tree: a10b3
pa...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
v1 v2 v3
commit
tree: 9a87b
parent: nil
author: Fird
committer: Matthew
message:
Major refactoring
of the Javascript rende...
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
RELEASE_1.0 HEAD
bug979branch
commit
c67db
commit
9bd21
commit
1c2d7
commit
8c2d1
commit
1bdcd
commit
2daa1
Architecture
Hash shortcuts
commitish & treeish
commitish = shorthand for commit hashes
treeish = shorthand for tree hashes
9AB22F
a certain commit
9AB22F^
one commit before a certain commit
9AB22F^^
two commits before a certain commit
9AB22F~5
five commits before a certain commit
9AB223..56CD77
between these two commits
HEAD
the most recent commit on this branch
HEAD^
one commit before the most recent commit
HEAD~2
two commits before the most recent commit
HEAD..HEAD^^^
between the given recent commits
master
the most recent commit on this branch
master^^
two commits before the most recent commit on this branch
master~5
five commits before the most recent commit on this branch
remotes/origin/master
the most recent commit on this remote tracking branch
origin/master
the most recent commit on this remote tracking branch
The Graph
Verification
git fsck
git verify-pack -v .git/objects/pack/FILENAME
The Graph
More graph navigation
master^{tree}
find this commit’s tree
git describe HASH
find nearest tag
:/some words
commit message that starts with
REF:FILE
blob spec
:0:FILE
index
:1:FILE
common ancestor
:2:FILE
target
:3:FILE
merging in
@matthewmccull
matthew@github.com
github.com/training
at                                                        with  Matthew  McCullough
GitGraphs, Hashes, and Compression, Oh...
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh My
Próxima SlideShare
Cargando en…5
×

Git Graphs, Hashes, and Compression, Oh My

494 visualizaciones

Publicado el

Git is a version control system. We can look at it from that high level. Git is a content tracking system. Some teachers advise us to look at it from that lowered elevation. But I will take you to the very bottom. The floor. The code. The algorithms. The directed acyclic graph of hashed bit sequences made efficient through LZW compression and deferred garbage collection determined by node reachability via hash relationships.

“But why?”, you may ask. “Why go this deep?”" Git is a tool that works so well for so many. It mystically corrects anticipated `merge` conflicts. It’s “where did code come from” results from `blame` are impressive. The ability to re-write history through `rebase` is awesome. The globally unique identifier nature of a hash-produced ref is revolutionary.

Uber-geeks are magic-slayers. We want and need to know precisely how things work. Like a hard 50 push-up workout, this study will make working with Git at the daily developer level a fraction of the effort — like a mere ten push-ups. Join Matthew McCullough of GitHub and let’s dig into the guts of Git.

Delivered on June 17, 2012

Publicado en: Tecnología
  • Sé el primero en comentar

Git Graphs, Hashes, and Compression, Oh My

  1. 1. at                                                        with  Matthew  McCullough GitGraphs, Hashes, and Compression, Oh My! ©2012,GitHub,Inc.
  2. 2. @matthewmccull matthew@github.com github.com/training
  3. 3. GIT - the stupid content tracker "git" can mean anything, depending on your mood. * random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant. * stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang. * "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room. * "goddamn idiotic truckload of sh*t": when it breaks Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals. Git is an Open Source project covered by the GNU General Public License. It was originally written by Linus Torvalds with help of a group of hackers around the net. It is currently maintained by Junio C Hamano. “ ”
  4. 4. 2005 git
  5. 5. Architecture Hashes
  6. 6. centralized VCSs use sequential revision numbers
  7. 7. Git uses a SHA-1 hash
  8. 8. 40 hex characters (20 bytes)
  9. 9. 9AB223D28B1AA46EF1780B22F304982E39872C34
  10. 10. 9AB223D28B1AA46EF1780B22F304982E39872C34 <html> <body> <p>This is a test</p> <img src="http://ai.com/icon.gif"> </body> </html>
  11. 11. <html> <body> <p>This is a test</p> <img src="http://ai.com/icon.gif"> </body> </html> 9AB223D28B1AA46EF1780B22F304982E39872C34
  12. 12. Hashed Content Git commits without Git
  13. 13. # Green field project $ git init newproject $ cd newproject # ...start coding
  14. 14. .git !"" COMMIT_EDITMSG !"" HEAD !"" MERGE_RR !"" config !"" description !"" hooks #   !"" pre-commit.sample #   $"" update.sample !"" index !"" info #   $"" exclude !"" logs #   !"" HEAD #   $"" refs #   $"" heads #   $"" master !"" objects #   !"" 54 #   #   $"" 3b9bebdc6bd5c4b22136034a95dd097a57d3dd #   !"" info #   $"" pack !"" refs    !"" heads    #   $"" master    $"" tags
  15. 15. $ printf "blob 12000Hello Worldn" | shasum
  16. 16. Architecture Hash Shortcuts
  17. 17. use as little of it as is unique
  18. 18. 9AB223D28B1AA46EF 1780B22F304982E39 872C34 a certain commit
  19. 19. 9AB22F a certain commit
  20. 20. git rev-parse 9AB22F expand the commit ref
  21. 21. Architecture Storage
  22. 22. Typical SCMs use delta storage
  23. 23. CVS / Subversion / darcs / Mercurial
  24. 24. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B
  25. 25. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B Δ Δ Δ Δ ΔΔΔ
  26. 26. Checkin Checkin Checkin Checkin Checkin Checkin Checkin Checkin Checkin Checkin Checkin Delta storage gets slower as the history of a file gets longer
  27. 27. Directed Acyclic Graph
  28. 28. Copy of the entire tree per checkin
  29. 29. cp -r srcfolder srcfolder.prev
  30. 30. Why?
  31. 31. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  32. 32. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  33. 33. hard link to existing identical blobs
  34. 34. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  35. 35. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File Cß
  36. 36. zlib deflates each blob at commit
  37. 37. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  38. 38. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  39. 39. zlib deflates the entire repo
  40. 40. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  41. 41. v1 v2 v3 v4 File A File B File C File A File B File B File C v5 File A File BFile B File A File A File C File C File C
  42. 42. 2100 MBbecame 205 MB Act I
  43. 43. Architecture Hash relationships
  44. 44. ‣Blob ‣Tree ‣Commit ‣Tag
  45. 45. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  46. 46. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  47. 47. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  48. 48. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  49. 49. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  50. 50. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  51. 51. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  52. 52. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  53. 53. tree tree: 7e8b1 web blob: 9ab16 index.html a10b3 tree blob: 8d162 logo.jpg blob: 51d22 draw.js 7e8b1commit tree: a10b3 parent: nil author: Fird committer: Matthew message: Major refactoring of the web content. c67db blob<html> <body></body> </html> 9ab16 blob //Some more javascript var renderSize 51d22 blob 7D 8D B3 7F BD 12 9F E9 7B 78 9D 3F 5C A6 72 CB 8d162
  54. 54. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  55. 55. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  56. 56. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  57. 57. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  58. 58. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  59. 59. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  60. 60. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  61. 61. v1 v2 v3 commit tree: 9a87b parent: nil author: Fird committer: Matthew message: Major refactoring of the Javascript rendering engine. c67db commit tree: b22c1 parent: c67db author: Tim committer: Fird message: Minor update to HTML 9bd21 commit tree: b22c1 parent: 9bd21 author: Johnny committer: Joe message: New language transations 1c2d7
  62. 62. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  63. 63. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  64. 64. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  65. 65. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  66. 66. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  67. 67. RELEASE_1.0 HEAD bug979branch commit c67db commit 9bd21 commit 1c2d7 commit 8c2d1 commit 1bdcd commit 2daa1
  68. 68. Architecture Hash shortcuts
  69. 69. commitish & treeish
  70. 70. commitish = shorthand for commit hashes
  71. 71. treeish = shorthand for tree hashes
  72. 72. 9AB22F a certain commit
  73. 73. 9AB22F^ one commit before a certain commit
  74. 74. 9AB22F^^ two commits before a certain commit
  75. 75. 9AB22F~5 five commits before a certain commit
  76. 76. 9AB223..56CD77 between these two commits
  77. 77. HEAD the most recent commit on this branch
  78. 78. HEAD^ one commit before the most recent commit
  79. 79. HEAD~2 two commits before the most recent commit
  80. 80. HEAD..HEAD^^^ between the given recent commits
  81. 81. master the most recent commit on this branch
  82. 82. master^^ two commits before the most recent commit on this branch
  83. 83. master~5 five commits before the most recent commit on this branch
  84. 84. remotes/origin/master the most recent commit on this remote tracking branch
  85. 85. origin/master the most recent commit on this remote tracking branch
  86. 86. The Graph Verification
  87. 87. git fsck
  88. 88. git verify-pack -v .git/objects/pack/FILENAME
  89. 89. The Graph More graph navigation
  90. 90. master^{tree} find this commit’s tree
  91. 91. git describe HASH find nearest tag
  92. 92. :/some words commit message that starts with
  93. 93. REF:FILE blob spec
  94. 94. :0:FILE index
  95. 95. :1:FILE common ancestor
  96. 96. :2:FILE target
  97. 97. :3:FILE merging in
  98. 98. @matthewmccull matthew@github.com github.com/training
  99. 99. at                                                        with  Matthew  McCullough GitGraphs, Hashes, and Compression, Oh My! ©2012,GitHub,Inc.

×