Post
Git commands: my cheat sheet
The Git commands I keep coming back to, grouped by what you're doing: daily work, branches, undoing, remotes, history, worktrees and more.
Anything marked ⚠️ can lose work. New to Git? Start with Git from zero to hero.
Setup and config
git config --global user.name "Name"sets your name, andgit config --global user.email "you@example.com"sets your email.git config --global init.defaultBranch mainmakes new repos start onmain.git config --global push.autoSetupRemote truemakes the firstgit pushof a new branch set the upstream for you.git config --global pull.rebase truemakesgit pullrebase instead of creating merge commits. The manual itself calls this possibly dangerous, since rebasing rewrites your local commits.git config --global pull.ff onlyis the stricter choice: it refuses anything that isn’t a fast-forward.git config --global core.editor "code --wait"picks the editor for commit messages.git config --listshows everything, andgit config --global alias.co checkoutmakes a shortcut (git co). Since Git 2.46 the manual prefers the subcommand formsgit config list,git config get <name>andgit config set <name> <value>; the older forms above still work.git help <command>opens the manual for a command.
Starting and cloning
git initstarts a repo in the current folder.git clone <url>clones a repo, andgit clone <url> <dir>clones it into a folder of your choice.git clone --depth 1 <url>takes only the latest snapshot, which is much faster for big histories.git clone --filter=blob:none <url>is a partial clone: full history, file contents downloaded on demand.
Daily workflow
git statusshows what changed, andgit status -sshows it in a short form.git add <file>stages one file,git add .stages everything here, andgit add -ustages only files Git already tracks (including deletions).git add -pstages chunk by chunk, so one messy file can become two clean commits.git commit -m "message"commits what’s staged, andgit commit -am "message"stages tracked files and commits in one step.git commit --amendrewrites the last commit (message or content). Add--no-editto keep the message.git commit --fixup <commit>records a fix for an older commit. Later,git rebase -i --autosquash <base>folds it in automatically.git rm <file>deletes a file and stages the deletion.git rm --cached <file>stops tracking it but keeps it on disk, for a file you added to.gitignoretoo late.git mv <old> <new>renames or moves a file.
Branches
git branchlists local branches,git branch -aincludes remote ones, andgit branch -vvshows each branch’s upstream and whether it’s ahead or behind.git switch <branch>changes branch, andgit switch -c <branch>creates one and switches to it.git switch -jumps back to the previous branch.git checkout <branch>andgit checkout -b <branch>do the same thing in the older style.git branch -d <branch>deletes a merged branch, andgit branch -D <branch>force-deletes it ⚠️.git branch -m <new-name>renames the current branch.git branch --mergedlists branches already merged into the current one, the quickest way to find what you can delete.git branch --set-upstream-to=origin/<branch>links a local branch to a remote one.git push origin --delete <branch>deletes a branch on the remote.
Merging and rebasing
git merge <branch>merges a branch into the current one.--no-ffalways creates a merge commit, and--squashcollapses the branch into one staged change.git rebase <branch>replays your commits on top of another branch.git rebase -i HEAD~3is the interactive rebase of the last three commits: squash, reorder, reword, drop.git rebase --onto <new-base> <old-base> <branch>moves a branch to a new starting point.git rebase --continue,git rebase --skipandgit rebase --abortsteer a rebase that stopped on a conflict.git merge --abortdoes the same for a merge.
Remotes and syncing
git remote -vlists remotes,git remote add origin <url>adds one, andgit remote set-url origin <url>changes its address.git fetchdownloads remote changes without merging them.git fetch --prunealso removes remote branches that no longer exist.git pullis fetch plus merge, andgit pull --rebaseis fetch plus rebase for a cleaner history.git pull --ff-onlyrefuses to create a merge commit.git pushsends your commits, andgit push -u origin <branch>also sets the upstream.git push --force-with-leaseis the safer force push: it refuses if someone else pushed in the meantime ⚠️.
Inspecting history
git logshows history, andgit log --oneline --graph --allshows a compact picture of every branch.git log -p <file>shows how a file changed over time, andgit log --statlists the files touched by each commit.git log -S"text"finds commits where that text was added or removed.git log --author="name"andgit log --since="2 weeks ago"filter by who and when.git log main..featurelists the commits that are onfeaturebut not onmain.git show <commit>shows one commit, andgit show <commit>:<path>shows a file as it was then.git diffcompares unstaged changes,git diff --stagedcompares staged ones,git diff <a> <b>compares two branches or commits, andgit diff --stator--name-onlykeep the output short.git blame <file>shows who last changed each line, and-L 10,20limits it to a line range.git grep "text"searches tracked files, which is faster thangrepin a big repo.git shortlog -snranks contributors by number of commits.
Undoing things
git restore <file>discards unstaged changes ⚠️, andgit restore --staged <file>unstages a file.git restore --source=<commit> <file>brings back a file as it was in another commit.git restore -pdoes it chunk by chunk.git checkout -- <file>is the classic way to discard changes ⚠️.git reset --soft HEAD~1undoes the last commit and keeps the changes staged.git reset --mixed HEAD~1undoes it and keeps the changes unstaged. This is the default.git reset --hard HEAD~1undoes it and throws the changes away ⚠️.git revert <commit>adds a new commit that undoes an older one, which is the safe choice for shared history. For a merge commit, add-m 1to say which side to keep.git clean -nshows what would be removed, andgit clean -fdremoves untracked files and folders ⚠️. Always run-nfirst.
Stashing
git stashsaves your changes aside, andgit stash -uincludes untracked files.git stash push -m "message"gives the stash a name, andgit stash push -- <path>stashes only that path.git stash listlists them, andgit stash show -pshows what’s inside one.git stash popapplies the latest and removes it,git stash applyapplies without removing, andgit stash dropdeletes one ⚠️.git stash branch <name>turns a stash into a new branch, for when it no longer applies cleanly.
Tags
git taglists tags,git tag <name>makes a lightweight tag, andgit tag -a v1.0 -m "message"makes an annotated one.git push --tagspushes tags, andgit push origin --delete <tag>removes one from the remote.git tag -d <tag>removes it locally.git describenames the current commit relative to the latest tag, for examplev1.0-3-gabc123.
Recovery and investigation
git reflogis the history of where HEAD has been: the lifesaver for commits lost after a bad reset or rebase.git cherry-pick <commit>copies one commit onto the current branch, and-xrecords where it came from.git bisect start, thengit bisect badandgit bisect good <commit>, finds the commit that introduced a bug by binary search.git bisect run <script>automates it, andgit bisect resetends it.
Worktrees
A worktree is a second folder checked out from the same repo, so you can have two branches open at once without cloning again. They share the same .git data, so a git fetch in one updates all of them. Each folder still needs its own node_modules.
git worktree add <path> <branch>checks out an existing branch in a new folder.git worktree add -b <new-branch> <path>creates a branch and checks it out there. Add a start point at the end to branch off somewhere specific.git worktree add --detach <path> <commit>opens a commit in detached HEAD, handy for inspecting or building.git worktree listlists all worktrees, and--porcelaingives machine-readable output.git worktree remove <path>removes one (it must be clean), and--forceremoves it even with changes ⚠️.git worktree move <path> <new-path>relocates one.git worktree lock <path>andunlockprotect one from pruning, for example on removable media.git worktree prunecleans up references to folders you deleted by hand, and-nis the dry run.git worktree repairfixes the links if you moved a folder yourself.
A typical case: you’re mid-feature and a hotfix lands. Instead of stashing, open a second folder:
git worktree add ../hotfix-login main # main checked out in a sibling folder
cd ../hotfix-login
git switch -c hotfix/login-bug # fix it here
# ... fix, commit, push ...
cd ../my-project # your feature work is untouched
git worktree remove ../hotfix-login # clean up
Git won’t check out the same branch in two worktrees at once; use --detach or another branch.
Big repos and housekeeping
git sparse-checkout set <folder>checks out only part of a large repo.git maintenance startschedules background upkeep (fetching, repacking) so the repo stays fast.