Git
Git stores snapshots of files and the history connecting them. Branches and tags give names to points in that history.
Objects
A blob stores file contents. A tree records filenames, modes and other trees. A commit points to a tree and its parent commits. An annotated tag adds metadata to an object.
Objects are identified by hashes. Changing a commit or its ancestry changes its hash. git cat-file -p shows an object's contents.
Refs and the index
Branches point to commits. HEAD usually points to the current branch; in detached mode it points directly to a commit.
The index holds the next snapshot to commit. git add updates it; later edits to the same file remain unstaged.
git reflog records local ref updates and can help recover commits after a reset or rebase. Entries expire, so it is not a backup.
Merging
A three-way merge combines two branches using their common ancestor. Conflicts need a manual resolution. merge.conflictStyle = zdiff3 includes the original text in conflict markers, and rerere can reuse earlier resolutions.
Git infers renames from content similarity; it does not store them explicitly.
Rewriting
rebasereplays commits onto a new base. Interactive rebase can reorder, edit or squash them.reset --softmoves the branch;--mixedalso resets the index;--hardalso discards tracked working-tree changes.revertadds a commit undoing an earlier change. Use it when shared history should stay intact.cherry-pickapplies a commit elsewhere.-xrecords its origin.
If a secret was committed, rotate it first. Rewriting history cannot invalidate copies already made.
Finding things
git log -S finds changes in a string's occurrence count; -G searches changed lines with a regex. git blame -w ignores whitespace changes.
git bisect run finds a breaking commit using a test script. See Debugging.
Working with other people
Follow the project's merge and rebase conventions. Coordinate before rewriting a shared branch. --force-with-lease checks the remote ref against your expected value before replacing it.
The everyday workflow
Check git status before switching tasks. git diff shows unstaged changes; git diff --staged shows the snapshot you are about to commit. Stage related changes together and write a message describing the resulting behaviour.
git fetch updates your view of remote branches without merging them into your current branch. Decide whether to merge or rebase after inspecting the history. git pull combines fetching with an integration step determined by your configuration.
Resolving a conflict
Read both versions and the common ancestor. Keep the intended behaviour, remove the conflict markers, then run the relevant checks. Stage the resolved files and continue the operation. Use the operation's --abort command if you need to return to its starting point.
A conflict-free merge can still be wrong. Two changes may disagree about a function's meaning without touching the same lines.
Ignored files and recovery
Ignore generated files, local environments and credentials. Adding a tracked file to .gitignore does not stop tracking it.
Before recovering a lost commit, create a branch pointing to it so it has a durable name. Check uncommitted changes separately: the reflog records ref movements, not every edit to a file.