Stashing Work and Tagging Releases
Park unfinished changes with git stash and bring them back later, then mark releases with annotated tags, push them to GitHub and create GitHub Releases.
On this page 12 sections
Introduction
Two situations come up constantly in real projects. First: you are halfway through a change when an urgent fix is needed, and your work is not ready to commit. Second: you have finished a version and want to mark exactly which commit went live. Git’s stash handles the first, and tags handle the second.
- How to stash unfinished work and restore it later.
- How to include new, untracked files in a stash.
- The difference between lightweight and annotated tags.
- How to push tags and turn them into GitHub Releases.
Why Stash?
Priya is in the middle of changing the page width in style.css when a friend points out that the email address on her contact page is not clickable. She wants to fix that in a clean commit of its own, without mixing in her half-finished styling:
git status --shortClick Run to see what this code prints.
Stashing Changes
git stash saves your uncommitted changes on a stack and returns your working directory to the last commit. Adding a message with push -m helps when you have several stashes:
git stash push -m "WIP: page width and spacing"Click Run to see what this code prints.
git stash listgit status --shortClick Run to see what this code prints.
git status --short prints nothing: the working tree is clean, and the half-finished styling is safely stored as stash@{0}. Now Priya makes and commits the quick fix:
git commit -am "Make email address a clickable link"Click Run to see what this code prints.
Bringing Changes Back
git stash pop re-applies the most recent stash and removes it from the list:
git stash popClick Run to see what this code prints.
| Command | What it does |
|---|---|
| git stash pop | Re-apply the latest stash and delete it from the list |
| git stash apply | Re-apply the latest stash but keep it in the list |
| git stash apply stash@{2} | Re-apply a specific stash |
| git stash show -p stash@{0} | Show the changes inside a stash |
| git stash drop stash@{0} | Delete a stash |
| git stash branch new-branch | Create a branch from the stash and apply it there |
If the stashed changes conflict with commits you made in the meantime, Git reports a conflict just like a merge. Resolve it, and drop the stash yourself afterwards — Git keeps it in the list when a pop runs into conflicts, so nothing is lost.
Stashing New Files
By default, git stash only saves changes to files Git already tracks. Priya has also started a new ideas.md file. Watch what happens:
git stashgit status --shortClick Run to see what this code prints.
The untracked file was left behind. After bringing the stash back with git stash pop, she tries again with -u (--include-untracked):
git stash -ugit status --shortClick Run to see what this code prints.
This time git status --short prints nothing: both the edit and the new file are in the stash.
You edited app.js (already tracked) and created a new file notes.txt. You run git stash. What does git status show afterwards?
What Are Tags?
A tag is a permanent name for a specific commit, usually used to mark releases such as v1.0.0. Unlike a branch, a tag never moves. There are two kinds:
| Lightweight tag | Annotated tag | |
|---|---|---|
| Create with | git tag v1.0.0 | git tag -a v1.0.0 -m "message" |
| Stores | Just a name pointing to a commit | Name, tagger, date and a message |
| Use for | Private, temporary bookmarks | Releases and anything you share |
Creating and Sharing Tags
Priya finishes the styling, commits it, and decides her portfolio is ready for its first public version:
git tag -a v1.0.0 -m "First public version of my portfolio"git tagClick Run to see what this code prints.
git show --no-patch v1.0.0Click Run to see what this code prints.
The annotated tag records who tagged it, when and why, followed by the commit it points to. Tags can also be added to older commits by giving the commit ID:
git tag -a v0.1.0 -m "First draft" 55024d8git tagClick Run to see what this code prints.
git push does not send tags automatically. Push a tag by name (or all tags with git push origin --tags):
git push origin v1.0.0Click Run to see what this code prints.
Tags also appear in git log next to the commit they mark:
git log --oneline -3Click Run to see what this code prints.
Semantic Versioning and Releases
Most projects number releases with semantic versioning: MAJOR.MINOR.PATCH. Increase PATCH for bug fixes (1.0.1), MINOR for new features that do not break anything (1.1.0), and MAJOR for changes that break existing behaviour (2.0.0).
On GitHub, open the repository’s Releases section and choose “Draft a new release”. Pick your tag, write release notes (GitHub can generate them from merged pull requests), attach any files such as installers, and publish. Users then get a clear page for every version, with downloadable source code.
Your app is at version 2.3.1. You add a new optional feature without breaking anything. What should the next version be?
Common Mistakes
- Leaving work in the stash for weeks and forgetting it exists — stashes are for short pauses, branches for longer work.
- Using git stash without -u and wondering where new files went (they never left).
- Forgetting to push tags, so the release exists only on your computer.
- Moving or re-using a tag that others have already downloaded; create a new version instead.
Frequently Asked Questions
No. Stashes are local only. If you need to move unfinished work to another computer, commit it on a branch and push the branch.
git tag -d v1.0.0 deletes it locally and git push origin --delete v1.0.0 deletes it on GitHub. Avoid deleting tags that others may already use.
Yes: git switch --detach v1.0.0 puts your files at that version (in a “detached HEAD” state, not on any branch). To make changes from there, create a branch with git switch -c fix/v1.0.1.
Key Takeaways
- git stash saves uncommitted changes and cleans your working directory; -u includes untracked files.
- git stash pop re-applies and removes the latest stash; git stash list shows them all.
- Tags permanently name a commit; use annotated tags (git tag -a) for releases.
- Push tags explicitly with git push origin <tag> or --tags.
- Use semantic versioning (MAJOR.MINOR.PATCH) and GitHub Releases to publish versions.
Summary
You can now pause work cleanly and mark releases permanently. You have learned every core Git command; the next lesson zooms out to how teams organise branches and commits — the workflows you will meet in real jobs.