Git Cheat Sheet — Commands by Task

Git commands organised by what you want to do: undo the last commit, rename a branch, delete a remote branch. Modern switch/restore with classic equivalents and danger badges.

Last verified: 2026-10-18 against the git-scm.com reference for Git 2.56 and the GitHub CLI manual. Sources: Git reference (git-scm.com/docs), git restore, git switch, git reset, git config, GitHub CLI manual.

97 commands
Common:

Rewrites history safe only on commits nobody else has pulled · ⚠ Discards work may delete changes for good. Copy buttons leave out the # comments.

Setup (once per machine)

Settings go to ~/.gitconfig with --global. Since Git 2.46 the documented form is git config set / get / list; the classic form still works.

Set your name and email#Git 2.46+
git config set --global user.name "Ana Lee"
git config set --global user.email "ana@example.com"

Classic: git config --global user.name "Ana Lee"

Recorded in every commit you make. Use the email your Git host knows so commits link to your account.

Make new repositories start on main#
git config set --global init.defaultBranch main

Classic: git config --global init.defaultBranch main

Without it, git init still names the first branch master (and prints a hint).

Choose the editor for commit messages#
git config set --global core.editor "code --wait"

Classic: git config --global core.editor "code --wait"

Any command that blocks until the file is closed works: "nano", "vim", "subl -n -w".

Handle Windows / macOS line endings#
git config set --global core.autocrlf true  # Windows
git config set --global core.autocrlf input  # macOS, Linux

Classic: git config --global core.autocrlf true

Commits LF, checks out CRLF on Windows. For a whole team, a .gitattributes file with "* text=auto" is more reliable than per-person settings.

Check which Git version you have#
git --version

git switch and git restore need 2.23+, git config subcommands 2.46+.

Start a repository

Turn a folder into a repository#
git init
git init -b main  # name the first branch

Creates a .git directory. Add a .gitignore before the first commit so build output and secrets never get in.

Copy an existing repository#
git clone https://github.com/owner/repo.git
git clone git@github.com:owner/repo.git my-folder

Downloads the full history and sets the remote "origin". The second form uses SSH and a custom folder name.

Clone only the latest version (faster)#
git clone --depth 1 https://github.com/owner/repo.git

Skips history; good for CI and big repositories. git fetch --unshallow gets the rest later.

Publish a new local repository#
git remote add origin git@github.com:owner/repo.git
git push -u origin main

Create the empty repository on the host first (or use gh repo create, below). -u remembers origin/main as the upstream.

Stage and commit

See what changed#
git status
git status -s  # short form

Lists staged, unstaged and untracked files, and suggests the next command.

Stage files for the next commit#
git add file.txt
git add .  # everything in this folder and below

git add -A stages deletions everywhere in the repository too.

Stage only part of a file#
git add -p file.txt

Walks through each change ("hunk"): y to stage, n to skip, s to split, e to edit.

Commit staged changes#
git commit -m "Add login form"
git commit -am "Fix typo"  # stage tracked files and commit

-a picks up modified and deleted tracked files, never new ones.

Rename or delete a tracked file#
git mv old.txt new.txt
git rm file.txt

Both stage the change for you. Git detects renames by content, so a plain mv plus git add works too.

Stop tracking a file but keep it on disk#
git rm --cached .env
echo ".env" >> .gitignore

Removes it from the repository from the next commit on. It stays in earlier commits: if it held a secret, rotate the secret.

Branches

List branches#
git branch
git branch -a  # include remote branches
git branch -vv  # show upstream and ahead/behind

The current branch is marked with *.

Create a branch and switch to it#Git 2.23+
git switch -c feature/login

Classic: git checkout -b feature/login

Starts from the current commit; add a start point to branch from elsewhere: git switch -c hotfix origin/main.

Switch to another branch#Git 2.23+
git switch main
git switch -  # back to the previous branch

Classic: git checkout main

If only origin/feature exists, git switch feature creates a local tracking branch automatically.

Rename a branch#
git branch -m new-name  # current branch
git branch -m old-name new-name

Renames locally only. To rename on the remote too, see the next entry.

Rename a branch on the remote#
git branch -m old-name new-name
git push -u origin new-name
git push origin --delete old-name

There is no remote rename: push the new name and delete the old one. Open pull requests on the old name may close; GitHub's rename button in the web UI retargets them.

Delete a local branch#⚠ Discards work
git branch -d feature/login
git branch -D feature/login  # even if unmerged

-d refuses if the branch has commits not merged into its upstream or HEAD; -D deletes anyway.

Recovery: Unmerged commits are still in the reflog: git reflog, find the tip, then git branch feature/login <sha>.

Delete a remote branch#⚠ Discards work
git push origin --delete feature/login

Classic: git push origin :feature/login

Teammates still see it until they run git fetch --prune.

Recovery: Anyone with the branch locally (or you, via git reflog) can push it back.

Set or change the upstream branch#
git branch -u origin/main
git push -u origin HEAD  # push current branch and track it

Classic: git branch --set-upstream-to=origin/main

The upstream is what plain git pull and git push use.

Look at an old commit (detached HEAD)#Git 2.23+
git switch --detach a1b2c3d
git switch -c rescue  # keep work made there

Classic: git checkout a1b2c3d

Commits made while detached belong to no branch; create one before switching away or they are only reachable via the reflog.

Merge, rebase and cherry-pick

Merge a branch into the current one#
git switch main
git merge feature/login
git merge --no-ff feature/login  # always create a merge commit

Fast-forwards when possible; --no-ff keeps the branch visible in history.

Squash a branch into one commit#
git merge --squash feature/login
git commit -m "Add login"

Stages the combined changes without recording a merge; the branch is not marked as merged afterwards.

Resolve a merge conflict#
git status  # list conflicted files
# edit the files, remove <<<<<<< ======= >>>>>>> markers
git add file.txt
git commit  # or: git rebase --continue

Take one side wholesale with git restore --ours file.txt or --theirs. During a rebase "ours" is the branch being rebased onto, the reverse of a merge.

Abort a merge in progress#⚠ Discards work
git merge --abort

Returns to the state before the merge started.

Recovery: Conflict resolutions you made are lost. If you had uncommitted changes when the merge started, --abort may not be able to restore them, so commit or stash before merging.

Rebase a branch onto main#Rewrites history
git switch feature/login
git rebase main

Replays your commits on top of main for a linear history. Resolve conflicts, git add, then git rebase --continue; --abort gives up.

Recovery: Right after: git reset --hard ORIG_HEAD. Later: find the old tip in git reflog.

Squash, reorder or reword recent commits#Rewrites history
git rebase -i HEAD~3

Opens a list: change pick to squash/fixup to combine, reword to edit a message, drop to delete, or reorder lines.

Recovery: git reflog shows the commit before the rebase; git reset --hard <sha> restores it.

Fix an older commit#Rewrites history
git commit --fixup=a1b2c3d
git rebase -i --autosquash a1b2c3d~1

The fixup commit is folded into a1b2c3d automatically when you rebase.

Recovery: Same as interactive rebase: git reflog.

Pull without merge commits#
git pull --rebase
git config set --global pull.rebase true  # make it the default

Rebases your local commits on top of what was fetched.

Copy a commit from another branch#
git cherry-pick a1b2c3d
git cherry-pick -x a1b2c3d  # note the source in the message

Creates a new commit with the same changes. A range: git cherry-pick A..B (excludes A).

Remotes: fetch, pull, push

Show and change remotes#
git remote -v
git remote set-url origin git@github.com:owner/repo.git

set-url switches a clone from HTTPS to SSH (or to a renamed repository).

Download changes without merging#
git fetch
git fetch --prune  # also drop deleted remote branches

Updates origin/* only; your branches are untouched.

Update the current branch#
git pull

git fetch plus merge (or rebase, if pull.rebase is set).

Push commits#
git push
git push -u origin HEAD  # first push of a new branch
git config set --global push.autoSetupRemote true

With push.autoSetupRemote (Git 2.37+), a plain git push on a new branch sets the upstream itself.

Force-push safely after rewriting history#Rewrites history
git push --force-with-lease

Refuses if the remote has commits you have not fetched, unlike --force. Add --force-if-includes (Git 2.30+) for extra safety with background fetches.

Recovery: Overwritten remote commits survive in the reflog of whoever had them, and GitHub keeps them reachable by SHA for a while.

Update a fork from the original repository#
git remote add upstream https://github.com/original/repo.git
git fetch upstream
git switch main
git merge upstream/main

Or with GitHub CLI: gh repo sync.

Undo things

Pick by where the mistake is: in the working tree, in the staging area, in a local commit, or in a commit already pushed. Anything that was ever committed can usually be found again with git reflog; uncommitted edits that you discard cannot.

Undo the last commit (keep the changes)#Rewrites history
git reset --soft HEAD~1

The commit disappears; its changes stay staged, ready to recommit. Use git reset HEAD~1 (no --soft) to keep them unstaged instead.

Recovery: git reset ORIG_HEAD brings the commit back. If it was already pushed, use git revert instead.

Throw away the last commit and its changes#⚠ Discards work
git reset --hard HEAD~1

Moves the branch back one commit and resets every tracked file to match.

Recovery: The commit is in git reflog (unreachable entries expire after 30 days by default): git reset --hard HEAD@{1}. Uncommitted changes in tracked files are gone for good.

Undo a commit that is already pushed#
git revert a1b2c3d
git revert HEAD  # the latest commit

Adds a new commit that reverses the old one, so nobody else's history changes. This is the safe undo for shared branches.

Revert a merge commit#
git revert -m 1 <merge-sha>

-m 1 keeps the first parent (usually main). Re-merging the branch later needs a revert of this revert first.

Change the last commit message#Rewrites history
git commit --amend -m "Better message"

Replaces the last commit with a new one. Fine before pushing; after pushing it needs --force-with-lease.

Recovery: git reset --soft HEAD@{1} returns to the commit before the amend.

Add a forgotten file to the last commit#Rewrites history
git add forgotten.txt
git commit --amend --no-edit

Keeps the message, adds the file.

Recovery: git reset --soft HEAD@{1}.

Unstage a file (undo git add)#Git 2.23+
git restore --staged file.txt
git restore --staged .  # everything

Classic: git reset HEAD file.txt

Changes stay in the working tree; only the staging is undone.

Discard changes to a file#⚠ Discards workGit 2.23+
git restore file.txt

Classic: git checkout -- file.txt

Resets the file to the staged version (or the last commit if nothing is staged).

Recovery: Not recoverable from Git: the edits were never committed. Your editor's local history may still have them.

Discard all local changes#⚠ Discards workGit 2.23+
git restore --staged --worktree .
git clean -fd  # also delete untracked files

Classic: git reset --hard git clean -fd

Back to the last commit. Run git clean -n first to see what would be deleted.

Recovery: Not recoverable: uncommitted edits and untracked files are deleted. git stash -u is the reversible alternative.

Restore a deleted file#Git 2.23+
git restore file.txt  # deletion not committed
git restore --source=a1b2c3d~1 file.txt  # deleted in commit a1b2c3d

Classic: git checkout a1b2c3d~1 -- file.txt

Find the commit that deleted it with git log --diff-filter=D -- file.txt.

Get a file as it was in another commit or branch#⚠ Discards workGit 2.23+
git restore --source=main -- config.yml

Classic: git checkout main -- config.yml

Overwrites the working copy only; add --staged --worktree to stage it too. To just look: git show main:config.yml.

Recovery: Uncommitted edits to that file are overwritten.

Find lost commits or a deleted branch#
git reflog
git branch rescued a1b2c3d

The reflog records every place HEAD has been. Find the SHA from before the mistake and put a branch on it.

Undo a merge you have not pushed#⚠ Discards work
git reset --hard ORIG_HEAD

ORIG_HEAD is set by merge, rebase and reset to where you were before. It is overwritten by the next such command.

Recovery: git reflog still lists the merge commit.

Undo a rebase#⚠ Discards work
git reflog  # find "rebase (start)"; the entry below it is the old tip
git reset --hard HEAD@{5}

Straight after the rebase, git reset --hard ORIG_HEAD does the same.

Recovery: Uncommitted changes are discarded by --hard; stash them first.

Undo a git reset#⚠ Discards work
git reset --hard HEAD@{1}

HEAD@{1} is where HEAD was before the last move. Works for committed work only.

Remove a committed secret or huge file from history#Rewrites history
git filter-repo --invert-paths --path secrets.env

git filter-repo is a separate tool (pip install git-filter-repo), recommended by the git-filter-branch docs. Every clone must re-clone afterwards. Rotate the secret regardless: it was public from the moment it was pushed.

Recovery: filter-repo works on a fresh clone; keep the old clone until you are sure.

Stash

Put work aside temporarily#
git stash
git stash push -m "half-done login"
git stash -u  # include untracked files

Saves tracked changes and cleans the working tree so you can switch branches.

Bring stashed work back#
git stash pop  # apply and drop
git stash apply stash@{1}  # apply, keep the stash

Conflicts are possible; with pop, the stash is kept if applying fails.

List and inspect stashes#
git stash list
git stash show -p stash@{0}

Newest first; stash@{0} is the latest.

Stash only some files#
git stash push -- src/login.ts
git stash push --staged  # only what is staged (2.35+)

Path-limited stashes leave everything else in place.

Turn a stash into a branch#
git stash branch feature/login stash@{0}

Creates the branch at the commit where you stashed, applies the stash and drops it; avoids conflicts.

Delete stashes#⚠ Discards work
git stash drop stash@{0}
git stash clear

clear removes every stash.

Recovery: A dropped stash is an unreachable commit until garbage collection: git fsck --unreachable | grep commit, then git stash apply <sha>.

History and diffs

Show history as a graph#
git log --oneline --graph --all

One line per commit with branch structure. Add --decorate on very old Git to see branch names.

History of one file#
git log --follow -p -- path/file.txt

--follow continues across renames; -p shows each change.

Commits by author or date#
git log --author="Ana" --since="2 weeks ago" --oneline

Also --until, --grep="fix" for messages, and main..feature for commits on feature but not main.

Show one commit or an old file version#
git show a1b2c3d
git show a1b2c3d:path/file.txt

The second form prints the file as it was in that commit without touching your copy.

See changes not yet committed#
git diff  # unstaged
git diff --staged  # staged, i.e. what will be committed

--stat summarises per file; --word-diff is better for prose.

Compare two branches#
git diff main...feature  # changes on feature since it branched
git diff main feature  # the two tips directly

Three dots compare against the merge base, which is what a pull request shows.

Who changed each line#
git blame -L 10,20 path/file.txt

Add -w to ignore whitespace and -C to follow lines moved from other files.

Find the commit that introduced a bug#
git bisect start
git bisect bad  # current commit is broken
git bisect good v1.4.0  # this one worked
# test, then mark each step good or bad
git bisect reset

Binary search: about log2(n) steps. git bisect run ./test.sh automates it.

Search the tracked files#
git grep -n "TODO"

Faster than grep on large repositories and skips ignored files. Add a commit to search an old version.

Tags and releases

Tag a release#
git tag -a v1.2.0 -m "Release 1.2.0"
git tag -a v1.1.1 a1b2c3d -m "Hotfix"  # tag an older commit

Annotated tags (-a) store author, date and message; prefer them for releases. git tag v1.2.0 alone makes a lightweight tag.

Push tags#
git push origin v1.2.0
git push --follow-tags  # annotated tags reachable from pushed commits

git push does not send tags by default. git push --tags sends every tag, including stray local ones.

Delete a tag locally and on the remote#⚠ Discards work
git tag -d v1.2.0
git push origin --delete v1.2.0

Avoid re-using a deleted release tag name: other clones keep the old tag.

Recovery: The tagged commit is unaffected; re-create the tag on it.

List tags and describe the current version#
git tag -l "v1.*"
git describe --tags

describe prints the nearest tag plus commits since, e.g. v1.2.0-3-ga1b2c3d.

Submodules and worktrees

Add a submodule#
git submodule add https://github.com/owner/lib.git vendor/lib
git commit -m "Add lib submodule"

Records the URL in .gitmodules and pins an exact commit of the other repository.

Get submodules after cloning#
git clone --recurse-submodules <url>
git submodule update --init --recursive  # already cloned

Without this, submodule folders are empty.

Move submodules to their latest commit#
git submodule update --remote
git commit -am "Bump submodules"

Fetches each submodule's tracked branch; commit the new pins in the parent.

Work on two branches at once#
git worktree add ../repo-hotfix hotfix
git worktree add -b review ../repo-review origin/main

A second working folder sharing the same repository; no stash or second clone needed.

List and remove worktrees#
git worktree list
git worktree remove ../repo-hotfix
git worktree prune  # forget folders deleted by hand

remove refuses if the worktree has uncommitted changes (use --force to override).

Cleaning up

Preview which untracked files would be deleted#
git clean -n -d

Always run this before git clean -f.

Delete untracked files#⚠ Discards work
git clean -fd  # untracked files and folders
git clean -fdx  # also ignored files (build output, .env!)

-x removes ignored files too, which includes local config such as .env.

Recovery: Not recoverable: these files were never in Git.

Delete branches already merged into main#
git branch --merged main
git branch -d branch-a branch-b

Review the list first; -d refuses unmerged branches, so it is safe to try.

Remove stale remote-tracking branches#
git fetch --prune
git config set --global fetch.prune true

Drops origin/* refs whose branches were deleted on the server.

Speed up a big repository#
git maintenance start
git gc

maintenance start schedules background prefetch, commit-graph and repack jobs; gc packs objects and prunes unreachable ones now.

Config and aliases

See all settings and where they come from#Git 2.46+
git config list --show-origin

Classic: git config --list --show-origin

Shows system, global and repository values with the file each one is in.

Create an alias#Git 2.46+
git config set --global alias.st "status -s"
git config set --global alias.lg "log --oneline --graph --all"

Classic: git config --global alias.st "status -s"

Then git st and git lg. Prefix with ! to run a shell command: alias.root "!pwd".

Useful defaults worth setting#Git 2.46+
git config set --global pull.rebase true
git config set --global push.autoSetupRemote true
git config set --global rerere.enabled true
git config set --global merge.conflictStyle zdiff3
git config set --global diff.algorithm histogram

Classic: git config --global pull.rebase true

Rebase on pull; auto upstream on first push (2.37+); remember conflict resolutions; show the common ancestor in conflicts (2.35+); clearer diffs.

Ignore files in every repository#
git config set --global core.excludesFile ~/.gitignore_global

Classic: git config --global core.excludesFile ~/.gitignore_global

For OS and editor clutter (.DS_Store, .idea/). Project-specific rules belong in the repository's .gitignore.

GitHub CLI (gh) basics

gh is GitHub's own command-line tool, installed separately from Git.

Log in to GitHub#
gh auth login
gh auth setup-git  # let git use gh for HTTPS credentials

Opens a browser or takes a token; works for github.com and GitHub Enterprise.

Create a GitHub repository from a local folder#
gh repo create my-app --private --source=. --push

Creates the repository, adds it as origin and pushes the current branch.

Clone by owner/name#
gh repo clone owner/repo

For a fork, also adds the parent repository as the upstream remote.

Open a pull request#
gh pr create --fill
gh pr create --draft --title "WIP: login" --body "…"

--fill uses the commit messages for the title and body.

Check out someone's pull request#
gh pr checkout 123

Fetches the PR branch (forks included) and switches to it.

List, view and merge pull requests#
gh pr list
gh pr view 123 --web
gh pr merge 123 --squash --delete-branch

gh pr status shows PRs relevant to you.

Create and list issues#
gh issue create --title "Bug: …" --body "…"
gh issue list --assignee @me

gh issue view 42 --comments reads a thread in the terminal.

Watch GitHub Actions runs#
gh run list
gh run watch

gh run view --log-failed prints only the failing steps.

Need a starting .gitignore? Use the .gitignore generator. Comparing two versions of a file outside Git? The diff checker shows the changes side by side.

A static reference: search runs in your browser and nothing you type is sent anywhere. Browse all free tools.

Found a problem, or something that could be better? We read every message and we fix things quickly.

This git cheat sheet is organised by task, not by command, because nobody searches for “git reset --soft”; they search for “undo last commit”. Find what you are trying to do, copy the command, and read the one-line explanation of what it changes. Search ranks tasks first, so “delete remote branch” or “rename branch” goes straight to the right entry.

Commands that rewrite history or throw work away are marked, with a note on what can be recovered: almost anything that was ever committed can be found again with git reflog, while uncommitted edits you discard with restore, reset --hard or clean are gone. Where Git now has a clearer command (git switch and git restore since 2.23, git config set and list since 2.46), that is shown first with the classic form alongside, so the sheet works whether your team learned Git last year or in 2010. Checked against the git-scm.com reference for Git 2.56.

How to use

  1. Type what you want to do in the search box, such as “undo last commit”, “unstage” or “squash commits”, or click one of the common tasks.
  2. Read the badges before you run anything: amber means the command rewrites history, red means it can discard work. The recovery note says how to get back.
  3. Click Copy command. The copy leaves out the # comments so it pastes cleanly into a terminal; replace placeholders such as a1b2c3d or feature/login with your own.
  4. Share a specific answer with the # link next to each task, or print the whole sheet as a two-column PDF.

Frequently asked questions

How do I undo the last commit in git?

If you have not pushed it, git reset --soft HEAD~1 removes the commit and keeps its changes staged, and git reset HEAD~1 keeps them unstaged. git reset --hard HEAD~1 removes the commit and its changes. If the commit is already pushed to a shared branch, use git revert HEAD instead, which adds a new commit that undoes it without rewriting anyone's history.

What is the difference between git reset, git restore and git revert?

git restore changes files: it discards edits in the working tree or unstages them, and never moves a branch. git reset moves the current branch to another commit (and with --hard also overwrites your files), so it rewrites history. git revert creates a new commit that applies the opposite of an earlier one; history only grows, which makes it the safe choice on branches other people use.

How do I rename a git branch, locally and on the remote?

git branch -m new-name renames the branch you are on (git branch -m old new for another one). Remotes have no rename operation, so push the new name with git push -u origin new-name and delete the old one with git push origin --delete old-name. On GitHub, renaming the branch in the web interface also retargets open pull requests.

Should I use git switch or git checkout?

Either works. git checkout does two unrelated jobs, switching branches and restoring files, which is why Git 2.23 split them into git switch and git restore. The new commands are clearer and harder to misuse (git checkout -- file silently discards edits), so this sheet shows them first. git checkout is not deprecated and every command here lists its classic equivalent.

Can I recover a commit after git reset --hard?

Usually, yes. Run git reflog, find the line from before the reset, and run git reset --hard HEAD@{n} or create a branch on that SHA. Commits stay reachable through the reflog for 30 days by default once nothing else points to them. What cannot be recovered is uncommitted work: changes that were never committed or stashed are overwritten for good.

What does git push --force-with-lease do?

It overwrites the remote branch only if the remote still points where your last fetch saw it. If someone pushed in the meantime, the push is refused instead of silently deleting their commits, which is what plain --force does. Use it after a rebase or amend on a branch you have already pushed.

Which undo command? Decide by where the change is

• Edited a file and want the edit gone: git restore file. Not recoverable, because it was never committed.

• Staged something by mistake: git restore --staged file. Nothing is lost; the edit stays in the file.

• Committed but not pushed: git reset --soft HEAD~1 to redo the commit, or git commit --amend to fix it in place.

• Committed and pushed to a shared branch: git revert <sha>. Do not reset a branch other people have pulled.

• Lost a commit, a branch or the result of a bad rebase: git reflog, then git branch rescued <sha>.

The rule underneath: anything that rewrites commits is fine while the commits are only yours, and becomes everyone's problem once they are shared.

Merge or rebase?

Both bring the changes from one branch into another. A merge records that two histories joined, with a merge commit that has two parents; nothing is rewritten, so it is always safe on shared branches. A rebase replays your commits on top of the other branch, producing a straight line of history as if you had started from the latest commit, but it creates new commit IDs, so anyone who already has the old ones must reconcile.

A common team convention: rebase your own feature branch onto main to stay current (git pull --rebase, or git rebase main), and merge the finished branch into main through a pull request. Squash-merging gives one commit per feature on main; plain merges keep every commit and the branch shape. Pick one per repository and set it in the host's settings, so history stays consistent.

Git settings worth changing from the defaults

• pull.rebase true: git pull rebases instead of creating merge commits for every sync.

• push.autoSetupRemote true (Git 2.37+): the first git push of a new branch sets its upstream, no -u needed.

• merge.conflictStyle zdiff3 (Git 2.35+): conflict markers include the common ancestor, which makes most conflicts obvious.

• rerere.enabled true: Git remembers how you resolved a conflict and reapplies it when the same conflict comes back during a rebase.

• fetch.prune true: remote branches deleted on the server disappear locally on the next fetch.

• init.defaultBranch main: new repositories start on main.

Related free tools

  • .gitignore Generator — Combine .gitignore templates for languages, frameworks, editors and operating systems into one clean file.
  • Diff Checker — Compare two versions of a text, code or JSON file and see exactly which lines, words and characters changed.
  • Markdown Cheat Sheet — Every Markdown element with source and rendered preview, extended syntax (tables, task lists, footnotes, math, Mermaid, alerts), a 9-platform compatibility table and a live playground.
  • Regex Cheat Sheet — Every regular expression token with a working example, support in JavaScript, PCRE/PHP, Python, Go, Java and .NET, and a Try it link that opens the regex tester pre-filled.