git soft reset moves the current branch HEAD to a specified commit while leaving the index and working tree completely untouched.
git reset --soft [<commit>]
| Mode | HEAD | Index | Working Directory |
|---|---|---|---|
--soft |
Moved to target | Unchanged | Unchanged |
--mixed (default) |
Moved to target | Reset to target | Unchanged |
--hard |
Moved to target | Reset to target | Reset to target |
Usage Examples
1. Undo the last commit while keeping staged changes
git reset --soft HEAD~1
# Files remain staged; recommit with improved message
git commit -c ORIG_HEAD
From git-scm.com: after a soft reset, ORIG_HEAD holds the previous commit hash; git commit -c ORIG_HEAD reuses its message and authorship without editing.
2. Save staged work before switching branches
git commit -m "staged snapshot" # temporarily commit
git switch master
git switch feature
git reset --soft HEAD~1 # recover exact staged state
Common pattern from Stack Overflow: commit a WIP snapshot, switch branches, do unrelated work, then return and soft reset to restore the original index exactly as it was.
3. Simulate a merge with multiple parents (advanced)
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
git commit
Manually populates .git/MERGE_HEAD to impersonate an octopus merge before committing. Git treats the resulting commit as having two parents.
Troubleshooting & Common Errors
fatal: ambiguous argument – The supplied commit reference does not exist or is misspelled. Verify with git log --oneline or git rev-parse --verify HEAD. If the branch has no commits, the reset is a no-op.
Cannot do soft reset with paths – --soft rejects path arguments; use git reset -- <file> to unstage a file without moving HEAD.
fatal: not a git repository – Command issued outside a working tree. Navigate into a cloned or initialized repository.
Frequently Asked Questions
What is the difference between ‘git reset –soft’ and ‘git reset –mixed’?
Answer: --soft moves only HEAD, preserving both the index and working directory. --mixed (the default) resets the index to match the target commit but leaves file modifications in the working tree. Use --soft to rewrite commit history without unstaging changes.
git reset --soft HEAD~1 # staged changes kept
git reset --mixed HEAD~1 # staged changes become unstaged
When should I use ‘git reset –soft’?
Answer: Undo a commit while keeping all changes staged. After a soft reset you can amend the staged snapshot with git commit -c ORIG_HEAD or squash multiple commits by resetting further back and recommitting.
git reset --soft HEAD~1
git commit --amend
How do I fix ‘fatal: ambiguous argument’ when using git reset –soft?
Answer: Ensure the current branch has at least one commit. If the repository is empty, create an initial commit with git commit --allow-empty -m "initial". Always verify the commit range with git log --oneline before resetting. Typing the ref incorrectly (e.g., HEAd~1 instead of HEAD~1) also triggers this error.
git log --oneline | head -5
Does ‘git reset –soft’ work in CI/CD pipelines?
Answer: Yes, it works in any Git environment (GitHub Actions, Jenkins, GitLab CI). For deep resets beyond the cloned depth, set fetch-depth: 0 in GitHub Actions and configure user.email and user.name if you plan to commit later.
- name: Soft reset for history rewrite
run: git reset --soft HEAD~2
What is the fastest way to undo the last commit while keeping staged changes?
Answer: git reset --soft HEAD~1 is optimal. It moves HEAD without touching the index or working tree — extremely fast regardless of repository size. To undo multiple commits at once and combine their staged changes, use git reset --soft HEAD~3.
git reset --soft HEAD~1 # single commit undo
git reset --soft HEAD~3 # undo three commits, all changes staged together

Command Line Expert & Software Engineer
Welcome! I’m Thomas Heinrich, a software engineer and system administrator with a deep passion for the Command Line Interface (CLI). With years of experience navigating the terminal, building backend architectures, and automating server deployments, I created this space to share practical, real-world terminal knowledge.
Whether you are a beginner taking your first steps in a Linux environment or a seasoned DevOps engineer looking to optimize your deployment scripts, you will find actionable solutions here. My goal is to help you ditch the mouse, speed up your workflow, and harness the full power of the command line.