Git Rescue
A complete Git cheat sheet and a fix-it playbook for when things go wrong. 82 commands explained with real examples, 56 step-by-step rescue guides, and a plain-English glossary. Free, no login, nothing stored.
Three ways in
Pick the one that matches why you’re here — something is broken, you need a command, or a word in an error message makes no sense.
Fix-it guides
56 step-by-step walkthroughs for when something has gone wrong — deleted files, bad resets, rejected pushes, merge conflicts, leaked secrets. Each says up front whether the work can be recovered.
Find your fix →Git cheat sheet
All 82 commands across 15 categories with syntax, the flags you actually use, worked examples and a danger rating — including 36 deep cuts most cheat sheets skip.
Open the cheat sheet →Git glossary
20terms in plain English — HEAD, the index, detached HEAD, fast-forward, merge base, refspec. The vocabulary Git’s error messages assume you already know.
Read the glossary →Something just went wrong?
The emergencies people hit most. Each is a complete walkthrough — read it top to bottom and copy as you go.
Browse by problem type
56 guides sorted into 7 categories.
What is Git?
Git is a distributed version control system: it records the full state of your project every time you commit, and every clone carries the entire history rather than just the latest files. Created by Linus Torvalds in 2005 to manage Linux kernel development, it is now the default way software is tracked, shared and shipped. The practical consequence is that almost nothing you commit can be permanently lost — which is why this page exists.
Commits are snapshots, not diffs
Most people picture Git storing a list of changes. It doesn't — each commit records a complete picture of every tracked file, plus a pointer to its parent. Identical files are stored once and shared between commits, so this is far cheaper than it sounds, and it's why checking out any commit in history is instant.
Three places your work can live
The working directory is your actual files. The index (or staging area) is the commit you're composing. The repository is permanent history. Nearly every confusing Git error makes sense once you ask which of these three a command touches — and it's exactly what separates git reset --soft, --mixed and --hard.
Everything is content-addressed
Git hashes the contents of every file, tree and commit into a SHA identifier. Change one byte and you get a different hash, which is what makes history tamper-evident. It's also why staging a file makes it recoverable: the content is written into .git/objects at that moment and never modified again.
Branches are just pointers
A branch is a file containing a single commit hash. That's the whole implementation. Creating one is instant regardless of project size, deleting one throws away a pointer rather than any commits, and 'moving work between branches' really means pointing a different name at the same commits.
The reflog remembers everything
Git keeps a private journal of every position each reference has held — including states that no branch points to any more. This is the safety net beneath resets, rebases and deleted branches, and it's kept for 90 days by default. It's local only, so a fresh clone starts with an empty one.
Every clone is a full backup
Because clones contain the complete history, there is no single point of failure. A colleague force-pushing over your branch destroys one pointer on one server while the commits themselves survive in every clone that had fetched them. Distribution is what makes most Git disasters recoverable.
What Git is used for
Version control is the obvious answer, but that undersells it — Git is the substrate that collaboration, automation and deployment are all built on.
A time machine for your project
Return any file — or the whole project — to how it looked at any point in the past. This is what makes bold refactors safe: you can always get back to the version that worked.
Collaboration without overwriting each other
Several people work on the same codebase simultaneously and Git merges their changes, flagging only the spots where two people genuinely edited the same lines.
Risk-free experimentation
Branch off, try the idea, and either merge it or delete the branch. Because branches cost nothing, there's no reason not to try something — and no consequence if it fails.
Accountability and archaeology
Every line can be traced to the commit, author and date that introduced it. git blame explains why baffling code exists, and git bisect finds the exact commit that broke something.
The backbone of modern deployment
Pushing a tag triggers a release, merging a pull request deploys to production, and CI runs against every commit. Git is the event source that automation hangs off.
Far more than code
Documentation, infrastructure definitions, game design docs, configuration, legal contracts and academic papers all live in Git. Anything text-based benefits from versioned history and review.
Git alternatives
Git won, but it isn’t the only option — and for some kinds of work it genuinely isn’t the best one.
Mercurial (Hg)
Distributed VCSGit's closest philosophical sibling, born the same year for the same reason. Distributed, fast, and widely considered to have a cleaner and more consistent command set — its history is immutable by default, which makes it harder to shoot yourself in the foot.
Subversion (SVN)
Centralised VCSThe dominant system before Git. One central server holds the history and clients check out a working copy, so there's a single authoritative timeline and no local commits. File locking prevents two people editing the same binary at once.
Perforce (Helix Core)
Centralised VCSThe standard in AAA game development and other industries handling enormous binary assets. It handles multi-terabyte repositories and exclusive file locking gracefully — the two things Git struggles with most.
Unity Version Control (Plastic SCM)
Hybrid VCSBuilt for game teams and integrated directly into the Unity Editor. It handles large binaries well, offers both centralised and distributed workflows, and gives non-programmers a visual client they'll actually use.
Jujutsu (jj)
Distributed VCSA modern system that works on top of existing Git repositories, so you can adopt it without migrating anything. It treats the working copy as an automatically-amended commit, which eliminates staging, stashing and most of the situations that lead to lost work.
Fossil
Distributed VCSA single self-contained executable that bundles version control with a bug tracker, wiki, forum and web interface. Written by the author of SQLite and used to develop it, with history that is append-only by design.
The honest verdict: For almost every software project the honest answer is to use Git — not because it has the best interface, but because the ecosystem, the hosting platforms, the CI systems and the collective knowledge are all built around it. The genuine exceptions are asset-heavy work, where Perforce or Unity Version Control handle large binaries far better, and teams who need exclusive file locking because their files cannot be merged. If you like Git's model but resent its rough edges, Jujutsu is worth a look precisely because it runs on top of your existing Git repositories.
Frequently asked questions
Can Git recover a deleted file that was never committed?
Only if the file was staged with git add at some point. Staging writes the content into Git's object database, where it survives as a dangling blob that git fsck --lost-found can recover. If the file was never staged and never committed, Git never saw it and cannot help — your editor's local history or your operating system's file-versioning feature is the realistic route.
What is the most important Git recovery command?
git reflog. It lists every position HEAD and your branches have held, including states no branch points to any more, and it keeps them for 90 days by default. Commits lost to a bad reset, a botched rebase or a deleted branch are almost always sitting in the reflog waiting to be pointed at again.
Is anything in Git ever truly permanent?
Committed work is effectively safe until garbage collection prunes unreachable objects, typically weeks later. The genuinely unrecoverable category is content Git never received: uncommitted, unstaged edits destroyed by git reset --hard, git restore or git clean. If Git was never given the bytes, no Git command can produce them.
What is the difference between git reset, git revert and git restore?
git reset moves your branch pointer and can rewrite the index and working directory — it changes history. git revert adds a new commit that undoes an earlier one, leaving history intact, which makes it the safe choice on shared branches. git restore only affects file contents in your working directory or index and never touches history at all.
What is the difference between git reset --soft, --mixed and --hard?
All three move your branch pointer back. --soft leaves the index and working directory untouched, so the undone changes stay staged. --mixed (the default) also resets the index, so the changes remain as unstaged edits. --hard resets the working directory too, permanently discarding uncommitted changes — the only one of the three that can lose work.
When should I use merge instead of rebase?
Merge when the branch is shared or when you want history to reflect what genuinely happened. Rebase when the branch is yours alone and you want a clean linear history before opening a pull request. The rule that matters: never rebase commits that have already been pushed somewhere others pull from.
How long does Git keep deleted commits?
Reflog entries for reachable commits last 90 days and unreachable ones 30 days, after which git gc can prune the objects. Those defaults are configurable via gc.reflogExpire and gc.reflogExpireUnreachable. In practice you have weeks — but run git fsck sooner rather than later, and avoid git gc --prune=now while you're recovering.
What does git fsck --lost-found actually do?
It walks every object in .git/objects and reports the ones nothing references, writing them into .git/lost-found so you can browse them as real files. Dangling blobs are file contents from staged-but-never-committed work; dangling commits are whole snapshots from deleted branches and dropped stashes. It's the deepest recovery layer Git has.
Is force pushing always dangerous?
On a branch only you use it's routine and fine. On a shared branch it can destroy work others have pushed. Always prefer git push --force-with-lease, which aborts if the remote has moved since you last fetched — it prevents exactly the accident that plain --force causes.
Why was my push rejected?
Almost always because the remote has commits you don't have locally, so completing the push would orphan them. Run git pull --rebase to bring their work in and replay yours on top, then push again. The rejection is Git's most valuable safety check — force-pushing past it deletes whatever caused it.
Why does GitHub reject my password?
GitHub removed password authentication for Git operations in August 2021. Use a personal access token in place of the password, or switch the remote to SSH and authenticate with a key. If you already created a token and it still fails, your credential helper is replaying the old one — clear the stored credential for github.com.
Do I need GitHub to use Git?
No. Git is a complete version control system that works entirely offline, with full history, branching and commits on your own machine. GitHub, GitLab and Bitbucket are hosting platforms that add pull requests, issues, CI and a shared remote — convenient for collaboration, but not required.
What is the difference between git pull and git fetch?
git fetch downloads new commits and updates your remote-tracking branches without touching your files — completely safe, and it lets you inspect what's coming before accepting it. git pull is a fetch followed immediately by a merge or rebase into your current branch, which is why it's the command most likely to drop you into an unexpected conflict.
What is a detached HEAD and is it a problem?
It means HEAD points directly at a commit instead of at a branch, which happens when you check out a hash or tag. It's a normal state — bisect and CI use it deliberately — and only becomes a problem if you commit and then switch away, because those commits have no branch referencing them. Running git switch -c <name> before leaving avoids it entirely.
How do I undo the last commit without losing my changes?
git reset --soft HEAD~1 removes the commit and leaves every change staged, ready to be recommitted. Use the default --mixed mode if you'd rather have the changes unstaged. Avoid --hard unless you genuinely want the work destroyed, and if the commit is already pushed use git revert instead.
Why isn't .gitignore working?
Because .gitignore only applies to untracked files. Once a file has been committed, Git keeps tracking it regardless of ignore rules. Run git rm --cached <file> to untrack it while keeping your local copy, then commit — the ignore rule takes effect from that point.
Why does Git show every file as modified when I didn't change anything?
Usually line endings or file permissions. Windows writes CRLF and Unix writes LF, so the same file differs byte for byte across platforms — fix it with a committed .gitattributes containing `* text=auto` plus a one-off git add --renormalize. If the diff shows only mode lines, set core.fileMode false instead.
Should I use Git for a game project with large assets?
Git works if you set up Git LFS before committing binaries, so textures, audio and models are stored as pointers rather than full copies in every commit. Without LFS the repository bloats quickly and never shrinks. For studios versioning hundreds of gigabytes, Perforce or Unity Version Control genuinely handle it better.
Can Unity scenes and prefabs be merged in Git?
Yes, but only with setup. Set Asset Serialization to Force Text in Unity's editor settings, then register UnityYAMLMerge as Git's merge tool for .unity and .prefab files via .gitattributes. Without both, Git's line-based merge can silently corrupt a scene's internal object references.
How do I remove a secret I accidentally committed?
Rotate the credential first — that's the only step that actually restores security, since bots scrape public repositories within seconds and old commits may already be cached or cloned. Then purge it from history with git filter-repo and force-push. Deleting the file in a new commit does nothing, because every earlier commit still contains it.
How do I make my repository smaller?
Find the biggest objects by piping git rev-list --objects --all through git cat-file --batch-check, then remove them from history with git filter-repo --strip-blobs-bigger-than. Follow up with git reflog expire and git gc --prune=now to actually reclaim the disk, and move future binaries into Git LFS.
What does 'refusing to merge unrelated histories' mean?
The two branches share no common ancestor, so Git has no base to merge against. It usually means you initialised a repository locally and separately on the host. Add --allow-unrelated-histories to proceed — but first check you aren't accidentally merging two genuinely different projects, which is what the guard is for.
Is it safe to delete .git/index.lock?
Yes, as long as no Git process is genuinely running. The lock exists only to stop two commands writing the index simultaneously; if the process that created it died, the file is stale and Git recreates it when needed. Close any IDE or Git GUI first — they run Git in the background constantly.
How many Git commands do I actually need to know?
About a dozen cover ninety percent of daily work: status, add, commit, push, pull, switch, branch, merge, log, diff, restore and reset. The rest are worth knowing about so you recognise them when a situation calls for one — reflog and fsck in particular, because they're what get your work back.
Is this Git cheat sheet free?
Yes — completely free, with no account, no sign-up and no limits. Every command reference and rescue guide is a static page you can read, search and copy from, and nothing you type is sent anywhere.