datarekha

Git cheat sheet

Everyday Git plus the recovery commands — staging, branching, merging, rebasing, and undoing.

Setup and Config

git config --global user.name "Your Name"          # set name for all repos
git config --global user.email "you@example.com"   # set email for all repos
git config --global core.editor "code --wait"      # VS Code as default editor
git config --global init.defaultBranch main         # default branch name for new repos
git config --global pull.rebase false               # merge strategy on pull (safe default)
git config --list                                   # show all config values
git config --list --show-origin                     # show values + which file they come from
git init                                            # init repo in current directory
git init my-project                                 # init repo in a new folder

The Basic Cycle

git status                          # what's staged, modified, untracked
git status -s                       # short format: M=modified, A=added, ??=untracked

git add file.txt                    # stage one file
git add src/                        # stage an entire directory
git add -p                          # interactively stage hunks (patch mode)
git add .                           # stage everything in current directory

git commit -m "feat: add login"     # commit with inline message
git commit                          # open editor for multi-line message
git commit -am "fix typo"           # stage tracked files + commit in one step

git log                             # full commit history
git log --oneline                   # one commit per line
git log --oneline --graph --all     # visual branch graph
git log -n 5                        # last 5 commits
git log --author="Alice"            # commits by author
git log --since="2 weeks ago"       # commits since date
git log --stat                      # files changed per commit

git diff                            # unstaged changes vs last commit
git diff --staged                   # staged changes vs last commit
git diff HEAD~1                     # working tree vs one commit back
git diff main..feature              # all differences between two branches
git diff --stat main..feature       # just the file summary

.gitignore

# .gitignore syntax
node_modules/       # ignore a directory
*.log               # ignore all .log files
!important.log      # un-ignore a specific file
.env                # ignore env files
dist/               # ignore build output
**/*.test.js        # nested glob — ignore all test files anywhere

git check-ignore -v file.txt        # explain why a file is ignored
git rm --cached file.txt            # stop tracking a file already committed (keep it on disk)
git rm --cached -r node_modules/    # stop tracking a directory already committed

Branching

git branch                          # list local branches
git branch -a                       # list local + remote branches
git branch feature/auth             # create a branch (stay on current)
git switch feature/auth             # switch to branch (modern)
git switch -c feature/auth          # create + switch (modern)
git checkout feature/auth           # switch (classic, still works)
git checkout -b feature/auth        # create + switch (classic)

git branch -d feature/auth          # delete merged branch (safe)
git branch -D feature/auth          # force-delete even if unmerged

git merge feature/auth              # merge feature into current branch
git merge --no-ff feature/auth      # always create a merge commit (keep history)
git merge --squash feature/auth     # squash all changes into staging, then commit manually
git merge --abort                   # bail out of a conflicted merge

Conflict Resolution

git status                          # see which files conflict
# edit conflicted files, remove conflict markers, then:
git add resolved-file.txt
git commit                          # complete the merge

Remotes

git clone https://github.com/user/repo.git          # clone a repo
git clone https://github.com/user/repo.git my-dir   # clone into a specific folder
git clone --depth 1 https://github.com/user/repo    # shallow clone (latest snapshot only)

git remote -v                       # list remotes with URLs
git remote add origin https://github.com/user/repo.git   # add a remote
git remote rename origin upstream   # rename a remote
git remote remove upstream          # remove a remote
git remote set-url origin https://new-url.git            # change remote URL

git fetch origin                    # download changes, don't merge
git fetch --all                     # fetch all remotes
git fetch --prune                   # fetch + remove stale remote-tracking branches

git pull                            # fetch + merge (uses configured strategy)
git pull --rebase                   # fetch + rebase (cleaner history)
git pull origin main                # explicitly pull from origin/main

git push origin feature/auth        # push a branch to remote
git push -u origin feature/auth     # push + set upstream (use bare "git push" after)
git push                            # push current branch to its tracked upstream
git push origin --delete old-branch # delete a remote branch
git push --force-with-lease         # safe force-push (fails if remote has new commits)

GitHub PR Flow

StepCommand
Create feature branchgit switch -c feat/my-feature
Work and commitgit commit -am "..."
Push and set upstreamgit push -u origin feat/my-feature
Open PRGitHub UI or gh pr create
Pull in review feedbackgit commit, git push
Sync with main before mergegit fetch origin && git rebase origin/main
After merge, clean upgit switch main && git pull && git branch -d feat/my-feature
# GitHub CLI shortcuts (install: brew install gh)
gh pr create --title "feat: add auth" --body "Adds JWT login"
gh pr list
gh pr checkout 42       # check out PR #42 locally
gh pr merge 42 --squash # squash-merge PR #42

Rebasing

git rebase main                     # replay current branch on top of main
git rebase --abort                  # bail out, restore original state
git rebase --continue               # after resolving conflicts, continue
git rebase --skip                   # skip the current conflicting commit

git rebase -i HEAD~4                # interactive rebase: last 4 commits
# In the editor, per-commit commands:
# pick   = keep as-is
# reword = keep changes, edit message
# edit   = pause to amend the commit
# squash = meld into previous commit, combine messages
# fixup  = meld into previous commit, discard this message
# drop   = delete the commit entirely

git rebase -i --root                # interactive rebase from the very first commit

The golden rule: never rebase commits that exist on a shared remote branch. Rebase rewrites history — force-pushing rebased commits onto a shared branch breaks everyone else’s clone. Rebase freely on local or personal branches; merge on shared ones.

Stashing

git stash                           # stash tracked modifications
git stash -u                        # also stash untracked files
git stash push -m "WIP: auth form"  # stash with a description
git stash list                      # show all stashes
git stash pop                       # apply latest stash + drop it
git stash apply stash@{2}           # apply a specific stash, keep it in list
git stash drop stash@{0}            # delete a specific stash
git stash clear                     # delete all stashes
git stash branch fix/continue       # create a branch from a stash (avoids conflicts)
git stash show -p stash@{0}         # inspect stash contents as a diff

Undoing Changes

I want to…Command
Discard unstaged edits in a filegit restore file.txt
Discard all unstaged editsgit restore .
Unstage a file (keep edits)git restore --staged file.txt
Undo last commit, keep stagedgit reset --soft HEAD~1
Undo last commit, keep unstagedgit reset --mixed HEAD~1
Nuke last commit + all changesgit reset --hard HEAD~1
Safely undo a pushed commitgit revert HEAD
Amend the last commit messagegit commit --amend -m "new msg"
Add a forgotten file to last commitgit add file.txt && git commit --amend --no-edit
git restore file.txt                # discard unstaged changes to a file
git restore .                       # discard ALL unstaged changes
git restore --staged file.txt       # unstage (move out of index), keep edit
git restore --staged .              # unstage everything

git reset --soft HEAD~1             # undo commit, changes land back in staging
git reset --mixed HEAD~1            # undo commit, changes land in working tree (default)
git reset --hard HEAD~1             # undo commit, changes are gone (destructive)
git reset --hard origin/main        # hard-reset local branch to match remote

git revert HEAD                     # create a new commit that undoes HEAD (safe for shared history)
git revert abc1234                  # revert any commit by hash
git revert HEAD~3..HEAD             # revert a range (newest first)
git revert --no-commit HEAD~3..HEAD # stage the reversals without committing yet

git commit --amend -m "better msg"  # rewrite last commit message
git commit --amend --no-edit        # tack staged changes onto last commit, same message

Recovering Lost Work (Reflog)

Reflog is your safety net. Every time HEAD moves, Git logs it — even after a hard reset or deleted branch.

git reflog                          # full log of HEAD movements with short hashes
git reflog show feature/auth        # reflog for a specific branch

git checkout abc1234                # inspect a "lost" commit (detached HEAD)
git switch -c recovery/auth abc1234 # recreate a branch from a lost commit hash
git reset --hard abc1234            # restore current branch to that point (destructive)
git cherry-pick abc1234             # apply a single lost commit onto current branch

Reflog entries expire after 90 days by default. Act quickly after an accidental --hard reset.

Tags

git tag                             # list all tags
git tag v1.0.0                      # create lightweight tag at HEAD
git tag -a v1.0.0 -m "Release 1.0" # annotated tag (includes tagger info + message)
git tag -a v1.0.0 abc1234 -m "..."  # tag a specific commit
git show v1.0.0                     # show tag details + tagged commit

git push origin v1.0.0              # push a single tag
git push origin --tags              # push all tags
git push origin --follow-tags       # push commits + annotated tags (recommended)

git tag -d v1.0.0                   # delete a local tag
git push origin --delete v1.0.0     # delete a remote tag

Inspecting History

git show HEAD                       # show last commit diff + metadata
git show abc1234                    # show any commit by hash
git show HEAD:src/app.ts            # show a file as it was at that commit

git blame file.txt                  # who changed each line, and when
git blame -L 10,25 file.txt         # blame only lines 10–25
git blame -w file.txt               # ignore whitespace changes

git log --oneline --graph --all --decorate   # pretty branch graph
git log --oneline --follow -- oldname.ts     # follow a renamed file
git log -S "functionName"                    # commits that added/removed the string
git log --diff-filter=D -- deleted-file.txt  # find when a file was deleted

git bisect start                    # begin binary search for a bad commit
git bisect bad                      # mark current commit as bad
git bisect good v1.2.0              # mark a known-good commit
# Git checks out commits in between; keep marking good/bad until it narrows down
git bisect reset                    # end the bisect session

Useful One-Liners

# Discard all local changes (staged and unstaged)
git restore . && git restore --staged .

# Unstage everything
git restore --staged .

# Edit the last commit message
git commit --amend -m "fix: correct typo in header"

# Push to the same remote branch without typing the full ref
git push -u origin HEAD

# Pull with rebase to keep a linear history
git pull --rebase origin main

# See just the files changed in the last commit
git diff --name-only HEAD~1 HEAD

# Count commits since branching from main
git rev-list --count main..HEAD

# Clean up deleted remote branches locally
git remote prune origin

# Remove all untracked files and directories (dry-run first)
git clean -nd
git clean -fd

# List files changed between branches
git diff --name-status main..feature/auth

# Find the commit that introduced a string
git log -S "secretKey" --source --all

# Show remote URL
git remote get-url origin

# Apply changes from one branch file without switching
git checkout feature/auth -- src/config.ts

# Temporarily ignore tracked file changes (useful during experiments)
git update-index --skip-worktree .env
git update-index --no-skip-worktree .env   # undo

# Bundle a repo for offline transfer
git bundle create repo.bundle --all
git clone repo.bundle my-repo

Quick Reference

SituationCommand
Committed to main by mistakegit reset --soft HEAD~1 then switch branch
Pushed a bad commitgit revert HEAD && git push
Need latest main in my branchgit fetch origin && git rebase origin/main
Accidentally deleted a branchfind the commit in git reflog, then git switch -c branch-name COMMIT_SHA
Forgot to add a file to last commitgit add missed.txt && git commit --amend --no-edit
Want to try something riskygit stash or create a temp branch first
Merge is a disaster, bail outgit merge --abort
Rebase is a disaster, bail outgit rebase --abort
Need to move commits to another branchgit cherry-pick the hashes
Hard reset wiped my workgit reflog then git checkout the hash
Go deeper The full Git course →

Explore further

Skip to content