Must-Know Facts
Every topic's Must-Know Facts table in one place, for a fast revision pass. Tables are pulled in from the topic files, so this page never drifts from them. It grows as each module is added.
Foundations
What Is Git
| Fact | Value | Verify with |
| Type | Distributed VCS: every clone is a full repository with complete history | git log works offline |
| Storage model | Snapshots of the whole tree per commit, not per-file diffs | git cat-file -p HEAD |
| Object id | Content hash (SHA-1, SHA-256 for new repos); identical content, identical id | git hash-object |
| A commit | A tree plus parent(s), author, committer and message | git cat-file -p HEAD |
| The three areas | Working tree, index (staging area), repository | git status |
| Integrity | Every object is checksummed; corruption is detectable | git fsck |
| Local first | Commit, branch, diff and log need no network | any command offline |
| Created | Linus Torvalds, 2005, to host Linux kernel development | history |
Install and Config
| Fact | Value | Verify with |
| System scope | /etc/gitconfig, all users; git config --system | git config --show-scope --list |
| Global scope | ~/.gitconfig, one user; git config --global | git config --global --list |
| Local scope | .git/config, one repository; git config --local | git config --local --list |
| Precedence | Local overrides global overrides system | git config --show-origin <key> |
| Identity | user.name and user.email, stamped into every commit | git config user.email |
| Default branch | init.defaultBranch, main on current Git | git config init.defaultBranch |
| Editor | core.editor, for commit messages and rebases | git config core.editor |
| Alias | git config --global alias.<name> "<command>" | git config --get-regexp alias |
| Per-directory | includeIf "gitdir:~/work/" includes another config file | git config --show-origin user.email |
| Read one value | git config --get <key> | the value |
The Three Trees
| Fact | Value | Verify with |
| Working tree | The files on disk you edit | ls, git status |
| Index (staging area) | The proposed next commit, a full tree of entries | git ls-files -s |
HEAD | A pointer to the last commit on the current branch | git rev-parse HEAD |
git add | Copies working-tree content into the index | git diff --cached |
git commit | Writes the index as a new commit, advances HEAD | git log -1 |
git diff | Working tree vs index (unstaged changes) | git diff |
git diff --cached | Index vs HEAD (staged changes) | git diff --cached |
git restore <file> | Index to working tree (discard unstaged edit) | git status |
git restore --staged | HEAD to index (unstage) | git status |
reset --soft | Moves HEAD only | git status |
reset --mixed | Moves HEAD and index (default) | git status |
reset --hard | Moves HEAD, index and working tree | git status |
Core Workflow
Staging and Committing
| Fact | Value | Verify with |
| Stage a file | git add <path> copies it into the index | git status |
| Stage everything tracked | git add -u (updates and deletions, no new files) | git status |
| Stage all changes | git add -A (or git add . for the current dir) | git status |
| Stage part of a file | git add -p chooses hunks interactively | git diff --cached |
| Commit | git commit -m "<msg>" records the index | git log -1 |
| Commit tracked changes | git commit -am "<msg>" (adds tracked, not new files) | git log -1 |
| Amend last commit | git commit --amend (edit message or add files) | git log -1 |
| Short status codes | Column 1 = index, column 2 = working tree | git status -s |
?? | Untracked; A added; M modified; D deleted | git status -s |
| Empty commit | git commit --allow-empty records no change | git log -1 |
Inspecting History
| Fact | Value | Verify with |
| Compact log | git log --oneline (short SHA plus subject) | git log --oneline |
| Branch shape | git log --oneline --graph --all | git log --graph |
| Custom format | git log --pretty=format:'%h %ad %an %s' --date=short | git log |
| First parent back | HEAD~1 (or HEAD~n for n steps) | git rev-parse HEAD~1 |
| Nth parent | HEAD^2 selects the second parent of a merge | git rev-parse HEAD^2 |
| Log range | A..B = reachable from B, not from A | git log A..B |
| Log symmetric | A...B = commits on either side but not both | git log --left-right A...B |
| Diff two-dot | git diff A..B = tip-to-tip (A versus B) | git diff A..B |
| Diff three-dot | git diff A...B = B against the merge base of A and B | git diff A...B |
| Upstream | @{upstream} (or @{u}) is the tracked remote branch | git log @{u}..HEAD |
| One commit | git show <rev> shows its message and diff | git show HEAD |
| Line authorship | git blame <file> names the last commit per line | git blame <file> |
Ignoring and Attributes
| Fact | Value | Verify with |
| Ignore a path | A pattern line in .gitignore | git status --ignored |
| Directory pattern | Trailing slash, build/, matches a directory | git check-ignore -v build/x |
| Negate | !pattern re-includes a previously ignored path | git check-ignore -v |
| Which rule matched | git check-ignore -v <path> prints file:line:pattern | git check-ignore -v |
| Already tracked | .gitignore never untracks a committed file | git status |
| Untrack, keep on disk | git rm --cached <path> | git status |
| Global ignore | core.excludesFile, for editor and OS files | git config core.excludesFile |
| Attributes file | .gitattributes sets per-path behaviour | git check-attr -a <path> |
| Normalise endings | * text=auto stores LF, checks out native | git check-attr eol <path> |
| Mark binary | *.png binary disables text diff and merge | git check-attr -a <path> |
Undoing Changes
| Fact | Value | Verify with |
| Discard unstaged edit | git restore <file> (index to working tree) | git status |
| Unstage | git restore --staged <file> (HEAD to index) | git status |
| Undo commit, keep staged | git reset --soft HEAD~1 | git status |
| Undo commit, keep unstaged | git reset --mixed HEAD~1 (default) | git status |
| Undo commit, discard all | git reset --hard HEAD~1 (destructive) | git log |
| Undo a pushed commit | git revert <sha> (new inverse commit) | git log |
| File from an old commit | git restore --source=<rev> <file> | git status |
| Remove untracked files | git clean -fd (-n to preview) | git clean -nd |
| Recover after reset | git reflog still names the old tip | git reflog |
| Rule of thumb | revert shares safely; reset rewrites local only | team workflow |
Branching and Merging
Branches
| Fact | Value | Verify with |
| A branch | A file under refs/heads/ holding one 40-character commit SHA | cat .git/refs/heads/main |
HEAD | A pointer to the current branch, or to a commit when detached | cat .git/HEAD |
| Create only | git branch <name> creates without switching | git branch |
| Create and switch | git switch -c <name> (older: git checkout -b) | git branch --show-current |
| Switch | git switch <name> (older: git checkout <name>) | git branch --show-current |
| Previous branch | git switch - returns to the last branch | git branch --show-current |
| Rename | git branch -m <old> <new> | git branch |
| Delete merged | git branch -d <name> refuses if commits are unmerged | git branch |
| Delete forced | git branch -D <name> deletes even unmerged commits | git reflog |
| Upstream | The remote branch a local branch tracks | git branch -vv |
| Set upstream | git push -u origin <name> or git branch --set-upstream-to | git status -sb |
| Default name | init.defaultBranch, main on current Git | git config init.defaultBranch |
Merging
| Fact | Value | Verify with |
| Fast-forward | Possible when the current branch has no commits the other lacks; Git moves the pointer | git merge --ff-only <branch> |
| Three-way merge | Used when both branches advanced; creates a merge commit with two parents | git show --no-patch HEAD |
| Merge base | The common ancestor of the two branch tips | git merge-base A B |
| Default strategy | ort (Ostensibly Recursive's Twin), since Git 2.34 | git merge --no-edit output |
| Force a merge commit | git merge --no-ff <branch> even when fast-forward is possible | git log --graph |
| Squash | git merge --squash <branch> stages the result with no merge parent | git status -s |
| Abort | git merge --abort restores the pre-merge state | git status |
| No-op merge | Already up to date when the branch is already an ancestor | git merge <branch> |
| Parents | First parent is the branch merged into; second is the merged branch | git show --format=%p HEAD |
| Editor | Non-fast-forward merges open a message editor unless --no-edit | git config core.editor |
Rebasing
| Fact | Value | Verify with |
| Rebase | Replays the current branch's commits onto a new base as new commits | git rebase <base> |
| Result | Linear history; every replayed commit gets a new SHA | git log --oneline |
| Merge vs rebase | Merge keeps history and adds a merge commit; rebase rewrites it linearly | git log --graph |
| Golden rule | Never rebase commits others have already pulled | team policy |
--onto | git rebase --onto <newbase> <upstream> <branch> moves a commit range | git log --graph |
| After a conflict | git rebase --continue or git rebase --abort | git status |
| Pull with rebase | git pull --rebase replays local commits on top of fetched ones | git config pull.rebase |
| Interactive | git rebase -i <base> edits, squashes and reorders | git rebase -i HEAD~3 |
| Dirty tree | git rebase --autostash stashes and restores uncommitted work | git config rebase.autoStash |
| After rewriting | A pushed branch needs git push --force-with-lease | git push --force-with-lease |
Interactive Rebase
| Fact | Value | Verify with |
| Start | git rebase -i <base> opens a todo list of the commits after <base> | git rebase -i HEAD~3 |
pick | Keep the commit unchanged | the todo list |
reword ® | Keep the commit, edit its message | the todo list |
edit (e) | Stop at the commit to amend its content | the todo list |
squash (s) | Fold into the previous commit and combine messages | the todo list |
fixup (f) | Fold into the previous commit and discard this message | the todo list |
drop (d) | Remove the commit | the todo list |
| Reorder | Move a todo line to change commit order | the todo list |
| Autosquash | git commit --fixup=<sha> then git rebase -i --autosquash | git config rebase.autoSquash |
| Effect | Every commit from <base> forward gets a new SHA | git log --oneline |
Conflict Resolution
| Fact | Value | Verify with |
| Conflict | Both sides changed the same lines, so Git cannot merge them automatically | git status |
| Markers | <<<<<<< HEAD, =======, >>>>>>> <branch> wrap the two versions | grep -n '^<<<<<<<' <file> |
| Ours | The side above =======; HEAD during a merge | git checkout --ours <file> |
| Theirs | The side below =======; the merged-in branch during a merge | git checkout --theirs <file> |
| Status code | UU means both modified and unmerged | git status -s |
| Index stages | git ls-files -u lists stage 1 base, 2 ours, 3 theirs | git ls-files -u |
| Mark resolved | git add <file> after editing removes the conflict | git status |
| Finish | git commit for a merge, git rebase --continue for a rebase | git log --graph |
| Abort | git merge --abort or git rebase --abort | git status |
| Reuse | git config rerere.enabled true records and replays resolutions | git rerere status |
Cherry-Pick
| Fact | Value | Verify with |
| Cherry-pick | Applies one commit's diff onto the current branch as a new commit | git cherry-pick <sha> |
| New identity | Same change and message, new SHA and committer | git log -1 |
| Record source | -x appends (cherry picked from commit <sha>) | git log -1 --format=%b |
| Range | git cherry-pick A..B copies commits after A through B | git log --oneline |
| Author date | Preserved from the original; committer date is now | git show --format=fuller |
| Apply only | -n (--no-commit) stages the change without committing | git status |
| Conflict | Resolve, git add, then git cherry-pick --continue | git status |
| Abort | git cherry-pick --abort restores the pre-pick state | git status |
| Skip | git cherry-pick --skip drops the current commit in a range | git status |
| Main use | Backporting a fix to a maintenance or release branch | team workflow |
Remotes and Collaboration
Remotes
| Fact | Value | Verify with |
| Remote | A named URL for another repository | git remote -v |
origin | The default name for the clone source | git remote |
| Remote-tracking branch | origin/main, a local cache of the remote's main | git branch -r |
git fetch | Updates remote-tracking refs only; no working change | git branch -r |
git pull | git fetch then integrate (merge or rebase) | git status -sb |
| Add | git remote add <name> <url> | git remote -v |
| Rename | git remote rename <old> <new> | git remote |
| Change URL | git remote set-url <name> <url> | git remote -v |
| Inspect | git remote show <name> | the output |
| Prune stale | git remote prune <name> or git fetch --prune | git branch -r |
| Ahead/behind | git status -sb against the upstream | git status -sb |
Pushing and Pulling
| Fact | Value | Verify with |
| Set upstream | git push -u origin <branch> on the first push | git status -sb |
| Push | git push once an upstream is set | git status -sb |
| Rejected push | Remote moved: ! [rejected] ... (fetch first) | the push output |
| Pull (merge) | git pull (default) fetches then merges | git log --graph |
| Pull (rebase) | git pull --rebase replays local commits on top | git log --oneline |
| Config the default | pull.rebase=true, or pull.ff=only | git config pull.rebase |
| Force (unsafe) | git push --force overwrites whatever is there | remote history |
| Force safely | git push --force-with-lease refuses if the remote moved | the push output |
| Delete remote branch | git push origin --delete <branch> | git branch -r |
| Push tags | git push --tags or git push origin <tag> | git ls-remote --tags |
| Fact | Value | Verify with |
| Lightweight tag | A ref pointing at a commit, no metadata | git cat-file -t <tag> shows commit |
| Annotated tag | Its own object: tagger, date, message | git cat-file -t <tag> shows tag |
| Create lightweight | git tag <name> [<commit>] | git tag |
| Create annotated | git tag -a <name> -m "<msg>" | git show <tag> |
| List | git tag (add -l "<pattern>" to filter) | git tag |
| Describe a build | git describe = nearest annotated tag, distance, SHA | git describe |
| Push one tag | git push origin <tag> | git ls-remote --tags |
| Push all tags | git push --tags | git ls-remote --tags |
| Delete local | git tag -d <name> | git tag |
| Delete remote | git push origin --delete <tag> | git ls-remote --tags |
| Signed tag | git tag -s <name> (GPG or SSH) | git tag -v <name> |
Stashing
| Fact | Value | Verify with |
| Stash changes | git stash push -m "<msg>" | git stash list |
| Include untracked | git stash push -u (or --include-untracked) | git stash show |
| Include ignored too | git stash push -a (--all) | git stash show |
| List | git stash list (entries are stash@{n}) | git stash list |
| Inspect | git stash show -p stash@{0} | the diff |
| Restore and remove | git stash pop | git stash list |
| Restore and keep | git stash apply | git stash list |
| Drop one | git stash drop stash@{n} | git stash list |
| Clear all | git stash clear | git stash list |
| Stash to a branch | git stash branch <name> | git branch |
| Storage | A stash is a commit off refs/stash, not a file | git log -g refs/stash |
Forks and Pull Requests
| Fact | Value | Verify with |
| Fork | A server-side copy of a repo you can push to | the hosting platform |
origin | Your fork (you have push access) | git remote -v |
upstream | The original repository (usually read-only) | git remote -v |
| Add upstream | git remote add upstream <original-url> | git remote -v |
| Sync a fork | git fetch upstream, then update main from upstream/main | git log |
| Fast-forward only | git merge --ff-only upstream/main (no merge commit) | git status -sb |
| Contribute | Branch, push to origin, open a pull request | the platform |
| PR review, CODEOWNERS | Platform features, not Git itself | delivery/github/ |
Keep main clean | Work on branches, never commit to your fork's main | git branch |
Team Workflows
Branching Strategies
| Fact | Value | Verify with |
| Trunk-based | Short-lived branches, merge to main daily | git log --graph |
| GitHub flow | Branch, PR, review, merge to main, deploy | team practice |
| Gitflow | main, develop, feature/*, release/*, hotfix/* | git branch -a |
| Release branch | Stabilise a version while main/develop moves on | git log --graph |
| Hotfix | Branch from main, fix, merge back and forward | git log --graph |
| Short-lived vs long | Short branches minimise divergence and conflicts | conflict frequency |
| Squash merge | Collapse a branch to one commit on main | git log --oneline |
| Feature flags | Ship unfinished work behind a toggle, not a branch | code |
| Protected branch | Server-side rule; main takes no direct pushes | the host |
| Fits CD | Trunk-based; gitflow suits scheduled releases | team goal |
Commit Conventions
| Fact | Value | Verify with |
| Conventional Commit | type(scope): subject | git log --oneline |
| Common types | feat, fix, docs, refactor, test, chore | the convention |
| Subject style | Imperative mood, no trailing period, about 50 chars | git log |
| Body | Blank line, then why and what, wrapped near 72 chars | git show |
| Breaking change | type!: and a BREAKING CHANGE: footer | git show |
| Sign-off | git commit -s adds Signed-off-by: (DCO) | git show -s |
| Trailers | Key: value lines at the end (Co-authored-by, Refs) | git interpret-trailers |
| Atomic commit | One logical change, builds and passes on its own | code review |
| Fix a message | git commit --amend (last) or interactive rebase | git log -1 |
| feat vs fix | Drives minor vs patch version bumps | release tooling |
Code Review with Git
| Fact | Value | Verify with |
| Branch commits | git log <base>..<branch> | git log |
| Net change | git diff <base>...<branch> (three-dot, merge base) | git diff |
| Per-commit review | git log -p <base>..<branch> | git log -p |
| Run it | git switch <branch>, test, git switch - back | git branch |
| Between review rounds | git range-diff <base> <old-tip> <new-tip> | git range-diff |
| range-diff markers | = identical, ! changed, </> only one side | the output |
| Respond to a note | git commit --fixup=<sha> targeting the reviewed commit | git log --oneline |
| Fold fixups | git rebase -i --autosquash <base> | git log |
| Review a PR branch | git fetch origin <branch> then diff and run | git branch -r |
Release and Versioning
| Fact | Value | Verify with |
| Semantic version | MAJOR.MINOR.PATCH, for example 1.4.2 | the tag |
| MAJOR | Incompatible (breaking) change | BREAKING CHANGE commits |
| MINOR | Backward-compatible feature | feat commits |
| PATCH | Backward-compatible fix | fix commits |
| Pre-release | 1.4.0-rc.1, sorts before 1.4.0 | the tag |
| Release tag | Annotated (or signed) tag on the release commit | git show <tag> |
| Changelog input | git log <lasttag>..HEAD | git log |
| Current build | git describe names it from the last tag | git describe |
| Release branch | release/1.4 to stabilise while main moves on | git branch |
| Bump source | The commit types since the last release | release tooling |
History and Recovery
Reflog and Recovery
| Fact | Value | Verify with |
| Reflog | A local log of where HEAD (or a ref) has pointed | git reflog |
| Entry syntax | HEAD@{n} is the position n moves ago | git reflog |
| Per-branch reflog | git reflog show <branch> | git reflog show main |
| Recover after reset | git reset --hard HEAD@{1} (the pre-reset tip) | git log |
ORIG_HEAD | The tip before the last reset, merge or rebase | git rev-parse ORIG_HEAD |
| Recover a commit | git branch <name> <sha> at the lost SHA | git log <name> |
| Deleted branch | git branch -D prints the tip SHA; recreate from it | git reflog |
| Local only | The reflog is per-clone, never pushed or fetched | it stays local |
| Expiry | Unreachable entries expire (default 30/90 days), then gc prunes | git config gc.reflogExpire |
| Last resort | git fsck --lost-found finds dangling commits | git fsck |
Bisect
| Fact | Value | Verify with |
| Purpose | Find the first commit that introduced a regression | git bisect |
| Method | Binary search: about log2(n) tests for n commits | the step counts |
| Start | git bisect start <bad> <good> | Git checks out a midpoint |
| Mark manually | git bisect good / git bisect bad per checkout | the next midpoint |
| Automate | git bisect run <cmd> (exit 0 good, 125 skip, else bad) | the result |
| Skip untestable | git bisect skip (build broken at that commit) | the next midpoint |
| Result | <sha> is the first bad commit | the output |
| Finish | git bisect reset returns to where you started | git status |
| Exit 125 | Reserved: tells run the commit is untestable (skip) | the script |
Rewriting History
| Fact | Value | Verify with |
| Rewrite = new SHAs | A changed commit and all its descendants get new ids | git log --oneline |
| Amend | git commit --amend rewrites the last commit | git log -1 |
| Reset | git reset moves the branch, dropping commits | git reflog |
| Interactive rebase | git rebase -i squashes, reorders, rewords, drops | git log |
| Whole history | git filter-repo rewrites every commit (paths, content) | git log |
| Golden rule | Never rewrite commits others have pulled | team history |
| Safe scope | Local, unpushed commits, or a branch that is yours alone | git log @{u}..HEAD |
| After rewriting a pushed branch | git push --force-with-lease | the push output |
| Old commits survive | In the reflog until gc prunes them | git reflog |
| filter-branch | The old, slow, error-prone tool; prefer filter-repo | Git docs |
Filter-Repo and Secrets
| Fact | Value | Verify with |
| First response | Rotate the secret; assume it is already leaked | the provider |
| Tool | git filter-repo (separate install, not built in) | git filter-repo --version |
| Remove a file | git filter-repo --path <file> --invert-paths | git log -- <file> |
| Scrub a string | git filter-repo --replace-text <rules> | git log -p |
| Replacement rule | secret==>REDACTED per line in the rules file | the file |
| Rewrites everything | Every affected commit gets a new SHA | git log --oneline |
| Old tool | git filter-branch is slow and error-prone; avoid | Git docs |
| Alternative | BFG Repo-Cleaner, fast for blobs and strings | BFG docs |
| After rewrite | Force-push, and every clone must re-clone or reset | team coordination |
| Not a substitute | Rewriting does not un-leak; rotation does | incident process |
Internals
Object Model
| Fact | Value | Verify with |
| Blob | File content, no name or metadata | git cat-file -p <blob> |
| Tree | A directory: names, modes, and blob/tree SHAs | git cat-file -p <tree> |
| Commit | A tree plus parent(s), author, committer, message | git cat-file -p HEAD |
| Tag object | An annotated tag: target, tagger, message | git cat-file -t <tag> |
| Object id | Hash of type + size + content | git hash-object |
| Content addressed | Identical content, identical SHA (dedup) | git ls-tree HEAD |
| Type of an object | git cat-file -t <sha> | git cat-file -t HEAD |
| Size of an object | git cat-file -s <sha> | git cat-file -s HEAD |
| Snapshot | Each commit points at a full tree, not a diff | git cat-file -p HEAD |
| Immutability | Changing content changes the SHA, so a commit is fixed | git hash-object |
Refs and HEAD
| Fact | Value | Verify with |
| Ref | A name pointing at an object, usually a commit | git for-each-ref |
| Branch ref | refs/heads/<name>, a file with one SHA | cat .git/refs/heads/main |
| Tag ref | refs/tags/<name> | git rev-parse <tag> |
| Remote ref | refs/remotes/origin/<name> | git branch -r |
HEAD | A symbolic ref to the current branch | cat .git/HEAD |
Detached HEAD | HEAD holds a raw SHA, not a ref: | cat .git/HEAD |
| Symbolic ref | A ref pointing at another ref | git symbolic-ref HEAD |
| Loose ref | A file under .git/refs/ | ls .git/refs/heads |
| Packed ref | Collected into .git/packed-refs | cat .git/packed-refs |
| Peeled tag | An annotated tag ref dereferenced to its commit | git rev-parse <tag>^{commit} |
How Merge and Rebase Work
| Fact | Value | Verify with |
| Merge base | The common ancestor of two commits | git merge-base A B |
| Three-way merge | Combines base, ours and theirs into one tree | git merge |
| Merge commit | Has two (or more) parents | git cat-file -p <merge> |
| ort strategy | The default merge algorithm since Git 2.34 | git merge -s ort |
| Fast-forward | No merge commit; the ref moves up | git log --graph |
| Rebase | Replays each commit as a patch onto a new base | git rebase <base> |
| Rebase result | New SHAs, one parent each, linear history | git log --oneline |
| Rebase conflict | Per-commit, resolved then --continue | git status |
| Why SHAs change | New parent (and time) means a new commit hash | git log |
| Merge preserves DAG | Rebase rewrites it into a line | git log --graph |
Packfiles and GC
| Fact | Value | Verify with |
| Loose object | One zlib-compressed file under .git/objects/ | git count-objects -v |
| Packfile | Many objects in one delta-compressed .pack | ls .git/objects/pack |
git gc | Packs objects, prunes unreachable, packs refs | git count-objects -v |
| Delta compression | Similar objects stored as diffs against a base | git verify-pack |
| Auto gc | Runs when loose objects pile up (gc.auto) | git config gc.auto |
| Prune window | Unreachable objects kept ~2 weeks by default | git config gc.pruneExpire |
| Integrity check | git fsck verifies objects and connectivity | git fsck |
Hooks
| Fact | Value | Verify with |
| Location | .git/hooks/, one executable per hook name | ls .git/hooks |
| Not committed | .git/ is local, so hooks do not travel with a clone | clone and check |
| Shared hooks | Version a directory and point core.hooksPath at it | git config core.hooksPath |
| Client hooks | pre-commit, commit-msg, pre-push, post-checkout | run locally |
| Server hooks | pre-receive, update, post-receive | run on the remote |
| Exit code | Non-zero from a pre-* hook aborts the action | the hook output |
| Bypass | git commit --no-verify skips pre-commit/commit-msg | the commit succeeds |
| Sample hooks | .sample suffix means disabled; rename to enable | ls .git/hooks |
| pre-commit framework | A tool that manages hooks from a config file | .pre-commit-config.yaml |
| Enforcement | Local hooks are advisory; CI is the real gate | team policy |
Submodules
| Fact | Value | Verify with |
| A submodule is a pointer | The parent stores a commit SHA, not the files | git ls-files --stage <path> |
| Gitlink mode | 160000 marks a submodule entry in the tree | git ls-files --stage |
.gitmodules | Tracked file mapping path to URL | cat .gitmodules |
| Local config | .git/config holds the resolved URL per clone | git config --list |
| Add | git submodule add <url> <path> | git submodule status |
| Clone with them | git clone --recurse-submodules <url> | folder is populated |
| After a plain clone | git submodule update --init --recursive | folder is populated |
| Update to tracked tip | git submodule update --remote | new SHA checked out |
| Pointer move is a commit | The parent must commit the new SHA | git status |
| Remove | git submodule deinit then git rm | .gitmodules updated |
Worktrees
| Fact | Value | Verify with |
| Worktree | An extra checkout sharing one .git object store | git worktree list |
| Add | git worktree add <path> <branch> (-b for a new branch) | git worktree list |
| One branch, one worktree | A branch cannot be checked out in two at once | the error below |
Linked .git | In a linked worktree, .git is a file, not a directory | cat <path>/.git |
| Remove and prune | git worktree remove <path>; prune clears stale entries | git worktree list |
Large Repos
| Fact | Value | Verify with |
| Shallow clone | --depth N fetches only the last N commits | git rev-list --count HEAD |
| Deepen later | git fetch --deepen N adds more history | commit count grows |
| Unshallow | git fetch --unshallow fetches the rest | --is-shallow-repository |
| Partial clone | --filter=blob:none skips blobs until needed | missing-object count |
| Promisor | Absent blobs are fetched on demand from the remote | --missing=print |
| Sparse-checkout | Materialize only chosen paths in the working tree | git sparse-checkout list |
| Cone mode | Directory-based sparse patterns, the default and fast | sparse-checkout set |
| Git LFS | Stores large binaries out of band, a pointer in Git | git lfs ls-files |
| Maintenance | git maintenance start schedules background upkeep | git config maintenance.strategy |
| History is intact | Shallow/partial/sparse limit transfer, not the repo | the remote is complete |
Credentials and Signing
| Fact | Value | Verify with |
| SSH auth | Key pair; public key on the host, private key local | ssh -T git@host |
| HTTPS auth | A token via a credential helper, never a password | git config credential.helper |
| Credential helper | Caches or stores the token so it is not retyped | git config credential.helper |
| macOS helper | osxkeychain, built in | git config credential.helper |
| Windows helper | Git Credential Manager (manager) | git config credential.helper |
| Commit signing | gpg.format selects openpgp, ssh or x509 | git config gpg.format |
| SSH signing | Reuse an SSH key to sign commits (Git 2.34+) | git log --show-signature |
| Sign a commit | -S, or commit.gpgsign true for all | git log --pretty=%G? |
| Verify | Needs allowedSignersFile for SSH signatures | git log --show-signature |
| Signature status | %G? is G (good), B (bad), N (none) | git log --pretty=%G? |