Demystifying Git

This time last year, I gave a presentation internally at M&S, for our engineering community, called “Demystifying Git.” Rather than the usual how-to guide, I wanted people to walk away with a clearer picture of how Git actually works — and how that understanding can make it easier to use and to debug the awkward states repositories sometimes get into.

The session went down well, but I recently realised the slides have just been sitting idle on my laptop ever since. So, here they are! Take a look, and let me know if you learned something new - or if you’ve got something to add or correct.

Demystifying Git: How it actually works. Tim Searle, August 2024.
1 / 144

Use the Previous/Next buttons, the slider, or your keyboard arrow keys to navigate through the presentation.

Slide text (accessible transcript)
  1. Slide 1: Demystifying Git

    How it actually works Tim Searle - August 2024

  2. Slide 2: What are our goals?

    • Decipher weird git terminology

  3. Slide 3: What are our goals?

    • Decipher weird git terminology • Understand what is actually happening when you run certain commands

  4. Slide 4: What are our goals?

    • Decipher weird git terminology • Understand what is actually happening when you run certain commands • Comfortable navigating the git file system

  5. Slide 5: What are our goals?

    • Decipher weird git terminology • Understand what is actually happening when you run certain commands • Comfortable navigating the git file system • Most importantly, never saying “I’ll just re-clone the repository to solve this issue” again

  6. Slide 6: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked

  7. Slide 7: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked • His project goals were:

  8. Slide 8: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked • His project goals were: • Patching should take no more than three seconds

  9. Slide 9: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked • His project goals were: • Patching should take no more than three seconds • Take CVS as an example of what not to do; if in doubt, make the exact opposite decision

  10. Slide 10: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked • His project goals were: • Patching should take no more than three seconds • Take CVS as an example of what not to do; if in doubt, make the exact opposite decision • Distributed

  11. Slide 11: A brief history lesson...

    • Git was created by Linus Torvalds, the creator of Linux, to help manage contributions to Linux after its Bitkeeper license was revoked • His project goals were: • Patching should take no more than three seconds • Take CVS as an example of what not to do; if in doubt, make the exact opposite decision • Distributed • Include strong safeguards against corruption, either accidental or malicious

  12. Slide 12: git init

    git init

  13. Slide 13: git init — output

    Initialized empty Git repository in /Users/tim.searle/Desktop/demystify/.git/

  14. Slide 14: git init — output

    Initialized empty Git repository in /Users/tim.searle/Desktop/demystify/.git/ The .git/ suffix is emphasised in bold.

  15. Slide 15: Inside .git

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs.

  16. Slide 16: Before we dive in...

    We need to understand a key concept first - objects! https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  17. Slide 17: Objects

    Everything stored within a git repository, is an addressable object. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  18. Slide 18: Objects

    Everything stored within a git repository, is an addressable object. There are three primary types of objects: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  19. Slide 19: Objects

    Everything stored within a git repository, is an addressable object. There are three primary types of objects: • Commits https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  20. Slide 20: Objects

    Everything stored within a git repository, is an addressable object. There are three primary types of objects: • Commits • Trees https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  21. Slide 21: Objects

    Everything stored within a git repository, is an addressable object. There are three primary types of objects: • Commits • Trees • Blobs https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  22. Slide 22: Objects

    These objects form a tree structure, a directed acyclic graph, to be precise: Diagram: a commit points to its parent commit and a root tree. The root tree points to another tree, which points to two blobs. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  23. Slide 23: What's this?

    A single orange box labelled Blob.

  24. Slide 24: Blob

    In Git, a blob is the basic type of all content that is stored. This represents any file within Git. It’s a leaf node in the git graph, meaning it doesn’t point to anywhere else, just its content.

  25. Slide 25: And these?

    A single green box labelled Tree.

  26. Slide 26: Tree

    In Git, a tree object is a list of other objects, specifically a list of blobs or more trees. Git uses the tree object, alongside blobs, to represent the entire filesystem of your repository.

  27. Slide 27: And lastly...

    A single pink box labelled Commit.

  28. Slide 28: Commits

    A commit object contains multiple pointers to different objects, so that it can allow to git to re-construct your worktree (all of your files), back into your repository root directory.

  29. Slide 29: Commits

    A commit object contains multiple pointers to different objects, so that it can allow to git to re-construct your worktree (all of your files), back into your repository root directory. It knows about its parent commit, it knows about what tree object represents the root, and of course it has its own unique identifier.

  30. Slide 30: Commits

    A commit object contains multiple pointers to different objects, so that it can allow to git to re-construct your worktree (all of your files), back into your repository root directory. It knows about its parent commit, it knows about what tree object represents the root, and of course it has its own unique identifier. Let’s look at an example...

  31. Slide 31: Objects

    Let’s map this to a commit: Commit Hash: bd8e5847d8d0714624875eaa767a071f36a3da3d Tree: b9ad6e8349eb09ebdbab59b2232e5507f688e7b6 Author: Tim Searle <tim.searle@mnscorp.net> Date: Tue, 27 Aug, 2024, 14:09 Parent: a7d225c7d4bf9bfc2eaae9e48cc2fdae9810feef Signature: Valid Branches: main Stats: 2 files changed: -2 +2 Diagram: a commit points to its parent commit and a root tree. The root tree points to another tree, which points to two blobs. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  32. Slide 32: Commits

    Let’s map this to a commit log: Commit Hash: bd8e5847d8d0714624875eaa767a071f36a3da3d Tree: b9ad6e8349eb09ebdbab59b2232e5507f688e7b6 Author: Tim Searle <tim.searle@mnscorp.net> Date: Tue, 27 Aug, 2024, 14:09 Parent: a7d225c7d4bf9bfc2eaae9e48cc2fdae9810feef Signature: Valid Branches: main Stats: 2 files changed: -2 +2 Diagram: a commit points to its parent commit and a root tree. The root tree points to another tree, which points to two blobs. The commit is labelled bd8e584 and its parent a7d225c. Their hashes are highlighted in the metadata. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  33. Slide 33: Objects

    Let’s map this to a commit: Commit Hash: bd8e5847d8d0714624875eaa767a071f36a3da3d Tree: b9ad6e8349eb09ebdbab59b2232e5507f688e7b6 Author: Tim Searle <tim.searle@mnscorp.net> Date: Tue, 27 Aug, 2024, 14:09 Parent: a7d225c7d4bf9bfc2eaae9e48cc2fdae9810feef Signature: Valid Branches: main Stats: 2 files changed: -2 +2 Diagram: a commit points to its parent commit and a root tree. The root tree points to another tree, which points to two blobs. The root tree is labelled b9ad6e8 and highlighted in the metadata. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  34. Slide 34: But what are these?

    b9ad6e8

  35. Slide 35: Remember earlier?

    “Everything stored within a git repository, is an addressable object.”

  36. Slide 36: Remember earlier?

    “Everything stored within a git repository, is an addressable object.” Git uses a hash to represent all objects that it stores within its database. SHA-1 is the hash function that git uses internally to generate a unique identifier for every object.

  37. Slide 37: But what if two objects had the same identifier?

    We call this - a hash collision.

  38. Slide 38: But what if two objects had the same identifier?

    We call this - a hash collision. A SHA-1 hash function generates a 160-bit output from an arbitrary length input.

  39. Slide 39: But what if two objects had the same identifier?

    We call this - a hash collision. A SHA-1 hash function generates a 160-bit output from an arbitrary length input. That’s 2^160 permutations. That’s a lot.

  40. Slide 40: Hash collisions

    1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976

  41. Slide 41: Okay, back here again...

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs.

  42. Slide 42: .git: object database

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs. An arrow labelled Object Database points to objects.

  43. Slide 43: .git: references

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs. Arrows identify objects as the Object Database and refs as References.

  44. Slide 44: .git: lifecycle hooks

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs. Arrows identify hooks as Git Lifecycle Hooks, objects as the Object Database and refs as References.

  45. Slide 45: .git: what is HEAD?

    The demystify project’s .git directory contains config, description, HEAD, hooks, info, objects and refs. Arrows identify hooks as Git Lifecycle Hooks, objects as the Object Database and refs as References. A thinking-face emoji points to HEAD.

  46. Slide 46: HEAD

    The HEAD file represents the current “head” pointer of your graph that it is being used to construct your worktree (all of your files!). It can contain either a: • Reference

  47. Slide 47: HEAD

    The HEAD file represents the current “head” pointer of your graph that it is being used to construct your worktree (all of your files!). It can contain either a: • Reference • Commit object ID (SHA-1 hash)

  48. Slide 48: HEAD

    $ cat .git/HEAD

  49. Slide 49: HEAD

    $ cat .git/HEAD ref: refs/heads/main

  50. Slide 50: HEAD

    ...but what if we checkout a commit object ID? $ git checkout bd8e584

  51. Slide 51: HEAD

    ...but what if we checkout an object ID? $ git checkout bd8e584 Note: switching to 'bd8e5847d8d0714624875eaa767a071f36a3da3d'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch.

  52. Slide 52: Detached HEAD

    $ cat .git/HEAD bd8e5847d8d0714624875eaa767a071f36a3da3d Quite simply - a “detached HEAD” state, just means your HEAD file is currently set to a specific commit, rather than tracking a reference. When performing a commit during a detached HEAD state, the HEAD file is then updated to the new commit object ID. Contrasted to when your HEAD file represents a reference - it does not need to update.

  53. Slide 53: But what is a reference?!

    File browser: refs contains heads/main and a tags directory. • The “refs” folder contains all the “references” your project knows about

  54. Slide 54: But what is a reference?!

    File browser: refs contains heads/main and a tags directory. • The “refs” folder contains all the “references” your project knows about • A reference is simply a file, that contains a commit object ID, representing the head commit of that “ref”

  55. Slide 55: Let's take a quick look inside

    File browser: refs contains heads/main and a tags directory. $ cat .git/refs/heads/main

  56. Slide 56: Let's take a quick look inside

    File browser: refs contains heads/main and a tags directory. $ cat .git/refs/heads/main bd8e5847d8d0714624875eaa767a071f36a3da3d

  57. Slide 57: References

    File browser: refs contains heads/main and a tags directory. There are a few different types of a reference: • heads - the tips of branches

  58. Slide 58: References

    File browser: refs contains heads/main and a tags directory. There are a few different types of a reference: • heads - the tips of branches • tags - a human-readable name for a specific commit object ID

  59. Slide 59: References

    File browser: refs contains heads/main and a tags directory. There are a few different types of a reference: • heads - the tips of branches • tags - a human-readable name for a specific commit object ID • remotes - the tips of the branches on the remote, e.g. origin

  60. Slide 60: References

    File browser: refs contains heads/main and a tags directory. There are a few different types of a reference: • heads - the tips of branches • tags - a human-readable name for a specific commit object ID • remotes - the tips of the branches on the remote, e.g. origin • <surprise> - stay until the end to find out about this one...

  61. Slide 61: Quick recap...

    Objects: Commit, Tree, Blob. References: Heads, Tags, Remotes, <surprise>. HEAD: Reference or Commit.

  62. Slide 62: So how do we store an object?

    Say hello to your first plumbing command... https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

  63. Slide 63: Wait... plumbing command?

    Git started its life as a toolkit for a version control system - a lot of complex commands, allowing you to manipulate and access the filesystem we are talking about here. As it matured over the years, the interface for git became more clearly defined and more user-friendly, it transitioned into a version control system in its own right - this led to two levels of commands: https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

  64. Slide 64: Wait... plumbing command?

    Git started its life as a toolkit for a version control system - a lot of complex commands, allowing you to manipulate and access the filesystem we are talking about here. As it matured over the years, the interface for git became more clearly defined and more user-friendly, it transitioned into a version control system in its own right - this led to two levels of commands: • Porcelain commands • git checkout / git add etc https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

  65. Slide 65: Wait... plumbing command?

    Git started its life as a toolkit for a version control system - a lot of complex commands, allowing you to manipulate and access the filesystem we are talking about here. As it matured over the years, the interface for git became more clearly defined and more user-friendly, it transitioned into a version control system in its own right - this led to two levels of commands: • Porcelain commands • git checkout / git add etc • Plumbing commands... https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

  66. Slide 66: So how do we store an object?

    So, say hello to your first plumbing command... https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

  67. Slide 67: git hash-object

    git hash-object https://git-scm.com/docs/git-hash-object

  68. Slide 68: $ git hash-object README.md

    $ git hash-object README.md ba8894c152ab83a15e1ea581f05e2ddbf3355122

  69. Slide 69: $ git hash-object -w README.md

    $ git hash-object -w README.md ba8894c152ab83a15e1ea581f05e2ddbf3355122

  70. Slide 70: $ git hash-object -w README.md

    $ git hash-object -w README.md ba8894c152ab83a15e1ea581f05e2ddbf3355122 File browser: objects contains ba/8894c152ab83a15e1ea581f05e2ddbf3355122, info and pack.

  71. Slide 71: Object Store Structure

    Whenever Git needs to store an object, it uses an optimised structure to do so. It takes the first two character prefix of object ID, and creates a folder, and then it creates a file containing the object named the remaining characters of the hash. File browser: objects contains ba/8894c152ab83a15e1ea581f05e2ddbf3355122, info and pack.

  72. Slide 72: Object Store Structure

    When does git use hash-object?

  73. Slide 73: Object Store Structure

    When does git use hash-object? And when does it write that file to the store?

  74. Slide 74: Object Store Structure

    When does git use hash-object? And when does it write that file to the store? All. The. Time.

  75. Slide 75: Object Store Structure

    When does git use hash-object? And when does it write that file to the store? All. The. Time. • When you’re adding a file to your staging area

  76. Slide 76: Object Store Structure

    When does git use hash-object? And when does it write that file to the store? All. The. Time. • When you’re adding a file to your staging area • When you’re committing

  77. Slide 77: Object Store Structure

    When does git use hash-object? And when does it write that file to the store? All. The. Time. • When you’re adding a file to your staging area • When you’re committing • When you’re rebasing

  78. Slide 78: Inspecting object IDs

    We’ve talked about object IDs, we’ve thrown around unreadable SHA-1 hashes everywhere, and we even understand the folder structure - but what is in these files?!

  79. Slide 79: Inspecting object IDs

    We’ve talked about object IDs, we’ve thrown around unreadable SHA-1 hashes everywhere, and we even understand the folder structure - but what is in these files?! And, we can’t just look inside them in our file browser, they’re in a binary format.

  80. Slide 80: Inspecting object IDs

    We’ve talked about object IDs, we’ve thrown around unreadable SHA-1 hashes everywhere, and we even understand the folder structure - but what is in these files?! And, we can’t just look inside them in our file browser, they’re in a binary format. $ file .git/objects/a7/d225c7d4bf9bfc2eaae9e48cc2fdae9810feef

  81. Slide 81: Inspecting object IDs

    We’ve talked about object IDs, we’ve thrown around unreadable SHA-1 hashes everywhere, and we even understand the folder structure - but what is in these files?! And, we can’t just look inside them in our file browser, they’re in a binary format. $ file .git/objects/a7/d225c7d4bf9bfc2eaae9e48cc2fdae9810feef .git/objects/a7/d225c7d4bf9bfc2eaae9e48cc2fdae9810feef: zlib compressed data

  82. Slide 82: Inspecting object IDs

    We’ve talked about object IDs, we’ve thrown around unreadable SHA-1 hashes everywhere, and we even understand the folder structure - but what is in these files?! And, we can’t just look inside them in our file browser, they’re in a binary format. $ file .git/objects/a7/d225c7d4bf9bfc2eaae9e48cc2fdae9810feef .git/objects/a7/d225c7d4bf9bfc2eaae9e48cc2fdae9810feef: zlib compressed data Enter our next plumbing command...

  83. Slide 83: git cat-file

    git cat-file https://git-scm.com/docs/git-cat-file

  84. Slide 84: git-cat-file

    The cat-file command is how we can inspect and understand these object IDs that we’re referencing everywhere.

  85. Slide 85: git-cat-file

    The cat-file command is how we can inspect and understand these object IDs that we’re referencing everywhere. For example:

  86. Slide 86: $ git cat-file -t ba8894c15

    $ git cat-file -t ba8894c15

  87. Slide 87: $ git cat-file -t ba8894c15

    $ git cat-file -t ba8894c15 commit

  88. Slide 88: $ git cat-file -p ba8894c15

    $ git cat-file -p ba8894c15

  89. Slide 89: $ git cat-file -p ba8894c15

    $ git cat-file -p ba8894c15 tree a9cb16b453acfa52040e8e568b5a138875945587 author Tim Searle <tim.searle@mnscorp.net> 1724764152 +0100 committer Tim Searle <tim.searle@mnscorp.net> 1724764152 +0100 gpgsig -----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg9VSxwJVsCGW/6zaZmbA1HZTxqM Vb9AO4T2SAwolHpEgAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQI1sSDcNYbFsQLReCOcZ/3b22atktqiTRmmUTVtywq/qDH3uAAFZip+hqOkhGZ+8yA unUQsohms98PtmU7+7/wU= -----END SSH SIGNATURE----- First commit!

  90. Slide 90: Let's look at the tree object from that commit

    $ git cat-file -p a9cb16b

  91. Slide 91: Let's look at the tree object from that commit

    $ git cat-file -p a9cb16b 040000 tree 224e668053181aebca54fc1fa83027187cf956e2 src

  92. Slide 92: It's referencing another tree... let's keep going

    $ git cat-file -p a9cb16b 040000 tree 224e668053181aebca54fc1fa83027187cf956e2 src

  93. Slide 93: $ git cat-file -p 224e668053181aebca54fc1fa83027187cf956e2

    $ git cat-file -p 224e668053181aebca54fc1fa83027187cf956e2 100644 blob c790eda2963067baf3ba366b2ba3dea52c944660 hello.txt 100644 blob 304360caba487e6f7b707b5aa96774f85bf17b77 readme.txt

  94. Slide 94: Lastly, let's look at one of those blobs

    $ git cat-file -p c790eda2963067baf3ba366b2ba3dea52c944660

  95. Slide 95: Lastly, let's look at one of those blobs

    $ git cat-file -p c790eda2963067baf3ba366b2ba3dea52c944660 Hello!

  96. Slide 96: What did we just see?

    Diagram: a commit points to its parent commit and a root tree. The root tree points to another tree, which points to two blobs.

  97. Slide 97: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt.

  98. Slide 98: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c.

  99. Slide 99: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c. Current commit: bd8e584.

  100. Slide 100: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c. Current commit: bd8e584. The diagram labels hello.txt as 304360c. Transcript note: the diagram’s hello.txt label is incorrect; slide 93 shows hello.txt has hash c790eda and readme.txt has hash 304360c.

  101. Slide 101: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c. Current commit: bd8e584. The diagram labels hello.txt as 304360c. Root directory /: a9cb16b. Transcript note: the diagram’s hello.txt label is incorrect; slide 93 shows hello.txt has hash c790eda and readme.txt has hash 304360c.

  102. Slide 102: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c. Current commit: bd8e584. The diagram labels hello.txt as 304360c. Root directory /: a9cb16b. Directory src: 224e668. Transcript note: the diagram’s hello.txt label is incorrect; slide 93 shows hello.txt has hash c790eda and readme.txt has hash 304360c.

  103. Slide 103: What did we just see?

    Diagram: a commit points to its parent and the root directory /. The root directory points to src, which points to hello.txt and readme.txt. Parent commit: a7d225c. Current commit: bd8e584. The diagram labels hello.txt as 304360c. Root directory /: a9cb16b. Directory src: 224e668. The diagram also labels readme.txt as 224e668. Transcript note: the source diagram’s blob labels are incorrect. Slide 93 shows hello.txt has hash c790eda and readme.txt has hash 304360c; 224e668 is the src tree.

  104. Slide 104: So what?

    So what?

  105. Slide 105: Lost + Found

    • We talked about hash-object -w being called all the time, including when we stage a change

  106. Slide 106: Lost + Found

    • We talked about hash-object -w being called all the time, including when we stage a change • When we make a commit while in a detached head state, and switch back to a branch, this commit is left dangling with no ref owning it

  107. Slide 107: Lost + Found

    • We talked about hash-object -w being called all the time, including when we stage a change • When we make a commit while in a detached head state, and switch back to a branch, this commit is left dangling with no ref owning it • Why is this useful?

  108. Slide 108: Lost + Found

    Have you ever been involved in an accident where you reset your current branch and lost all of your staged changes?

  109. Slide 109: Lost + Found

    You may be entitled to compensation

  110. Slide 110: Lost + Found

    “You may be entitled to compensation” is crossed out.

  111. Slide 111: Lost + Found

    You might be interested in fsck

  112. Slide 112: Lost + Found

    • git fsck performs a “file system consistency check”

  113. Slide 113: Lost + Found

    • git fsck performs a “file system consistency check” • It’s used by git gc (garbage collector) to clean-up the object store to ensure it remains performant

  114. Slide 114: Lost + Found

    • git fsck performs a “file system consistency check” • It’s used by git gc (garbage collector) to clean-up the object store to ensure it remains performant • But it can also be used to retrieve those originally staged files

  115. Slide 115: $ git fsck --lost-found

    $ git fsck -lost-found Transcript note: the command’s long option is spelled --lost-found, with two hyphens.

  116. Slide 116: git fsck: dangling objects

    $ git fsck -lost-found dangling commit 7f34674533894902b5961cb070289342d8b5e53b dangling tree 44542c153c79cec057b725e9a5f45b74dbd3e2b0 dangling commit 56d9da26634bad2194858d0c4d2a6760a717c12a dangling blob e965047ad7c57865823c7d992b1d046ea66edf78 dangling blob ba8894c152ab83a15e1ea581f05e2ddbf3355122 dangling tree 3b6966478f24bf0db7da4f8a5b8acf1d8ef63235 Transcript note: the command’s long option is spelled --lost-found, with two hyphens.

  117. Slide 117: Lost + Found

    .git/lost-found/other contains: 3b6966478f24bf0db7da4f8a5b8acf1d8ef63235 (selected) ba8894c152ab83a15e1ea581f05e2ddbf3355122 e965047ad7c57865823c7d992b1d046ea66edf78 44542c153c79cec057b725e9a5f45b74dbd3e2b0 .git/lost-found/commit contains: 56d9da26634bad2194858d0c4d2a6760a717c12a 7f34674533894902b5961cb070289342d8b5e53b

  118. Slide 118: Logs

    Logs

  119. Slide 119: Logs

    • Git locally logs everything that you do

  120. Slide 120: Logs

    • Git locally logs everything that you do • Every object creation

  121. Slide 121: Logs

    • Git locally logs everything that you do • Every object creation • Every ref change

  122. Slide 122: Logs

    • Git locally logs everything that you do • Every object creation • Every ref change • This is powerful and really can save your day

  123. Slide 123: Logs

    Have you ever been involved in an accident where you reset your current branch back several commits and lost all of your committed changes?

  124. Slide 124: Logs

    You might be interested in reflog

  125. Slide 125: Logs

    • The reflog command parses the logs directory and produces a handy timeline of all ref changes that have occurred

  126. Slide 126: Logs

    • The reflog command parses the logs directory and produces a handy timeline of all ref changes that have occurred • Each of these changes include the SHA-1 for the change

  127. Slide 127: Logs

    • The reflog command parses the logs directory and produces a handy timeline of all ref changes that have occurred • Each of these changes include the SHA-1 for the change • This allows you to use git reset to set your worktree back to the state you need and recover those commits

  128. Slide 128: Logs

    $ git reflog bd8e584 (HEAD -> main) HEAD@{0}: reset: moving to head bd8e584 (HEAD -> main) HEAD@{1}: checkout: moving from 56d9da26634bad2194858d0c4d2a6760a717c12a to main 56d9da2 HEAD@{2}: commit: Test bd8e584 (HEAD -> main) HEAD@{3}: checkout: moving from main to bd8e5847d8d0714624875eaa767a071f36a3da3d bd8e584 (HEAD -> main) HEAD@{4}: checkout: moving from bd8e5847d8d0714624875eaa767a071f36a3da3d to main bd8e584 (HEAD -> main) HEAD@{5}: checkout: moving from main to bd8e5847d8d0714624875eaa767a071f36a3da3d bd8e584 (HEAD -> main) HEAD@{6}: checkout: moving from a7d225c7d4bf9bfc2eaae9e48cc2fdae9810feef to main a7d225c HEAD@{7}: checkout: moving from main to a7d2 bd8e584 (HEAD -> main) HEAD@{8}: commit: A commit a7d225c HEAD@{9}: commit (initial): First commit!

  129. Slide 129: Summary

    Summary

  130. Slide 130: Summary

    • We’ve covered a lot of ground

  131. Slide 131: Summary

    • We’ve covered a lot of ground • The concepts of objects and references, within the git filesystem, are incredibly powerful

  132. Slide 132: Summary

    • We’ve covered a lot of ground • The concepts of objects and references, within the git filesystem, are incredibly powerful • Understanding how git is effectively a content management system on disk allows you to intuit and derive certain behaviours

  133. Slide 133: Summary

    • We’ve covered a lot of ground • The concepts of objects and references, within the git filesystem, are incredibly powerful • Understanding how git is effectively a content management system on disk allows you to intuit and derive certain behaviours • Plumbing commands allow you to step beneath the “friendly” porcelain interface and manipulate that content more granularly

  134. Slide 134: One more thing…

    Photo: Steve Jobs on stage in front of a screen reading “One more thing…”. Photo credit: Adam Tow | AllThingsD.com.

  135. Slide 135: git notes

    git notes

  136. Slide 136: $ git notes add -m "I hope this message finds you well" -c <object_id>

    $ git notes add -m "I hope this message finds you well" -c <object_id> Transcript note: to attach a new message to <object_id>, use git notes add -m "I hope this message finds you well" <object_id>. The slide’s -c option instead expects an existing note object to reuse; it does not select the commit to annotate.

  137. Slide 137: git notes: attaching metadata

    $ git notes add -m "I hope this message finds you well" -c <object_id> This allows you attach notes/metadata to a commit, without actually modifying the commit object itself. Transcript note: to attach a new message to <object_id>, use git notes add -m "I hope this message finds you well" <object_id>. The slide’s -c option instead expects an existing note object to reuse; it does not select the commit to annotate.

  138. Slide 138: Notes

    • Notes are another type of reference in git

  139. Slide 139: Notes

    • Notes are another type of reference in git • They’re pretty useless

  140. Slide 140: Notes

    • Notes are another type of reference in git • They’re pretty useless • No one uses them - I haven’t seen a Git client that supports them, either

  141. Slide 141: Notes

    • Notes are another type of reference in git • They’re pretty useless • No one uses them - I haven’t seen a Git client that supports them, either • But why not sneak note objects into your git database?

  142. Slide 142: Notes

    • Notes are another type of reference in git • They’re pretty useless • No one uses them - I haven’t seen a Git client that supports them, either • But why not sneak note objects into your git database? • Homework: Can you push them to a remote?

  143. Slide 143: Where to learn more?

    • Inside the .git folder - Benjamin Kadel • A Git story: Not so fun this time - Brachiosoft Blog • Visual Cheatsheet • Official Documentation

  144. Slide 144: Any questions?

    Any questions?