Git for Interviews Cheat Sheet: Merge, Rebase, Reset, Revert and Reflog
Git's data model, merge vs rebase, reset soft/mixed/hard vs revert, reflog recovery, force-with-lease and team workflows, with a runnable script that proves each undo command.
Learning outcome
By the end of this cheat sheet you should be able to explain Git's data model in one minute, choose between merge and rebase, undo mistakes safely (reset, revert, restore, reflog), and describe a team branching workflow. These questions show up in .NET interviews because they reveal whether you can work on a shared codebase without losing anyone's work.
Intuition
Git is a content-addressed graph of snapshots:
- A commit is a snapshot (a tree of blobs) plus metadata plus parent pointer(s), named by its hash.
- A branch is just a movable pointer to a commit.
HEADpoints to the branch you are on (or directly to a commit: detached HEAD). - There are three places your changes live: the working tree, the index (staging area), and the repository (commits).
Most commands either move a pointer (reset, switch, merge --ff) or create new commits (commit, merge, revert, rebase, cherry-pick). "Rewriting history" means creating new commits and moving a branch pointer to them. The old commits still exist until garbage-collected, which is why reflog can save you.
Quick reference: everyday commands
| Task | Command |
|---|---|
| Start a branch from the current commit | git switch -c feature/x |
| See what changed (unstaged / staged) | git diff / git diff --staged |
| Stage part of a file | git add -p |
| Amend the last (unpushed) commit | git commit --amend |
| Update from remote without touching your branch | git fetch |
| Fetch + integrate | git pull --no-rebase (merge) or git pull --rebase; plain git pull follows configuration and version defaults |
| Shelve work in progress | git stash push -m "wip" → git stash pop |
| Show history as a graph | git log --oneline --graph --decorate --all |
| Who changed this line | git blame -L 10,20 path |
| Find the commit that introduced a bug | git bisect start, git bisect bad, git bisect good <sha> |
| Copy one commit onto the current branch | git cherry-pick <sha> |
| Tag a release | git tag -a v1.2.0 -m "v1.2.0" + git push origin v1.2.0 |
Merge vs rebase
git merge feature | git rebase main (on the feature branch) | |
|---|---|---|
| History | Keeps the true history; adds a merge commit (unless fast-forward) | Linear; replays your commits as new commits on top of main |
| Commit hashes | Unchanged | Changed for every replayed commit |
| Conflicts | Resolved once, in the merge commit | Possibly once per replayed commit |
| Safe on shared branches? | Yes | No: never rebase commits others have based work on |
| Typical use | Integrating into main (often via PR) | Tidying a private branch before review; git rebase -i to squash or reword |
- Fast-forward: if
mainhasn't moved, merge just moves the pointer.--no-ffforces a merge commit. - Squash merge (common PR option): one new commit on
main. The branch's individual commits are not part ofmain's history.
Undoing things
| Situation | Command | Rewrites history? |
|---|---|---|
| Discard unstaged edits to a file | git restore path | No |
| Unstage a file (keep the edits) | git restore --staged path | No |
| Undo the last commit, keep the changes staged | git reset --soft HEAD~1 | Yes (local) |
| Undo the last commit, keep the changes unstaged (default) | git reset HEAD~1 (--mixed) | Yes (local) |
| Undo the last commit and discard the changes | git reset --hard HEAD~1 | Yes, destructive |
| Undo a commit that is already pushed or shared | git revert <sha> (a merge needs -m <parent-number>; use 1 only when parent 1 is the intended mainline) | No: adds an inverse commit |
| Recover a "lost" commit or branch | git reflog → git switch -c rescue <sha> or git reset --hard HEAD@{1} | n/a |
| Abort a merge or rebase in progress | git merge --abort / git rebase --abort | n/a |
| Push after rewriting your own branch | git push --force-with-lease | Yes, on the remote |
--force-with-lease refuses to overwrite the remote branch if it moved since your last fetch. Plain --force silently discards a teammate's pushed commits.
Workflows interviewers ask about
| Workflow | Shape | Fits |
|---|---|---|
| Trunk-based development | Short-lived branches (hours to a day or two) merged to main often; feature flags for unfinished work | CI/CD, frequent deploys |
| GitHub flow | Branch → PR → review + CI → merge to main → deploy | Most SaaS teams |
| Git flow | develop, release/*, hotfix/*, main | Versioned products with scheduled releases; heavier |
Good PR hygiene: small focused changes, a meaningful commit message (imperative subject line, explanation of why), CI green, protected main with required reviews and checks.
.NET-specific notes
- Start every repo with
dotnet new gitignore(excludesbin/,obj/,.vs/, user files). - Never commit secrets (
appsettings.*.jsonwith keys). Usedotnet user-secretslocally and a vault in production. If a secret was pushed, rotate it. Rewriting history does not un-leak it. - Line endings: add a
.gitattributes(for example* text=auto) so Windows and Linux contributors don't produce whole-file diffs.
Failure modes
git reset --hardwith uncommitted work: that work is gone. Only committed (or stashed) work is in the reflog.- Rebasing or force-pushing a shared branch: teammates' history diverges, and their commits can be lost.
git pullcreating noisy merge commits on a feature branch. Usegit pull --rebase(orgit config pull.rebase true) for your private branches.- Long-lived feature branches: large, risky merges. Integrate small and often.
- Committing generated files (
bin/,obj/) or secrets.
Interview drill
- What is a branch, physically?
- Merge vs rebase: when would you refuse to rebase?
- You pushed a bad commit to
main. What do you do, and why notreset? - Explain
reset --soft,--mixedand--hardin one line each. - You ran
reset --hardby mistake on a committed branch. How do you get the work back? fetchvspull?- How would you find which commit introduced a regression among 200 commits? (
git bisect: about log₂ 200 ≈ 8 steps.)
Revision checklist
- Can I explain working tree, index and repository?
- Can I draw merge vs rebase on a whiteboard?
- Do I know which undo commands rewrite history and which don't?
- Do I default to
--force-with-leaseandreverton shared branches? - Can I describe trunk-based development vs Git flow?
Worked executable example
This Bash script builds a throwaway repository and proves the undo semantics: reset --soft keeps changes staged, --mixed unstages them, --hard drops the commit, reflog recovers it, revert adds an inverse commit, and rebase replays a feature commit on top of main.
Run this example
Requires Git 2.28+ (for git init -b, as well as git switch) and Bash. Save the script as git-demo.sh and run bash git-demo.sh. It works in a new temporary directory and touches nothing else.
#!/usr/bin/env bash
set -euo pipefail
cd "$(mktemp -d)"
git init -q -b main
git config user.email demo@example.com
git config user.name demo
log() { git log --format=%s | tr '\n' ' '; }
for n in 1 2 3; do echo "$n" >> f.txt; git add f.txt; git commit -qm "c$n"; done
git reset -q --soft HEAD~1
echo "soft: staged=[$(git diff --cached --name-only)] log=$(log)"
git commit -qm c3
git reset -q --mixed HEAD~1
echo "mixed: staged=[$(git diff --cached --name-only)] unstaged=[$(git diff --name-only)] log=$(log)"
git commit -qam c3
git reset -q --hard HEAD~1
echo "hard: file=$(tr '\n' ' ' < f.txt)log=$(log)"
git reset -q --hard 'HEAD@{1}'
echo "reflog: log=$(log)"
git revert --no-edit HEAD > /dev/null
echo "revert: log=$(log)"
git switch -q -c feature HEAD~2
echo x > g.txt; git add g.txt; git commit -qm feat
git rebase -q main
echo "rebase: log=$(log)"Expected output
soft: staged=[f.txt] log=c2 c1 mixed: staged=[] unstaged=[f.txt] log=c2 c1 hard: file=1 2 log=c2 c1 reflog: log=c3 c2 c1 revert: log=Revert "c3" c3 c2 c1 rebase: log=feat Revert "c3" c3 c2 c1
The feature branch started from c2. After the rebase, its commit feat sits on top of main's latest commit as a new commit with a new hash.
Related on TechInterviewNotes
- Production-Grade .NET Backend Interview Playbook
- Security, Configuration, Health Checks, and Production Delivery (Learn C# and .NET 10, lesson 24)
- Reviewed Migrations and Expand/Contract Schema Evolution (safe delivery alongside your Git workflow)