Skip to content
Development
Skill

/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

From plugin
dotclaude
540 skills1 agent1 command
Install
$ npx -y skills add KhaledSaeed18/dotclaude --skill git-undo --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/git-undo

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

git-undo.SKILL.md
name: git-undo
description: 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.
argument-hint: "(optional) what went wrong, e.g. 'committed to main', 'lost my commits'"

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.
Read more
Ships withdotclaude

Reusable Claude Code extension registry. skills, subagents, slash commands, and hooks for engineering, git, testing, and security workflows. Distributed as a shadcn GitHub registry and as installable plugins.

Get the whole plugin

Other skills on dotclaude.