Learning objectives
By the end you can:
- State, in one sentence and then in mechanism, what Git fundamentally stores (whole-tree snapshots, named by the content's own hash, not diffs against a previous version) and explain why that single design choice makes branching, history, and integrity checking cheap.
- Describe the three trees (working directory, staging area/index, repository) and say exactly what
git add,git commit,git status, andgit diffeach do to move content between them. - Explain a branch as nothing more than a movable pointer to a commit (never a copy of the files), and use that fact to predict whether a given
git mergewill be a silent fast-forward or require a true three-way merge. - Read, resolve, and correctly finish a real merge conflict, interpreting
<<<<<<</=======/>>>>>>>markers, choosing the right resolution, and completing the merge. - Contrast rebase and merge (what each does to commit history and to commit hashes) and state, and justify, the golden rule of rebasing.
- Distinguish
git reset(--soft/--mixed/--hard),git restore/checkout, andgit revert, and choose the safe option for a shared branch versus your own private work. - Use
git reflogas the practical safety net for "I just did something terrible," and explain why almost nothing in Git is immediately, permanently gone. - Drive the standard remote/collaboration workflow (clone, branch, commit, push, open a pull request, address review, merge) and distinguish
fetchfrompullfrompush. - Write a
.gitignorethat correctly keeps secrets, data dumps, and build artifacts out of history, and explain why removing a secret later does not erase it from a repository's past. - (Productivity objective: R10 duality.) Use an AI assistant to draft commit messages, explain a diff, or propose a fix for a confusing Git error or conflict, while never running an AI-suggested command, especially a destructive one, that you cannot first explain yourself.
Prerequisites & connections
Builds on. CS2.01 (Command Line, Environments & Reproducible Projects). This module assumes the comfort CS2.01 built: a shell prompt, cd/ls, running a small Python script, and (most importantly) why a reproducible project matters in the first place. Git is the other half of that reproducibility story: CS2.01 made your environment reproducible; this module makes your history reproducible. No calculus, no prior computer-science theory, and no finance background are required here, only ordinary comfort typing a command and editing a plain-text file. If you have never touched a terminal, work CS2.01 first; everything below assumes you can open one without hesitation.
Feeds forward. Every module from here on quietly assumes you are keeping your own practice work in a real Git repository, because that habit, once installed, outlasts any single lesson. Two links are load-bearing rather than incidental. CS2.06 (Software Engineering: Testing, Clean Code & AI-Assisted Dev) carries a dedicated unit on reviewing AI-generated code (debugging seeded AI-written code that hallucinates APIs or gets subtly wrong logic past the happy path) and that unit assumes you can create a throwaway branch to try a risky AI-suggested change, inspect it with git diff, and cleanly revert or discard it if it's wrong; without this module's fluency, "just try it on a branch" isn't actually available to you. QD2.04 (Reproducible Research, Deployment & the Quant Stack) builds a scheduled, logged, seeded research pipeline directly on top of the discipline installed here, a pipeline is not reproducible if the code that runs it isn't version-controlled, config-and-all. More loosely, CS2.03 (Databases & SQL) and every DA/QD module assume a learner who commits as a reflex, not an event. Reference this module rather than re-deriving any of it: the Git literacy is taught exactly once, here.
The problem: a folder is not a history
Before Git, "version control" for most people means a folder full of near-duplicate files, distinguished only by increasingly desperate names: model.py, model_new.py, model_new2.py, model_FINAL.py. This scheme fails in four specific, predictable ways, and naming them precisely is worth doing before any tool enters the picture. First, there is no record of intent, a diff between model.py and model_FINAL.py might be one line or two hundred, and nothing tells you why any particular change happened, only that it did. Second, there is no safe experimentation, trying a risky idea means either overwriting the only copy you have or manually duplicating the entire project, and "just try it and see" becomes expensive enough that people stop doing it. Third, there is no combination, if two people (or two future versions of yourself) each build on model_new.py independently, merging their work back together is a manual, error-prone, line-by-line reconciliation with no tool support at all. Fourth, and most quietly costly, there is no trust, with no record of what changed and when, "is this the version I ran last Tuesday's numbers with?" becomes an unanswerable question, which is precisely the failure mode that makes analytical work unauditable.