dotclaude

Skill in version-control

git-undo

Recover safely from Git mistakes such as discard, unstage, amend, reset, revert, restore lost commits via reflog, recover deleted branches, and fix bad rebases. Chooses the least-destructive fix and protects against data loss. Use when something in Git went wrong and needs undoing.

Arguments
(optional) what went wrong, e.g. 'committed to main', 'lost my commits'

Install

As a plugin

Bundled in the git plugin. Add the marketplace once, then install the bundle; it updates with the marketplace.

/plugin marketplace add KhaledSaeed18/dotclaude
/plugin install git@dotclaude

As a single item

Run from the project root; the skill lands under .claude/. Copy it to ~/.claude/ to make it global.

npx shadcn@latest add KhaledSaeed18/dotclaude/git-undo

Files installed

  • .claude/skills/git-undo/SKILL.md

What it does

Undo the mistake with the least-destructive tool that fits, after establishing two facts that change everything: has the work been committed, and has it been pushed/shared. Get those wrong and you either lose work or rewrite history other people depend on.

Hard rules: never break these

  • Diagnose before acting. Establish: committed or not? pushed or not? on a shared branch? Run git status, git log --oneline -10, and git reflog -20 first. The fix depends entirely on the answers.
  • Never rewrite published history casually. For anything already pushed to a shared branch, undo forward with git revert; do not reset/rebase/commit --amend and force-push unless the user explicitly owns the consequences and coordinates with collaborators.
  • Take a safety net before any destructive op. Before reset --hard, a force-push, or a history rewrite, snapshot the current tip: git branch backup/<desc> or git tag backup/<desc>. Reflog usually saves you, but a branch is free insurance.
  • --hard and clean destroy uncommitted work irrecoverably. Reflog only recovers committed states. Spell out exactly what will be lost and confirm before running them.
  • Confirm before any destructive or shared-history command: reset --hard, clean -fd, push --force*, history rewrites. Prefer push --force-with-lease over --force when a rewrite is genuinely required.

Step 1: Diagnose

  • git status: staged vs unstaged vs untracked; any operation in progress.
  • git log --oneline --graph -15: recent commits and branch shape.
  • git reflog -25: the time machine, every position HEAD has held, even "lost" ones. This is how you recover almost anything committed.
  • Determine shared or local: has the affected commit/branch been pushed? git status (ahead/behind), git branch -r --contains <sha>.

Step 2: Pick the fix

Match the situation to the safest tool:

Uncommitted work

  • Discard changes in a file → git restore <file> (was git checkout -- <file>).
  • Unstage but keep changes → git restore --staged <file> (was git reset HEAD <file>).
  • Set aside without losing → git stash push -m "<note>"; bring back with git stash pop.
  • Remove untracked files → git clean -nd (dry run first!), then git clean -fd once confirmed.

The last commit (not yet pushed)

  • Wrong message → git commit --amend.
  • Forgot a file → stage it, then git commit --amend --no-edit.
  • Undo the commit, keep changes staged → git reset --soft HEAD~1.
  • Undo the commit, keep changes unstaged → git reset --mixed HEAD~1 (default).
  • Undo the commit and discard changes → git reset --hard HEAD~1 (destructive; safety net first).

Already pushed / shared branch

  • Undo a commit safely → git revert <sha> (creates an inverse commit; history stays intact). Revert a merge with -m 1.

Wrong-branch / structural mistakes

  • Committed to the wrong branch → create the right branch from here (git branch feature), then git reset --hard origin/<wrong-branch> on the original (safety net first); or git cherry-pick the commits onto the right branch and drop them from the wrong one.
  • Need an old version of one file → git restore --source=<sha> -- <file>.

Recovering things that look lost

  • Hard reset / branch deletion / bad amend → find the old SHA in git reflog, then git branch recovered <sha> or git reset --hard <sha>.
  • Botched rebase/merge → git reset --hard ORIG_HEAD returns to the pre-operation tip.
  • Deleted branch with no reflog entry → git fsck --lost-found lists dangling commits.
  • Dropped a stash → git fsck --no-reflog | grep commit, or recover from git reflog stash.

Step 3: Safety net (before anything destructive)

Snapshot the current tip so the operation is reversible regardless of outcome:

git branch backup/before-undo        # or: git tag backup/before-undo

Note the current HEAD SHA too. This costs nothing and turns "irreversible" into "recoverable."

Step 4: Execute (with confirmation)

  1. State plainly: what command runs, what it changes, and what (if anything) is lost forever.
  2. For destructive or shared-history operations, get an explicit yes. For force-pushes, use --force-with-lease and confirm no one else's work is being overwritten.
  3. Run it.

Step 5: Verify

  • git status and git log --oneline -5 to confirm the tree and history are what you intended.
  • Confirm recovered work is present (file contents, expected commits).
  • Note the safety branch/tag you created; remove it once the user confirms the recovery is good.

This is the skill as installed, rendered from its source on GitHub. Read it as Markdown.

  • changelogGenerate a changelog or release notes from Git history, grouped by change type, written in user-facing language, with issue/PR links and breaking changes...
  • finish-branchWrap up a completed development branch by verifying tests pass, detecting the workspace state, then presenting clear merge / PR / keep / discard options...
  • git-commitCommit work the right way by gathering full repo state, respecting the project's commitlint/pre-commit/branch rules, staging only understood files, and...
  • git-worktreesSet up an isolated workspace for feature work so the current branch and working tree stay untouched, detecting existing isolation first, preferring the...
  • gitignoreGenerate or repair a .gitignore tailored to the project's actual stacks, frameworks, OS, and editors, and untrack files that are already committed but...
  • merge-conflictResolve Git merge, rebase, cherry-pick, revert, and stash conflicts safely by understanding both sides and the operation in progress before integrating...