Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Visual introduction to Git internals

Visual introduction to Git internals

Introduces the way Git works internally in a visual manner.
The goal is to present the core tenets of Git and to give the reader a grasp of what it does under the hood, which I find essential to efficiently use it.

It was presented as a lightning talk within a previous company of mine where I instigated the move from SVN to Git, to try and ease the transition for developers without them / before they dig deep into Git logic.

This a translation from the original one at https://speakerdeck.com/desseim/shi-jue-de-nagitnei-bu-ru-men .

Guillaume Legrand

February 22, 2012
Tweet

More Decks by Guillaume Legrand

Other Decks in Programming

Transcript

  1. Let's understand Git Bare repository !? squash !? rebase !?

    refs !? detached head WTF!? Fast forward!? HEAD !? Legrand Guillaume 2012/02/22
  2. Let's try and understand Git Bare repository !? refs !?

    detached head WTF!? HEAD !? Legrand Guillaume 2012/02/22
  3. $ git add ./src_dir Working directory src_dir src_file.pl print “txet”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; staged
  4. $ git commit -m “First commit” Working directory src_dir src_file.pl

    print “txet”; .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; 5fs342w 0f4de32 scr_file .pl c92a25a e6fae02 User.name 2012-02-22 First commit e6fae02 5fs342w scr_dir HEAD heads/master heads/master c92a25a
  5. $ Working directory src_dir src_file.pl print “txet”; .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; 5fs342w c92a25a First commit e6fae02 HEAD heads/master heads/master c92a25a
  6. $ vim ./src_dir/src_file.pl Working directory src_dir src_file.pl print “text”; .git/

    objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit modified 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  7. $ git add ./src_dir Working directory src_dir src_file.pl print “text”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit staged 8e27be7 print “text”; 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  8. $ git reset HEAD ./src_dir #unstage Working directory src_dir src_file.pl

    print “text”; .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 modified HEAD heads/master heads/master c92a25a
  9. $ git checkout -- ./src_dir Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 src_dir src_file.pl print “txet”; HEAD heads/master heads/master c92a25a
  10. $ git cat-file -p 8e27be7 print “text”; $ Working directory

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 src_dir src_file.pl print “txet”; HEAD heads/master heads/master c92a25a
  11. $ vim ./src_dir/src_file.pl Working directory src_dir src_file.pl print “text”; .git/

    objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit modified 5fs342w e6fae02 8e27be7 print “text”; HEAD heads/master heads/master c92a25a
  12. $ git add ./src_dir Working directory src_dir src_file.pl print “text”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit staged 8e27be7 print “text”; 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  13. $ git commit -m “2nd commit” Working directory .git/ objects/

    refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD heads/master heads/master 136b9d6
  14. $ git branch first c92a25a Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD heads/master heads/master 136b9d6 heads/first c92a25a
  15. $ git checkout first Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “txet”; HEAD heads/first heads/master 136b9d6 heads/first c92a25a
  16. $ git branch -D master Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “txet”; HEAD heads/first heads/first c92a25a
  17. $ git checkout 136b9d6 Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD 136b9d6 heads/first c92a25a detached head
  18. $ git fetch origin #assuming it had been pushed to

    origin previously Working directory .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD 136b9d6 detached head
  19. $ git checkout master Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD Heads/master heads/master 136b9d6
  20. $ echo 'c92a25a' > ./.git/refs/heads/master #don't actually do this! @see

    git-update-ref Working directory .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD Heads/master heads/master c92a25a
  21. Summary • Git repo == .git/ directory – Can be

    backed up with a cp -R – If you have this directory, you can go back to any previous state • Git doesn't loose any data – It's COW: update implies duplication – Whatever mistake you make, if you had at least git added your work, it's not lost – It does not store diffs (opposed to e.g. subversion) • Everything is compressed with zlib
  22. Summary • Analogous (esp. internally) to a file system with

    file history management (VFS) • Content ⇔ SHA-1 hash ⇔ history – E.g. if one does a rebase: the commit's parent changes ⇒ the commit's content changes ⇒ the commit's hash changes ⇒ the parent of the commit's children has changed ⇒ … == history changes – SHA-1 == unique ID • Git is perfectly suitable as a backup tool – Even not just source code