chmod Calculator
Unix permissions between symbolic and octal notation.
Describe what you want to do and get the right git commands, with warnings.
Runs entirely in your browser. Nothing you type or paste is sent anywhere.
Unix permissions between symbolic and octal notation.
Binary, octal, decimal and hex with a bit view and two’s complement.
Fill in a highlighted placeholder such as branch once and every command uses it. Nothing you type is saved.
74 scenarios.
Moves your branch back one commit without touching your files, so you can fix things and commit again.
Careful: Only for commits you haven’t pushed. Once a commit is shared, undo it with git revert instead.
Moves the branch back one commit and makes your files match it. The commit can still be found in the reflog for a while.
Destructive: reset --hard also wipes every uncommitted change in your working tree, and those can’t be recovered. Commit or stash anything you want to keep first.
git restore puts the file back to how it was when you last staged it; with --staged --worktree it goes back to the last commit.
Destructive: Your uncommitted edits to that file are gone for good — Git never had a copy of them.
Resets every tracked file and, optionally, removes files Git isn’t tracking — a clean slate at the last commit.
Destructive: All uncommitted work is deleted permanently. Run git stash -u instead if you might want it back.
Takes the file out of the next commit; your edits stay in the working tree.
Replaces the most recent commit with one that has the new message. Anything you’ve staged goes into it too.
Careful: This rewrites the commit. If it’s already pushed you’ll need git push --force-with-lease, which rewrites shared history.
Folds the newly staged changes into the previous commit and keeps its message.
Careful: Rewrites the last commit — only safe before you push it.
The reflog remembers the commit as it was before you amended it. A soft reset returns to it and leaves what the amend added staged.
Careful: Run it straight after the amend: HEAD@{1} means “where HEAD was one move ago”.
Creates a new commit that reverses the old one. History stays intact, so it’s the safe way to undo on shared branches.
git branch -D prints the commit the branch was on, and the reflog records it too. Recreate the branch at that commit.
Commits “lost” after a reset, rebase or detached HEAD usually still exist for at least 30 days by default. The reflog lists them so you can bring them back.
Every move of HEAD is in the reflog, so you can jump the branch back to its state before the operation. ORIG_HEAD also points there right after a reset, rebase or merge.
Destructive: reset --hard discards uncommitted changes. Stash them first if you have any.
Checking out a commit or tag directly leaves you on no branch. Create a branch to keep any work, or switch back.
Careful: Commits made while detached and not put on a branch can only be found through the reflog.
Stops the operation and puts everything back to how it was before you started it.
Fix each conflicted file, mark it resolved with git add, then continue. During a rebase “ours” is the branch you’re rebasing onto and “theirs” is your commit.
Edit each file: keep what you need and delete the <<<<<<< ======= >>>>>>> markers.
The file still exists in the commit just before the one that deleted it. If you haven’t committed the deletion yet, git restore <file> is enough.
Copies the file as it is in that branch, tag or commit into your working tree, without switching branches.
Careful: Replaces your copy of the file, including any uncommitted edits to it.
A soft reset un-commits the last N commits but keeps all their changes staged, ready to commit once. Interactive rebase gives finer control.
Careful: Rewrites history. If those commits are pushed, you’ll need git push --force-with-lease.
Applies the changes from one commit on top of your current branch as a new commit.
Interactive staging walks through each change so you can split unrelated edits into separate commits.
A commit with no changes — handy for kicking off a build or deploy without touching any files.
Needs Git 2.34 or newer. Add the same public key to GitHub or GitLab as a signing key to get the “Verified” badge. For GPG, skip the first line and set user.signingkey to your GPG key ID.
Set the right identity, then re-create the last commit with it.
Careful: Rewrites the last commit — force-push needed if it’s already pushed.
Creates the branch from where you are, switches to it, and pushes it. -u links it to the remote branch so plain git push and git pull work afterwards.
git switch is the modern, branch-only version of git checkout.
After fetching, switching to a branch name that only exists on origin creates a local tracking branch automatically.
Fixes “The current branch has no upstream branch” and “There is no tracking information”, so plain git pull and git push know where to go.
Brings the commits from <branch> into the current branch. If both changed the same lines you’ll get a conflict to resolve.
Points a new branch at your work, winds the current branch back, then carries on from the new branch.
Destructive: reset --hard discards uncommitted changes, so commit or stash them first. If the commits were already pushed to main, revert them there instead.
Renames the branch in your repository only.
Remotes have no rename: push the branch under its new name, then delete the old one. Teammates should run git fetch --prune and switch to the new branch.
Careful: Open pull requests and CI settings may point at the old name. For the default branch, change it in your host’s settings before deleting the old one.
Use -d normally: Git stops you deleting a branch with unmerged work. -D deletes it regardless.
Careful: With -D, unmerged commits are only recoverable through the reflog.
Removes the branch from the remote for everyone.
Careful: Anyone still working on it will need to push it again to restore it.
Sorting by commit date puts the branches you touched recently at the top.
Two dots in log means “reachable from the right, not the left”. Three dots in diff compares against the common ancestor — what a pull request shows.
Points origin somewhere else — for example after moving the repository, or switching from HTTPS to SSH.
A repository can have several remotes; each one gets its own <remote-name>/branch references.
Your fork doesn’t update itself. Fetch the original as upstream, bring its main into yours, then push to your fork.
Replays your local commits on top of what you fetched, keeping history linear instead of adding “Merge branch …” commits.
Moves your commits so they start from the latest main — a cleaner alternative to merging main into your branch.
Destructive: Rebasing rewrites your branch’s commits and the force-push replaces the copy on the remote. Fine for your own feature branch; never do it to a branch others build on.
Throws away local commits and changes on the current branch so it’s identical to the remote — the fix for “your branch and origin have diverged” when the remote is right.
Destructive: Local commits that aren’t on the remote, and all uncommitted changes, are discarded. Make the backup branch if you’re not sure.
Overwrites the remote branch with yours, but refuses if someone else pushed since you last fetched — unlike plain --force.
Destructive: Replaces history on the remote. Never force-push to shared branches like main; teammates will have to reset their copies.
Annotated tags store who tagged, when and why, and are what release tooling expects. Tags aren’t pushed unless you ask.
Removes a mistaken tag everywhere.
Careful: If anyone already fetched the tag, they keep their copy until they delete it too.
Removes origin/* references for branches that no longer exist on the remote, then shows local branches you may want to delete.
Shelves your uncommitted changes so you can switch tasks. A message makes the stash easy to find later.
apply leaves the stash in the list in case you need it again; pop removes it once it applies cleanly.
Deletes stashes you no longer need.
Destructive: Dropped and cleared stashes are very hard to get back (only via git fsck).
Everything after -- is a path, so only those files are stashed.
git diff on its own only shows changes you haven’t staged yet, which surprises a lot of people.
A compact branch-and-merge picture of the whole repository.
Shows the message, author and full diff of a single commit.
Every commit that touched the file, with diffs. --follow keeps going across renames.
blame shows the last commit to touch each line; log -L shows how those lines evolved.
The “pickaxe” lists commits where the number of occurrences of the text changed — perfect for “when did this function disappear?”
Answers “has this fix reached main yet?” and “which release shipped it?”.
A quick head count of who has committed to the current branch.
Git binary-searches between a good and a bad commit, so even 1,000 commits take about 10 steps.
Test the commit Git checks out, then run git bisect good or git bisect bad. Repeat.
git filter-repo rewrites every commit without the file or value. Rotating the secret is the real fix — rewriting history only stops it spreading further.
Destructive: Rewrites all history and every commit hash. Collaborators must re-clone, open pull requests break, and forks or cached copies on your host may still contain the secret.
1. Rotate or revoke the secret first: once pushed, assume it is compromised.
Interactive rebase opens a to-do list of the last N commits that you can rewrite line by line.
Careful: Rewrites every commit after the first one you change. Avoid on commits others have pulled.
.gitignore only affects untracked files. This removes the file from the repository while keeping it on your disk.
Careful: Others will see the file deleted when they pull, and it stays in old commits. If it held secrets, see “Remove a secret from history”.
Every commit records these. Use the email your Git host knows so commits link to your account.
A .gitattributes rule makes line endings consistent for everyone, whatever their editor or OS; renormalize fixes files already committed.
New repositories created with git init will start on main.
Leave out <dir> to use the repository’s own name.
Submodules are separate repositories pinned to a commit. Without these flags their folders stay empty.
Keeps a local tweak — say, a config file — out of git status and your commits without changing .gitignore.
Careful: Git stops showing changes to the file, and a pull that updates it will fail until you undo this. It only affects your clone.
Downloads just the latest snapshot — much faster for CI or a quick look.
A partial clone downloads file contents on demand; sparse checkout only puts the folders you name on disk.
Checks out another branch in a separate folder that shares the same repository — no stashing or second clone needed.
LFS keeps big binaries out of normal Git history and downloads them on demand. Your Git host must support it.
Destructive: lfs migrate rewrites every branch’s history and needs a force-push. Coordinate with your team before running it.
Removes files Git doesn’t track. Always preview with -n first.
Destructive: Deleted files don’t go to the trash and Git can’t restore them. Adding -x also deletes ignored files such as .env and local config.
Deletes every local branch fully merged into main, except main itself. -d refuses anything unmerged (and the branch you’re on), so it’s fairly safe.
Clears the staging area; your changes remain in the working tree.