git reset rewinds your branch to a commit and decides what happens to staged and working changes.
Reset is the main "undo commits" tool. The mode (--soft/--mixed/--hard) controls how much it touches.
What it does
git reset moves the current branch ref to a target commit. --soft keeps the index and working tree, --mixed (default) resets the index, --hard resets index and working tree, discarding changes.
Common usage
Terminal
git reset --soft HEAD~1 # undo commit, keep changes staged
git reset HEAD~1 # undo commit, unstage changes
git reset --hard origin/main # match remote, discard local work
git reset HEAD file.txt # unstage one file
Options
Flag
What it does
--soft
Move HEAD only; keep index and working tree
--mixed
Default: reset index, keep working tree
--hard
Reset index and working tree (destructive)
--merge / --keep
Reset but try to preserve local changes
Common errors in CI
--hard silently discards uncommitted work and there is no "error" - that is the danger. If you reset too far, recover with git reflog to find the prior HEAD and git reset --hard <sha> back to it. Note: reset does NOT remove untracked files; use git clean for those.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git reset: Usage, Options & Common CI Errors?
Reset is the main "undo commits" tool. The mode (--soft/--mixed/--hard) controls how much it touches.
What it does?
git reset moves the current branch ref to a target commit. --soft keeps the index and working tree, --mixed (default) resets the index, --hard resets index and working tree, discarding changes.
Common errors in CI?
--hard silently discards uncommitted work and there is no "error" - that is the danger. If you reset too far, recover with git reflog to find the prior HEAD and git reset --hard <sha> back to it. Note: reset does NOT remove untracked files; use git clean for those.