Git commands: an everyday cheat sheet with examples
The core Git commands are git init and git clone to create a repository, git status, git add and git commit to save changes, git branch, git switch and git merge to work with branches, git push, git fetch and git pull to sync with the server, plus git restore, git reset and git revert to undo changes.
Below is a practical Git cheat sheet: commands are grouped by task, each with an example and a short explanation. It's handy to keep open next to your terminal: nearly everything a developer does with Git in a day fits into 20–30 commands from these tables.
To make sense of the commands, keep three areas in mind: the working directory (files on disk), the index or staging area (what goes into the next commit), and the repository (the commit history in the .git folder). Most Git commands move changes between these three areas or between your local and a remote repository.
Setting up Git
You run these once after installing. The --global flag writes settings to ~/.gitconfig and applies them to all of your repositories; without it, they apply to the current repository only.
| Command | What it does |
|---|---|
git config --global user.name "Jane Smith" | Commit author name |
git config --global user.email "jane@example.com" | Commit author email |
git config --global init.defaultBranch main | Default branch name for new repositories |
git config --global core.editor "code --wait" | Editor for commit messages (VS Code here) |
git config --global pull.rebase false | Default git pull behavior — merge |
git config --global core.autocrlf input | Convert CRLF to LF on commit (macOS/Linux; usually true on Windows) |
git config --list --show-origin | Show all settings and the file each one comes from |
git config --global alias.st status | Alias: git st instead of git status |
git --version | Installed Git version |
git help commit | Full manual for a command (or git commit -h for a short version) |
Creating and cloning a repository
| Command | What it does |
|---|---|
git init | Creates an empty repository (a .git folder) in the current directory |
git init my-project | Creates a my-project directory with a repository in it |
git clone https://github.com/user/repo.git | Copies a remote repository with its full history |
git clone git@github.com:user/repo.git app | Clones over SSH into the app folder |
git clone --depth 1 URL | Shallow clone: only the latest commit, fast and small |
git clone -b develop URL | Clones and checks out the develop branch right away |
The basic loop: status, add, commit
This is the core of daily work: see what changed, stage what you need, and record it in a commit.
| Command | What it does |
|---|---|
git status | State of things: modified, staged and untracked files |
git status -s | Short format: M — modified, A — added, ?? — untracked |
git add file.txt | Stage a file |
git add . | Stage all changes in the current directory and below, including deletions |
git add -A | Stage all changes in the entire repository |
git add -p | Interactively pick individual chunks (hunks) of changes |
git commit -m "Add login form" | Create a commit from the index with a message |
git commit -am "Fix typo" | Stage all tracked modified files and commit; new files are not included |
git commit --amend | Rewrite the last commit: add something you forgot to stage or fix the message |
git commit --amend --no-edit | Add to the last commit without changing the message |
git rm file.txt | Delete a file from disk and from the index |
git rm --cached secret.env | Stop tracking a file while keeping it on disk |
git mv old.js new.js | Rename or move a file |
A typical workflow looks like this:
git status
git add src/login.js src/login.css
git diff --staged # check exactly what goes into the commit
git commit -m "Add login form"
Don't use --amend on commits you've already pushed to a shared branch: it creates a new commit with a different hash, and your teammates will have to deal with diverged history.
Viewing history and changes
| Command | What it does |
|---|---|
git log | Commit history of the current branch |
git log --oneline | One line per commit: short hash and subject |
git log --oneline --graph --all | Graph of all branches in the terminal |
git log -p file.txt | History of a file with the diff of each commit |
git log --author="Jane" --since="2 weeks ago" | Filter by author and date |
git log -S "getUser" | Commits that added or removed the string getUser |
git log main..feature | Commits that are in feature but not in main |
git diff | Changes in the working directory that aren't staged yet |
git diff --staged | Staged changes compared to the last commit (same as --cached) |
git diff main feature | Difference between the tips of two branches |
git diff HEAD~3 -- src/ | Changes in the src folder over the last three commits |
git show a1b2c3d | Metadata and diff of a specific commit |
git show HEAD:README.md | Contents of a file in the latest commit |
git blame app.js | Who last changed each line, and in which commit |
git shortlog -sn | Number of commits per author |
Commit references come in handy everywhere: HEAD is the current commit, HEAD~1 is its parent, HEAD~3 is three steps back along the first parent, and HEAD^2 is the second parent of a merge commit.
Branches: create, switch, delete
Since version 2.23, Git has git switch for branches and git restore for files — they split up the overloaded git checkout. The old forms still work.
| Command | What it does |
|---|---|
git branch | List local branches; the current one is marked with * |
git branch -a | Local and remote-tracking branches |
git branch -vv | Branches with their latest commit and ahead/behind status vs. upstream |
git branch feature/login | Create a branch without switching to it |
git switch feature/login | Switch to a branch |
git switch -c feature/login | Create a branch and switch to it (same as git checkout -b) |
git switch - | Go back to the previous branch |
git branch -m new-name | Rename the current branch |
git branch -d feature/login | Delete a branch if it's already merged |
git branch -D feature/login | Force-delete a branch, even if unmerged |
git branch --merged | Branches already merged into the current one — candidates for deletion |
Merging and rebasing
| Command | What it does |
|---|---|
git merge feature | Merge feature into the current branch (fast-forward if possible) |
git merge --no-ff feature | Always create a merge commit |
git merge --squash feature | Stage all of the branch's changes as a single set, then run git commit |
git merge --abort | Abort a conflicted merge and return to the original state |
git rebase main | Replay the current branch's commits on top of main |
git rebase -i HEAD~4 | Interactively squash, reword, reorder or drop the last 4 commits |
git rebase --continue | Continue after resolving a conflict |
git rebase --abort | Cancel the rebase entirely |
git cherry-pick a1b2c3d | Apply a single commit to the current branch as a new one |
Resolving a merge conflict almost always looks the same:
git merge feature
# CONFLICT (content): Merge conflict in app.js
git status # files listed under "both modified"
# edit app.js, remove the <<<<<<< ======= >>>>>>> markers
git add app.js
git commit # Git suggests a ready-made merge commit message
The golden rule of rebase: don't rebase commits that are already on a shared branch where others are building on them.
Working with remote repositories
| Command | What it does |
|---|---|
git remote -v | List remotes and their URLs |
git remote add origin git@github.com:user/repo.git | Add a remote repository named origin |
git remote set-url origin NEW_URL | Change a remote's URL (for example, HTTPS to SSH) |
git remote remove upstream | Remove a remote |
git fetch | Download new commits and branches without touching your files |
git fetch --prune | Same, plus remove references to branches deleted on the server |
git pull | git fetch + merge the upstream branch into the current one |
git pull --rebase | git fetch + rebase your commits on top of the fetched ones |
git push | Push the current branch's commits to its upstream |
git push -u origin feature/login | First push of a branch, setting its upstream |
git push --force-with-lease | Overwrite the remote branch only if nobody else has pushed new commits to it |
git push origin --delete feature/login | Delete a branch on the server |
git push --tags | Push all local tags |
Instead of git push --force, get used to --force-with-lease: if a teammate has pushed to the same branch in the meantime, the command refuses to overwrite their work.
Undoing changes
The most nerve-racking part of Git. The key question before picking a command: are the changes only in your files, already staged, in a local commit, or in a published commit?
| Situation | Command |
|---|---|
| Discard edits to a file (restore it to the last commit) | git restore app.js |
| Unstage a file while keeping the edits | git restore --staged app.js |
| Restore a file from a specific commit | git restore --source=a1b2c3d app.js |
| Undo the last commit, keeping the changes staged | git reset --soft HEAD~1 |
| Undo the last commit, keeping the changes in your files | git reset HEAD~1 (default --mixed mode) |
| Delete the last commit and all its changes | git reset --hard HEAD~1 |
| Undo a published commit with a new "inverse" commit | git revert a1b2c3d |
| Undo a merge commit | git revert -m 1 <merge-hash> |
| Preview which untracked files will be deleted | git clean -n |
| Delete untracked files and folders | git clean -fd |
| Find a "lost" commit after a reset or rebase | git reflog, then git reset --hard HEAD@{2} |
git reset --hard and git clean -f permanently delete uncommitted changes: the reflog only keeps commits, not edits in the working directory. Run git stash first, or at least git status.
Stash: set unfinished work aside
| Command | What it does |
|---|---|
git stash | Stash changes to tracked files and clean the working directory |
git stash push -u -m "wip: form" | Stash including untracked files, with a label |
git stash list | List stashes: stash@{0}, stash@{1}… |
git stash show -p stash@{0} | Show the diff of a stash |
git stash pop | Restore the latest stash and remove it from the list |
git stash apply stash@{1} | Restore a stash, keeping it in the list |
git stash drop stash@{1} | Delete a single stash |
git stash branch fix-form | Create a branch from the commit where the stash was made and apply it |
Tags and releases
| Command | What it does |
|---|---|
git tag | List tags |
git tag -a v1.2.0 -m "Release 1.2.0" | Annotated tag with author, date and message |
git tag v1.2.0 a1b2c3d | Lightweight tag on a specific commit |
git push origin v1.2.0 | Push a single tag |
git tag -d v1.2.0 | Delete a tag locally |
git push origin --delete v1.2.0 | Delete a tag on the server |
git describe --tags | Nearest tag and the number of commits since it, e.g. v1.2.0-3-ga1b2c3d |
Advanced Git commands
| Command | What it does |
|---|---|
git bisect start, git bisect bad, git bisect good v1.1.0 | Binary search for the commit that introduced a bug; finish with git bisect reset |
git worktree add ../hotfix main | A second working folder with another branch from the same repository |
git submodule update --init --recursive | Fetch submodules after cloning |
git grep "TODO" | Fast search through tracked files |
git format-patch -1 HEAD / git apply fix.patch | Save a commit as a patch and apply a patch to the working directory |
git gc | Pack objects and clean up the repository (Git usually does this itself) |
Common mistakes and how to fix them
Committed to main instead of a new branch
If the commit hasn't been pushed yet, create a branch at the current commit and roll main back:
git branch feature/login # the branch points to your commit
git reset --hard HEAD~1 # main goes back one step
git switch feature/login
Forgot to add a file to the last commit
git add forgotten.js
git commit --amend --no-edit
Push rejected: non-fast-forward
The server has commits you don't. Pull them first, then push:
git pull --rebase
git push
Accidentally committed a file with passwords
Stop tracking it and add it to .gitignore: git rm --cached .env, then commit. If the commit has already been pushed, consider the secret compromised and rotate it — it's still in the history.
Summary
A short set covers day-to-day work: status, add, commit, switch, merge, pull, push and log --oneline. Choose among the undo commands — restore, reset, revert — based on whether the commit has been published, and remember reflog as your last-resort safety net. All the Git commands in this cheat sheet are covered hands-on in the Git course, where you try each one in your own repository.
FAQ
How many Git commands does a beginner need to know?
10–12 are enough to get started: init, clone, status, add, commit, log, diff, branch, switch, merge, pull and push. You'll pick up the rest as tasks come up.
What's the difference between git switch and git checkout?
git switch only switches and creates branches, while git checkout also restores files. The split into switch and restore was made so you don't accidentally wipe out edits by confusing a branch with a file.
How do I get help for any Git command?
Run git help command-name for the full manual or git command-name -h for a short list of flags. The same documentation is available on git-scm.com.
Can I shorten long Git commands?
Yes, with aliases: git config --global alias.lg "log --oneline --graph --all" lets you type git lg.
Do these commands work on Windows?
Yes, the commands are the same on every system. On Windows, you can run them in Git Bash, PowerShell or your code editor's terminal.
This topic is covered in depth with practice in the course “Git from Scratch to Confident Developer”.
- First Repository: init, add, commit, and the Magic of the Index
- Reading History: log, diff, show and Navigating the Past
- Branches: The Parallel Reality of Your Code
- Undoing Mistakes: restore, reset, revert — Doing It Right and the Dangers
- GitHub and Remote Repositories: Your Code in the Cloud
- Advanced Tools: Rebase, Stash, Cherry-pick and Tags