Andrew Mercer
on this page

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:

  1. Snapshots, not diffs. A commit records the full state of the tree. Git computes differences when asked.
  2. Everything is content-addressed. Objects are named by the hash of their content, so history is tamper-evident and identical content is stored once.
  3. 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/*). HEAD says 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 main daily, feature flags for unfinished work.
  • GitHub/GitLab flow — feature branch → PR/MR → main (deployable). The default recommendation.
  • Git Flow — long-lived develop, plus release/* and hotfix/*; suits scheduled, versioned releases.

See branching strategies.

6. Working with remotes

  • git fetch downloads and updates remote-tracking refs; it never changes your branches.
  • git pull = fetch + integrate. With pull.rebase=true it rebases your local commits on top of upstream.
  • git push uploads 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 status and git branch -vv show 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

  1. Start every change on a new branch from an up-to-date main.
  2. Make small, focused commits with imperative subjects ≤ 50 characters and a ticket key if your team uses one.
  3. git status and git diff --cached before every commit.
  4. Fetch/rebase often so conflicts stay small.
  5. Prefer --force-with-lease; never force-push shared branches.
  6. Stash or commit before switching branches, rebasing or resetting.
  7. Enforce conventions with hooks and CI rather than memory.
  8. Never commit secrets; if you do, rotate them first, clean history second.
  9. Keep .gitignore current so build output and editor files stay out.
  10. When something goes wrong, stop and read git status and git reflog before 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