Git: A Comprehensive Overview¶
This is the entry point to a set of git notes. It explains how git works and how the pieces fit together;
the numbered documents go deep on each area and the git-adm tool automates the common flows.
Contents¶
| Doc | Covers |
|---|---|
| 01 · Setup and configuration | Config levels, recommended settings, aliases, credentials, .gitignore, shell prompt |
| 02 · Repositories and remotes | init/clone, bare repos, remotes, forks, fetch/pull/push, sparse checkout, submodules |
| 03 · Everyday workflow | Feature-branch flow, merging, conflicts, staging, commit hygiene, history commands, tags, branching models |
| 04 · Rebase | How rebase works, rules, squashing, --onto, undoing a rebase |
| 05 · Undo, recovery and troubleshooting | reset/revert/restore, reflog, recovering files and commits, common errors, bisect |
| 06 · Stash | Stash operations and when to prefer a WIP commit |
| 07 · Branch management | Create/rename/delete/prune, protection, worktrees, cherry-pick |
| 08 · Hooks | Hook types, shared hooks dir, commit-msg and pre-push examples |
| 09 · Internals | Objects, refs, index, .git layout, gc, plumbing |
| 10 · Resources | Books, interactive tutorials, videos, alternative forges |
1. What git is¶
Git is a distributed version control system. Every clone is a complete repository containing the full history, so almost every operation (commit, branch, log, diff) is local and fast, and you can work offline. A "central" server is a convention, not a requirement: it is just another repository that people agree to push to.
Three ideas explain most of git:
- Snapshots, not diffs. A commit records the full state of the tree. Git computes differences when asked.
- Everything is content-addressed. Objects are named by the hash of their content, so history is tamper-evident and identical content is stored once.
- Branches are cheap pointers. A branch is a 41-byte file naming a commit. Creating one costs nothing, which is why branch-per-change workflows are practical.
Details: Internals.
2. The mental model: four places your work can live¶
Working tree ──git add──▶ Index (staging) ──git commit──▶ Local repo ──git push──▶ Remote
▲ ▲ │ ▲ │
└──────git restore───────────┴─────────git reset / switch──────┘ └─────git fetch───────┘
(git pull = fetch + merge/rebase)
| Place | What it is | Look at it with |
|---|---|---|
| Working tree | Files you edit | git status, git diff |
| Index / staging area | The exact contents of your next commit | git diff --cached |
| Local repository | Commits and refs in .git/ |
git log, git branch |
| Remote | Another repository (origin) |
git fetch, git remote show origin, git branch -r |
Because the index sits between your files and the commit, you can build commits deliberately (git add -p),
committing only part of your changes.
3. The object model in one page¶
- blob — file content. tree — a directory listing pointing to blobs and subtrees. commit — a tree + parent(s) + author/committer + message. tag — a named, optionally signed pointer.
- Commits form a directed acyclic graph (DAG). Each commit points back to its parent(s); a merge has two.
- Refs name commits: branches (
refs/heads/*), remote-tracking branches (refs/remotes/origin/*), tags (refs/tags/*).HEADsays which branch (or commit) you are on. - Rewriting history (amend, rebase, reset) never edits a commit; it creates new commits and moves a ref. The old ones linger until garbage-collected, which is why the reflog can rescue you.
A ── B ── C ── D main
\
E ── F feature (each letter is a commit; arrows point to parents)
4. Life of a change¶
git switch -c PROJ-1234-fix-login # 1. branch from an up-to-date main
$EDITOR src/login.py # 2. edit the working tree
git status # 3. see what changed
git add -p # 4. stage the pieces you want
git commit -m "PROJ-1234 - Fix login redirect" # 5. record a snapshot locally
git fetch origin && git rebase origin/main # 6. replay onto the latest main
git push -u origin HEAD # 7. publish; open a pull/merge request
Then review → merge on the host → delete the branch → git switch main && git pull.
Full walk-through: Everyday workflow.
5. Branching and integrating work¶
Integrating one line of history into another can be done three ways:
| Technique | Command | Resulting history | Use when |
|---|---|---|---|
| Merge | git merge feature |
Preserves both lines; adds a merge commit (or fast-forwards) | Integrating shared/long-lived branches |
| Rebase | git rebase main |
Replays your commits after main; linear; new SHAs |
Updating your own unpublished/private branch |
| Squash | git merge --squash feature / host "Squash and merge" |
All changes become one commit | Feature with noisy history |
| Cherry-pick | git cherry-pick <sha> |
Copies a single commit | Back-porting a fix |
Guidance: merge shared history, rebase private history. Never rebase what others have based work on. Deep dives: Rebase, Branch management.
Team workflows
- Trunk-based — very short branches, integrate to
maindaily, feature flags for unfinished work. - GitHub/GitLab flow — feature branch → PR/MR →
main(deployable). The default recommendation. - Git Flow — long-lived
develop, plusrelease/*andhotfix/*; suits scheduled, versioned releases.
See branching strategies.
6. Working with remotes¶
git fetchdownloads and updates remote-tracking refs; it never changes your branches.git pull= fetch + integrate. Withpull.rebase=trueit rebases your local commits on top of upstream.git pushuploads commits and moves the remote branch; it is refused if it would discard remote commits.- After rewriting pushed history use
--force-with-lease, never plain--force. - A branch's upstream is the remote branch it tracks;
git statusandgit branch -vvshow ahead/behind. - Use SSH keys or a credential helper. Never embed tokens in remote URLs.
More: Repositories and remotes, Setup.
7. Reading history¶
git log --oneline --graph --decorate --all # the shape of the DAG
git log -p -- <path> # a file's history with diffs
git log -S'text' # when did this string appear/disappear?
git blame <file> # who last changed each line
git diff A..B git diff A...B # tip-to-tip vs. since-they-forked
git show <sha> # a single commit
git bisect start / good / bad # binary-search for a regression
8. Undoing things: a decision guide¶
Ask two questions: Is it committed? Is it pushed?
| State | Reach for |
|---|---|
| Uncommitted, want to drop | git restore <file> (stash first if unsure) |
| Staged by mistake | git restore --staged <file> |
| Committed locally, not pushed | git commit --amend, git reset --soft/--mixed HEAD~1, or rebase |
| Pushed / shared | git revert <sha> (adds an undo commit; no history rewrite) |
| "I broke everything" | git reflog then git reset --hard <good-sha> |
| Deleted a branch/commit | git reflog → git switch -c <name> <sha> |
Full table, reset modes and common errors: Undo, recovery and troubleshooting.
Setting work aside without committing: Stash.
9. Habits that prevent most git problems¶
- Start every change on a new branch from an up-to-date
main. - Make small, focused commits with imperative subjects ≤ 50 characters and a ticket key if your team uses one.
git statusandgit diff --cachedbefore every commit.- Fetch/rebase often so conflicts stay small.
- Prefer
--force-with-lease; never force-push shared branches. - Stash or commit before switching branches, rebasing or resetting.
- Enforce conventions with hooks and CI rather than memory.
- Never commit secrets; if you do, rotate them first, clean history second.
- Keep
.gitignorecurrent so build output and editor files stay out. - When something goes wrong, stop and read
git statusandgit reflogbefore typing more commands.
10. Command map¶
| Task | Command | Doc |
|---|---|---|
| Configure git | git config |
01 |
| Ignore files | .gitignore, git check-ignore |
01 |
| Get a repo | git clone, git init |
02 |
| Manage remotes | git remote, fetch, pull, push |
02 |
| Record changes | git add, commit, restore |
03 |
| Inspect | status, log, diff, show, blame |
03 |
| Release marks | git tag |
03 |
| Combine work | merge, rebase, cherry-pick |
03, 04, 07 |
| Undo | reset, revert, reflog, clean |
05 |
| Park work | git stash |
06 |
| Branches | switch, branch, worktree |
07 |
| Automate checks | hooks | 08 |
| Debug history | bisect, fsck, cat-file |
05, 09 |
11. The git-adm tool¶
git-adm wraps these workflows with prompts, dry-run and safety rails (it refuses destructive operations on
main/master, stashes before discarding, uses --force-with-lease, and warns when you are behind the base branch).
Source and usage: git-adm/README.md.
| Task | git-adm command |
|---|---|
| Apply recommended global config | git-adm setup |
| Clone (short names, SSH key, insecure) | git-adm clone |
| Branch create / delete / rename / nuke / prune | git-adm branch … |
| Commit with ticket-key prefix | git-adm commit, amend |
Bump a version file |
git-adm bump |
| Push with squash offer, version check, PR link | git-adm push |
| Rebase onto origin/base (+ explain) | git-adm rebase [--explain] |
| Safe undo of a pushed commit | git-adm revert <sha> |
| Reflog rollback / restore deleted files / fix index | git-adm undo, restore, fix-index |
| Stash | git-adm stash … |
| Throw away local changes safely | git-adm discard |
| Status, log, staged, remotes | git-adm status, log, staged, remote |
| Hooks | git-adm hooks list \| path \| install-commit-msg |
| Plain-English explanations | git-adm explain <topic> |
12. Glossary¶
| Term | Meaning |
|---|---|
| Commit | Immutable snapshot + metadata + parent pointer(s) |
| Branch | Movable pointer to a commit |
| HEAD | The commit/branch you currently have checked out |
| Detached HEAD | HEAD points at a commit directly, not a branch |
| Index / staging area | Proposed contents of the next commit |
| Working tree | Files on disk you edit |
| Remote | A named URL of another repository |
| Upstream | The remote branch a local branch tracks |
| Fast-forward | Moving a branch pointer forward along a straight line; no merge commit |
| Merge commit | A commit with two or more parents |
| Rebase | Replay commits onto a new base, creating new commits |
| Cherry-pick | Apply the change from one commit as a new commit elsewhere |
| Squash | Combine several commits into one |
| Stash | Local shelf for uncommitted changes |
| Reflog | Local log of where refs/HEAD used to point; your undo history |
| Tag | Named pointer to a commit (lightweight) or an annotated object |
| Bare repository | Repo with no working tree, used as a shared server copy |
| Hook | Script git runs at defined points (commit, push, ...) |
| Submodule | A repo pinned at a specific commit inside another repo |
| Worktree | An additional checked-out working directory for the same repo |
| PR / MR | Host feature for reviewing and merging a branch |
| Porcelain / plumbing | User-facing vs low-level commands |
| Packfile | Compressed bundle of objects in .git/objects/pack |