Git
Git is a distributed version control system. Every developer has a full copy of the repository — history, branches, everything — not just the files. That single design decision is why git works offline, why branching is cheap, and why losing the server does not mean losing the project.
Git does not store diffs. It stores snapshots. Each commit is a complete picture of every tracked file at a moment in time. Diffs are computed on demand by comparing snapshots. This is counterintuitive but it is why git is fast.
The three areas
Understanding git means understanding where your changes live at any moment. There are three places — and most confusion comes from not knowing which one you are in.
git add──▶ index ──git commit──▶ repo
Branch visualiser
A branch is just a pointer to a commit — a 41-byte file containing a commit hash. Creating one costs nothing. Use the buttons to build a history and watch how branches move.
Commands
Git has over 150 commands. In practice, about 15 cover 95% of daily work. Click any command to see what it does.
Merge vs Rebase
Both integrate changes from one branch into another. The difference is in the history they leave behind. Neither is universally better.
Undoing things
Git gives you several ways to undo, each with different consequences. The key variable: has the commit been pushed to a shared remote yet?
# The flow you will use every single day
git status # see what changed
git add . # stage everything
git commit -m "your message" # snapshot it
git push origin main # share it
# The flow when things go wrong
git log --oneline # find the bad commit
git revert <hash> # safe undo (new commit)
git stash # hide WIP temporarily
The golden rule
Never rebase or amend commits that have already been pushed to a branch others are working on. Rebasing rewrites commit hashes — everyone else's local copy will diverge.
# Safe — rewrites only local, unpushed history
git commit --amend
git rebase -i HEAD~3
# Dangerous — only if you are the only one on the branch
git push --force-with-lease # at least checks first
git push --force # nuclear, no checks