Contents
  1. git diff
  2. git log
  3. git reset
  4. git stash
  5. git fetch
  6. fetch —prune
  7. git cherry-pick
  8. Conflicts during cherry-pick
  9. -n / --no-commit
  10. git worktree
  11. Listing and removing worktrees
  12. When worktree is useful
  13. git rebase
  14. git reflog
  15. git bisect
  16. Quick Reference
← All posts

Git: Everyday Commands and Advanced Tools

A practical reference for the git commands you reach for most — diff, reset, fetch, log, stash — plus advanced tools like cherry-pick and worktree that solve specific problems cleanly.

git diff

git diff shows what has changed but not yet been staged. git diff --cached (or --staged) shows what is staged and ready to commit. git diff HEAD shows everything changed since the last commit, staged or not.

git diff                   # unstaged changes
git diff --cached          # staged changes
git diff HEAD              # all changes since last commit
git diff HEAD~2 HEAD       # changes between two commits
git diff main feature/foo  # diff between two branches

Adding --stat gives a summary of which files changed and how many lines, without showing the full diff content. Useful for a quick overview before reviewing.

git diff --stat
git diff --stat HEAD~1 HEAD

git log

git log is the history viewer. The default output is verbose. Most of the time you want a condensed view.

git log --oneline          # one line per commit
git log --oneline -10      # last 10 commits
git log --oneline --graph  # ASCII branch graph
git log --oneline --graph --all  # all branches in the graph

Filtering by author, date, or file:

git log --author="Brian"
git log --since="2024-01-01" --until="2024-06-01"
git log -- src/components/PostCard.astro  # commits that touched a specific file

Searching commit messages:

git log --grep="fix"       # commits whose message contains "fix"

git reset

git reset moves the current branch pointer and optionally changes the index and working tree. The three modes differ in how much they touch:

ModeBranch pointerIndex (staging)Working tree
--softMovesUnchangedUnchanged
--mixed (default)MovesClearedUnchanged
--hardMovesClearedCleared
git reset HEAD~1           # undo last commit, keep changes staged (--mixed)
git reset --soft HEAD~1    # undo last commit, keep changes staged
git reset --hard HEAD~1    # undo last commit, discard all changes
git reset HEAD src/foo.ts  # unstage a specific file

--hard is destructive. The working tree changes are gone. Use with care.


git stash

Stash saves your current working tree and index state so you can switch branches or pull without committing half-finished work.

git stash                  # stash everything (tracked files)
git stash -u               # include untracked files
git stash push -m "wip: refactor header"  # named stash
git stash list             # see all stashes
git stash pop              # apply most recent stash and drop it
git stash apply stash@{2}  # apply a specific stash without dropping it
git stash drop stash@{0}   # delete a specific stash
git stash clear            # delete all stashes

pop = apply + drop. Prefer apply when you want to keep the stash around in case the apply goes wrong.


git fetch

git fetch downloads changes from the remote without merging them into your working branch. It updates origin/* tracking refs so you can inspect what changed before integrating.

git fetch                  # fetch all remotes
git fetch origin           # fetch a specific remote
git fetch origin main      # fetch a specific branch

fetch —prune

--prune removes remote-tracking refs that no longer exist on the remote. If a branch was deleted on GitHub, origin/that-branch will linger locally until you prune.

git fetch --prune
git fetch --prune --all    # prune from all remotes

You can set this to happen automatically on every fetch:

git config --global fetch.prune true

git cherry-pick

Cherry-pick applies the changes introduced by one or more commits onto the current branch, creating new commits with the same diff but different SHAs.

git cherry-pick <sha>                 # apply a single commit
git cherry-pick <sha1> <sha2>         # apply multiple commits
git cherry-pick <sha1>..<sha2>        # apply a range (exclusive of sha1)
git cherry-pick <sha1>^..<sha2>       # apply a range (inclusive of sha1)

Common use cases:

  • A hotfix was committed to main and needs to go to release too
  • A useful commit from a feature branch that got abandoned
  • Moving a commit that was made on the wrong branch

Conflicts during cherry-pick

If there’s a conflict, git pauses and lets you resolve it:

# resolve conflicts in your editor, then:
git add <resolved-files>
git cherry-pick --continue

# or abort entirely:
git cherry-pick --abort

-n / --no-commit

Apply the changes to your working tree and index without immediately committing. Useful when you want to squash multiple cherry-picks into one commit.

git cherry-pick -n <sha1> <sha2>
# make any additional edits
git commit -m "apply fixes from main"

git worktree

A worktree lets you check out a different branch in a separate directory, while your main working directory stays on its current branch. Both are backed by the same .git directory, no cloning needed.

Added in Git 2.5 (2015), but became reliable and widely used around 2024–2025.

git worktree add ../project-hotfix hotfix/login-bug
# now ../project-hotfix has the hotfix branch checked out
# your main directory is still on main/master

You can work in both directories simultaneously. Build tools, editors, and servers can run in each independently.

Listing and removing worktrees

git worktree list          # see all active worktrees
git worktree remove ../project-hotfix  # remove when done
git worktree prune         # clean up stale worktree metadata

When worktree is useful

  • Reviewing a PR while keeping your in-progress work untouched
  • Running a long build or test suite on one branch while working on another
  • Applying a hotfix to production without stashing or committing WIP on main

Each worktree is its own directory. You can open it in a separate editor window, run a dev server on a different port, and close it when done.


git rebase

Rebase replays commits from one branch on top of another, rewriting history. The result is a linear history without merge commits.

git rebase main            # rebase current branch onto main
git rebase --interactive HEAD~3  # interactively edit the last 3 commits

Interactive rebase (-i) lets you squash, reorder, reword, or drop commits before they’re shared. Only use rebase on commits that haven’t been pushed to a shared branch.


git reflog

The reflog is a local log of every position HEAD has been at. It’s your safety net for recovering commits that were lost to a reset, rebase, or accidental branch deletion.

git reflog                 # show HEAD history
git reflog show main       # show history for a specific branch

If you ran git reset --hard and want the commit back:

git reflog                 # find the SHA before the reset
git checkout -b recovery <sha>  # recover it into a new branch

Reflog entries expire after 90 days by default.


git bisect

Bisect performs a binary search through commit history to find which commit introduced a bug. You tell it a good commit and a bad commit; it checks out the midpoint and asks you to test.

git bisect start
git bisect bad             # current commit is broken
git bisect good v1.4.0     # this tag was working
# git checks out a commit halfway between
# test your code, then:
git bisect good            # or: git bisect bad
# repeat until git identifies the first bad commit
git bisect reset           # return to original HEAD when done

Quick Reference

CommandWhat it does
git diff --cachedShow staged changes
git log --oneline --graph --allVisual branch history
git reset --soft HEAD~1Undo last commit, keep changes staged
git reset --hard HEAD~1Undo last commit, discard changes
git stash push -m "name"Save WIP with a label
git fetch --pruneFetch and remove stale remote refs
git cherry-pick <sha>Apply a specific commit to current branch
git worktree add <path> <branch>Check out a branch in a new directory
git reflogRecover lost commits
git bisect startBinary search for a buggy commit
← All posts