The Object Model (immutable content)

Life as a Git repositoryintermediate · standard · comprehensive | model: claude-opus-4-8 | 2026-06-22
Quick ref
git cat-file -p <oid> inspect any object
git rev-parse HEAD resolve ref to OID
git reflog history of where refs were
git switch -c feat create + move to branch
git restore --staged f unstage a path
git fsck --lost-found find dangling objects
git for-each-ref enumerate all refs

The Object Model (immutable content)

Git stores four object types in a content-addressed store; the SHA-1/SHA-256 of type + length + content is the object ID. Identical content is stored once.

ObjectHoldsReferences
blobRaw file bytes (no name, no mode)nothing
treeDirectory: mode, name, OID rowsblobs & subtrees
commitTree OID, parents, author/committer, messageone tree + parents
tagAnnotated tag: target, tagger, messageany object
git hash-object -w file
Write a blob, print its OID.
git cat-file -t <oid>
Show object type; -s for size, -p to pretty-print.
git write-tree
Snapshot the index into a tree object.
git commit-tree <tree> -p <parent> -m msg
Forge a commit by hand; prints new OID.
Note Commits are a DAG, not a list: history is whatever is reachable backward through parent pointers. Nothing is ever edited in place — "changing" history mints new objects.

Refs, HEAD & Reflogs (mutable pointers)

Refs are mutable names for OIDs living under refs/; HEAD is usually a symbolic ref to the current branch. Moving a ref and copying objects are separate operations.

git update-ref refs/heads/x <oid>
Point a branch at an OID directly (plumbing).
git symbolic-ref HEAD refs/heads/main
Read/set HEAD's target; detach with a raw OID.
git for-each-ref --sort=-committerdate
Scriptable listing of refs with format fields.
git reflog show main
Local log of every value a ref has held.
cat .git/packed-refs
Packed refs file; loose refs override it.
git rev-parse --symbolic-full-name @{u}
Resolve the configured upstream ref.
Tip Reflogs are your safety net: after a bad reset or rebase, git reset --hard HEAD@{1} rewinds to the previous position.

Working Tree · Index · Reset Family

Three states: the working tree (files on disk), the index/staging area (a proposed next tree), and HEAD (the last commit). Most commands move data between these layers.

Staging plumbing

git update-index --add path registers a blob in the index; git ls-files -s dumps index entries with mode and stage.

Porcelain

git add -p stages hunks interactively; git status summarizes the diffs index↔HEAD and worktree↔index.

CommandHEADIndexWorktree
reset --soft <c>moves
reset --mixed <c>movesreset
reset --hard <c>movesresetreset
restore --staged freset
restore freset
git switch <branch>
Change HEAD's branch; safer, narrower than checkout.
git checkout <c> -- path
Legacy multitool: branch switch + file restore.
git clean -fdn
Dry-run remove untracked files/dirs (drop n to act).
git stash push -u -m wip
Shelve worktree+index (incl. untracked) as commits.

Revision Selection & Pathspecs

HEAD~3 / HEAD^2
Nth ancestor by first parent / second parent.
A..B
Reachable from B but not A (commit range).
A...B
Symmetric difference; with log shows both sides.
:/fix typo
Most recent commit whose message matches.
main@{2.days.ago}
Ref value from the reflog at a past time.
':(exclude)*.log'
Negative pathspec to filter out matches.

Attributes & ignores

.gitattributes sets text=auto, diff/merge drivers, filter (e.g. LFS); .gitignore excludes untracked paths, overridden by git add -f.

merge-base

git merge-base A B finds the common ancestor — the pivot for diffs, three-way merges, and rebase "what's new".

Integrate: Merge, Conflic