Verified7 commandsAI-assisted

Git

Verified against git 2.43.0, flags verified via `git <cmd> -h` and tested against a live repo, 2026-08-20 · official docs

The daily-driver subset of Git — branching, rebasing, stashing, filtering history, diffing, and recovering from mistakes with the reflog. Not the full manpage; just the commands that actually come up while working.

Branching#

Create, switch, rename, and clean up branches.

git branch                          # list local branches
git branch -a                       # list local + remote-tracking branches
git branch --show-current           # print the current branch name
git switch -c feature/new-thing     # create and switch to a new branch
git switch main                     # switch to an existing branch
git branch -m old-name new-name     # rename a branch
git branch -d feature/done          # delete a branch (only if merged)
git branch -D feature/abandoned     # force-delete a branch (even if not merged)

git switch is the modern, safer replacement for git checkout <branch> — it only touches branches, so it can't accidentally discard file changes the way checkout can. Prefer it for branch operations.

Stashing changes#

Shelve work-in-progress without committing it.

git stash                           # stash tracked changes
git stash push -u -m "wip: auth"    # stash including untracked files, with a message
git stash list                      # show all stashes
git stash show -p stash@{0}         # view a stash's diff
git stash pop                       # apply the most recent stash and drop it
git stash apply stash@{1}           # apply a specific stash without dropping it
git stash drop stash@{1}            # delete a specific stash
git stash branch new-branch stash@{0}  # create a branch from a stash (useful after a conflict)

stash pop fails and leaves the stash in place if applying it produces a conflict — resolve the conflict, then git stash drop manually.

Rebasing#

Rewrite a branch's history onto a new base, or clean it up before merging.

git rebase main                     # replay current branch's commits onto main
git rebase -i HEAD~5                # interactively squash/reorder/reword the last 5 commits
git rebase --onto main old-base feature   # move a branch to a different base commit
git rebase --continue               # after resolving a conflict mid-rebase
git rebase --skip                   # skip the commit currently causing a conflict
git rebase --abort                  # bail out and restore the branch to its pre-rebase state

Never rebase a branch other people have already pulled — it rewrites commit hashes, so anyone with the old history will get diverged/duplicate commits on their next pull. Rebase local/unshared branches only.

Viewing history#

Filter and format commit history for what you're actually looking for.

git log --oneline --graph --decorate    # compact visual history
git log --author="jane"                 # commits by a specific author
git log --since="2 weeks ago" --until="yesterday"   # commits in a date range
git log --grep="fix"                    # commits whose message matches a pattern
git log -- path/to/file.py              # history of a single file
git log -p -2                           # full diff for the last 2 commits
git log --stat -1                       # files changed + line counts for the last commit

git log -S"someFunction" (the "pickaxe") finds commits that changed the number of times a string appears — useful for finding when a specific line of code was introduced or removed, which plain --grep (message text only) can't do.

Diffing#

git diff                            # unstaged changes vs the index
git diff --staged                   # staged changes vs HEAD
git diff main..feature              # diff between two branches
git diff HEAD~3 HEAD                # diff between two points in history
git diff --stat                     # summary (files + line counts) instead of full diff
git diff -- path/to/file.py         # diff limited to one file

Cherry-picking#

git cherry-pick <commit-sha>        # apply a single commit onto the current branch
git cherry-pick -n <commit-sha>     # apply the changes but don't auto-commit
git cherry-pick --continue          # after resolving a conflict mid-cherry-pick
git cherry-pick --abort             # bail out of an in-progress cherry-pick

Undoing changes and recovering with the reflog#

git restore --staged path/to/file.py    # unstage a file (keep the changes)
git restore path/to/file.py             # discard unstaged changes to a file
git reset --soft HEAD~1                 # undo the last commit, keep changes staged
git reset --mixed HEAD~1                # undo the last commit, keep changes unstaged (default mode)
git reset --hard HEAD~1                 # undo the last commit and discard the changes entirely
git revert <commit-sha>                 # create a new commit that undoes a prior commit (safe for shared history)
git reflog                              # show a log of everywhere HEAD has pointed, including "lost" commits
git reset --hard HEAD@{2}               # recover to a state from the reflog (e.g. before a bad reset/rebase)

reset --hard is destructive to your working tree, but it is not destructive to the repository — every commit it seems to throw away still exists and is recoverable via git reflog until git's garbage collector eventually prunes unreferenced commits (default ~90 days for reflog entries). If you ever do a reset --hard or a rebase you regret, git reflog is the first thing to check, not a last resort.

For a branch already pushed and pulled by others, use git push --force-with-lease instead of git push --force after a rebase — it aborts the push if the remote has commits you haven't seen yet, preventing you from silently clobbering someone else's work.