git cat-file -p <oid> print any objectgit rev-parse HEAD resolve ref to OIDgit reflog find lost commitsgit for-each-ref list all refsgit fsck --lost-found recover dangling objectsgit push origin HEAD:branch move a remote refThe Immutable Object Model
Git is a content-addressable store: four object types keyed by the SHA-1/SHA-256 hash of their contents. Identical content yields identical OIDs; changing anything mints a new object.
| Object | Contains | Points to |
|---|---|---|
blob | raw file bytes (no name) | nothing |
tree | names, modes, OIDs | blobs & subtrees |
commit | tree, parents, author, message | one tree + parent commits |
tag | target OID, tagger, message | any object (annotated tags) |
Plumbing Beneath the Porcelain
git hash-object -w filegit cat-file -t|-s|-p <oid>git update-index --add filegit write-treegit commit-tree <tree> -p <parent>git commit.git update-ref refs/heads/x <oid>commit ≈ write-tree → commit-tree → update-ref. Knowing this makes recovery and scripting trivial.Refs, HEAD & Reflogs
Ref anatomy
Refs are files under .git/refs/ (or packed in packed-refs) holding an OID. HEAD is a symbolic ref pointing at the current branch; detached HEAD points straight at a commit.
The reflog
Every ref movement is logged locally in .git/logs/. HEAD@{2} or main@{yesterday} reaches prior positions — your undo history and primary recovery tool.
git symbolic-ref HEADgit for-each-ref --sort=-committerdategit reflog expire --expire=now --allgit pack-refs --allpacked-refs.Working Tree, Index & State Movement
Three trees: the working tree (files on disk), the index (staging area), and HEAD (last commit). Commands differ in which they touch.
| Command | Moves HEAD | Touches index / worktree |
|---|---|---|
git reset --soft | yes | neither |
git reset --mixed | yes | index only (default) |
git reset --hard | yes | index + worktree |
git restore --staged f | no | index only |
git restore f | no | worktree only |
git switch <branch> | moves HEAD ref | updates worktree |
git switch -c featurecheckout -b).git stash push -m "wip"refs/stash.git clean -fdxreset --hard and clean destroy uncommitted work that was never an object — the reflog cannot save what was never committed.Revision Selection, Pathspecs & Attributes
HEAD~3 / HEAD^2main..featuremain...feature--left-right shows sides.:(exclude)*.test.js.gitignore / .gitattributesgit check-ignore -v fileIntegration: Merge, Rebase & Conflicts
Integration is separate from transport — these only rearrange the local DAG. Rewriting always mints new commits; originals linger until gc