49 Git commands with flags, real-world use cases, and gotchas. Searchable and filterable, with a dedicated Recovery Commands section for undoing mistakes. Verified against official Git docs.
Everything runs in your browser. No commands or data are sent to any server.
5 essential commands to get you started. The full reference is right below.
git status See what's staged, unstaged, and untracked before committing. This is the command you should run before nearly every other Git command.
git add <file> Move a modified or new file into the staging area before committing it.
git commit -m "commit message" Save a snapshot of staged changes to the local repository history with a descriptive message.
git push origin <branch-name> Upload your local commits to the shared remote branch so teammates and CI can see them.
git log See the commit history of the current branch, including author, date, and message for each commit.
git init ↓ Click command to explain
When to use this
Start tracking a new project with Git in the current directory.
git clone https://github.com/user/repo.git ↓ Click command to explain
When to use this
Get a full local copy of a remote repository, including its entire history, to start working on it.
git config --global user.name "Your Name" ↓ Click command to explain
When to use this
Set the name attached to every commit you make on this machine, before your first commit.
git config --global user.email "you@example.com" ↓ Click command to explain
When to use this
Set the email attached to every commit, which platforms like GitHub use to link commits to your profile.
git config --list ↓ Click command to explain
When to use this
Check which settings are active and where they came from, whether system, global, or local repo config, when something behaves unexpectedly.
Gotcha
Config is layered: system, then global, then local repo config, with later ones overriding earlier ones. A local .git/config override is a common reason a setting doesn't match what you expect from your global config.
git add <file> ↓ Click command to explain
When to use this
Move a modified or new file into the staging area before committing it.
git add -p ↓ Click command to explain
When to use this
Stage only specific changes within a file for a clean, atomic commit instead of staging everything in the file at once.
git status ↓ Click command to explain
When to use this
See what's staged, unstaged, and untracked before committing. This is the command you should run before nearly every other Git command.
git commit -m "commit message" ↓ Click command to explain
When to use this
Save a snapshot of staged changes to the local repository history with a descriptive message.
git commit --amend ↓ Click command to explain
When to use this
Fix a typo in the last commit message or add a forgotten file to the previous commit instead of creating a new one.
Gotcha
Only amend commits that have NOT been pushed to a shared branch. Amending a pushed commit requires a force push, which rewrites history for everyone who already pulled it.
git diff --staged ↓ Click command to explain
When to use this
Review exactly what's about to be committed before running git commit, as a final sanity check.
Gotcha
Plain git diff only shows unstaged changes. If you've already run git add, you need --staged (or --cached) to see what will actually be committed.
git branch ↓ Click command to explain
-a List remote-tracking branches too, not just local ones When to use this
See all local branches and which one is currently checked out.
git branch <branch-name> ↓ Click command to explain
When to use this
Create a new branch pointing at the current commit, without switching to it yet.
git checkout -b <branch-name> ↓ Click command to explain
When to use this
Start a new feature branch off your current commit in a single command.
git switch <branch-name> ↓ Click command to explain
-c Create the branch if it doesn't already exist, same as checkout -b When to use this
Move to a different branch using the newer, more explicit command introduced to replace overloaded uses of checkout.
git merge <branch-name> ↓ Click command to explain
When to use this
Bring the changes from a feature branch into the branch you currently have checked out, such as merging a feature into main.
Gotcha
A merge that touches the same lines on both branches produces conflict markers you must resolve by hand before the merge can be completed.
git rebase main ↓ Click command to explain
When to use this
Replay your branch's commits on top of the latest main to keep a linear, easy-to-read history before opening a pull request.
Gotcha
Never rebase a branch that other people are working on. Rebase rewrites commit hashes, and the history on shared branches diverges in ways that are painful to resolve.
git cherry-pick <commit-hash> ↓ Click command to explain
When to use this
Pull a single bugfix commit onto a release branch without merging the entire branch it originated on.
Gotcha
Cherry-pick creates a new commit with a different hash even if the content is identical. The original commit still exists on its original branch. This is a copy, not a move.
git remote -v ↓ Click command to explain
When to use this
Check which URL origin (or any other remote) actually points to before pushing, especially after cloning a fork.
git remote add origin https://github.com/user/repo.git ↓ Click command to explain
When to use this
Connect a local repository created with git init to a remote repository on GitHub, GitLab, or another host.
git fetch ↓ Click command to explain
When to use this
Download new commits and branches from the remote without merging them into your current branch, to review before integrating.
git pull ↓ Click command to explain
When to use this
Bring your local branch up to date with the remote in one step before starting new work.
Gotcha
git pull is git fetch plus git merge combined. If you'd rather review incoming changes first, or prefer rebasing over merging, run fetch and merge (or rebase) separately.
git push origin <branch-name> ↓ Click command to explain
When to use this
Upload your local commits to the shared remote branch so teammates and CI can see them.
git push --force-with-lease ↓ Click command to explain
When to use this
Push a rewritten history, such as after an interactive rebase, without blindly overwriting a teammate's work.
Gotcha
Safer than --force because it fails if someone else pushed to the branch since you last fetched. Use this instead of --force in almost every situation.
git stash push -m "work in progress on login form" ↓ Click command to explain
When to use this
Temporarily shelve uncommitted work so you can switch branches to handle an urgent fix, then come back to it later.
Gotcha
Stash is a stack, not a single slot, so you can stash multiple times and pop them in order. Name your stashes with git stash push -m "message" or you will forget what each one contains.
git stash list ↓ Click command to explain
When to use this
See every stash currently saved before deciding which one to restore.
git stash pop ↓ Click command to explain
When to use this
Bring back your shelved work after switching back to the branch you were working on.
Gotcha
Pop can produce merge conflicts if the branch changed since you stashed. If you want to keep the stash in case the pop goes wrong, use git stash apply instead, which doesn't delete it from the stack.
git stash drop stash@{0} ↓ Click command to explain
When to use this
Remove a stash you no longer need, such as an outdated work-in-progress that's no longer relevant.
Gotcha
Dropped stashes are not immediately gone. They can often still be recovered with git fsck --unreachable for a short time before garbage collection, but don't rely on this.
git revert <commit-hash> ↓ Click command to explain
When to use this
Undo a specific commit on a shared branch by creating a new commit that reverses it, safe even after the commit has been pushed.
Gotcha
Unlike reset, revert never rewrites history. It's the safe way to undo something on a branch other people have already pulled.
git reset --soft HEAD~1 ↓ Click command to explain
When to use this
Combine your last commit with new changes into a single commit, by uncommitting but keeping everything staged and ready to recommit.
Gotcha
Soft reset keeps changes staged, unlike a plain reset which unstages them. Useful specifically when you want to immediately recommit with an amended set of changes.
git clean -fd ↓ Click command to explain
-n Dry run, showing what would be deleted without actually deleting anything When to use this
Wipe out build artifacts, generated files, and other untracked clutter to get back to a pristine working directory.
Gotcha
This permanently deletes untracked files with no undo. Always run git clean -n first to preview exactly what would be removed before adding -f.
git rm --cached <file> ↓ Click command to explain
When to use this
Remove a file from Git tracking, such as one that should have been in .gitignore from the start, while leaving it on disk.
Gotcha
The file still exists locally after this. Only Git's tracking of it is removed. Add it to .gitignore too, or it will show up as untracked and be easy to accidentally re-add.
git checkout -- <file> ↓ Click command to explain
When to use this
Discard uncommitted changes to a single file, using the older syntax still seen in many existing scripts and tutorials.
Gotcha
This older overloaded syntax has been superseded by git restore, which is unambiguous about whether you're restoring a file or switching a branch. Prefer git restore in new scripts.
git log ↓ Click command to explain
When to use this
See the commit history of the current branch, including author, date, and message for each commit.
git log --oneline --graph --all ↓ Click command to explain
When to use this
Visualize how branches diverged and merged across the whole repository in a single compact view.
git show <commit-hash> ↓ Click command to explain
When to use this
Inspect the full diff and metadata of one specific commit without checking it out.
git diff <commit-1> <commit-2> ↓ Click command to explain
When to use this
Compare what changed between two arbitrary points in history, such as two release tags.
git blame <file> ↓ Click command to explain
When to use this
Find the commit that introduced a specific line, to understand the reasoning behind it before changing it.
Gotcha
The goal is to find context, not to blame people. Use it to understand why a line was written, not who wrote it, and check the linked commit message for the actual reasoning.
git tag ↓ Click command to explain
When to use this
See all tags in the repository, such as version releases, before creating a new one.
git tag -a v1.0.0 -m "Release 1.0.0" ↓ Click command to explain
When to use this
Mark a specific commit as an official release with a message, author, and date attached, unlike a lightweight tag.
Gotcha
Prefer annotated tags (-a) over lightweight tags for releases. They store the tagger, date, and message as a full Git object, which lightweight tags don't.
git push --tags ↓ Click command to explain
When to use this
Share a newly created release tag with the remote, since tags are not pushed automatically by a plain git push.
Gotcha
A regular git push does not push tags by default. Forgetting --tags after tagging a release is a common reason a CI pipeline watching for tags never triggers.
git tag -d <tag-name> ↓ Click command to explain
When to use this
Remove a tag created by mistake, such as one pointing at the wrong commit, before anyone pulls it.
Gotcha
Deleting a local tag does not remove it from the remote. Also run git push origin :refs/tags/<tag-name> if it was already pushed.
git reset HEAD~1 ↓ Click command to explain
When to use this
You committed too early or bundled the wrong files, and want to fix the staging before recommitting, without losing any code.
Gotcha
Step by step: this moves the commit back to your staging area, so the commit itself disappears but your code changes are not lost. They show up as staged changes in git status. Fix what you need, then run git commit again.
git reset --hard HEAD~1 ↓ Click command to explain
When to use this
You committed something completely wrong, like a debug commit with garbage content, and want it gone entirely, code included.
Gotcha
Step by step: this permanently destroys both the commit and all the code changes it introduced. There is no undo once this runs. Only use this if you are absolutely certain you do not want those changes back. If in doubt, use the non-destructive git reset HEAD~1 instead.
git checkout -b <branch-name> <commit-hash> ↓ Click command to explain
When to use this
You or a teammate deleted a branch that still had unmerged work on it, and need it back.
Gotcha
Step by step: run git reflog to find the last commit hash the deleted branch was pointing at. Reflog shows every HEAD movement for 90 days by default, so the branch's last commit is still there until garbage collection runs. Then run git checkout -b <branch-name> <commit-hash> using that hash to recreate the branch pointing at exactly where it left off.
git commit --amend -m "correct message" && git push --force-with-lease ↓ Click command to explain
When to use this
You pushed a commit with a typo or an incorrect message and need to correct it on the remote branch.
Gotcha
Step by step: first run git commit --amend to rewrite the message locally, then git push --force-with-lease to update the remote. This rewrites history, so anyone who already pulled the original commit will have a diverged branch. Coordinate with your team before doing this on a shared branch.
git restore --staged <filename> ↓ Click command to explain
When to use this
You ran git add on the wrong file, or on everything with git add ., and want to remove just one file from staging before committing.
Gotcha
Step by step: this moves the file back to unstaged without touching its contents on disk. This is the correct modern command. Older tutorials show git reset HEAD <filename>, which also works, but restore is clearer about intent.
git restore <filename> ↓ Click command to explain
When to use this
You made experimental edits to a file that didn't work out, and want to revert it back to the last committed version.
Gotcha
Step by step: this permanently discards all uncommitted changes to that file with no undo. Double-check with git diff <filename> before running this. Once it runs, the edits are gone for good.
git reflog ↓ Click command to explain
When to use this
Recover commits that seem lost after a hard reset or an accidental branch deletion. Git keeps a local log of every HEAD movement for 90 days by default, so this is your undo button for things that feel undoable.
Gotcha
The reflog is local to your machine only. It is never pushed or shared, so it won't help recover another teammate's lost commits, only your own local history.
Git organizes every change you make across four distinct areas, and most confusion new users run into comes from not knowing which area a file currently sits in. The working directory is the literal files on disk that you edit in your editor. The staging area, sometimes called the index, is a holding area where you explicitly place changes with git add before they become part of a commit. This intermediate step is what lets you build a clean, focused commit out of a messy set of edits. The local repository is the full history of commits stored in the .git folder on your machine, private until you push it. And the remote repository is the shared copy, typically on GitHub or GitLab, that your teammates and CI systems interact with. Nearly every Git command moves something between two of these four areas, and once you can name which area a command touches, its behavior stops feeling arbitrary.
Commands that rewrite history, such as git commit --amend, git rebase, and force pushes, feel dangerous because they genuinely are, in a very specific and narrow way: they change commit hashes that other people or systems may already be relying on. A commit hash is effectively a fingerprint of a commit's content plus its parent, so changing a commit's message, reordering commits, or squashing them all produce a brand new hash, even when the code ends up looking identical. If a teammate already pulled the original hash, their local history and the rewritten remote history now disagree, and reconciling that divergence usually means their branch needs to be manually reset or re-fetched. This is exactly why rewriting history is safe on a private, unpushed branch, since nobody else has a copy to diverge from, but risky the moment it touches anything shared.
What makes Git forgiving despite all this is a safety net most developers never learn about until they desperately need it: the reflog. Every time HEAD moves, whether through a commit, a checkout, a reset, or even a rebase, Git silently records that movement in a local log that persists for about 90 days by default. This means that even after a git reset --hard that appears to have permanently destroyed a commit, or after deleting a branch that still had valuable work on it, the actual commit objects are usually still sitting in Git's object database, simply unreferenced by any branch. Running git reflog surfaces every one of those past HEAD positions with their commit hashes, and a plain git checkout -b against the right hash brings the 'lost' work straight back. Very few things in Git are ever truly gone within that 90-day window. They're just temporarily unreachable, and the reflog is the map back to them.