Stash, Cherry-Pick & Tag
This chapter covers three commands that don't fit neatly into "branching" or "merging" but come up constantly once you're working on real projects: temporarily shelving unfinished changes, taking one specific commit and applying it somewhere else, and permanently marking a specific point in history as a release.
git stash — Pausing Unfinished Work
Imagine you're mid-edit on a feature, and an urgent bug needs fixing on a different branch right now. Your changes aren't ready to commit, but you need a clean working directory to switch branches. git stash sets your uncommitted changes aside temporarily, without committing them anywhere.
$ git stash
Saved working directory and index state WIP on feature/login: a1b2c3d Add validation
$ git switch hotfix/urgent-bug
# ...fix the bug, commit, push, switch back...
$ git switch feature/login
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: login.js
Useful stash variations
$ git stash list
stash@{0}: WIP on feature/login: a1b2c3d Add validation
$ # Add a description, since "WIP on ..." gets unhelpful with several stashes
$ git stash push -m "half-finished password strength meter"
$ # Apply a stash WITHOUT removing it from the stash list
$ git stash apply
$ # Discard a stash you no longer need
$ git stash drop
git stash pop applies the most recent stash AND removes it from the list. git stash apply applies it but leaves it in the list — useful if you want to apply the same stashed changes to more than one branch.
git cherry-pick — Taking One Specific Commit Elsewhere
Sometimes you need exactly one commit from another branch — not a full merge, not a rebase, just that one specific change — copied onto your current branch. git cherry-pick does precisely that.
$ git log other-branch --oneline
9f8e7d6 Fix critical null-check bug
a1b2c3d Add unrelated feature
$ # Apply just that one commit to your current branch
$ git cherry-pick 9f8e7d6
[your-branch 4f3e2d1] Fix critical null-check bug
When cherry-picking genuinely earns its place
- Backporting a fix. A critical bug fix landed on
main, but you also need it on an older release branch that's still being maintained — cherry-pick the one commit rather than merging all of main's other changes too. - Recovering a commit made on the wrong branch. Accidentally committed to the wrong branch? Cherry-pick it onto the correct one, then remove it from the wrong one (Course 1, Chapter 8's reset tools).
- Avoid it as a substitute for merging — repeatedly cherry-picking individual commits between two branches that should really just be merged tends to create confusing, duplicated history over time.
git tag — Marking a Release Permanently
A tag is a permanent, named pointer to one specific commit — unlike a branch (Course 1, Chapter 4), a tag's pointer never moves once created. Tags are how releases get marked: "this exact commit is version 1.2.0."
| Tag type | What it is |
|---|---|
| Lightweight | Just a named pointer to a commit — no extra metadata. Quick, simple, fine for personal/internal markers. |
| Annotated | A full object with its own message, author, and date — recommended for actual releases, since it carries proper metadata (and can be cryptographically signed — Course 3, Chapter 6). |
$ git tag v1.2.0-rc1
$ # Annotated tag — the recommended way to mark a real release
$ git tag -a v1.2.0 -m "Release 1.2.0 — login fixes and performance improvements"
$ # List existing tags
$ git tag
v1.0.0
v1.1.0
v1.2.0
$ # Tags don't push automatically — push them explicitly
$ git push origin v1.2.0
# Or push every local tag at once:
$ git push origin --tags
Command Reference
| Command | What it does |
|---|---|
| git stash | Temporarily shelves uncommitted changes |
| git stash pop | Reapplies the most recent stash and removes it from the list |
| git stash list | Shows all currently stashed change-sets |
| git cherry-pick <hash> | Copies one specific commit's changes onto your current branch |
| git tag -a <name> -m "msg" | Creates an annotated tag marking the current commit |
| git push origin --tags | Pushes all local tags to the remote (tags don't push automatically) |
Chapter 5 Quick Reference
- git stash — temporarily shelves uncommitted work so you can switch branches cleanly; pop to reapply
- git cherry-pick <hash> — copies one specific commit onto your current branch as a new commit
- Cherry-pick is best for: backporting fixes, recovering commits made on the wrong branch — not as a merge substitute
- git tag — a permanent pointer to one commit; unlike branches, never moves once created
- Annotated tags (-a) are preferred for real releases — carry message, author, date metadata
- Tags don't push automatically — use git push origin <tag> or --tags explicitly
- Next chapter: GitHub Issues, Projects, and linking pull requests to issues