Git Commands Cheat Sheet

Most used
git status                        # what changed?
git add -p                        # stage changes interactively
git commit -m "Fix login timeout" # commit staged changes
git switch -c feature/login       # create and switch to a branch
git pull --rebase                 # update from the remote, linear history
git push -u origin feature/login  # push a new branch and track it

Install Git and set it up first: see installing and configuring Git on Linux. For pushing to GitHub or GitLab over SSH, you need a key: set up SSH keys. Commands here use the modern git switch and git restore; older tutorials use git checkout for both.

Setup and config

CommandWhat it does
git config --global user.name "Your Name"Name recorded in commits
git config --global user.email [email protected]Email recorded in commits
git config --global init.defaultBranch mainName new repositories' first branch main
git config --global core.editor vimEditor for commit messages
git config --global pull.rebase trueMake git pull rebase instead of merge
git config --global push.autoSetupRemote trueFirst git push on a new branch sets upstream automatically
git config --global alias.lg "log --oneline --graph --all"Create a shortcut: git lg
git config --list --show-originAll settings and the file each comes from
git initTurn the current directory into a repository
git clone URL [dir]Copy a remote repository
git clone --depth 1 URLShallow clone: latest commit only, much faster

Staging and committing

CommandWhat it does
git status -sbShort status with branch info
git add fileStage a file
git add .Stage all changes in the current directory and below
git add -pChoose hunks to stage interactively
git restore --staged fileUnstage a file (keep the change in the working tree)
git commit -m "message"Commit what is staged
git commit -am "message"Stage all tracked modified files and commit (new files are not included)
git commit --amendChange the last commit's message or add forgotten changes
git commit --amend --no-editAdd staged changes to the last commit, same message
git rm fileDelete a file and stage the deletion
git rm --cached fileStop tracking a file but keep it on disk
git mv old newRename and stage

Branches

CommandWhat it does
git branchList local branches (-a includes remote ones, -vv shows tracking)
git switch nameSwitch to a branch
git switch -c nameCreate a branch and switch to it
git switch -Switch back to the previous branch
git switch --detach v1.2.0Check out a tag or commit without a branch
git branch -m new-nameRename the current branch
git branch -d nameDelete a merged branch (-D forces)
git branch --merged mainBranches already merged into main
git worktree add ../hotfix hotfix-branchCheck out another branch in a second directory at the same time

Merging and rebasing

CommandWhat it does
git merge featureMerge feature into the current branch
git merge --no-ff featureAlways create a merge commit
git merge --squash featureStage all of feature's changes as one commit to make
git merge --abortGive up a merge with conflicts
git rebase mainReplay current branch's commits on top of main
git rebase -i HEAD~5Edit, squash, reorder or drop the last 5 commits
git rebase --continue / --abortAfter fixing conflicts / give up the rebase
git cherry-pick abc1234Apply one commit from elsewhere onto the current branch
git diff --name-only --diff-filter=UList files that still have conflicts
git mergetoolOpen a configured merge tool for conflicts

Remotes: fetch, pull, push

CommandWhat it does
git remote -vList remotes and their URLs
git remote add origin [email protected]:user/repo.gitAdd a remote
git remote set-url origin URLChange a remote's URL (e.g. HTTPS to SSH)
git fetchDownload new commits without changing your branches
git fetch --pruneAlso remove references to deleted remote branches
git pullFetch and integrate the upstream branch
git pull --rebaseFetch and rebase local commits on top
git pushPush the current branch to its upstream
git push -u origin namePush a new branch and set its upstream
git push --force-with-leaseOverwrite the remote branch only if nobody else pushed meanwhile
git push origin --delete nameDelete a remote branch
git push --tagsPush all tags

Undoing things

Know what is recoverable

Committed work can almost always be recovered with git reflog. Uncommitted changes discarded with restore, reset --hard or clean are gone. Commit or stash first if in doubt.

CommandWhat it does
git restore fileDiscard unstaged changes to a file
git restore --source=HEAD~2 fileGet a file as it was two commits ago
git reset --soft HEAD~1Undo the last commit, keep changes staged
git reset HEAD~1Undo the last commit, keep changes unstaged (--mixed, the default)
git reset --hard HEAD~1Undo the last commit and throw its changes away
git reset --hard origin/mainMake the branch exactly match the remote (local work lost)
git revert abc1234New commit that reverses a commit (safe for pushed history)
git clean -n then git clean -fdPreview, then delete untracked files and directories
git reflogEvery position HEAD has been in; find "lost" commits
git reset --hard HEAD@{2}Go back to a reflog entry

Stash, history and diffs

CommandWhat it does
git stashSet aside uncommitted changes to tracked files
git stash -u -m "wip login"Include untracked files and add a description
git stash listList stashes
git stash popReapply the latest stash and remove it
git stash apply stash@{1}Reapply a stash and keep it
git log --oneline --graph --allCompact history graph of all branches
git log -p fileHistory of one file with diffs
git log -S 'functionName'Commits that added or removed a string
git log --since='2 weeks ago' --author=aliceFilter by date and author
git diffUnstaged changes
git diff --stagedStaged changes (what will be committed)
git diff main...featureChanges on feature since it branched from main
git show abc1234One commit with its diff
git blame -L 10,30 fileWho last changed lines 10-30
git bisect start, bad, good v1.0Binary-search for the commit that introduced a bug
git tag -a v1.0 -m "Release 1.0"Create an annotated tag

Common recipes

Start a feature, keep it up to date, and push it:

git switch main && git pull
git switch -c feature/search
# ...work and commit...
git fetch origin
git rebase origin/main
git push -u origin feature/search

Committed to main by mistake? Move the commit to a new branch:

git branch feature/oops        # new branch points at your commit
git reset --hard origin/main   # move main back to the remote state
git switch feature/oops

Squash your last 3 commits into one before opening a pull request:

git reset --soft HEAD~3
git commit -m "Add search feature"
git push --force-with-lease

Stop tracking a file that is now in .gitignore:

echo '.env' >> .gitignore
git rm --cached .env
git commit -m "Stop tracking .env"

Switch a repository from HTTPS to SSH:

git remote set-url origin [email protected]:user/repo.git
ssh -T [email protected]     # test the key

Recover a branch you deleted:

git reflog | grep 'feature/x'
git branch feature/x abc1234

Clean up merged local branches:

git fetch --prune
git branch --merged main | grep -vE '^\*|^\s*main$' | xargs -r git branch -d

Gotchas

  • "fatal: detected dubious ownership in repository". Git refuses to work in a repository owned by another user (common with sudo, Docker volumes and shared drives). See fixing dubious ownership; don't blindly set safe.directory '*'.
  • Don't rewrite pushed history. reset, rebase and --amend create new commits. If others pulled the old ones, use revert. When you must force-push your own branch, use --force-with-lease, never plain --force.
  • git commit -a skips new files. Untracked files must be added with git add first.
  • HEAD~1 vs HEAD^. They're the same for one step; HEAD^2 means the second parent of a merge, while HEAD~2 means two commits back.
  • Divergent branches warning on pull. Git asks you to choose. Set git config --global pull.rebase true (or pull.ff only) once.
  • Line endings. Files edited on Windows show every line as changed. On Linux set core.autocrlf input, or add a .gitattributes with * text=auto.
  • Secrets in history. Deleting a committed password in a new commit doesn't remove it from history. Rotate the secret; rewriting history needs git filter-repo.

Reference: the official Git documentation and the free Pro Git book. Containers next: Docker commands cheat sheet.

Frequently asked questions

How do I undo the last commit but keep my changes?

git reset --soft HEAD~1 removes the commit and leaves the changes staged. If you already pushed it, use git revert HEAD instead so you don't rewrite shared history.

What is the difference between git switch and git checkout?

git switch only changes branches and git restore only restores files; together they split up the overloaded git checkout. Both have existed since Git 2.23 and are what git status suggests in its hints.

How do I delete a branch locally and on the remote?

git branch -d name deletes it locally (-D forces it if unmerged) and git push origin --delete name deletes it on the remote.

What is the difference between merge and rebase?

Merge joins two histories with a merge commit and keeps everything as it happened. Rebase replays your commits on top of another branch for a linear history, but rewrites those commits, so don't rebase commits others have already pulled.

How do I discard all local changes?

git restore . discards unstaged changes to tracked files and git clean -fd deletes untracked files. git reset --hard also discards staged changes. These can't be undone, so check git status first.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.