Here is the uncomfortable version of the pitch. If you are building with an AI tool and you have not set up git, your entire project has exactly one save point: whatever is on disk right now. The next prompt overwrites it. Most of the time the next prompt is fine. Once in a while it deletes half the checkout flow, or rewrites the database rules, or "cleans up" a file that everything depended on, and there is nothing to go back to.

Git fixes that, and you do not need to learn all of git to get the fix. You need four words, five commands, and one habit. This is the written version of the guide from the video, and it covers what the video did not have time for: the exact clicks for each builder, what the builders' own undo buttons do and do not restore, how to break your app on purpose and roll it back, and the two evening rules that cost real money when people skip them.

A timeline of three commits (login works, Stripe checkout, settings screen), then a red box where a prompt to clean up the checkout deleted 312 lines, with a green arrow labelled git restore pointing back to commit 3. Below: without git there is one save point, whatever is on disk now; with git there is a save point at every commit, on your laptop and on GitHub.
The whole idea in one picture. A commit is a save point. A bad prompt only costs you the distance back to the last one.

You can read this top to bottom in fifteen minutes. The "one day" in the title is the doing: morning for the ideas, midday to get your app into a repo, afternoon to practise the loop and a rollback, evening for the rules. Do it on a day when you are not under pressure, because the whole point is that the next time you are under pressure, this is already set up.

Why bother, in one paragraph

Three reasons, in order of how soon they will matter to you. First, git is the undo button for your whole codebase, not just the last edit: every commit is a point you can return to, today or in a year. Second, it is the copy that lives outside the tool. Your Lovable project, your Bolt project, your Cursor folder each hold your app in one place; pushing to GitHub means a copy exists that your builder's outage, your account getting locked, or your laptop dying cannot touch. Third, it is the first thing any engineer you ever hire will ask for. "Send me the repo" is how every real handoff starts. No repo, no handoff, and that is a real part of why quotes to fix a vibe-coded app start with a "discovery" line item.

Before you start: what your builder's undo button actually does

Every AI builder now ships some kind of undo, and this is where people get a false sense of safety. The undo is good. It is also, by the builders' own description, not version control. Here is what each one restores, and where its GitHub switch is. Every line below comes from the tool's own documentation as of August 2026; the links are to the pages.

ToolBuilt-in undoWhat it restoresWhere the GitHub switch isWorth knowing
LovableHistory toggle in the top bar; every change is a version; Revert, plus bookmarksCode only. Lovable's docs: reverting "does not restore or roll back your database data."Project settings → Git → GitHub, or the + menu in the chat. Two-way sync; every change Lovable makes lands as a commit.One repo per project; Lovable edits one branch at a time. Don't delete, transfer, or move the repo to another account once connected. Available on all plans for github.com.
BoltOnce GitHub is connected, Bolt "creates a commit for you" every time you make a change that doesn't break the projectCommits, in your repoGitHub icon, top right → Log in to GitHub. Bolt checks GitHub every 30 seconds and pulls in changes made outside it.Branches are supported in-app; merging is not. Merge on GitHub.
Base44Version history in the editorApp codeDashboard → GitHub icon (top right) → Connect to GitHub. Two-way sync.Requires the Builder plan or higher. Base44's docs: "GitHub sync is permanent. You can't disconnect or transfer the project back to Base44."
v0Chat history; each generation is a versionCodeGit section in the chat sidebar → Connect. v0 handles branches and commits; Publish → Open PR → merge.Optional; you can use v0 without it and export the code instead. Works best with a Vercel project attached.
ReplitAgent checkpoints, "stored in Git", with one-click rollbackProject files, the AI conversation, and connected databases (the only one on this list that includes data)Tools → + → Git → Connect to a Git provider. Stage, commit, and push from the Git pane, no terminal.Replit's own docs still say to "consider using Git commits for long-term version tracking and collaboration."
CursorCheckpoints on each agent turn; Restore Checkpoint buttonThe agent's changes. Cursor's docs: checkpoints are "stored locally and separate from Git. Only use them for undoing Agent changes; use Git for permanent version control."It's a folder on your machine: the terminal, GitHub Desktop, or ask the agent (below).Nothing leaves your laptop until you push.
Claude Code/rewind, or Esc twice; a checkpoint before every promptClaude's own file edits in this session. Not files changed by shell commands (rm, mv), not edits from other sessions, and the docs are explicit: "Not a replacement for version control."Same as Cursor: it's a folder. Ask it in English, or use the terminal.Keeps the 100 most recent checkpoints per session; checkpoints are deleted with the session after 30 days.

Sources: Lovable version history and Lovable GitHub sync, Bolt GitHub, Base44 GitHub, v0 FAQ, Replit version control, Cursor checkpoints, Claude Code checkpointing.

The Claude Code documentation page for Checkpointing. The right-hand table of contents lists Automatic tracking, Rewind and summarize, and under Limitations: Bash command changes not tracked, Subagent edits not restored, External changes not tracked, and Not a replacement for version control.
Claude Code's own checkpointing page. Read the limitations list on the right; the last item is the title of this guide.

So the picture is: builder undo for the last few minutes, git for the whole project, GitHub for the copy that is not inside the tool. Everything below is how to get the second and third.

Morning: the four words

Forget commands for now. If you understand these four words you understand git; the commands are just how you say them to a computer.

Four cards: repo, your project folder with a memory (git init); commit, a save point, a snapshot of every file with a note (git add . then git commit -m); branch, a copy you are allowed to wreck, merged back into main (git switch -c new-feature); push, send your commits to GitHub so they survive your laptop (git push). Below: git is the tool on your computer, GitHub is the website that keeps a copy; and the one rule, commit before you prompt.
Repo, commit, branch, push. Plus the distinction that trips everyone up once: git is the tool, GitHub is the website.
  1. Repo. Your project folder, with a memory. It is the same folder you already have, plus a hidden .git folder inside it that remembers every save. git init turns a folder into a repo. If your builder has GitHub sync, it did this for you.
  2. Commit. A save point. A snapshot of every file in the repo, with a one-line note and a timestamp. You can return to any commit, forever. "Commit" is the whole game; everything else exists to make commits and move between them.
  3. Branch. A copy you are allowed to wreck. main is the branch your users get. When you are about to try something risky, you make a branch, build on it, test it, and merge it back into main when it works. If it doesn't work, you delete the branch and main never knew.
  4. Push. Send your commits from your machine to GitHub. This is the step that makes "my laptop died" and "my builder locked my account" survivable. The copy that is not on your machine is the one that saves you.

And the distinction that trips everyone up exactly once: git is the tool on your computer that makes the save points. GitHub is a website that keeps a copy of them. They are made by different companies. You need both, and GitHub's free plan includes private repositories, so there is no reason your repo has to be public.

The one rule: commit before you prompt. Every big instruction to Claude, Lovable, Bolt, or Cursor gets a save point first. Small, often, boring. You will never regret a commit; you will regret the missing one.

Midday: your first save point, on your tool

The goal for midday is one thing: your app exists as a repo on GitHub, with at least one commit, and you have looked at it there with your own eyes. Pick your tool.

If you build in Lovable

docs.lovable.dev → Git sync · all plans (github.com) · two-way

Open the project, then Project settings → Git → GitHub (or the + menu in the chat). Connect your GitHub account; Lovable creates a repository and, from then on, every change Lovable makes to your project lands in it as a commit. It is two-way: if you (or Claude Code, or an engineer) push a change to the active branch on GitHub, it syncs back into Lovable.

Three things from Lovable's docs worth knowing before you click: each project connects to one repository; Lovable edits and syncs one branch at a time (you can switch or create branches from the picker); and once connected, don't delete the repo, rename your GitHub account or organisation, or transfer the repo to another account, because the connection breaks. Renaming the repo itself is fine.

Lovable's documentation page titled Sync your Lovable project with GitHub, explaining export and two-way sync with github.com, GitHub Enterprise Cloud, or GitHub Enterprise Server for code backup, collaboration, and deployment.
Lovable's GitHub sync page. The important sentence is that it is two-way: changes pushed to the active branch sync back into Lovable.

If you build in Bolt

support.bolt.new → GitHub for version control · auto-commits

Open a project and click the GitHub icon in the top-right corner, then Log in to GitHub and authorise the Bolt app. Bolt's docs: "Every time you make a change that doesn't break the project, Bolt creates a commit for you." It also checks GitHub every thirty seconds for changes made outside Bolt and pulls them in, so you can work in Bolt, then in Cursor, then in Bolt again. You can create and switch branches from the GitHub menu in Bolt; merging happens on GitHub, not in Bolt.

Bolt's help centre page GitHub for version control: connect a GitHub repository to back up your Bolt project, sync commits automatically, and work across branches. Benefits listed: handles Git automatically, keeps branches separate, gives you control.
Bolt's GitHub page. "Handles Git automatically" is accurate, and you should still open the repo on GitHub once to see the commits are really landing.

If you build in Base44 or v0

Base44 GitHub integration · v0 FAQ

Base44: click Dashboard in the app editor, then the GitHub icon at the top right, then Connect to GitHub. Two-way sync, on the Builder plan or higher. Read the warning in their docs before you do it: "GitHub sync is permanent. You can't disconnect or transfer the project back to Base44." For most people that is the right trade (your code now lives somewhere you control), but it is a one-way door.

v0: click the Git section in the chat sidebar, then Connect. v0 handles branching and commits; when you Publish it offers to open a pull request you merge when ready. It is optional, and you can keep exporting code instead, but connecting is the easier path once the app matters.

If you build in Replit

docs.replit.com → Using the Git pane · visual, no terminal

In the Tools section, click + and choose Git. The pane has a Connect to a Git provider option for GitHub, a Review Changes section where you pick files and write a message, a commit button, and a one-click push. Replit's Agent checkpoints are "stored in Git" and their rollback includes the connected database, which makes Replit the most forgiving tool on this list. Their own docs still point you at regular commits for long-term history.

Replit's documentation page Using the Git pane: a visual interface for Git operations, eliminating the need to use command-line Git commands. Features listed: repository management, commit tracking, branch operations, conflict resolution, shell integration.
Replit's Git pane docs. Everything in this guide's command list has a button here.

If you build in Claude Code, Cursor, or any local folder

the terminal, or plain English, or GitHub Desktop

Here there is no sync switch, because the project is a folder on your machine and git is the thing that connects it to GitHub. You have three ways in, and they end in the same place.

A terminal showing git init, git add ., git commit -m first save, then creating a private repo on github.com, git remote add origin, git branch -M main, git push -u origin main. Beside it a mock GitHub repo page showing my-app, Private, 1 commit, the src and supabase folders, .gitignore and package.json, and a note that .env is not there on purpose. Below: or in Claude Code just say: set up git here, add a .gitignore that excludes .env, make the first commit, and push it to a new private GitHub repo.
Midday in six lines, or one sentence to the agent. Either way the check is the same: open the repo on github.com and see "1 commit".
  1. Say it in English. In Claude Code or Cursor's agent, paste: "Set up git in this project. Add a .gitignore for this stack that excludes .env and node_modules. Make the first commit with the message 'first save: app as of today'. Then create a new private GitHub repository called my-app and push to it." Claude Code runs the commands and shows you each one; if it asks you to install or sign in to GitHub's gh tool, say yes and follow the prompt. This is the way we actually do it.
  2. Or type the six lines yourself. Install git first if git --version says it's missing (git-scm.com; on a Mac, typing git offers to install it). Then, inside the project folder:
    # make it a repo and take the first save point
    git init
    git add .
    git commit -m "first save: app as of today"
    # on github.com: New repository → Private → Create. Then connect and push:
    git remote add origin [email protected]:YOUR-NAME/my-app.git
    git branch -M main
    git push -u origin main
    If git push asks you to sign in, GitHub's page for the new repo shows the exact commands for your account, including the HTTPS version if you would rather not set up SSH keys.
  3. Or use GitHub Desktop, and never see a terminal. It is a free app from GitHub with buttons for everything in this guide: add the folder, it becomes a repo; type a message, click Commit; click Publish repository; later, click Push. The History tab is git log with a GUI. If the terminal is the reason you have been putting this off, this is your way in.
The GitHub Desktop homepage: Experience Git without the struggle, a Download now button, and a screenshot of the app with a Changes tab showing three changed files and a diff.
GitHub Desktop. Commit, push, branch, and history as buttons. Free, Mac and Windows.

How to check it worked

Open the repository on github.com. You should see your project's files and a commit count ("1 commit", or many if your builder has been syncing). Click the count to see the list; that list is your history. Two things to look for right now: your .env file should not be in the file list (if it is, go straight to the evening section before you do anything else), and the repository should say Private next to its name unless you chose otherwise.

Afternoon: the loop, then break it on purpose

Now the habit. This is the part the builders with GitHub sync do for you automatically, and the part you do by hand (or by sentence) in Claude Code and Cursor. Either way, know what it is, because it is the shape of every professional software team's day.

A diagram with a main branch line (live today, merge, deploy) and a feature branch called add-stripe splitting off below it with three nodes (prompt, check, commit; prompt, check, commit; push, open a pull request) before merging back into main. Below: the loop in English for Claude Code or Cursor: make a branch called add-stripe, build, commit this as add Stripe checkout, push and open a pull request, merge on GitHub.
The loop. main is what your users get; the branch is where you are allowed to be wrong.
  1. Branch before anything risky. git switch -c add-stripe, or "make a branch called add-stripe". Small copy fixes can go straight on main; anything you would be nervous to show a user goes on a branch.
  2. Prompt, check, commit. Give the agent the instruction. Look at the result in the app, not just in the chat. If it works, git add . && git commit -m "add Stripe checkout", or "commit this as 'add Stripe checkout'". Then the next prompt. The commit message is the note you would want to read tomorrow, so "fix" is a bad one and "stop the cart total going negative on refunds" is a good one.
  3. Push often. git push, or "push". Pushing after every commit is fine. Pushing once a day is the minimum.
  4. Merge when it works. Open a pull request on GitHub (the green button that appears after you push a branch), look at the diff once as a human, and merge it into main. If your host deploys from main, that merge is your release. Builder users: Lovable edits one branch at a time, so for most solo builders the honest version is "stay on main, but commit before every prompt"; Bolt and v0 let you branch in-app and merge on GitHub.

Break it on purpose

This is the one exercise in the guide, and the reason the day works. Until you have watched something disappear and then come back, you will not trust the undo button, and not trusting it is what makes people afraid of the prompt box. So: on a branch, with everything committed, tell your agent to do something destructive on purpose. "Delete the settings screen." Watch it go. Then bring it back.

Two terminals. Left, not committed yet: a prompt to clean up the checkout screen deletes Checkout.tsx and stripe.ts; git status shows both as deleted; git restore . brings both back. Right, already committed: git log --oneline lists the save points, git revert on the bad commit undoes it with a new commit, and git checkout with a commit hash and a file path brings back one file from an older save. Each has the English equivalent to say to Claude Code or Cursor.
The two rollbacks you will actually use. Left: you noticed immediately. Right: you noticed later, after it was committed.

If you have not committed yet (you just watched it happen):

git status        # what changed since the last save point?
git diff          # show me exactly what changed, line by line
git restore .     # throw away every uncommitted change. everything is back.

In English, to Claude Code or Cursor: "show me what's changed since the last commit", then "undo everything since the last commit."

If it was already committed (you noticed a day later):

git log --oneline                         # the list of save points, newest first
git revert a91f2c0                        # make a new commit that undoes that one. history stays intact.
git checkout 7d3e1b4 -- src/lib/stripe.ts # bring back just one file from an older save point

In English: "revert the commit called 'clean up checkout'", or "bring back src/lib/stripe.ts from two commits ago."

Notice what is not in that list: git reset --hard. It exists, it is what a lot of tutorials reach for, and it deletes history rather than adding to it. Until you are comfortable, prefer restore for uncommitted changes and revert for committed ones, because neither of them can lose anything. In Lovable, the equivalent of the first case is the History toggle and Revert; for the second case, and for anything that involves the database, keep reading.

The thing that changes after this exercise: you stop treating every prompt as a risk. Fear of the prompt box is what makes people prompt timidly, accept half-working output, and avoid the refactor the app needs. With a save point behind you, the worst a bad prompt can do is cost two seconds.

Evening: the two rules that cost real money

1. Keys live in .env. .env never goes into git.

Two files side by side. .env contains STRIPE_SECRET_KEY=sk_live_, OPENAI_API_KEY=sk-proj-, SUPABASE_SERVICE_ROLE_KEY, RESEND_API_KEY, with a note that anything starting sk_live, sk-, service_role, or SECRET belongs here. .gitignore contains node_modules, dist, .DS_Store, .env (this line), .env.*, and a note to keep .env.example with no values. Below, a red box: a pushed key is public forever; deleting it in the next commit does not help; GitHub's guidance is to revoke or rotate first.
One line in .gitignore is the whole rule. The red box is why.

Every app has secrets: the Stripe secret key, the OpenAI key, the Supabase service-role key, the email provider's key. They go in a file called .env on your machine (and in your host's environment settings in production, which is a dashboard, not a file in the repo). And .env goes in .gitignore, the list of things git pretends not to see. That is it. node_modules, build folders like dist or .next, and .DS_Store go in there too, because they are large and a machine can regenerate them. Keep an .env.example with the key names and no values, so the next person (or the next agent) knows what the app expects.

The reason this is an evening rule and not a footnote: a pushed key is public forever. Deleting it in the next commit does nothing; the old commit is still in the history, still in every clone, and GitHub's own page on removing sensitive data says the data "remains accessible" in forks, in pull requests that reference it, and "directly via their SHA-1 hashes in cached views on GitHub". Their first instruction is not to clean the history; it is that "as a first step you need to revoke and/or rotate that secret," after which rewriting the history "may not be warranted" (GitHub docs). If you ever find sk_live in a commit, rotate the key in Stripe first, then fix the file. This is the same check as the first item in our twenty-minute self audit, for the same reason: a live key in the wrong place is a bill with your name on it.

GitHub's documentation page About push protection: push protection is a secret scanning feature designed to prevent hardcoded credentials, such as secrets or tokens, from ever being pushed to your repository. It blocks pushes from the command line, commits made in the GitHub UI, file uploads, and REST API requests.
GitHub's push protection. Note the scope: on by default for your pushes to public repositories. Your private repo is not covered unless you turn it on in the repository's security settings.

GitHub has a safety net here called push protection: it recognises the shape of known keys and blocks the push with an explanation. Two caveats from their docs. It is on by default for users pushing to public repositories, and off by default for a repository itself, so your private repo gets it only if you enable it in the repository's security settings (do that; it is one toggle). And "anyone with write access to the repository can bypass push protection by specifying a bypass reason," so it is a guardrail, not a wall. The .gitignore line is the wall.

2. main is what your users get. Be slow with it.

If your app deploys from main (Vercel, Netlify, Cloudflare Pages, and most hosts do this by default once connected to GitHub), then every merge into main is a release. Treat it that way. Risky work on a branch, look at the pull request once with human eyes, then merge. The agents are good; the one thing they cannot do is know which of your users is in the middle of a checkout right now. For a more complete version of this, with staging and a tested restore, that is Gate 3 in the production guide.

And the thing git does not cover at all

Four cards. Your code: covered by git; commit often, push, branch for risky work. Your database: not covered; the rows real users created, git never sees them, Lovable's docs say reverting does not restore database data; use scheduled backups and restore one once. Your secrets: not covered; API keys must not be in git so git cannot restore them; .env locally, host settings in production, a password manager. Uploads and settings: not covered; files users uploaded, Stripe dashboard config, DNS, App Store listing; storage backups and written notes. Footer: the July 2025 Replit story is this diagram.
Git is the undo button for your code. It is not the undo button for your app.

Git tracks files in the folder. The rows your real users created live in Supabase, Firebase, Replit's database, or wherever your host put them, and git never sees a single one. Lovable says it plainly: reverting "restores your project's code only" and "does not restore or roll back your database data." The most-told story in this world is exactly this gap: in July 2025 an AI agent deleted a live production database for SaaStr's Jason Lemkin despite an explicit instruction not to change anything, then told him a rollback was impossible (it was not; the data came back), and Replit's CEO called it "unacceptable" and shipped automatic separation of development and production databases in response (Fortune). Git would have restored every line of his code and not one row of his data.

So the evening's last job is to go and find your database's backup setting (Supabase, Firebase, and Replit all have one), turn it on, and, once, restore a backup into a scratch project so you know the restore works. Then the rule that makes the Replit story impossible for you: the AI gets a key to staging, never to the database your users are in. Git makes bad code cheap. Backups and a staging wall make bad data survivable. You want both.

The one-page version

Everything above, as the list you will actually keep open. Left column is what to type; right column is what to say to Claude Code or Cursor if you would rather not.

CommandWhat it doesSay this instead
git initTurns this folder into a repo (once per project)"set up git in this project"
git statusWhat has changed since the last save point"what's changed since the last commit?"
git diffThe changes, line by line"show me the diff"
git add .Pick everything to go into the next save point(part of "commit this")
git commit -m "…"Make the save point, with a note"commit this as 'add Stripe checkout'"
git pushSend your commits to GitHub"push"
git switch -c nameMake a branch and move onto it"make a branch called name"
git switch mainGo back to main"switch back to main"
git log --onelineThe list of save points, newest first"show me the recent commits"
git restore .Throw away every uncommitted change"undo everything since the last commit"
git revert HASHUndo one commit with a new commit (history intact)"revert the commit called '…'"
git checkout HASH -- pathBring back one file from an older save point"bring back path/file from two commits ago"
git pullGet the latest from GitHub (after your builder or a teammate pushed)"pull the latest"
git stash / git stash popPut uncommitted work in a drawer, then take it back out"stash my changes" / "bring my stash back"

And the rules, which are shorter than the commands: commit before you prompt; .env in .gitignore; main is what your users get; git does not back up your database.

Questions people ask

What is the difference between git and GitHub?

Git is the tool on your computer that makes the save points (commits) and lets you go back to them. GitHub is a website that keeps a copy of those save points so they survive your laptop and your builder. You need both. Git without GitHub means your history dies with your machine; GitHub without git is just a folder of files.

My builder already has undo and version history. Do I still need git?

Yes, and the builders say so themselves. Claude Code's docs call checkpoints "not a replacement for version control"; Cursor's say to "use Git for permanent version control"; Lovable's say reverting "restores your project's code only" and "does not restore or roll back your database data". Builder undo is for the last few minutes. Git is for the whole project, on a copy that is not inside the tool, and it is what any engineer you ever hire will ask for first.

Can git restore my database?

No. Git tracks files in your project folder. The rows real users created live in Supabase, Firebase, or your host's database, and git never sees them. For that you need scheduled backups, and you should restore one once so you know the restore works. The July 2025 Replit incident, where an agent deleted a production database, is the cautionary case: git would have brought back every line of code and not one row of data.

I pushed an API key to GitHub. What do I do?

Revoke or rotate the key first, right now, in the provider's dashboard (Stripe, OpenAI, Supabase, Resend). GitHub's own guidance is that once the key is revoked it can no longer be used and rewriting history may not be warranted, because the old commit is still in every clone, in forks, and in GitHub's cached views. Then move the key into .env, add .env to .gitignore, and commit that. Treat the key as copied the moment it was pushed.

Do I have to use the terminal?

No. If you build in Lovable, Bolt, Base44, v0, or Replit, connect GitHub in the builder's settings and it makes the commits for you. If you work in a local folder with Claude Code or Cursor, you can say the git steps in English ("commit this as add Stripe checkout", "undo everything since the last commit") and the agent runs the commands, or use GitHub Desktop, which is a free app with buttons for commit, push, and history. Knowing the five commands still helps, because then you understand what the button or the agent just did.

How often should I commit?

Before every big prompt, and after anything that works. Small, often, boring. A commit costs nothing and a missing commit can cost a day. If you use a builder with GitHub sync, it commits for you on every change; your job is to check the repo on GitHub once so you know it is really there.

What should be in .gitignore?

At minimum: .env and any .env.* file, node_modules, build output folders like dist or .next, and .DS_Store. The rule is that secrets and anything a machine can regenerate stay out. Keep an .env.example with the key names and no values so the next person (or the next agent) knows which keys the app expects.