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 thetree
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
andmaster
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 directlyHEAD
-> 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 theobjects
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 toa3
,git merge deputy
from master with move master toa3
- 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 abravo
repository that lives in another directory and is fetched withgit fetch bravo
.