Git questions look like trivia, but they're really testing one thing: do you have a mental model of what Git is doing, or do you memorise commands and hope? An interviewer can tell the difference in one sentence. "Rebase rewrites history" is a memorised fact; "rebase replays your commits as new commits with new hashes, which is why you never do it to shared branches" is a model.
Below are the questions that come up in almost every developer interview, grouped by topic. Each has a short model answer, a command example where it helps, and a note on what the interviewer is really checking. Notice the pattern in every answer: name the mechanism, give the one rule or trade-off that matters, then stop.
A quick foundation that makes the rest click: a branch is just a movable pointer to a commit, a commit is a snapshot plus a parent link, and HEAD points to "where you are now". Almost every answer below is a consequence of those three facts.
Core concepts
What's the difference between git fetch and git pull?
fetch downloads the latest commits and refs from the remote but doesn't touch your working branch — it updates your remote-tracking refs (origin/main) so you can inspect what changed first. pull is fetch plus an automatic merge (or rebase) of those changes into your current branch.
git fetch origin # safe: just updates origin/*, nothing merged
git log HEAD..origin/main # see what you'd be pulling in
git pull # fetch + merge (or --rebase) into your branch
So fetch is the look-before-you-leap option; pull is the convenience that can surprise you with an unexpected merge commit. Many teams set git config pull.rebase true to keep history linear.
What they're testing: that you understand local vs. remote state, not just the two commands.
What is the staging area (the index)?
It's an intermediate layer between your working directory and the repository. git add moves changes into staging; git commit records exactly what's staged — not what's in your working directory. That extra step is what lets you craft a commit: stage only some files, or even part of a file with git add -p, instead of committing everything at once.
Git's three "trees" are the working directory, the index (staging), and HEAD (the last commit). Nearly every confusing Git command makes sense once you ask "which of the three trees does this touch?"
What they're testing: the three-tree model — the foundation for reset, diff, and clean commits.
Merge vs. rebase — what's the difference, and the rule?
merge combines two branches with a merge commit, keeping history exactly as it happened (non-linear, but truthful). rebase replays your commits on top of another branch, producing a clean linear history — but it creates new commits with new hashes; the originals are abandoned.
git checkout feature
git rebase main # replay feature's commits on top of main
# vs
git merge main # create a merge commit joining the two
The golden rule: rebase your own local, unpushed work to tidy it up; never rebase a branch others have already pulled. Rewriting shared history forces everyone else to reconcile commits that no longer exist in your branch.
What they're testing: whether you understand history rewriting and the one rule that keeps a team sane.
What is HEAD, and what's a "detached HEAD"?
HEAD is a pointer to your current location — normally it points at a branch, which points at a commit. A detached HEAD is when HEAD points directly at a commit instead of a branch, which happens when you git checkout <commit-hash> or a tag. You can look around and even commit, but those commits aren't on any branch — if you walk away, they're hard to find again.
git checkout a1b2c3d # detached: HEAD -> commit, not a branch
git switch -c fix-here # rescue: make a branch so commits aren't lost
What they're testing: that you really grasp "a branch is a pointer" — detached HEAD is the edge case that proves it.
Branching & merging
What is a fast-forward merge?
When the branch you're merging into hasn't diverged — your target is strictly behind the branch you're merging — Git doesn't need a merge commit; it just moves the branch pointer forward. That's a fast-forward. If the branches have diverged, Git has to create a real merge commit. Use git merge --no-ff when you want a merge commit even on a fast-forward, to keep feature branches visible in history.
What they're testing: the pointer model of branches, again.
How do you resolve a merge conflict?
When two branches change the same lines, Git marks the conflict in the file:
<<<<<<< HEAD
your version
=======
their version
>>>>>>> feature
You open the file, edit it into the result you actually want, delete the markers, then stage and continue:
git add resolved_file.py
git commit # or: git rebase --continue
The tooling doesn't decide for you — resolving a conflict is a human judgement about what the code should be. git merge --abort backs out entirely if you want to start over.
What they're testing: that you've actually done this, not just read about it.
What does git cherry-pick do, and when would you use it?
It applies the changes from a specific commit onto your current branch, as a new commit. Useful for pulling one bug-fix commit from another branch without merging the whole thing — a hotfix that needs to go to both main and a release branch.
git cherry-pick a1b2c3d
The trade-off: it duplicates the change as a new commit, so overusing it creates divergent copies that are annoying to reconcile later.
What they're testing: that you can move a single change around deliberately, not just merge whole branches.
Undoing things
git revert vs. git reset — when do you use each?
revert creates a new commit that undoes a previous one, leaving history intact — safe for anything already pushed. reset moves the branch pointer backwards, rewriting history — for local, unpushed work only.
git revert a1b2c3d # public, safe: adds an "undo" commit
git reset --hard HEAD~1 # private: discards the last commit entirely
The rule mirrors rebase: revert what's public, reset what's private. Using reset on a pushed branch and force-pushing is how you ruin a teammate's afternoon.
What they're testing: the difference between a safe undo and a destructive one.
What do --soft, --mixed and --hard do on git reset?
All three move HEAD to the commit you name; they differ in how much they touch afterwards — which maps straight onto the three trees:
| Flag | Moves HEAD | Index (staging) | Working dir |
|---|---|---|---|
--soft |
✅ | kept (staged) | kept |
--mixed (default) |
✅ | reset (unstaged) | kept |
--hard |
✅ | reset | discarded |
So --soft is for re-committing (e.g. squashing the last few commits into one), --mixed un-stages, and --hard is the one that loses work — reach for it deliberately.
What they're testing: precision, and awareness that --hard is destructive.
What does git stash do?
It shelves your uncommitted changes and reverts your working directory to a clean state, so you can switch context — jump to a branch for an urgent fix — without committing half-done work.
git stash # shelve changes, clean working dir
git switch main # do the urgent thing
git switch - # back to your branch
git stash pop # reapply your shelved changes
It's a workflow convenience, not part of history.
What they're testing: everyday fluency, not theory.
You ran git reset --hard and lost commits. Can you get them back?
Usually yes — with git reflog. The reflog records every move HEAD makes, even ones that aren't reachable from any branch anymore. Find the commit you were on and reset back to it.
git reflog # find the lost commit's hash
git reset --hard a1b2c3d # or: git branch rescue a1b2c3d
This is a great answer to give unprompted — it shows you know Git rarely really deletes anything until garbage collection runs.
What they're testing: depth — most people don't know the reflog exists, and it's the safety net for every "destructive" command above.
Real-world workflow
How do you find which commit introduced a bug?
git bisect. You mark a known-good commit and a known-bad one; Git checks out the midpoint, you test it and mark it, and it binary-searches to the first bad commit in log-n steps instead of checking every commit.
git bisect start
git bisect bad # current commit is broken
git bisect good v1.2.0 # this old tag worked
# test each checkout, mark good/bad... or automate:
git bisect run pytest tests/test_thing.py
git bisect reset
What they're testing: knowing the right tool exists — and that it's a binary search, not a linear hunt.
How do you change the most recent commit?
git commit --amend — to fix the message or add a file you forgot. But amending rewrites that commit's hash, so only amend commits you haven't pushed. Amending a pushed commit forces everyone to reconcile a rewritten history — the same shared-history trap as rebase and reset.
git add forgotten_file.py
git commit --amend --no-edit # fold it into the last commit, keep the message
What they're testing: that you know "change the last commit" means rewriting it, with all that implies.
You committed a file that shouldn't be tracked (say, .env). What now?
Add it to .gitignore and stop tracking it — note that .gitignore alone won't untrack a file that's already committed:
echo ".env" >> .gitignore
git rm --cached .env
git commit -m "Stop tracking .env"
And if it was a secret and it's already been pushed, it's now in the history forever: rotate the secret. Removing it from the current tree doesn't remove it from past commits — you'd need a history rewrite with git filter-repo or BFG, and even then anyone who already pulled still has it. The honest answer in an interview is "rotate first, clean history second".
What they're testing: security awareness, and the gotcha that .gitignore doesn't untrack.
How to actually answer these
The difference between a pass and a fail on Git questions is showing a model, not reciting flags. Say what the command does to the repo — pointers, history, the three trees — name the one rule that matters (rebase/reset only what's private), and stop.
Three things that quietly raise your score:
-
Reach for the mechanism, not the memorised command. "I'd move the branch pointer back and keep the changes staged" beats blanking on whether that's
--softor--mixed. - Volunteer the safety net. Mentioning the reflog, or "I'd rotate the secret first", signals real experience.
- If you forget an exact flag, describe the effect and say you'd check the docs. That reads far better than a confident wrong flag.
Rehearse these out loud, scored. Peakblick asks you Git questions like these on a timer and scores every answer 1–10 with feedback — so you find the weak spots before the real interview. Free to try, no card.
Top comments (0)