git add .
git commit -m "oops, wrong files"
git undo                           # Back to before commit, files still staged
git undo                           # Back to before add, clean working directory# Assume we're on main
git switch feature-branch
git back # back to main
git back # back to feature-branchgit add .
git commit -m "oops, wrong files"
git undo                           # Back to before commit, files still staged
git undo undo                      # Back to commited again# Make some changes
git add file.txt
git undo --dry-run # shows hint to run "git restore --staged ."
git commit -m "test commit"
git undo --dry-run # shows hint to run "git reset --soft HEAD~1"Now you can use Git confidently, knowing any command is easily undoable.
curl -fsSL https://raw.githubusercontent.com/amberpixels/git-undo/main/install.sh | bashgit clone https://github.com/amberpixels/git-undo.git
cd git-undo
./install.shRequirements: Git, Go ≥ 1.21, Bash/Zsh
alias gu="git undo"
alias gub="git back"
alias guu="git undo undo"
alias gul="git undo --log | head"| Git Command | How it's undone | Notes | 
|---|---|---|
git add | 
git restore --staged <files> or git reset <files> | 
Unstages files. Uses git reset if no HEAD exists | 
git commit | 
git reset --soft HEAD~1 | 
Keeps changes staged. Handles merge commits and tagged commits | 
git branch <name> | 
git branch -D <name> | 
Deletes the created branch | 
git checkout -b <name> | 
git branch -D <name> | 
Deletes branch created by checkout -b | 
git switch -c <name> | 
git branch -D <name> | 
Deletes branch created by switch -c | 
git switch <branch> | 
git switch - | 
Returns to previous branch | 
git merge <branch> | 
git reset --merge ORIG_HEAD | 
Handles both fast-forward and merge commits | 
git cherry-pick <commit> | 
git reset --hard HEAD~1 | 
Removes cherry-picked commit | 
git revert <commit> | 
git reset --hard HEAD~1 | 
Removes revert commit | 
git reset | 
git reset <previous-head> | 
Restores to previous HEAD position using reflog | 
git stash / git stash push | 
git stash pop | 
Pops and removes the stash | 
git rm <files> | 
git restore --source=HEAD --staged --worktree <files> | 
Restores removed files | 
git rm --cached <files> | 
git add <files> | 
Re-adds files to index | 
git mv <old> <new> | 
git mv <new> <old> | 
Reverses the move operation | 
git tag <name> | 
git tag -d <name> | 
Deletes the created tag | 
git restore --staged <files> | 
git add <files> | 
Re-stages the files | 
| Git Command | Reason | 
|---|---|
git checkout <branch> | 
Only checkout -b is supported (regular checkout navigation not undoable) | 
git clean | 
Cannot recover deleted untracked files (would need pre-operation backup) | 
git restore --worktree | 
Previous working tree state unknown | 
git restore --source=<ref> | 
Previous state from specific reference unknown | 
git stash pop/apply | 
Would need to re-stash, which is complex | 
| Branch/tag deletion | Cannot restore deleted branches/tags (would need backup) | 
After installation both shell hooks and git hooks are installed, that track any git command and send them to git-undo (a git plugin) binary. There git commands are categorized and stored in a tiny log file (.git/git-undo/commands). Later, when calling git undo it reads the log and decide if it's possible (and how) to undo previous command.
Undo a merge:
git merge feature-branch
git undo                 # resets --merge ORIG_HEADUndo adding specific files:
git add file1.js file2.js
git undo                 # unstages just those filesUndo branch creation:
git checkout -b new-feature
git undo                 # deletes branch, returns to previousGet the version information:
git undo self version # same as git undo versionUpdate to latest version:
git undo self updateUninstall:
git undo self uninstallFound a Git command that should be undoable? Open an issue or submit a PR!
MIT - see LICENSE file.
Make Git worry-free!
⭐ Star this repo if git undo makes your development workflow better!