# Git Cheat Sheet: Branches, Undo, Remotes and Deploys

Source: https://srvscripts.com/guides/git-cheat-sheet/
Updated: 2026-10-09
Publisher: srvScripts (https://srvscripts.com/)

**Short answer:** Day to day, Git comes down to `git status`, `git add`, `git commit`, `git log` and `git diff`. You also need `git switch` and `git merge` for branches, `git fetch`, `git pull` and `git push` for remotes. To undo, use `git restore` for files, `git revert` for shared commits and `git reset` for local ones. `git reflog` finds commits you thought were lost. The tables below group the commands by task.

The examples in this Git cheat sheet were run with Git 2.43.0 in a scratch repository on 9 October 2026, including the merge, rebase, revert, reset, stash and push-to-deploy steps.

## Setup and first commit

| Command | What it does |
| --- | --- |
| git config --global user.name "Jane Admin" | Name recorded in commits (also set user.email) |
| git config --list --show-origin | Every setting and the file it comes from |
| git init -b main | New repository with main as the first branch |
| git clone https://example.com/repo.git | Copy a remote repository. Use git@host:repo.git for SSH |
| git status --short | Compact status: ?? untracked, M modified, M staged |
| git add nginx.conf / git add -A | Stage one file / everything, including deletions |
| git add -p | Stage hunk by hunk; answer y or n for each change |
| git commit -m "Add nginx config" | Commit what is staged |
| git commit -am "msg" | Stage tracked files and commit in one step (new files are not included) |
| git check-ignore -v .env | Which .gitignore line ignores a file |

A `.gitignore` for a config repository usually starts with secrets and noise:

```
*.log
.env
*.key
*.pem
```

## Viewing changes and history

| Command | What it does |
| --- | --- |
| git diff | Unstaged changes |
| git diff --staged | What the next commit will contain |
| git diff --stat HEAD~3 | Files changed in the last three commits, with line counts |
| git log --oneline --graph --decorate --all | Compact history of every branch as a graph |
| git log --since="2026-10-01" --author="Jane" --format='%h %an %ad %s' --date=short | Filter by date and author with a custom format |
| git log -p -S 'ssl_protocols' -- nginx.conf | Commits that added or removed a string (the “pickaxe”) |
| git show --stat HEAD | Last commit: message and files |
| git show HEAD~2:nginx.conf | A file as it was two commits ago |
| git blame -L 10,20 nginx.conf | Who last changed lines 10 to 20, and in which commit |
| git shortlog -sn HEAD | Commit count per author |
| git grep -n gzip | Search tracked files only |

In a script or cron job, give `git shortlog` an explicit revision such as `HEAD`. Without one, and with no terminal attached, it waits to read a log from standard input, and our test run hung until it was stopped.

## Branches and merging

| Command | What it does |
| --- | --- |
| git switch -c feature/tls | Create a branch and move to it (older form: git checkout -b) |
| git switch main | Move to an existing branch |
| git branch -a | Local and remote-tracking branches |
| git branch --show-current | Current branch name, handy in prompts and scripts |
| git merge --no-ff feature/tls | Merge and always create a merge commit |
| git merge --ff-only feature/tls | Merge only if no merge commit is needed; otherwise stop |
| git rebase main | Replay the current branch on top of main for a straight history |
| git cherry-pick 8605c9c | Copy one commit onto the current branch |
| git branch --merged | Branches already merged into the current one, safe to delete |
| git branch -d feature/tls / -D | Delete a merged branch / force-delete an unmerged one |

Only rebase commits that nobody else has pulled. Rebasing rewrites commit IDs, and anyone who based work on the old ones will have to untangle it.

## Undoing changes

| Situation | Command |
| --- | --- |
| Discard edits to a file | git restore nginx.conf |
| Unstage a file but keep the edits | git restore --staged nginx.conf |
| Bring back an older version of a file | git restore --source=HEAD~2 nginx.conf |
| Fix the last commit message or add a forgotten file | git add file then git commit --amend -m "New message" |
| Undo a pushed commit safely | git revert  (adds a new commit that reverses it) |
| Undo a merge commit | git revert -m 1  (without -m, Git refuses) |
| Remove the last commit, keep its changes staged | git reset --soft HEAD~1 |
| Remove the last commit, keep changes unstaged | git reset HEAD~1 (the default --mixed) |
| Throw away the last commit and all local changes | git reset --hard HEAD~1 |
| Find a lost commit | git reflog, then git switch -c rescue  |
| Delete untracked files | git clean -n to preview, then git clean -f (-d for directories) |

`git reset --hard` and `git clean -f` delete uncommitted work for good. The reflog can bring back commits, but never changes that were not committed. Use `revert`, not `reset`, on branches that others have pulled.

## Stashing work in progress

| Command | What it does |
| --- | --- |
| git stash push -m "wip readme" | Put tracked changes aside and clean the working tree |
| git stash -u | Include untracked files as well |
| git stash list | Stashes, newest as stash@{0} |
| git stash pop | Re-apply the newest stash and drop it |
| git stash apply stash@{1} | Re-apply a stash but keep it in the list |
| git stash drop stash@{1} | Delete one stash |

## Remotes, fetch, pull and push

| Command | What it does |
| --- | --- |
| git remote -v | Configured remotes and their URLs |
| git remote add origin git@example.com:ops/configs.git | Add a remote |
| git push -u origin main | First push; sets upstream so later git push and git pull need no arguments |
| git fetch origin | Download new commits without touching your files |
| git status -sb | Shows [behind 1] or [ahead 2] against the upstream |
| git log --oneline main..origin/main | Commits on the remote that you do not have yet |
| git pull --rebase | Fetch, then replay your local commits on top |
| git push --force-with-lease | Force-push only if the remote has not moved since your last fetch. Safer than --force |

## Tags and releases

| Command | What it does |
| --- | --- |
| git tag -a v1.0 -m "First release" | Annotated tag (stores author, date and message) |
| git tag -l | List tags |
| git describe --tags | Nearest tag, plus commits since it, for version strings |
| git push origin v1.0 / git push origin --tags | Tags are not pushed by default |
| git switch --detach v1.0 | Check out a tag to inspect it |

## Deploying configs with Git

For server admins, a bare repository with a `post-receive` hook is a simple way to deploy configuration or a static site on push. On the server:

```
git init --bare /srv/git/site.git
cat > /srv/git/site.git/hooks/post-receive
