Aller au contenu principal
The zero-to-master on-ramp — Git, the command line, a systems language, and the tooling every engineer uses daily.

Foundations & Tooling

The zero-to-master on-ramp — Git, the command line, a systems language, and the tooling every engineer uses daily.

Git State Explorer

See how Git moves work from edit to commit to branch

This walkthrough makes the three-state model and branching feel concrete. Each step shows how files move through the working tree, the staging area, and the commit history.

Working tree
Staging area
HEAD / branches
Story

Command
Timeline
Legend
  • • Working tree = files you’ve changed locally
  • • Staging area = files prepared for the next commit
  • • Branch pointer = a movable label to a commit

Git & Version Control

Beginner (1/5) ~3–4 hours Working Tree Staging Area Commits Branches Merges Remotes

What Problem Does Version Control Solve?

Every serious engineering project is a collaborative, evolving artifact. Without version control you have three problems:

  • History — you can’t answer “what changed, when, and why?” for any file.
  • Collaboration — two people editing the same file overwrite each other.
  • Safety — a bad change can’t be undone; there is no “revert.”

Git solves all three with a content-addressable store of snapshots plus cheap, decentralized branching. It is the substrate for code review, CI/CD (every pipeline triggers off a push), rollbacks, and incident analysis — the single most transferable tool in this curriculum.

The Three-State Model

Git tracks your work through three states, and each maps to a distinct area:

StateAreaMeaning
ModifiedWorking treeThe file on disk differs from what Git last recorded
StagedIndex (staging area)You’ve marked the change to go into the next commit
CommittedRepository (HEAD)The change is safely stored in Git’s history

The flow is working tree → git add → index → git commit → HEAD. The staging area is Git’s killer feature: it lets you assemble a commit from parts of your changes, so each commit tells one coherent story.

Committing and Inspecting History

git status                 # which files are modified/staged
git diff                   # unstaged changes
git diff --staged          # staged changes
git add <file>             # stage a file (or -p to stage hunks interactively)
git commit -m "feat: add rate limiter"   # snapshot the index
git log --oneline --graph --decorate     # readable history
git show <commit>          # what a specific commit changed

A commit is a snapshot: the content of every tracked file plus metadata (author, message, timestamp) and a pointer to its parent. Because a commit records the full tree (not a diff), Git can jump to any point in history instantly.

Branches Are Cheap Pointers

A branch is just a movable pointer to a commit. Creating one is O(1) — it’s a label, not a copy:

git switch -c feature/login     # create + switch (git checkout -b in older syntax)
git switch main                 # switch back
git merge feature/login         # integrate the branch
git branch -d feature/login     # delete after merging

Merging combines histories. A fast-forward merge just moves the pointer when the branch has no divergent commits; a merge commit is created when two branches have diverged, joining them.

When Git can’t merge a region automatically it leaves conflict markers (<<<<<<<, =======, >>>>>>>) in the file for you to resolve by hand — then git add the resolved file and git commit.

Rewriting History

Sometimes you want to edit commits, not just add new ones:

git commit --amend          # fix the last commit's message or absorb small changes
git rebase -i HEAD~3        # interactive: squash, reorder, reword the last 3 commits
git push --force-with-lease # publish a rewritten branch (use --force-with-lease, never --force)

Rule of thumb: rewriting local, unpushed history is normal and encouraged; rewriting shared history is dangerous because every collaborator’s clone diverges. Only force-push branches you own (topic branches), never main.

Remotes, Push, and Pull

A remote is another copy of the repository — typically a hosted one (GitHub, GitLab) that acts as the team’s source of truth:

git clone <url>                # copy a remote repo locally (sets up 'origin')
git remote -v                  # list remotes
git pull                       # fetch + merge (fetch then merge origin/main into yours)
git push                       # publish your commits
git fetch                      # download objects without merging

git pull is shorthand for git fetch + a merge. On a diverged main, git pull --rebase replays your local commits on top of the fetched ones, producing linear history instead of merge commits — the common trunk-based style.

Collaboration Workflows

  • GitHub Flow — main is always deployable; every change is a feature branch, a pull request, a code review, and a merge. Simple, dominant for web teams.
  • Trunk-based development — everyone commits to main (or short-lived branches) multiple times a day behind feature flags. Enables continuous delivery; popular at scale.
  • Feature branching / Git Flow — long-lived develop/release/hotfix branches; heavier ceremony, mainly legacy or release-train teams.

Which you choose matters less than consistency. Pick one, write good commit messages (type: subject — feat:, fix:, refactor:, docs:, chore:), keep commits focused, and make main your deployable source of truth.

Undoing Mistakes Safely

MistakeSafe fix
Staged the wrong filegit restore --staged <file>
Discard uncommitted editsgit restore <file>
Committed too earlygit commit --amend
Committed to the wrong branchgit switch <branch> then git cherry-pick <commit>
Broke something in historygit revert <commit> (safe, adds an undo commit)
Lost a commit entirelygit reflog → git reset --hard <sha> (recovery net)

git revert is the shared-history-safe undo: it adds a new commit that inverts the bad one, so everyone can pull the fix. git reset moves your branch pointer and is only safe for local, unpublished work.

Practice Trajectory

  1. Initialize a repo, make five commits with git status/git diff/git log between each — watch the three-state model in action.
  2. Create a feature branch, commit three changes, then merge it into main with both a fast-forward and a forced merge commit.
  3. Introduce a conflict deliberately (two branches editing the same line) and resolve it by hand.
  4. Squash three messy commits into one with git rebase -i, then verify history with git log --oneline --graph.
  5. Commit a mistake, git revert it, and explain why revert (not reset) is the right tool for shared history.

When It’s the Right Tool

SituationTakeaway
Learning the toolchainThe three-state model + branching is 90% of daily Git
Solo workEven alone, commits are your undo buffer and documentation
Team collaborationBranch + PR + review keeps main green
Continuous deliveryTrunk-based + small commits + --force-with-lease discipline
Incident responsegit log, git bisect, git revert are first responders