Skip to main content
Building with AI (Vibe Coding)

⏱ About 20 min20 XP

Version Control as a Safety Net

AI-assisted development is fast. Prompts generate large amounts of code quickly, and the temptation is to keep the momentum going — generate, paste, run, generate more. Speed without a safety net is how projects reach a state where nothing works and no one knows what changed. Version control is that safety net: a system that records the history of every change to your project so you can understand what changed, when, and why — and undo it if necessary. For AI-assisted builders specifically, version control is not optional infrastructure; it is a core practice.

What Version Control Does

Version control (also called source control) is a system that tracks changes to a set of files over time. The dominant version control system in software development is Git. At a conceptual level, Git does three things: 1. Records snapshots: a commit is a snapshot of all tracked files at a specific moment in time. Each commit has a unique identifier, an author, a timestamp, and a message describing what changed and why. The complete sequence of commits is the history of the project. 2. Enables comparison: at any point, you can compare the current state of any file against any previous commit. This produces a diff — exactly the structured comparison described in Lesson 5. Reviewing what changed between commits is how you understand the current state of the project and how you catch regressions. 3. Enables recovery: if a change introduces a problem you cannot fix quickly, you can revert to a previous commit — restoring the project to a known-good state. This is the safety net: no matter how badly a prompting session goes, if you committed the working state before you started, you can always go back. Commit (definition): a recorded snapshot of the project's files at a specific point in time, with a message describing the change. Commits are the atomic units of version control history. Repository (definition): the database in which version control stores the history of a project — all commits, all branches, all file versions.

Commit Before You Experiment

The single most important version control habit for AI-assisted development is: commit before you make any significant change. A commit before an experiment costs thirty seconds and guarantees you can recover the working state if the experiment fails. Skipping this step is how hours of debugging turn into hours of recovery.

Three version control habits are especially important in AI-assisted projects: 1. Commit working states, not aspirational states. Commit when the project is in a working, coherent state — not in the middle of a change, not after accepting AI output you have not yet reviewed. A commit message like 'add recurring field to expenses table' should describe a change that has been reviewed and confirmed to work. 2. Write descriptive commit messages. A commit message is not a formality; it is documentation. 'Fixed it' is not useful. 'Fix Read route to include recurring field in response; resolves empty array bug for expenses created after 2026-05-01' is useful. When you return to the project after a break, commit messages are how you reconstruct the history of decisions. 3. Use branches for experiments. A branch is a parallel line of development — a copy of the project history on which you can make changes without affecting the main line. When you want to try a significant AI-generated change that you are uncertain about, create a branch, apply the change there, test it, and only merge it into the main line when you are confident it works. If the experiment fails, you delete the branch. The main line is untouched. Branch (definition): a named parallel line of development within a repository, allowing changes to be made and tested independently before being merged into the main project history.

Flashcards — click each card to reveal the answer

Version Control and the AI Build Loop

Version control integrates directly into the build loop described in Lesson 1. The natural points for commits are: After the review phase, when you have confirmed that the generated output is correct: commit the working state before moving to the next loop. Before the generate phase of a significant change: commit the current working state as a checkpoint, so you can revert if the generated code is problematic. After integration: when two components are connected and confirmed to work together, commit that milestone explicitly. The commit message is part of your project documentation. Reading the commit history should tell the story of the project's development: what was built, in what order, why decisions were made. For a project built with AI assistance, commit messages also provide a record of which parts of the codebase were AI-generated and which were manually written — useful information if you later need to audit or refactor a section.

Commit Messages Are Project Memory

When a project has hundreds of commits, the commit history is how you reconstruct why the code looks the way it does. A message like 'switch from string amount to numeric to fix front-end rendering; API returns number not string as of this commit' preserves a decision that would otherwise require reading hundreds of lines of code to rediscover. Invest in descriptive messages — your future self will be grateful.

A developer accepts a large AI-generated change and discovers it broke three features. They have no version control. What is the most likely outcome?

Why should you commit before making a significant change, not only after confirming it works?

Commit History Analysis

  1. Below is a fictional commit history for the expense tracker project. Read each commit message and answer the questions that follow.
  2. Commit A (oldest): 'Initial project structure — Express server, PostgreSQL connection, empty routes file'
  3. Commit B: 'Add expenses table schema with id, amount, category, date, note columns'
  4. Commit C: 'Add POST /expenses route with server-side validation for amount and category'
  5. Commit D: 'Add GET /expenses route returning all records for current month'
  6. Commit E: 'Fix GET /expenses — was returning all records regardless of month filter'
  7. Commit F: 'Add recurring boolean column to expenses table; update POST and GET routes'
  8. Commit G: 'WIP front-end'
  9. Commit H: 'Fix stuff'
  10. Questions:
  11. 1. Which commit introduced a bug? How do you know?
  12. 2. Which commits represent good commit messages? What makes them good?
  13. 3. Which commits represent poor commit messages? What is missing?
  14. 4. If you discovered that the recurring feature (commit F) broke the category summary, what commit would you revert to in order to get back to a working state?
  15. 5. Rewrite commit G and commit H as descriptive commit messages (invent plausible content for each).