Git is the version control system that powers almost every software project on the planet. Whether you are writing code alone or collaborating with a team of 500 engineers, Git tracks every change you make, lets you travel back in time, and keeps parallel workstreams from colliding.
This guide starts from absolute zero. By the end, you will understand every common Git command, know how to install and use the GitHub CLI, and learn how AI tools like Claude Code and Cursor can run Git for you — with explanations at five levels of depth.
What Is Git and Why Should You Care?
Before typing a single command, understand what Git is solving.
When you write code without Git:
- You manually duplicate folders:
project-v1/,project-final/,project-FINAL-final/ - You overwrite something and can’t get it back
- Two people edit the same file and one person’s work disappears
- You can’t remember what changed between yesterday and today
Git solves all of this. It is a distributed version control system — every developer has the full history of the project on their machine. There is no single point of failure.
Your machine Teammate's machine GitHub (remote)
───────────── ────────────────── ───────────────
Full history ←──→ Full history ←──→ Full history
Every “save point” in Git is called a commit. Commits form a chain (a graph) called the repository history.
Part 1: Installing Git
macOS
# Option 1: Xcode Command Line Tools (simplest)
xcode-select --install
# Option 2: Homebrew (recommended for developers)
brew install git
Linux (Debian/Ubuntu)
sudo apt update && sudo apt install git
Linux (Fedora/RHEL)
sudo dnf install git
Windows
Download the installer from git-scm.com. During installation, select “Git Bash” and “Use Git from the Windows Command Prompt.”
Verify installation
git --version
# git version 2.44.0
Part 2: First-Time Setup
Before your first commit, tell Git who you are. This information is attached to every commit you make.
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Set your default branch name to 'main' (modern standard)
git config --global init.defaultBranch main
# Set VS Code as the default editor (optional)
git config --global core.editor "code --wait"
Check everything is set correctly:
git config --list
Part 3: Core Git Commands — The Daily Workflow
These are the commands you will use every single day. Learn them first.
Starting a repository
# Create a new Git repo in the current folder
git init
# Clone an existing repo from GitHub
git clone https://github.com/username/repo-name.git
# Clone into a specific folder name
git clone https://github.com/username/repo-name.git my-project
Checking status
# See what has changed since your last commit
git status
# See a compact version
git status -s
Output explained:
On branch main
Changes not staged for commit:
modified: src/index.js ← file changed, not yet staged
Untracked files:
notes.txt ← new file, Git doesn't know about it yet
The staging area (index)
Git has a two-step save process. First you stage changes (choose what to include), then you commit them (create the snapshot).
Working directory → Staging area → Repository history
(edit files) (git add) (git commit)
# Stage a specific file
git add filename.txt
# Stage all changes in the current directory
git add .
# Stage parts of a file interactively (powerful)
git add -p filename.txt
# Unstage a file (keep changes, just remove from staging)
git restore --staged filename.txt
Making commits
# Commit staged changes with a message
git commit -m "feat: add login form validation"
# Stage all tracked files AND commit in one step
git commit -am "fix: correct typo in header"
# Open your editor to write a detailed commit message
git commit
Viewing history
# Full commit history
git log
# Compact one-line format
git log --oneline
# Visual branch graph
git log --oneline --graph --all
# Show changes introduced by each commit
git log -p
# Limit to last 5 commits
git log -5 --oneline
Seeing differences
# Changes in working directory (not yet staged)
git diff
# Changes that ARE staged (ready to commit)
git diff --staged
# Diff between two commits
git diff abc1234 def5678
# Diff between two branches
git diff main feature/login
Undoing things
# Discard changes to a file (restore to last commit)
git restore filename.txt
# Unstage a file
git restore --staged filename.txt
# Undo the last commit but keep the changes staged
git reset --soft HEAD~1
# Undo the last commit and unstage everything (keep file changes)
git reset HEAD~1
# Create a new commit that reverses a previous one (safe for shared repos)
git revert abc1234
Warning:
git reset --harddiscards all uncommitted changes permanently. Use with caution.
Part 4: Branching and Merging
Branches let you work on features or fixes in isolation without touching the main codebase.
main: A ── B ── C ────────────── G
\ /
feature: D ── E ── F ──
Branch basics
# List all branches
git branch
# List all branches including remote ones
git branch -a
# Create a new branch
git branch feature/user-auth
# Switch to a branch
git switch feature/user-auth
# Create AND switch in one command (modern syntax)
git switch -c feature/user-auth
# Old syntax (still works everywhere)
git checkout -b feature/user-auth
# Delete a branch (after merging)
git branch -d feature/user-auth
# Force delete (even if not merged)
git branch -D feature/user-auth
# Rename current branch
git branch -m new-branch-name
Merging
# Switch to the branch you want to merge INTO
git switch main
# Merge the feature branch into main
git merge feature/user-auth
# Merge with a commit message (no fast-forward)
git merge --no-ff feature/user-auth -m "Merge feature/user-auth into main"
Resolving merge conflicts
When two branches change the same line, Git marks the conflict:
<<<<<<< HEAD
const greeting = "Hello";
=======
const greeting = "Hi there";
>>>>>>> feature/user-auth
You manually edit the file to the desired result, remove the markers, then:
git add filename.js
git commit -m "resolve merge conflict in greeting"
Rebasing (advanced alternative to merge)
# Replay your branch commits on top of main (linear history)
git switch feature/user-auth
git rebase main
# Interactive rebase — squash, reorder, or edit last 3 commits
git rebase -i HEAD~3
Part 5: Working with Remote Repositories
A remote is a version of your repo hosted on a server (GitHub, GitLab, Bitbucket, etc.).
# Show configured remotes
git remote -v
# Add a remote (typically done automatically by git clone)
git remote add origin https://github.com/username/repo.git
# Push your branch to the remote (first time)
git push -u origin main
# Push subsequent times
git push
# Pull (fetch + merge) latest changes from remote
git pull
# Fetch without merging (inspect before integrating)
git fetch origin
# Push a new branch to remote
git push -u origin feature/user-auth
# Delete a remote branch
git push origin --delete feature/user-auth
The push/pull flow for a team
1. git pull ← get latest changes from teammates
2. (write code)
3. git add .
4. git commit -m "..."
5. git push ← share your work
Part 6: Stashing
Stash temporarily shelves work-in-progress so you can switch contexts.
# Save current changes to the stash
git stash
# Save with a descriptive label
git stash push -m "half-finished login form"
# List all stashes
git stash list
# Apply the most recent stash (keep it in stash list)
git stash apply
# Apply AND remove from stash list
git stash pop
# Apply a specific stash
git stash apply stash@{2}
# Delete a stash
git stash drop stash@{0}
# Clear all stashes
git stash clear
Part 7: Tags
Tags mark specific points in history — typically release versions.
# Create a lightweight tag
git tag v1.0.0
# Create an annotated tag (recommended — includes message)
git tag -a v1.0.0 -m "First stable release"
# List all tags
git tag
# Push tags to remote (they don't push automatically)
git push origin --tags
# Push a single tag
git push origin v1.0.0
# Delete a local tag
git tag -d v1.0.0
# Delete a remote tag
git push origin --delete v1.0.0
Part 8: Useful Everyday Commands
# See who last changed each line in a file
git blame filename.js
# Search commit history for a string
git log -S "functionName" --oneline
# Find which commit introduced a bug (binary search)
git bisect start
git bisect bad # current commit is broken
git bisect good v1.0.0 # this tag was working
# Git checks out midpoints — you test and mark good/bad
git bisect good # or: git bisect bad
git bisect reset # when done
# Show details of a specific commit
git show abc1234
# Clean untracked files (dry run first)
git clean -n
git clean -fd
# See a file as it was at a specific commit
git show abc1234:src/index.js
Part 9: Installing and Using GitHub CLI (gh)
The GitHub CLI (gh) lets you manage pull requests, issues, and repos from your terminal — no browser needed.
Installation
macOS:
brew install gh
Linux (Debian/Ubuntu):
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update && sudo apt install gh
Linux (Fedora/RHEL):
sudo dnf install gh
Windows:
winget install --id GitHub.cli
# or
choco install gh
Verify:
gh --version
Authentication
gh auth login
# Follow the prompts:
# → GitHub.com
# → HTTPS
# → Login with a web browser
# → Paste the one-time code shown in your terminal
Core gh commands
# Create a new repository
gh repo create my-project --public --clone
# Clone a repo (shorthand)
gh repo clone username/repo-name
# View repo in browser
gh repo view --web
# Create a pull request
gh pr create --title "Add login form" --body "Implements #42"
# Create PR with interactive prompt
gh pr create
# List open pull requests
gh pr list
# Review and checkout a PR
gh pr checkout 42
# Merge a PR
gh pr merge 42 --squash
# Create an issue
gh issue create --title "Bug: login crashes on mobile" --body "Steps to reproduce..."
# List issues
gh issue list
# Close an issue
gh issue close 42
# View CI/CD status for current branch
gh run list
gh run view
# Open a PR in the browser
gh pr view --web
gh workflow example
# 1. Start work on a feature
git switch -c feature/dark-mode
# 2. Write code and commit
git add .
git commit -m "feat: add dark mode toggle"
# 3. Push to remote
git push -u origin feature/dark-mode
# 4. Create PR without leaving the terminal
gh pr create --title "feat: add dark mode toggle" --body "Closes #88"
# 5. Check if CI passed
gh run list
# 6. Merge when approved
gh pr merge --squash
Part 10: Using Claude Code and Cursor to Run Git for You
You do not have to memorize every command. AI coding tools can run Git operations for you — just describe what you want in plain English.
Claude Code
Claude Code is Anthropic’s terminal-based AI agent. It can read your files, understand your project context, and execute Git commands on your behalf.
How to use it:
# Install Claude Code
npm install -g @anthropic-ai/claude-code
# Start a session in your project
cd my-project
claude
Then just talk to it:
> Stage all my changes and commit them with a good conventional commit message
> Create a new branch called feature/payment-integration and push it to GitHub
> I need to undo my last commit but keep the changes
> Show me what changed in the last 5 commits
> Create a pull request for my current branch targeting main
Claude Code reads your diff, understands what changed, writes a meaningful commit message, and runs the commands. It also explains what it’s doing and why, so you learn as you go.
Real example interaction:
You: I finished the login page. Commit everything and push.
Claude Code: I'll stage your changes and create a commit.
Running: git add src/pages/login.tsx src/components/LoginForm.tsx
Running: git commit -m "feat(auth): add login page with form validation"
Running: git push -u origin feature/login-page
Done. Your branch is on GitHub.
Cursor
Cursor is a VS Code fork with an integrated AI agent that understands your codebase.
How to use Git in Cursor:
- Press
Cmd+L(Mac) orCtrl+L(Windows/Linux) to open the AI chat - Type what you need:
Stage all my changes and write a commit message for me
Create a branch for the new payment feature
Show me the git log as a visual graph
Help me resolve this merge conflict in src/api/users.ts
Cursor’s agent runs the terminal commands inside its integrated terminal. It also shows the output and explains what happened.
Cursor’s Source Control panel:
For visual Git workflows, Cursor inherits VS Code’s built-in Source Control panel (Ctrl+Shift+G). You can stage, unstage, commit, and see diffs graphically — no commands needed.
When to use AI tools vs. learning commands
| Situation | Recommendation |
|---|---|
| Learning Git fundamentals | Type commands manually — muscle memory matters |
| Repetitive tasks (commit, push, PR) | Let AI tools handle it |
| Complex operations (rebase, bisect) | Ask AI to explain AND run it — learn from it |
| Emergency situations (lost commits) | Use AI assistance — less room for mistakes |
| Teaching someone else | Use manual commands so you can explain each step |
Data Flow and Mental Models
The four Git states
┌──────────────────────────────────────────────────────┐
│ Untracked │ Modified │ Staged │ Committed │
│ (new file) │ (changed) │ (index) │ (history) │
│ │ │ │ │
│ git add ──────────────►│ │ │
│ │ git add ──────────►│ │
│ │ │ git commit ──────────────► │
│ │◄── git restore ─────│ │
│ │ │◄── git restore --staged │
└──────────────────────────────────────────────────────┘
The remote workflow
Local Remote (GitHub)
───── ───────────────
git init / git clone ←────────── origin/main
git add + git commit
│
▼
Local commits ──── git push ───► origin/main
│
Other people's commits ◄─ git pull ───┘
Branch merging strategies
Fast-forward merge (no divergence):
main: A ── B
feature: B ── C ── D
result: A ── B ── C ── D (linear, clean)
Three-way merge (diverged):
main: A ── B ── C ────────── M
\ /
feature: D ── E ── (merge commit M created)
Rebase (replay commits):
main: A ── B ── C
feature: B ── D'── E' (D and E replayed on top of C)
Five Levels of Understanding
Level 1 — Basic: What is Git doing?
Git is a time machine for your code. Every git commit takes a snapshot. You can always go back. Branches are parallel timelines. push sends your work to GitHub. pull brings other people’s work to you.
The three commands you need to survive:
git add .
git commit -m "describe what you did"
git push
Level 2 — Medium: The staging model
Git’s staging area (index) is intentional. It lets you craft commits precisely — staging only the changes relevant to one logical unit, even if you edited many files.
A good commit answers: “If applied, this commit will…” Each commit should be one logical change. This makes git log, git bisect, and code review dramatically more useful.
The key commands at this level: git diff, git diff --staged, git log --oneline --graph, git stash, git branch.
Level 3 — Advanced: The commit graph
Git stores data as a directed acyclic graph (DAG) of commit objects. Each commit contains:
- A pointer to the tree object (snapshot of the file system)
- A pointer to the parent commit(s)
- Author, timestamp, and message
- A SHA-1 hash that uniquely identifies it
commit abc1234
├── tree: root directory snapshot
├── parent: def5678
├── author: Luis <luis@example.com>
└── message: "feat: add login form"
HEAD is just a pointer to the current commit. Branches are pointers to commits. git reset moves these pointers. git rebase creates new commits with the same changes but different parents.
Level 4 — Expert: Internals and performance
Git’s object store uses content-addressable storage. Two files with identical content share one blob object. This makes Git space-efficient across large repos.
Pack files (.git/objects/pack/) bundle objects together using delta compression. git gc triggers garbage collection and repacking.
For performance at scale:
git fetch --depth=1for shallow clones in CI/CDgit sparse-checkoutfor monorepos (only download what you need)git worktreefor multiple branches checked out simultaneously.gitattributesfor LFS (large file storage) configurationgit maintenancefor scheduled background optimization
Rebasing rewrites history — SHA hashes change. Never rebase commits that have been pushed to a shared branch. Use git revert instead (additive, safe).
Level 5 — Legendary: Architecture and team workflows
At scale, Git workflow design becomes an architectural decision with real organizational consequences.
Trunk-based development (used by Google, Meta) — everyone commits directly to main with feature flags. Minimizes merge conflicts. Requires strong CI/CD and discipline.
GitFlow — structured branches for main, develop, feature/*, release/*, hotfix/*. Higher overhead, better for versioned software with scheduled releases.
GitHub Flow — simplified: main plus short-lived feature branches. Pull request required for every merge. Good default for most teams.
The choice affects:
- How often integration conflicts occur
- How quickly features reach production
- How easy rollbacks are
- How new team members onboard
Git’s distributed nature also means every clone is a full backup. Catastrophic server failures are recoverable from any developer’s machine. This is not a coincidence — Linus Torvalds designed it this way after the Linux kernel project’s central CVS server suffered data loss.
Follow-Up Questions to Go Deeper
- What is the difference between
git mergeandgit rebaseand when should I use each? - How does
git bisecthelp me find exactly which commit introduced a bug? - What are Git hooks and how can I automate tasks on commit or push?
- How does GitHub’s pull request review process work, and what makes a good PR?
- What is a monorepo, and how does Git handle very large repositories?
- How do I set up SSH keys instead of HTTPS for GitHub authentication?
- What is
git reflogand how can it save me when I think I lost commits? - How does Git handle binary files, and what is Git LFS?
- What is trunk-based development and why do large companies prefer it?
- How can I set up commitlint and Husky to enforce commit message conventions automatically?
Sources
- Pro Git Book — Scott Chacon & Ben Straub — The definitive free reference, covers everything from basics to internals
- GitHub CLI Documentation — Official
ghcommand reference - GitHub CLI Installation Guide
- Git Official Documentation — Command references and tutorials
- Conventional Commits v1.0.0 — Commit message specification
- Atlassian Git Tutorials — Visual explanations of branching and merging
- Git Branching — Learn Git Branching (Interactive) — Browser-based visual Git exercises
- GitHub Docs — About pull requests
- Claude Code Documentation — Anthropic
- Cursor Documentation
- How to Write a Git Commit Message — Chris Beams
- Trunk Based Development — trunkbaseddevelopment.com
- Git Internals — Plumbing and Porcelain