Look at the figure above: the round nodes are commits (each stamped with its SHA), the arrows point backward to parents (that is what "acyclic" buys us — you can always walk toward the past, never in a loop), and the two rounded sticky-notes are branches. The little flag labelled HEAD sits on a branch, not on a commit directly.
Every line: decide true or false, then give the reason — the reason is the whole point.
A branch stores a copy of all your files
False. A branch is a 41-byte file holding one commit SHA; the files live inside the commits it points to. That is why creating a branch is O(1).
Making 100 branches meaningfully bloats the repository
False. Each branch is just a tiny pointer file in .git/refs/heads/; the heavy content (snapshots) is shared and stored once, thanks to Immutability and content-addressable storage.
A fast-forward merge creates a new merge commit
False. If the target is a direct ancestor there is nothing to reconcile, so Git only slides the pointer forward — no commit is made unless you force it with --no-ff. (See the "fast-forward" panel of the merge figure below.)
A merge commit always has exactly two parents
Mostly true, but not always. A normal merge has two parents; an "octopus" merge of several branches at once can have three or more. Ordinary commits have one parent, and the very first commit has zero.
Rebase and merge produce identical commit SHAs for your work
False. Merge keeps your original commits untouched; rebase re-applies them as brand-new commits, so their SHAs change even if the code is identical — a new parent means a new hash.
git rebase deletes your old commits immediately
False. The old commits become unreferenced (orphaned) but survive in the reflog until garbage collection; you can recover them for a while. "Nothing is lost, only pointers move."
Cherry-picking a commit copies its exact SHA to the new branch
False. Cherry-pick re-applies the diff as a new commit with a new SHA, because the parent (and thus the hash) is different.
git stash pop and git stash apply do the same thing
False. Both reapply the shelved changes, but pop also removes the entry from the stash stack — and only if the reapply was clean; apply always leaves the entry on the stack.
Bisect requires you to test every commit between good and bad
False. Let N = the number of suspect commits in the good→bad range. Bisect tests only about ⌈log2N⌉ of them, because each answer halves that range — that is Binary Search over history (see the bisect figure).
A conflict means Git has a bug or made a mistake
False. A conflict is a precise, correct signal: both sides changed the same region differently since the merge base, so no unique answer exists and only a human can decide. The conflict figure below shows exactly which region triggers it.
HEAD and a branch name are the same kind of thing
False. A branch points at a commit; HEAD points at where you are now — usually at a branch (attached), but it can point straight at a commit ("detached HEAD"). Compare the two flag positions in the first figure.
Rebasing a branch you already pushed is safe as long as your tests pass
False. Passing tests say nothing about shared history; rewriting pushed commits orphans the commits teammates built on. The golden rule is: never rebase shared/published commits.
Each item states a plan or belief with a hidden flaw. Name the flaw and the fix.
"I'll cherry-pick a fix into main, then later merge the whole feature branch — the fix appears once."
Error: the change now exists as two different commits (the cherry-pick and the original), so the merge may re-introduce it or conflict. Fix: integrate via merge/rebase, and reserve cherry-pick for truly isolated hot-fixes.
"To integrate main into my shared team branch cleanly, I'll git rebase main."
Error: rebase rewrites SHAs on a shared branch, orphaning teammates' work. Fix: use git merge main for public branches; rebase is only for local, unpushed history.
"My stash pop hit a conflict, so I ran git stash drop to clean up."
Error: dropping discards the still-saved stash and your uncommitted work with it. Fix: resolve the conflict markers first; on a clean result the stash auto-drops, otherwise it is deliberately kept.
"Bisect said commit X is the culprit, but the bug depends on a flaky test — the result is trustworthy."
Error: bisect assumes a monotonic good→bad transition; a nondeterministic test can label a commit "good" that is actually bad, sending the search down the wrong half. Fix: make the test deterministic, or use git bisect skip on uncertain commits.
"I'll git branch feature and start committing — my work goes onto feature."
Error: git branch only creates the pointer; it does not move HEAD. Your commits still land on the old branch. Fix: git switch feature (or git switch -c feature) to actually move there.
"A merge produced no conflict, so the merged code is definitely correct."
Error: the Three-way merge algorithm resolves textual non-overlap, not semantic correctness — two files can merge cleanly yet break each other logically. Fix: always run the tests after a clean merge.
"Rebase gives a linear history, so it also removes the risk of conflicts."
Error: rebase re-applies each commit in turn, and any of those replays can conflict — sometimes the same conflict repeatedly. Fix: expect and resolve per-commit conflicts; git rebase --continue after each.
Why is creating a branch essentially free while creating one in some older version-control systems was expensive?
Because a Git branch is one pointer file holding a SHA — writing 41 bytes — whereas older systems physically copied the working files.
Why does a three-way merge need the merge base and not just "ours" and "theirs"?
The base is the common ancestor that tells Git who changed what: if only one side differs from the base, that side wins automatically; only when both differ does a conflict arise (this is the three-column comparison drawn in the conflict figure).
Why does rebasing change commit SHAs?
A commit's hash is computed from its content and its parent SHA; rebasing gives each commit a new parent (the new base), so the hash necessarily changes — see Immutability and content-addressable storage.
Why can't Git switch branches when you have conflicting uncommitted changes?
The switch would overwrite files Git cannot safely reconstruct, so it refuses to lose your work; stashing (a temporary commit) gives it a clean HEAD to move from.
Why is bisect logarithmic instead of linear?
With N = the number of remaining suspect commits, each good/bad answer eliminates half of them, and halving N down to 1 takes about log2N steps — the defining feature of Binary Search.
Why does cherry-pick sometimes conflict even for a tiny one-line fix?
It applies the diff parent(C) → C, and if the surrounding lines on the target branch differ, the patch's context no longer matches, forcing a manual resolution just like a merge (see Diff and patch (Myers algorithm)).
Why do trunk-based workflows prefer short-lived branches and frequent merges?
Long-lived branches diverge far from the base, so merges accumulate large, painful conflicts; short branches keep the merge base recent — a core trade-off in Trunk-based vs GitFlow.
Why does git merge --no-ff exist if fast-forward already integrates the work?
Fast-forward erases the fact that a feature was developed separately; --no-ff records an explicit merge commit so the branch topology (and thus review history) is preserved.
Boundary and degenerate scenarios — the ones the tutorials skip.
What are the parents of the very first commit in a repository?
Zero parents — it is the root of the Directed Acyclic Graph, so it has nothing to point back to.
What happens if you rebase and the range of commits to replay is empty (nothing since the base)?
Rebase is a no-op fast-forward — there is nothing to re-apply, so your branch simply moves to the target tip with no new commits.
What if both branches make the identical change to the same line?
No conflict — the three-way rule says if ours == theirs the shared value is taken; identical edits agree, so Git accepts them silently.
What if bisect's good and bad are the same commit, or bad is an ancestor of good?
The search space is empty or inverted; Git errors out because the required good→bad monotonic ordering does not hold — you have mislabeled the endpoints.
What does git stash do if your working tree is already clean?
Nothing to save — it reports "No local changes to save" and creates no stash entry.
What happens to commits on a branch you delete while others still point at them?
They stay alive — deleting a branch removes only that pointer; any commit still reachable from another branch, tag, or HEAD survives.
What is the merge base of two branches that share no common ancestor (e.g. two unrelated histories)?
There is none; Git refuses by default and needs --allow-unrelated-histories, treating every line as a potential conflict since there is no base to diff against.
Can git cherry-pick bring over a merge commit?
Not without help — a merge commit has two parents, so Git cannot tell which side's diff to apply; you must specify a mainline with -m to pick one parent as the reference.
Recall One-line summary of the whole trap set
Almost every Git surprise reduces to one of three truths: (1) branches are pointers, not copies; (2) a commit's identity is its content plus its parent, so replays get new SHAs; (3) conflicts are the honest "both sides changed the same spot" signal — never a bug.