Moves the branch back one commit. Everything the commit contained is still in your files and still staged, so you can fix it up and commit again.
Stages the exact reverse of the last commit without committing yet. Review it, then commit and push — the pushed commit itself stays in history.
Moves the branch back one commit and unstages its changes. Your files keep the edits; nothing is staged.
Puts the reverse of the pushed commit into your files, unstaged, so you can adjust before committing the undo.
Moves the branch back one commit and resets your files to match. The commit's changes are removed from your working copy.
Creates a new commit that reverses the pushed one, then you push as normal. The tip of the branch no longer contains the change, and shared history stays intact.
DestructiveRead the note beside this command before running it.Also deletes any uncommitted changes in tracked files, permanently. The discarded commit stays recoverable via git reflog for at least 30 days by default.
CautionRead the note beside this command before running it.Everyone who pulls gets the reverting commit. If teammates built on the original commit, coordinate before reverting it.
Check it worked
git log --oneline -3
The undone commit no longer appears at the top (or, on the pushed path, a new revert commit sits above it).
Worth knowing
git reset only rewrites your local branch — if the commit was pushed, resetting locally makes your branch diverge from the remote.
Moves the branch back to the chosen commit. Every change from the undone commits stays in your files, staged as one batch.
Stages the reverse of every commit after the chosen one, newest first, without committing. Review, commit, push.
Moves the branch back to the chosen commit and resets your files to match it exactly.
Creates one reverting commit per undone commit, newest first, leaving shared history intact. Push when done.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Deletes uncommitted changes in tracked files permanently and drops the newer commits from the branch. The dropped commits stay in git reflog for at least 30 days by default.
CautionRead the note beside this command before running it.Everyone who pulls gets the reverting commits. If the range includes a merge commit, revert stops and asks for -m — revert merges one at a time instead.
Check it worked
git log --oneline -5
The branch tip is the chosen commit (local path) or new revert commits sit on top (pushed path).
Moves the file's uncommitted changes into a stash and restores the committed version. Get them back any time with git stash pop.
Overwrites the file with the last committed version.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Uncommitted changes in this file are deleted permanently — they were never committed, so no reflog entry exists to recover them.
Check it worked
git status --short
The file no longer appears in the list of modified files.
Using Git older than 2.23?
Before Git 2.23 the discard was spelled: git checkout -- <path>
Stashes every tracked edit and every untracked file, leaving a clean working tree. Restore with git stash pop.
Resets every tracked file to the last commit and deletes untracked files and folders.
DestructiveRead the note beside this command before running it.Uncommitted edits and untracked files are deleted permanently — nothing here was committed, so git cannot recover any of it.
Rewinds the branch to where it was just before the merge (git saved that spot as ORIG_HEAD) while keeping uncommitted edits that don't overlap the merge.
Creates a commit that reverses everything the merge brought in. -m 1 means 'keep the side I was on when I merged'.
Rewinds the branch to just before the merge and resets every file to match.
Creates a commit that reverses everything the merge brought in — reverting never touches your uncommitted files, so there is nothing extra to discard.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.The merge commit leaves the branch. It stays recoverable via git reflog for at least 30 days by default.
CautionRead the note beside this command before running it.After reverting a merge, merging the same branch again brings nothing in — git considers it already merged. Revert the revert first if you need the branch back later.
DestructiveRead the note beside this command before running it.Also deletes uncommitted changes in tracked files, permanently. The merge commit stays recoverable via git reflog for at least 30 days by default.
CautionRead the note beside this command before running it.After reverting a merge, merging the same branch again brings nothing in — git considers it already merged. Revert the revert first if you need the branch back later.
Check it worked
git log --oneline -3
The merge commit is gone from the top (local path) or a 'Revert' commit sits above it (pushed path).
Stops the conflicted merge and puts the branch and your files back exactly as they were before you ran git merge.
CautionRead the note beside this command before running it.Any conflict resolutions you already typed are discarded. Changes committed before the merge are untouched.
Check it worked
git status --short
No 'unmerged' entries remain; the merge state is gone.
the entry before 'rebase (start)' is your pre-rebase position
git reset --hard ORIG_HEAD
Shows every place your HEAD has pointed recently. Right after a rebase, ORIG_HEAD and the reflog both know the old position.
Moves the branch back to where it was before the rebase (git saved that spot as ORIG_HEAD) and resets your files to match.
DestructiveRead the note beside this command before running it.Deletes uncommitted changes in tracked files permanently. Run the inspect step first if you are not sure ORIG_HEAD still points at the pre-rebase commit.
Check it worked
git log --oneline -5
The branch history matches what you had before the rebase.
The reflog records every commit your HEAD has pointed at, including ones a hard reset removed from the branch. Copy the id you want back.
Moves the branch to the recovered commit and resets your files to match it.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.This is itself a hard reset: uncommitted changes in tracked files are deleted permanently. Double-check the commit id with the inspect step first.
Check it worked
git log --oneline -3
The recovered commit is back at the top of the branch.
Worth knowing
Reflog entries for commits a reset removed expire after 30 days by default (gc.reflogExpireUnreachable) — recover sooner rather than later.
A dry run: prints every untracked file and folder that a real clean would delete, and touches nothing.
Deletes every untracked file and folder in the working tree.
DestructiveRead the note beside this command before running it.Untracked files were never committed, so git keeps no copy — this deletion is permanent. Run the preview first.
Check it worked
git status --short
No ?? entries remain (delete) or everything is unchanged (preview).
Worth knowing
Files matched by .gitignore are NOT removed unless you add -x — build outputs usually survive a plain clean.
Replaces the working copy of the file with the version from the chosen commit. Nothing is committed until you stage and commit it.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Overwrites the file's current uncommitted content in your working tree, which git cannot get back.
Check it worked
git status --short
The file shows as modified — its content now matches the old commit.
Using Git older than 2.23?
Before Git 2.23 this was spelled: git checkout <commit> -- <path>
Re-applies the newest stash to your working tree and leaves the stash entry in place as a safety copy.
Re-applies the newest stash and deletes it from the list — but only if it applied cleanly; on conflict the stash is kept.
CautionRead the note beside this command before running it.Once popped cleanly the stash entry is gone. Use apply if you might need the same stash again.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.The drop prints the stash's commit id — keep it; git stash store can resurrect the stash from that id until git garbage-collects it.
DestructiveRead the note beside this command before running it.Clears every stash at once and prints no commit ids, so recovery means digging with git fsck before garbage collection runs. Prefer dropping one at a time.
Renames the branch you are on. Commits, history and staged work are untouched.
Renames locally, publishes the new name with tracking set up, then removes the old name from the remote — in that order, so the branch is never absent from the remote.
Renames another local branch without checking it out first.
Renames the other branch locally, publishes the new name, then removes the old name from the remote.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Teammates still on the old name will see their pushes fail once it is deleted; they can switch with git fetch followed by git switch to the new name.
CautionRead the note beside this command before running it.Teammates still on the old name will see their pushes fail once it is deleted; they can switch with git fetch followed by git switch to the new name.
Check it worked
git branch -vv
The new name is listed (and, on the pushed path, tracks the remote's new name).
Deletes the branch, but only when its commits are already reachable from your current branch — the built-in safety net.
Deletes the branch even when its commits are not merged anywhere else.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Unmerged commits lose their branch label. They stay in git reflog for at least 30 days by default — recover with the 'recover a deleted branch' task.
Check it worked
git branch --list
The deleted branch no longer appears in the list.
Worth knowing
You cannot delete the branch you are currently on — switch to another branch first.
companion: delete your local copy too (skip if you never had one)
The push removes the branch from the remote for everyone. The companion -d then removes your local copy — it refuses if the branch holds unmerged work, which is your safety net.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Deleting a remote branch affects everyone using that remote, and remotes usually keep no reflog. If you still have the commit id, anyone can restore it with: git push <remote> <commit>:refs/heads/<branch>
Check it worked
git ls-remote --heads <remote> <branch>
No output means the branch is gone from the remote.
Worth knowing
Remotes refuse to delete their default branch (usually main) — change the default first if that is really what you want.
Prints just the current branch name — empty output means you are on a detached HEAD, not on any branch.
Check it worked
git status --short
Runs clean; the branch name matches what git status reports.
In detached HEAD state?
Empty output means detached HEAD: you are on a commit, not a branch. Commits made here need a branch before you switch away — see 'save work from a detached HEAD'.
Uncommitted changes travel with you: creating and switching to the new branch takes them along, and the old branch is left exactly at its last commit.
The new branch keeps every commit (step 1) before the wrong branch is rewound (step 2), so nothing is ever unreachable.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Step 2 is a hard reset on the wrong branch: uncommitted changes in tracked files are deleted permanently. The moved commits themselves are safe on the new branch.
Switches to the target branch and replays the commit there. The original stays where it was — remove it from the wrong branch afterwards with the 'undo the last commit' task.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Cherry-picking copies a commit; the same change now exists in two places until you clean up the source branch.
Check it worked
git log --oneline -3
The copied commit is at the top of the target branch.
Creates a branch at the commit the stash was made from, applies the stash there, and drops it on success — the cleanest way out when a stash no longer applies to your moved branch.
The command keeps its placeholders until the fields above are filled in.
Check it worked
git status --short
You are on the new branch with the stashed changes back in your files.
Puts your working tree at the tagged commit in detached-HEAD mode — ideal for inspecting or building a release.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.You are now on a commit, not a branch: new commits made here are lost when you switch away unless you create a branch first.
Check it worked
git status --short
git reports a detached HEAD at the tagged commit and a clean tree.
In detached HEAD state?
To keep any commits you make here, run: git switch -c <branch> before leaving — see 'save work from a detached HEAD'.
Moves your working tree to that commit in detached-HEAD mode so you can look around or test without touching any branch.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.You are now on a commit, not a branch: new commits made here are lost when you switch away unless you create a branch first.
Check it worked
git status --short
git reports a detached HEAD at the chosen commit.
Using Git older than 2.23?
Before Git 2.23 this was spelled: git checkout <commit>
In detached HEAD state?
To keep any commits you make here, run: git switch -c <branch> before leaving — see 'save work from a detached HEAD'.
Forgets the remote: its URL, its remote-tracking branches and related settings are removed from this clone. The remote repository itself is untouched.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Branches that tracked this remote lose their upstream link; re-add the remote and use 'set a branch's upstream' to relink them.
Replaces the remote branch with your rewritten one, but only if the remote still looks the way your last fetch saw it — if a teammate pushed meanwhile, the push is refused and nothing is lost.
Replaces the remote branch unconditionally with your local one.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Anyone who already pulled the old history must rebase onto the rewritten branch. Announce rewrites on shared branches.
DestructiveRead the note beside this command before running it.Overwrites any commits pushed by others since your last fetch — they vanish from the branch without warning. Prefer --force-with-lease, which fails instead of overwriting.
Check it worked
git ls-remote --heads <remote> <branch>
The remote branch id now matches your local branch tip.
Worth knowing
--force-with-lease checks the remote against your remote-tracking snapshot and refuses when the remote has commits you haven't fetched. Fetching renews that lease — so if you fetch first, inspect what arrived (git log <branch>..<remote>/<branch>) before pushing; a blind fetch-then-push defeats the protection. Background fetches from IDEs can do the same.
Shallow clones can't see older history — log and blame stop at the cut-off — so review what a rewrite replaces from full history: deepen a shallow clone with the 'convert a shallow clone' task before force-pushing.
Fetches, then merges the remote branch into yours, recording a merge commit when both sides have new work.
Fetches, then replays your unpushed commits on top of the remote branch, producing a straight-line history.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Rebasing rewrites your unpushed commits (new ids). That is routine for local work — but avoid it if you already pushed these commits somewhere.
Check it worked
git log --oneline -5
Remote commits are in your history — linearly (rebase) or via a merge commit.
Removes the tag from the remote for everyone, then deletes your local copy so a later git push --tags cannot resurrect it by accident.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Anyone who already fetched the tag keeps it locally, and releases pinned to it lose their anchor. If you must move a tag, delete-then-recreate like this is the honest way — retagging in place silently diverges across clones.
Check it worked
git ls-remote --tags <remote>
The deleted tag no longer appears in the remote's tag list.
Publishes every local branch to the remote in one command — useful when moving a repository to a new home.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Half-finished local experiments become visible to everyone with access to the remote. Check git branch first.
Replaces the last commit with an identical one carrying the new message. Staged changes, if any, are folded in too.
Rewrites the message locally, then replaces the pushed commit. --force-with-lease refuses if a teammate pushed meanwhile, so you never overwrite unseen work.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Amending gives the commit a new id. That is harmless while it is local — never amend a commit others already have.
CautionRead the note beside this command before running it.Everyone who pulled the old commit must rebase onto the rewritten one. For busy shared branches, prefer leaving the message and moving on.
Check it worked
git log --oneline -3
The top commit shows the new message.
Worth knowing
Amend rewrites only the LAST commit. Older messages need an interactive rebase, which is outside this tool's copy-paste lane.
Stages the file and folds it into the last commit. --no-edit keeps the existing message.
Folds the file into the pushed commit and replaces it on the remote. --force-with-lease refuses if a teammate pushed meanwhile.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Amending gives the commit a new id. That is harmless while it is local — never amend a commit others already have.
CautionRead the note beside this command before running it.Everyone who pulled the old commit must rebase onto the rewritten one. On busy shared branches, a small follow-up commit is often kinder.
Check it worked
git log --oneline -3
Still one commit at the top — now containing the forgotten file.
Rewrites the last commit with the author you give as 'Name <email>', keeping the message and content unchanged.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Amending gives the commit a new id; if it was already pushed, follow up with the force-push task and coordinate with your team.
Check it worked
git log -1 --format=%an%x20%ae
Prints the top commit's author name and email — now the corrected identity.
Worth knowing
Fix the default for FUTURE commits too, or the next commit repeats the mistake — see 'set your name and email'.
undo the commits but keep all their changes staged
git commit -m <message>
git reset --soft <commit>
git commit -m <message>
git push --force-with-lease <remote> <branch>
Rewinds to the chosen commit with every later change still staged, then records them as a single new commit — a squash with no interactive rebase.
Squashes locally, then replaces the pushed history. --force-with-lease refuses if a teammate pushed meanwhile.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.The squashed-away commits leave the branch (reflog keeps them for at least 30 days by default). Uncommitted work is untouched by --soft.
CautionRead the note beside this command before running it.Everyone who pulled the old commits must rebase onto the squashed branch. Coordinate before squashing shared history.
Check it worked
git log --oneline -3
One combined commit now sits where the several used to be.
Reverting a merge needs to know which side to keep: -m 1 keeps the branch you were on when you merged and backs out everything the merged branch brought in.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.After reverting, merging the same branch again brings nothing in — git considers it already merged. Revert the revert first if the branch comes back later.
Check it worked
git log --oneline -3
A Revert commit sits above the merge; the merged changes are gone from the files.
Replays every commit after the start (exclusive) up to the end (inclusive), oldest first, each as its own commit.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.If one commit in the range conflicts, the pick pauses there — resolve and run git cherry-pick --continue, or back out with the abort task.
Check it worked
git log --oneline -5
The picked commits appear on top in their original order.
Removes the file from the last commit only — enough when the mistake was just committed and never existed before. Add it to .gitignore so it can't come back.
Rewrites every commit on the current branch with the file deleted from the snapshot. Commit ids all change.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.If the commit was already pushed, the amended commit must be force-pushed, and the file remains visible in the remote's old history until that history is unreachable.
DestructiveRead the note beside this command before running it.This rewrites all history: every collaborator must re-clone, every open branch must be rebuilt, and the rewrite must be force-pushed. If the file held a secret, rotate the secret — rewriting does not un-leak it.
Check it worked
git log --oneline -- <path>
No commits mention the file any more (last-commit path: the newest commit doesn't).
Worth knowing
git filter-branch is git's built-in but deprecated rewriter; for large repositories the separately-installed git-filter-repo tool is the maintained, faster option.
Copy the whole-history line exactly as printed, FILTER_PATH= prefix included: the quoted filter is a command git runs itself, and it reads the path from that variable rather than having it pasted inside the quotes.
If that commit contained nothing but this file, --amend refuses to create an empty commit — undo the commit instead (git reset --soft HEAD~1) and re-commit whatever should remain, or rerun the amend with --allow-empty.
Replays every commit after the doomed one onto its parent — the commit disappears and the rest keep their order. If a later commit depended on it, the rebase pauses with a conflict.
Drops the commit locally, then replaces the pushed branch. --force-with-lease refuses if a teammate pushed meanwhile.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.The branch's later commits get new ids, and the dropped commit's changes leave the branch (reflog keeps everything for at least 30 days by default).
DestructiveRead the note beside this command before running it.Everyone who pulled the old branch must rebase onto the rewritten one, and the dropped commit's changes vanish from shared history. If others may have built on it, revert instead.
Check it worked
git log --oneline -5
The dropped commit no longer appears in the history.
undo the commit; its changes stay in your files, unstaged
git add -- <path>
stage just the first piece
git commit -m <message>
repeat add + commit for the remaining pieces
Unpacks the last commit into your working tree, then lets you re-commit it in as many pieces as you like.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.The original single commit is replaced (reflog keeps it for at least 30 days by default). Don't split commits that were already pushed without coordinating a force-push.
Check it worked
git status --short
After the first piece is committed, the remaining changes are still listed, ready for the next commit.
Lists only commits that DELETED the path — the top result is when it disappeared. Restore it from that commit's parent with the 'recover a deleted file' task.
The command keeps its placeholders until the fields above are filled in.
HEAD@{1} is where your branch pointed just before the amend — resetting softly there restores the original commit while keeping the amend's extra changes staged.
CautionRead the note beside this command before running it.Relies on the reflog entry created by the amend; run it before anything else moves HEAD, or find the right entry with git reflog first.
Removes the cherry-picked commit from the tip while keeping its changes staged (assumes it is the newest commit).
Stages the inverse of the cherry-picked commit; review, commit, push.
Removes the cherry-picked commit and its changes from your working copy (assumes it is the newest commit).
Creates a commit reversing the cherry-pick, leaving pushed history intact.
The command keeps its placeholders until the fields above are filled in.
DestructiveRead the note beside this command before running it.Also deletes uncommitted changes in tracked files, permanently. The removed commit stays in git reflog for at least 30 days by default.
CautionRead the note beside this command before running it.Everyone who pulls gets the reverting commit — coordinate if others built on the pick.
Check it worked
git log --oneline -3
The cherry-picked commit is gone (local) or a revert sits above it (pushed).
The command git launches for commit messages and similar prompts. For VS Code use 'code --wait' — the --wait keeps git waiting until you close the tab.
The command keeps its placeholders until the fields above are filled in.
Every git pull now rebases your local commits on top of the fetched branch — the setting that silences the 'divergent branches' hint with linear history.
Every git pull merges the fetched branch, recording a merge commit when needed.
This repository stops treating executable-bit changes as modifications — the usual fix when a mounted drive or another OS flips permissions on everything.
Check it worked
git config --get core.fileMode
Prints false — mode-only diffs are now ignored here.
Worth knowing
Scripts that genuinely need the executable bit tracked should keep fileMode true; set this per-repository, not globally.
Git remembers credentials in memory for 15 minutes by default — nothing is ever written to disk.
Git saves credentials to ~/.git-credentials and never asks again.
CautionRead the note beside this command before running it.The store helper writes credentials UNENCRYPTED to a file in your home directory. Your OS keychain (osxkeychain, wincred, libsecret) is the safer permanent option when available.
.gitignore only affects UNtracked files — this is the missing step. The file leaves version control at this commit but stays in your working tree; add it to .gitignore so it never comes back.
The command keeps its placeholders until the fields above are filled in.
CautionRead the note beside this command before running it.Collaborators who pull this commit have their copy of the file DELETED from their working tree (theirs was tracked). Warn them to back up local values first.
Check it worked
git status --short
The file now shows as untracked (??) — or not at all once ignored.
From now on, a plain git push on a branch with no upstream publishes it and sets up tracking automatically — the 'fatal: the current branch has no upstream' error disappears (Git 2.37+).
Check it worked
git config --get push.autoSetupRemote
Prints true — new branches now push without ceremony.
Colors status, diff, branch and log output when writing to a terminal, and stays plain when piping to files or other commands.
Check it worked
git config --get color.ui
Prints auto.
No matching task
The search looks at task names, plain-English intents and the git commands themselves. Try one verb — undo, delete, rename, unstage — or clear the search to see all five groups again.
Do it offline:$ git log --oneline -3
How to use it
Search the directory in plain words — undo last commit, rename branch, force push. Matching covers task names and intent phrases; an empty search shows all five groups.
Answer the outcome questions. Toggles say what happens — Keep my changes (staged), not --soft — and the safer choice always comes first.
Fill in names where a command shows a <branch>-style placeholder. It stays put until you type; an invalid name is refused with the offending character and its position.
Copy the command — multi-step tasks list their lines in run order — then run the verify line underneath to confirm the result.
Undo a commit is only the front door: this page holds 104 git tasks across undo & recover, branches, remotes, history and config. Open one, answer outcome questions — keep my changes, or throw them away — instead of recalling flags, then copy the exact command: destructive variants carry a labelled warning, and every task ends with a line that checks the result. Names you type are substituted right on this page.
How it works
Each task is a small decision tree stored as data: every combination of its toggle answers maps to a command sequence enumerated ahead of time, so switching an answer swaps in a different pre-built variant rather than editing a string. Within a toggle the safer variant is listed before the dangerous one, and each destructive variant carries its own warning note.
The directory is verified by execution, not proofreading: all 163 command variants run against a real repository — a scratch working copy with a local bare repository standing in for origin. Every line must exit zero, the task's verify command must exit zero, and the outcome is then confirmed with plumbing such as rev-parse, status --porcelain and ls-remote. The date below is that run's date.
Name checking mirrors git check-ref-format. A branch or remote name is refused for a space, a control character, any of ~ ^ : ? * [ \, the sequences .., @{ and //, a segment starting with a dot or ending in .lock, or a leading dash — each with the position that failed. Values that pass but would still confuse a shell are quoted on substitution, so an apostrophe in a commit message never breaks the copied line.
Commands target the spellings git has used since 2.23, when restore and switch took over the undo duties of checkout; where an older spelling differs, the task carries it in a separate note. Tasks that rewrite history fork on one question — has this been pushed? Local-only answers use reset and amend; pushed answers build a revert, which undoes by adding a commit instead of rewriting shared history.
Examples
undo-last-commit · keep my changes (staged) · not pushed
↓
git reset --soft HEAD~1
The directory's default variant. The branch pointer moves back one commit while its changes stay staged, ready to fix and recommit; git log --oneline -3 then shows the undone commit no longer on top. The old tip remains in the reflog.
Two ordered lines: the push removes feature/x from the remote for everyone, then the companion -d removes your local copy — and refuses if it still holds unmerged work. Empty output from the verify line means the remote branch is gone.
rename-branch · the one I'm on · also on the remote
Renaming away a typo while standing on the branch. The order matters: rename locally, publish the new name with tracking set (-u), and only then delete the old name — the branch is never absent from the remote.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Detached HEAD is a place, not an error
Checking out a tag or a raw commit puts you on a commit instead of a branch, and git branch --show-current prints nothing. Commits made there need a branch before you switch away, so the affected tasks carry a note pointing at the save-my-work step: git switch -c with a new name.
Already pushed changes the whole answer
Undo tasks fork on whether the commit left your machine. Rewriting locally is routine; rewriting a pushed branch makes it diverge from the remote for everyone tracking it. The pushed paths therefore build revert commands, and local-only is a visible pre-selected answer, never a hidden assumption.
Before Git 2.23, the spelling differs
git restore and git switch arrived in 2.23 (August 2019). Older installations spell the same operations with reset and checkout — git reset HEAD <path> to unstage, git checkout -- <path> to discard — and affected tasks show the older line in a per-task note. The behaviour is identical.
A blind fetch defeats --force-with-lease
The lease compares the remote branch against your remote-tracking snapshot and refuses the push when the remote has commits you haven't fetched. Fetching renews that lease, so a bare fetch-then-push waves through whatever just arrived — inspect the new commits (git log main..origin/main) before pushing, and remember that background fetches from IDEs renew the lease the same way.
Branch labels are cheap; remote deletions are not
Deleting a local branch — even force-deleting — removes a label; the commits stay in your reflog for at least 30 days by default. Remotes usually keep no reflog, so deleting a remote branch is the step that actually strands work. That task's warning includes the push syntax that restores it from a commit id.
Common errors
A space at position 3 can't be used in a branch name — git ref names never contain spaces, control characters or ~ ^ : ? * [ \.
Usually a pasted ticket title rather than a name. Swap spaces for dashes; the message points at the first offending character.
A branch name can't contain ".." — found at position 8; remove or separate those characters.
Two dots form git's range syntax (main..feature), so names may not contain them. A single dot is fine away from the edges.
A branch name can't start with "-" — git would read it as a command option; start with a letter or digit instead.
A leading dash makes the name look like an option flag to every git command that receives it, so it is refused up front.
"HEAD" is reserved by git and can't be used as a branch name — pick another name.
HEAD always means the commit you currently have checked out; a branch with that exact name would shadow it everywhere.
A space at position 5 can't be used in a revision — use a commit hash, a branch or tag name, or a form like HEAD~2.
Revisions accept hashes, names and navigation forms such as HEAD~2 or main@{1}, never whitespace. Written as one token, HEAD~1 passes.
This value is 257 characters long — the limit for a command parameter is 256 characters; shorten it before building the command.
Parameters cap at 256 characters and the refusal names the limit. Reaching it usually means a paste caught more than intended.
FAQ
How do I undo a git commit that has already been pushed?
Answer yes on the pushed toggle and the task builds a revert: git revert --no-edit HEAD adds a new commit reversing the last one, so shared history is never rewritten and teammates simply pull the reverting commit. Resetting instead would make your branch diverge from the remote.
Does git reset --soft delete my changes?
No. It moves the branch pointer back one commit and leaves your files and staging area untouched — the undone commit's changes sit staged, ready to commit again. Deletion enters only with --hard, which sits behind an explicit throw-the-changes-away answer and wears the destructive label.
What is the difference between git push --force and --force-with-lease?
--force replaces the remote branch unconditionally, including commits you have never seen; --force-with-lease refuses the push when the remote no longer matches your last fetch, failing instead of overwriting a teammate's work. The force-push task lists the lease form first.
How do I unstage a file without losing my edits?
git restore --staged -- <path> takes the file out of the staging area and touches nothing in your working copy. Before Git 2.23 the identical operation was git reset HEAD <path>. Discarding the edits themselves is a different task here, and its discard variant is labelled destructive.
How long can a deleted commit be recovered?
Commits dropped by a reset or branch deletion stay in your reflog — by default about 90 days for reachable entries, 30 for unreachable ones — until garbage collection prunes them; git reflog lists them for recovery. Remotes are the exception: a deleted remote branch usually leaves no reflog at all.
Why does git say my branch name is invalid?
Ref names follow git check-ref-format: no spaces or control characters, none of ~ ^ : ? * [ \, no .., @{ or //, no segment starting with a dot or ending in .lock, no leading dash. The name fields on this page apply the same rules and point at the exact character that fails.
Can I undo a git merge?
Yes — the undo-merge task forks the usual way. Local-only uses git reset --merge ORIG_HEAD to step back to the pre-merge state; a pushed merge is reversed with git revert -m 1, where -m 1 names the mainline parent a two-parent commit cannot infer on its own.
Keyboard shortcuts
⌘/Ctrl + C
Copy the open task's command when no text is selected
⌘/Ctrl + Shift + C
Copy even while text is selected
t
Switch the theme
? or ⌘/Ctrl + /
Open the shortcut help
Esc
Dismiss dialogs and transient state
Related tools
Gitignore Generator — Multi-select your stacks and get one merged, deduplicated .gitignore — with every rule explained, not just dumped.
Conventional Commits Helper — Compose a spec-correct Conventional Commits message from a form — or paste one and lint it with commitlint-compatible checks.
Semver Toolkit — Validate versions, compare precedence, test npm ranges — caret vs tilde made explicit — and calculate bumps.
Changelog Generator — Paste git log output, get a grouped CHANGELOG.md section — Conventional Commits sorted into Features, Fixes and Breaking Changes.
Git URL Converter — Convert Git repository URLs instantly between SSH, HTTPS, and Web formats with organization and repository parsing.
Regex Tester (JavaScript) — Test JavaScript regular expressions live — highlighted matches, groups and replace preview, entirely on this device.
Nothing you paste here leaves this tab. State only ever travels in links you explicitly create.