The Half-Written Assignment in the Drawer
You are halfway through writing an assignment when your teacher calls: “Please make the attendance chart for tomorrow, right now.” You do not throw away your half-written pages, and you do not hand them in unfinished. You put them neatly in a drawer, do the urgent job on a clean desk, and then take your pages out again and continue from the same line.
Git has a drawer too. It is called the stash. In this lesson Asha meets exactly this situation while building Utsav, the college fest site, with Ravi and Imran. You will also learn two other handy tools: cherry-pick, which copies one single commit to another branch, and tags, which put a permanent label such as v1.0 on an important commit, for example the day the site goes live.
git stash: Put Unfinished Work Away
Normally Git lets you switch branches with uncommitted changes, but if those changes clash with the other branch, Git refuses. And even when it allows the switch, your half-done edits travel with you, which is confusing. You could make a “temporary” commit, but that leaves a messy history. git stash is the clean answer: it saves your uncommitted changes in a safe place and gives you back a clean working folder.
# You are on the gallery branch with unfinished changes
git status --short
# Put the unfinished changes away and get a clean working folder
git stash
# Check: nothing left to commit
git status
You will see something like:
Saved working directory and index state WIP on gallery: 334bde7 Add gallery page
On branch gallery
nothing to commit, working tree clean
WIP means “work in progress”. The ID and message after it are from the last commit on the branch, so yours will differ. Your changes are not lost: they are stored inside the repository, ready to come back.
Stash with a message and see the list
You can stash more than once. Each stash goes on top of a pile, like papers in the drawer. A short message makes the pile easy to understand later.
# Stash with a message, so you remember what is inside
git stash push -m "half-done photo grid"
# See every stash you have saved
git stash list
You will see something like:
stash@{0}: On gallery: half-done photo grid
stash@{1}: WIP on gallery: 334bde7 Add gallery page
stash@{0} is always the newest one. Older stashes move down to stash@{1}, stash@{2} and so on.
apply or pop: taking work out of the drawer
# Bring back the newest stash AND remove it from the list
git stash pop
# Bring back the newest stash but KEEP it in the list
git stash apply
# Bring back an older stash by its number
git stash apply stash@{1}
# Delete a stash you no longer need
git stash drop stash@{1}
| Command | Brings changes back? | Removes the stash from the list? |
|---|---|---|
git stash pop | Yes | Yes, if there is no conflict |
git stash apply | Yes | No, it stays until you drop it |
git stash drop | No | Yes |
Use pop for everyday work. Use apply when you want to try the same changes on two branches, or when you want a backup in case something goes wrong. If the changes clash with the current files, Git shows a conflict and keeps the stash safely in the list, even with pop.
Untracked files need -u
A new file you have never added with git add is untracked. Plain git stash only saves changes to files Git already knows, so a new file stays in your folder and follows you to the other branch.
# A brand-new file is "untracked", so plain git stash leaves it behind
git status --short
# ?? gallery-grid.css
# -u also stashes untracked files
git stash push -u -m "photo grid with new CSS file"
Stash is a drawer, not a cupboard. It is for a few hours or a day. Stashes are not pushed to GitHub, so they exist only on your computer. For anything longer, commit your work on a branch and push it.
A Real Interruption: The Wrong Fest Date
It is Thursday afternoon. Asha is halfway through the gallery page: a new CSS file and some half-written HTML, nothing ready to commit. Then Imran messages the group: “The home page says the fest is on 14 March. It is 15 March! The posters are going out today.”
The fix must go to main now. Here is what Asha does:
# 1. Asha is halfway through the gallery. Save it away.
git stash push -u -m "gallery: half-done photo grid"
# 2. Go to main and get the latest version
git switch main
git pull
# 3. Fix the wrong date on the home page in a small branch
git switch -c fix-fest-date
# (edit index.html: change 14 March to 15 March)
git add index.html
git commit -m "Fix fest date on home page"
git push -u origin fix-fest-date
# Open a pull request on GitHub, Ravi approves, merge it.
# 4. Back to the gallery, and take the half-done work out of the drawer
git switch gallery
git stash pop
Within ten minutes the date is fixed on the live site, and Asha is back exactly where she stopped, with every half-written line of the gallery still in place.
git cherry-pick: Copy One Commit to Another Branch
Sometimes the fix you need is already sitting in another branch. While working on the gallery, Asha noticed that the fest logo was broken on every page and fixed it in commit F on her gallery branch. The gallery is not ready to merge, but main needs the logo fix today.
git cherry-pick takes the changes of one commit and applies them as a new commit on your current branch. Think of picking one cherry from a tree instead of taking the whole branch.
Before:
main: A---B---C
\
gallery: D---F---G F = "Fix broken logo path"
After "git cherry-pick F" while on main:
main: A---B---C---F' F' has the same change as F, with a new ID
\
gallery: D---F---G
# Find the ID of the commit you want to copy
git log --oneline gallery
# Go to the branch that needs the fix
git switch main
# Copy that one commit here
git cherry-pick e4f5a6b
You will see something like:
[main 8309ee9] Fix broken logo path
Date: Thu Mar 5 18:42:10 2026 +0530
1 file changed, 1 insertion(+), 1 deletion(-)
Like a rebased commit, the copy gets a new ID. The original commit stays on gallery. Later, when the gallery branch is merged, Git usually sees that the same change is already in main and does not complain.
If the commit does not fit cleanly, cherry-pick stops with a conflict. Solve it the usual way, then run git add and git cherry-pick --continue, or cancel with git cherry-pick --abort.
Use cherry-pick for small, separate fixes. If you find yourself copying many commits, it is a sign that you should merge or rebase the branch instead.
Tags: Labels for Important Moments
A branch keeps moving as new commits arrive. A tag is a fixed name for one commit that never moves. Teams use tags to mark releases: v1.0 for the launch, v1.1 for the version with the gallery, and so on. The “v” and numbers are just a common habit; Git accepts any name.
Git has two kinds of tags. A lightweight tag (git tag v1.0) is only a name. An annotated tag (git tag -a) also stores who made it, when, and a message, so it is the right choice for releases.
# Make sure you are on the commit you want to mark
git switch main
git pull
# Create an annotated tag with a message
git tag -a v1.0 -m "Utsav site launch: home, schedule, registration"
# List all tags
git tag
# See the tag details and the commit it points to
git show v1.0
You will see something like:
tag v1.0
Tagger: Asha Verma <asha@example.com>
Date: Fri Mar 6 20:15:32 2026 +0530
Utsav site launch: home, schedule, registration
commit 8309ee9... (HEAD -> main, tag: v1.0, origin/main)
Author: Asha Verma <asha@example.com>
...
Pushing tags to GitHub
A normal git push does not send tags. Push them on purpose:
# Tags are NOT sent by a normal git push. Push one tag:
git push origin v1.0
# Or push all your tags at once
git push origin --tags
You will see something like:
To https://github.com/asha-utsav-demo/college-fest-site.git
* [new tag] v1.0 -> v1.0
Visiting an old version
You can look at the files exactly as they were at a tag. Because a tag is not a branch, Git puts you in detached HEAD state: you are visiting, not working on a branch. If you try git switch v1.0 without --detach, Git refuses and asks you to add it.
# Look at the site exactly as it was at v1.0 (read-only visit)
git switch --detach v1.0
# Older guides write: git checkout v1.0
# Come back to normal work
git switch main
# Want to change old code? Start a branch from the tag
git switch -c hotfix-1.0 v1.0
Real-Life Example: Launching Utsav v1.0 with a GitHub Release
On Friday night the home page, schedule and registration form are finished and merged. The team decides this is version 1.0. Asha runs the tag commands above on main and pushes the tag. Then she turns the tag into a GitHub Release, a page that tells visitors what is in this version:
- Open the repository
asha-utsav-demo/college-fest-siteon GitHub. - Click Releases on the right side of the main page, then Draft a new release (or Create a new release).
- In Choose a tag, select
v1.0. - Give it a title such as “Utsav site v1.0: launch”.
- Write short notes: what is included (home, schedule, registration), and who worked on what. The Generate release notes button can list the merged pull requests for you.
- Click Publish release.
GitHub adds downloadable ZIP and TAR.GZ copies of the code at that tag. If something breaks after the gallery is added next week, the team can always look at, or go back to, the exact launch version.
Try these changes:
- Make two stashes with different messages and bring back the older one with
git stash apply stash@{1}. - Create a lightweight tag and compare
git showfor it with the annotatedv1.0. - Run
git switch --detach v1.0, look at the files, then return withgit switch main.
Common Mistakes
- Forgetting
-u. A new file stays behind and ends up committed on the wrong branch. Fix: usegit stash push -uwhen you have new files. - Forgetting the stash completely. Weeks later,
git stash listshows ten unnamed stashes. Fix: always add a message with-m, and pop your stash as soon as you return. - Thinking
git pushsends tags. The release page then cannot findv1.0. Fix: rungit push origin v1.0orgit push origin --tags. - Tagging the wrong commit. If you tag before pulling, the tag may miss your friends’ work. Fix: pull first. If the tag is still only on your computer, delete it with
git tag -d v1.0and tag again. Avoid moving a tag that others have already pulled. - Committing in detached HEAD. Commits made while visiting a tag do not belong to any branch and are easy to lose. Fix: create a branch first with
git switch -c.
Practice Task: Interruption, Fix and Release
Use your own college-fest-site repository:
- Create a branch
sponsorsand start a new filesponsors.html. Do not commit it. - Stash the work, including the untracked file, with a clear message. Check that the working tree is clean.
- Switch to
main, make a small fix toindex.htmland commit it. - Copy that fix to the
sponsorsbranch with cherry-pick. - Bring back your stashed draft and check that the stash list is empty.
- On
main, create an annotated tagv0.9and push it to GitHub. Check that it appears under Tags on the repository page.
Show one possible answer (try it yourself first!)
# 1. Start a feature and leave it half done
git switch -c sponsors
echo "<h1>Our Sponsors</h1>" > sponsors.html
# (do not commit)
# 2. Stash it, including the new untracked file
git stash push -u -m "sponsors page draft"
git stash list
git status # working tree clean
# 3. Make the urgent fix on main
git switch main
# (edit index.html: fix the venue name)
git commit -am "Fix venue name on home page"
# 4. Copy the same fix to the sponsors branch
git log --oneline -1 # note the ID, for example c3d4e5f
git switch sponsors
git cherry-pick c3d4e5f
# 5. Bring back the draft
git stash pop
git stash list # empty again
# 6. Tag and push (from main)
git switch main
git tag -a v0.9 -m "Practice release before the fest"
git push origin main
git push origin v0.9
Key Takeaways
git stashputs uncommitted work away; add-m "message"to name it and-uto include new files.git stash popbrings work back and removes the stash;git stash applybrings it back and keeps it.git cherry-pick <commit>copies one commit to the current branch as a new commit.- Annotated tags (
git tag -a v1.0 -m "...") mark releases with a name, date and message. - Tags must be pushed on purpose, and a GitHub Release turns a tag into a page with notes and downloads.