Skip to content

Instantly share code, notes, and snippets.

@raphaelmerx
Created November 1, 2016 05:11
Show Gist options
  • Save raphaelmerx/e5957a2b4862db797b1892b0794a4b59 to your computer and use it in GitHub Desktop.
Save raphaelmerx/e5957a2b4862db797b1892b0794a4b59 to your computer and use it in GitHub Desktop.

Follows https://codewords.recurse.com/issues/two/git-from-the-inside-out

  • Adding a file will hash its content, and add a file in the objects directory to track it. The object content is just a compressed version of the file contents. The first two letters of the file content become the directory that the object is stored in, and the rest of the hash is the object file name.
  • Each object is a full snapshot of the file content. It does not represent a diff. Because the file name and location are not stored in the blobs, two identical files will point to the same blob.
  • When there are too many loose objects, git packs them into the pack folder that can store diffs instead of full file contents.
  • When commiting, git creates a snapshot of the current blobs and trees. trees are used to track directories, and point to blobs or other trees. Files are represented by blobs.
  • A commit is also an object, that points to the tree for the root directory: https://codewords.recurse.com/images/two/git-from-the-inside-out/2-a1-commit.png
  • working copy is the current files in the directory. index is the files hashed in the .git repository, HEAD is what has been committed.
  • HEAD and master are both refs. They can be followed until you reach a tree. For example: HEAD -> master -> first commit.
  • Detached HEAD state: instead of having HEAD -> branch-name -> commit, you have directly HEAD -> commit.
  • When adding a second commit, if a file was unchanged, the tree of the second commit points to the same object for that file as the first commit.
  • objects is immutable. All content ever added will be stored in the objects directory, even if no commit points to it.
  • Fast-forward merge: when the current commit is an ancestor of the giver commit. The merge is as simple as moving the branch ref to the giver commit. For example, when master points to a2 and deputy points to a3, git merge deputy from master with move master to a3
  • A merge commit is a commit with two parents.
  • merge strategy when both master and deputy has changed:
    • Find the common ancestor for the master and deputy branches.
    • Compare master with the base, and deputy with the base. Deduce the changes that master and deputy made.
    • If no conflicting changes, apply both changes to the working tree.
    • Then apply the changes to the index.
    • Then commit the index.
  • origin is just an alias for "the repository that lives at URL x". You can do git add bravo ../bravo to set up a bravo repository that lives in another directory and is fetched with git fetch bravo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment