Undoing Things and Team Workflows
Restore, reset, revert, stash and the reflog safety net.
What you will learn
- Undo safely
- Use stash
- Recover with reflog
Everyone makes mistakes: a commit in the wrong branch, a bad edit, a message typo. Git gives you many ways to undo, but they behave differently. Knowing which is safe on shared history versus local history keeps you out of trouble.
git restore file.txt # throw away edits to a file (cannot be undone!)
git restore --staged file.txt # unstage, keep the edits
git clean -n # preview untracked files that would be removedgit commit --amend -m "Better message" # change message
git add forgotten.txt
git commit --amend --no-edit # add a file to the last commit--amend rewrites the last commit, so only do it before you push.
revert: the safe undo for shared history
git revert creates a new commit that reverses an earlier one. History is preserved, so it is safe to push.
git revert a1b2c3dgit reset --soft HEAD~1 # undo the commit, keep changes staged
git reset HEAD~1 # undo the commit, keep changes unstaged (--mixed)
git reset --hard HEAD~1 # undo the commit AND delete the changes--hard discards work. Never reset commits that are already pushed and shared; use revert instead.
stash: set work aside
Need to switch branches but your changes are not ready to commit?
git stash push -m "wip login form"
git switch other-branch
# ...do something...
git switch -
git stash list
git stash pop # bring the changes backreflog: your safety net
Git records every place HEAD has been, for about 90 days, even for commits no branch points to. If you think you lost work after a bad reset or a deleted branch, look here.
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# 9f8e7d6 HEAD@{1}: commit: Add checkout page
git reset --hard 9f8e7d6 # jump back to before the mistakeOther useful tools
git cherry-pick <sha>: copy one commit onto the current branch.git bisect: binary search through history to find the commit that introduced a bug.git tag v1.0.0: mark a release.
Team workflow summary
- GitHub Flow: short-lived branches and PRs into
main, deploy from main. Simple and popular. - Trunk-based: very small changes merged to main daily, behind feature flags.
- Git Flow: long-lived develop and release branches. Heavier; suited to versioned releases.
Try it yourself
Make two commits, then use git reset --hard HEAD~1 to lose the second. Recover it using git reflog.
Show solution
echo 1 > f && git add f && git commit -m "one"
echo 2 >> f && git commit -am "two"
git reset --hard HEAD~1
git reflog # find the SHA of "two"
git reset --hard <sha-of-two>