Skip to main content
Early access — new tools and guides added regularly
🟢 Zero to Claude Code — Guide 8 of 9
View track
>_ claude codeBeginner30 min

Git Fundamentals for AI-Assisted Development

Master Git from init to merge conflict resolution. Learn the version control skills that make AI-assisted development safe and reversible.

What you will build
A Git-tracked project with branches, merges, and the ability to undo any AI-generated change

Why Git is non-negotiable for AI-assisted development

Git is your safety net when working with AI coding tools. Without Git, every change Claude Code makes is permanent. With Git, every change is reversible. This single fact makes Git the most important tool in your AI development workflow — more important than the AI itself. Here is the scenario every AI user encounters: you ask Claude Code to refactor a file, and the result is worse than what you started with. Without Git, you are stuck trying to manually undo the changes, hoping you remember what the original code looked like. With Git, you run `git checkout -- filename.ts` and the file is restored instantly. Or `git stash` to save the changes for later review without losing them. Git also gives you a complete history of your project. Every change, every decision, every experiment is recorded. When you ask Claude Code to add authentication and it works perfectly, that change is preserved as a commit you can reference, share, or revert to. Professional development teams require Git. If you plan to collaborate with developers, contribute to open source, or work on any serious project, Git is mandatory. But even for solo projects, Git is invaluable because it turns every change into a checkpoint you can return to. Install Git from git-scm.com if you have not already. Run `git --version` to confirm. Then configure your identity: `git config --global user.name 'Your Name'` and `git config --global user.email 'your@email.com'`. These appear in your commit history and identify who made each change.

Init, add, and commit: the core loop

Every Git workflow revolves around three commands. First, `git init` creates a new Git repository in your current directory. Run this once when you start a new project: `mkdir my-project && cd my-project && git init`. You will see Initialized empty Git repository. Git is now tracking this folder. Second, `git add` stages files for the next commit. Think of staging as putting files in a box that you are about to ship. `git add index.ts` stages one file. `git add src/` stages everything in the src directory. `git add .` stages everything that has changed. You can be selective — stage only the files you want to commit and leave others for later. Third, `git commit -m 'your message'` saves a snapshot of all staged files. The -m flag lets you write a message describing what changed. Good messages are short and descriptive: Add user authentication, Fix login page redirect bug, Update dependencies to latest versions. Bad messages: stuff, fix, changes. Run `git status` at any time to see the current state: which files are modified, which are staged, and which are untracked. Run `git log` to see your commit history. Run `git log --oneline` for a compact view. The workflow is: make changes, `git add .`, `git commit -m 'description'`, repeat. After every meaningful change Claude Code makes, commit. This creates checkpoints you can return to if anything goes wrong. A good rule of thumb: commit after every successful Claude Code interaction. Small, frequent commits give you fine-grained control over your project history.

Branching: safe experimentation

Branches let you experiment without affecting your working code. The main branch (called main or master) is your stable version. When you want to try something new — a feature, a refactor, an experiment — create a branch. `git branch feature-auth` creates a branch called feature-auth. `git checkout feature-auth` switches to it. Or combine both: `git checkout -b feature-auth` creates and switches in one step. Now every change you make happens on this branch. Your main branch is untouched. If the experiment works, you merge it back. If it fails, you delete the branch and nothing is lost. This is extraordinarily powerful with Claude Code. Say you want Claude Code to try a different approach to your database layer. Create a branch: `git checkout -b try-prisma`. Let Claude Code rebuild the database layer with Prisma. If you like it, merge it. If not, switch back: `git checkout main` and delete the branch: `git branch -d try-prisma`. You can even have Claude Code try multiple approaches on different branches and compare them. Create approach-a, let Claude Code build it, commit. Switch to main and create approach-b, let Claude Code try a different approach, commit. Now compare: `git diff approach-a approach-b` shows exactly how they differ. View all branches with `git branch`. The asterisk shows your current branch. Switch between them freely with `git checkout branch-name`. Each branch is an independent timeline of your project that you can merge or discard at will.

Merging branches

When your experiment succeeds and you want to bring the changes into main, you merge. First, switch to the branch you want to merge into: `git checkout main`. Then merge the feature branch: `git merge feature-auth`. If main has not changed since you created the branch, Git does a fast-forward merge — it simply moves main forward to include your new commits. The result is a clean, linear history. If main has changed (maybe you or Claude Code made other commits on main while you were on the feature branch), Git does a merge commit. This creates a new commit that combines both sets of changes. You will see a message like Merge branch feature-auth into main. In most cases, Git handles this automatically. After merging, delete the feature branch: `git branch -d feature-auth`. It has served its purpose. The commits are now part of main. A practical Claude Code workflow: always create a branch before asking Claude Code to make significant changes. `git checkout -b claude-refactor`, then work with Claude Code. If you like the results, merge into main. If not, `git checkout main && git branch -D claude-refactor` (capital -D forces deletion of unmerged branches). This workflow makes every Claude Code session risk-free. You can be bold in your requests because you know you can always get back to where you started. The branch is disposable and your main branch remains sacred and stable.

Resolving merge conflicts

Merge conflicts happen when two branches modify the same lines of the same file. Git cannot decide which version to keep, so it asks you. When a conflict occurs, `git merge` will output CONFLICT (content): Merge conflict in src/index.ts. Open the file and you will see conflict markers. The <<<<<<< HEAD marker starts your current branch version. The ======= separator divides the two versions. The >>>>>>> feature-branch marker ends the incoming branch version. You need to edit the file to resolve the conflict: keep the version you want, delete the conflict markers, and make sure the code makes sense. Then `git add src/index.ts` to mark it as resolved, and `git commit` to complete the merge. Here is where Claude Code shines. Instead of manually resolving conflicts, tell Claude Code: We have a merge conflict in src/index.ts. The HEAD version uses the old API structure and the feature branch uses the new one. Resolve the conflict by keeping the new API structure but preserving the error handling from the old version. Claude Code reads the conflict markers, understands both versions, and produces a clean resolution. This is one of the most valuable Claude Code use cases — merge conflict resolution that would take a developer 20 minutes of careful reading takes Claude Code 30 seconds. To practice, intentionally create a conflict: make a branch, change line 5 of a file, commit. Switch to main, change the same line 5 differently, commit. Now `git merge branch-name` and see the conflict. Resolve it manually first to understand the process, then try it with Claude Code to see the difference.

Remote repositories: push, pull, and clone

So far, everything has been local on your machine only. Remote repositories store your code on a server like GitHub, GitLab, or Bitbucket. This gives you backup, collaboration, and deployment capabilities. Create a repository on GitHub by going to github.com and clicking New Repository. GitHub shows you the commands to connect your local project: `git remote add origin https://github.com/username/repo-name.git` links your local repo to GitHub. `git push -u origin main` uploads your commits. The -u flag sets up tracking so future pushes just need `git push`. After the first push, the cycle is: make changes locally, commit, `git push`. Your code appears on GitHub within seconds. To download a project from GitHub: `git clone https://github.com/username/repo-name.git`. This creates a local copy with the full Git history. Clone is how you download open source projects, starter templates, and team codebases. When working with others or on multiple machines, `git pull` downloads changes from the remote: `git pull origin main`. Always pull before you start working to make sure you have the latest version. The complete remote workflow: `git pull` to get latest, make changes, `git add .`, `git commit -m 'message'`, `git push` to share your changes. If git push is rejected, it means someone else pushed changes you do not have. Run `git pull` first, resolve any conflicts, then push again. For Claude Code projects, pushing to GitHub gives you free backup and a way to share your projects. Over time, your GitHub profile becomes a portfolio of everything you have built.

The Git safety toolkit: stash, reset, and reflog

These commands are your emergency tools. `git stash` saves your uncommitted changes and reverts your working directory to the last commit. It is like putting your current work in a drawer. `git stash pop` brings the changes back. Use stash when Claude Code is mid-way through changes and you need to switch branches: `git stash`, switch branches, do what you need, switch back, `git stash pop`. The `git reset` command comes in three flavours. `git reset --soft HEAD~1` undoes the last commit but keeps the changes staged — as if you had not committed yet. `git reset --mixed HEAD~1`, which is the default, undoes the last commit and unstages the changes — the changes are still in your files but not staged. `git reset --hard HEAD~1` undoes the last commit and deletes the changes entirely. Use --hard with extreme caution. The command `git checkout -- filename.ts` discards all uncommitted changes to a specific file, restoring it to the last committed version. This is your single-file undo button. `git reflog` is the ultimate safety net. It shows every change to your repository HEAD pointer, including commits that were apparently lost by reset or branch deletion. If you accidentally delete a branch or reset too far, `git reflog` shows you the commit hash you need to recover. Run `git checkout commit-hash` to get back. Nothing is truly lost in Git until it is garbage collected, which takes weeks. These tools mean you can work fearlessly with Claude Code. Let it make bold changes knowing you can always recover.

Git workflow for Claude Code sessions

Here is the recommended Git workflow for every Claude Code session. Before starting: run `git status` to confirm you are on the right branch with a clean working directory. If there are uncommitted changes, commit or stash them. Create a branch for the session: `git checkout -b claude-add-auth` using a descriptive name. Start Claude Code and work on your task. Commit frequently during the session: after each successful Claude Code interaction, run `git add . && git commit -m 'description of what Claude Code just did'`. This creates fine-grained checkpoints. If Claude Code makes a change you do not like, `git checkout -- .` reverts all uncommitted changes. If you committed and want to go back further, `git reset --soft HEAD~1` undoes the last commit. When the session is complete and you are happy with the results: `git checkout main && git merge claude-add-auth`. Delete the branch: `git branch -d claude-add-auth`. Push to remote: `git push`. This workflow gives you maximum safety and flexibility. Each Claude Code interaction is a separate commit, so you can cherry-pick the good changes and revert the bad ones. The branch keeps your main branch stable until you are satisfied. And the commit messages create a readable history of what you asked Claude Code to do. Over time, this history becomes a valuable reference — you can look back at what prompts worked well and what approaches Claude Code took for similar problems. The five-minute investment in proper Git workflow saves hours of frustration when something goes wrong.

Related Lesson

Your Development Environment

This guide is hands-on and practical. The full curriculum covers the conceptual foundations in depth with structured lessons and quizzes.

Go to lesson