Learn Git in 30 Minutes: The Only Commands You Actually Need
Git is the version control system used by virtually every software project in the world. It tracks changes to your files, lets you undo mistakes, and makes collaboration possible without chaos. And despite its reputation for complexity, the core of Git is a small set of commands that cover the vast majority of what you will ever need to do.
This guide teaches you the 12 Git commands that matter most, plus the mental model that makes them all make sense. Skip the esoteric features. Master these commands, and you will be able to track your projects, collaborate with others, and recover from mistakes with confidence.
The Mental Model
Before touching any commands, understand how Git thinks about your files. There are four places your code can live.
Working directory. This is the folder on your computer where you actually edit files. It is your normal file system. When you open a file in your editor and make changes, you are modifying the working directory.
Staging area (also called the index). This is a holding area where you prepare changes before committing them. Think of it as a loading dock. You choose which changes go on the truck (the next commit), and which stay behind. This lets you commit some changes while keeping others as works in progress.
Local repository. This is Git's database of all committed changes, stored in a hidden .git folder inside your project. Every commit you make is saved here, creating a complete history of your project that you can browse, search, and revert to at any time.
Remote repository. This is a copy of your repository hosted on a server like GitHub, GitLab, or Bitbucket. It enables collaboration by giving your team a shared location to push and pull changes.
The flow is: edit files in your working directory, stage the changes you want to keep, commit them to your local repository, and push them to the remote for others to access.
git init: Starting a New Repository
git init creates a new Git repository in your current directory. It adds a hidden .git folder that stores all of Git's tracking data.
mkdir my-project
cd my-project
git init
This creates an empty repository. Git is now tracking this folder, but no files have been committed yet. You only run git init once per project, at the very beginning.
You will typically use this when starting a new project from scratch. If you are working on an existing project that is already on GitHub, you will use git clone instead.
git clone: Copying an Existing Repository
git clone downloads an existing repository from a remote server to your computer. It copies the entire history, all branches, and all files.
git clone https://github.com/username/project-name.git
This creates a new folder called project-name containing the full repository. The remote connection is set up automatically, so you can push and pull changes without additional configuration.
# Clone into a specific folder name
git clone https://github.com/username/project-name.git my-folder
Cloning is how you start working on most projects. You find the repository on GitHub, copy the URL, and clone it to your machine.
git status: Seeing What Changed
git status shows you the current state of your working directory and staging area. It tells you which files have been modified, which are staged for commit, and which are untracked (new files Git does not know about).
git status
A typical output looks like this:
On branch main
Changes not staged for commit:
modified: index.html
Untracked files:
styles.css
no changes added to commit
This tells you that index.html has been modified but not staged, and styles.css is a new file that Git is not tracking yet. Run git status constantly. It is your compass. When you are unsure what is happening, git status will orient you.
git add: Staging Changes
git add moves changes from your working directory to the staging area. This tells Git which changes you want to include in your next commit.
# Stage a specific file
git add index.html
# Stage multiple specific files
git add index.html styles.css
# Stage all changed and new files
git add .
The period . means "everything in the current directory and below." This is convenient but use it carefully. Make sure you are not accidentally staging files you do not want to commit (like temporary files, credentials, or build artifacts).
After running git add, use git status to verify that the right files are staged. Files will appear under "Changes to be committed."
git commit: Saving a Snapshot
git commit takes everything in the staging area and saves it as a permanent snapshot in your local repository. Each commit has a unique identifier, a timestamp, the author's name, and a message describing the change.
# Commit with a message
git commit -m "Add navigation bar to homepage"
# Commit with a longer message (opens your text editor)
git commit
Write commit messages that explain why you made the change, not just what you changed. "Fix login bug where users were redirected to wrong page" is better than "Fix bug." Your future self and your teammates will thank you.
# Stage and commit all modified files in one step
git commit -am "Update footer styles"
The -am flag combines git add (for already-tracked files) and git commit. It does not add new untracked files, only files that Git already knows about.
git log: Viewing History
git log shows the history of commits in your repository, starting with the most recent.
# Full log
git log
# Compact one-line format
git log --oneline
# Show the last 5 commits
git log --oneline -5
# Show which files changed in each commit
git log --stat
The one-line format is the most useful for quick reference:
a1b2c3d Add contact form validation
e4f5g6h Update homepage hero image
i7j8k9l Initial commit
Each line shows the abbreviated commit hash (a unique identifier) and the commit message. You can use these hashes to reference specific commits in other commands.
git branch: Managing Branches
Branches let you work on different features or fixes in isolation. The main branch is your primary branch. Feature branches let you develop new things without affecting main until you are ready.
# List all branches (* marks the current branch)
git branch
# Create a new branch
git branch feature-login
# Delete a branch (after it has been merged)
git branch -d feature-login
Creating a branch does not switch you to it. It just creates the branch. You need git switch or git checkout to actually move to it.
Think of branches as parallel timelines. You can make changes on one branch without affecting any other branch. When the work is done, you merge the changes back.
git checkout / git switch: Switching Branches
These commands move you between branches. git switch is the modern, cleaner command. git checkout is the older version that still works everywhere.
# Switch to an existing branch (modern)
git switch feature-login
# Switch to an existing branch (classic)
git checkout feature-login
# Create a new branch and switch to it (modern)
git switch -c feature-signup
# Create a new branch and switch to it (classic)
git checkout -b feature-signup
When you switch branches, Git updates your working directory to match the state of that branch. Files will appear, disappear, or change to reflect the branch you switched to.
Make sure you commit or stash your changes before switching branches. If you have uncommitted changes and they conflict with the branch you are switching to, Git will refuse to switch.
git merge: Combining Branches
git merge takes the changes from one branch and integrates them into your current branch.
# First, switch to the branch you want to merge INTO
git switch main
# Then merge the feature branch into it
git merge feature-login
If the changes do not conflict (they modify different files or different parts of the same file), Git merges them automatically. If they do conflict, Git pauses and asks you to resolve the conflicts manually. More on this below.
After merging, the feature branch still exists. You can delete it with git branch -d feature-login if you are done with it.
git pull: Getting Changes from the Remote
git pull downloads changes from the remote repository and merges them into your current branch. It is how you stay up to date with your team's work.
git pull
This fetches changes from the remote and merges them into your current branch. If you and a teammate both changed the same file, you may need to resolve a merge conflict.
Run git pull before starting new work each day. This ensures you are building on the latest version of the code and reduces the chance of conflicts later.
# Pull from a specific remote and branch
git pull origin main
origin is the default name for your remote repository. main is the branch. Most of the time, plain git pull does what you need.
git push: Sending Changes to the Remote
git push uploads your committed changes to the remote repository so others can access them.
git push
This pushes your current branch to the remote. If the branch does not exist on the remote yet, Git will tell you and suggest the command to set it up:
# Push a new branch to the remote for the first time
git push -u origin feature-login
The -u flag sets up tracking so that future git push and git pull commands on this branch work without specifying the remote and branch name.
You can only push if your local branch is up to date with the remote. If someone else pushed changes since your last pull, you need to git pull first, resolve any conflicts, and then push.
git diff: Seeing Exactly What Changed
git diff shows the specific lines that were added, removed, or modified in your files.
# See unstaged changes (working directory vs. staging area)
git diff
# See staged changes (staging area vs. last commit)
git diff --staged
# See changes between two commits
git diff a1b2c3d e4f5g6h
# See changes in a specific file
git diff index.html
The output uses + to indicate added lines and - to indicate removed lines. git diff is invaluable for reviewing your changes before committing. It catches accidental changes, debugging leftovers, and other issues that git status alone does not reveal.
.gitignore: Telling Git What to Skip
Not every file should be tracked by Git. Build artifacts, dependency folders, credentials, and operating system files should be ignored. The .gitignore file tells Git which files and folders to skip.
Create a file called .gitignore in the root of your repository:
# Dependencies
node_modules/
venv/
# Build output
dist/
build/
*.pyc
# Environment and credentials
.env
*.key
credentials.json
# Operating system files
.DS_Store
Thumbs.db
# IDE files
.vscode/
.idea/
Each line is a pattern. Files and folders matching these patterns will be invisible to Git. It will not track them, stage them, or commit them.
Add your .gitignore file early in the project, ideally as part of your first commit. If you accidentally commit a file and then add it to .gitignore, Git will continue tracking it. You need to explicitly remove it from tracking with git rm --cached filename.
Resolving Merge Conflicts
Merge conflicts happen when two branches modify the same part of the same file. Git cannot decide which version to keep, so it asks you to choose.
When a conflict occurs, Git marks the conflicting sections in the file:
<<<<<<< HEAD
Your changes on the current branch
=======
Changes from the branch being merged
>>>>>>> feature-login
To resolve the conflict:
- Open the file and find the conflict markers (
<<<<<<<,=======,>>>>>>>). - Decide which version to keep, or combine both versions manually.
- Remove the conflict markers entirely.
- Save the file.
- Stage the resolved file with
git add. - Commit the merge with
git commit.
# After manually resolving conflicts in the file:
git add index.html
git commit -m "Resolve merge conflict in index.html"
Conflicts sound scary but they are a normal part of collaboration. They just mean two people edited the same thing, and Git needs a human to decide which version is correct.
A Typical Daily Workflow
Here is what a typical day looks like when working with Git on a team project.
# Start the day: get the latest changes
git pull
# Create a branch for your new feature
git switch -c feature-user-profile
# ... do your work, edit files ...
# Check what changed
git status
git diff
# Stage and commit your changes
git add user_profile.py templates/profile.html
git commit -m "Add user profile page with bio and avatar"
# Push your branch to the remote
git push -u origin feature-user-profile
# When approved, merge into main
git switch main
git pull
git merge feature-user-profile
git push
# Clean up
git branch -d feature-user-profile
This workflow keeps your main branch stable, your features isolated, and your team informed. It scales from solo projects to teams of hundreds.
Common Mistakes and How to Fix Them
"I committed to the wrong branch." If you have not pushed yet, you can move the commit to the right branch. Switch to the correct branch, use git cherry-pick <commit-hash> to apply the commit there, then switch back to the wrong branch and use git reset HEAD~1 to undo it.
"I want to undo my last commit but keep the changes." Use git reset --soft HEAD~1. This removes the commit but leaves your changes staged and ready to recommit.
"I want to discard all uncommitted changes." Use git checkout -- filename to discard changes to a specific file, or git stash to temporarily shelve all changes so you can retrieve them later.
"I accidentally committed a secret or credential." This is serious. Changing the file and making a new commit does not remove it from history. You need to use git filter-branch or a tool like BFG Repo Cleaner to rewrite history, and you should immediately rotate the exposed credential.
What You Can Skip
Git has hundreds of commands and options. You do not need most of them. Specifically, you can safely ignore git rebase, git cherry-pick, git bisect, git stash (until you need it), git reflog, and interactive staging until you have been using Git comfortably for months. The 12 commands in this guide cover the overwhelming majority of daily Git usage. Learn them well before branching out.
Git is a tool that rewards consistency. Use it on every project, commit frequently with clear messages, and the workflow will become second nature within weeks.
Build projects with AI in our free Vibe Coding textbook.