Skip to content

Round 1: Screening

Screening rounds test whether fundamentals are solid: short "explain", "why" and "difference" questions, usually 20 to 30 minutes. Every topic's L1 checkpoints are collected here; answer each aloud before expanding it. This page grows as each module is added.


Foundations

What Is Git

L1: What does it mean that Git is a distributed version control system?

Say first: every clone is a full repository with the complete history, so committing, branching, diffing and viewing log all work locally without a server.

Proof: git log and git commit run offline; only fetch, push and pull touch the network.

Follow-up: How is that different from Subversion or CVS?

L1: Does Git store diffs or snapshots?

Say first: snapshots; each commit points to a tree that names the complete set of files, and unchanged files reuse the same blob rather than being re-stored.

Proof: git cat-file -p HEAD shows the commit's tree; git ls-tree HEAD lists the blobs the snapshot references.

Follow-up: If it stores snapshots, why does git log -p show diffs?

Install and Config

L1: What are the three config scopes and their order of precedence?

Say first: system (/etc/gitconfig, all users), global (~/.gitconfig, one user) and local (.git/config, one repository); local overrides global, which overrides system.

Proof: git config --show-origin user.email names the file the effective value came from.

Follow-up: How do you give one repository a different committer email from your default?

L1: Where does Git get the name and email it puts on a commit?

Say first: from user.name and user.email, resolved through the scope precedence, with the local repository value winning if set.

Proof: git config user.email prints the effective value; git config --show-scope --get-all user.email shows every scope that defines it.

Follow-up: What does Git do if neither is set anywhere?

The Three Trees

L1: What are the three trees in Git?

Say first: the working tree (files on disk), the index or staging area (the proposed next commit), and HEAD (a pointer to the last commit on the current branch).

Proof: git status reports the gap between working tree and index, and between index and HEAD.

Follow-up: Which two trees does git diff compare, and which does git diff --cached compare?

L1: What is the difference between git diff and git diff --cached?

Say first: git diff shows working tree against the index (unstaged changes); git diff --cached shows the index against HEAD (what a commit would record).

Proof: an edit you have not git added appears in git diff but not in git diff --cached.

Follow-up: Where does git add move content, and where does git commit move it?


Core Workflow

Staging and Committing

L1: What does the staging area (index) do, and why does Git have one?

Say first: it holds exactly what the next commit will contain, so you can build a focused commit from a subset of your working-tree changes rather than committing everything at once.

Proof: git add copies content into the index; git commit records the index, not the working tree.

Follow-up: How do you stage only part of a single file's changes?

L1: What is the difference between git commit -m and git commit -am?

Say first: -m commits whatever is already staged; -am first stages modifications and deletions to tracked files, but neither form stages new untracked files.

Proof: a new file stays ?? in git status -s after git commit -am, and is left out of the commit.

Follow-up: How do you include a brand-new file in that commit?

Inspecting History

L1: How do you see the branch and merge structure of a repository quickly?

Say first: git log --oneline --graph --all draws every branch and merge as an ASCII graph with short SHAs and subjects.

Proof: the |\ and column layout show a merge commit's two parents and the two lines of work.

Follow-up: What does HEAD~2 select, and how is it different from HEAD^2?

L1: What is the difference between HEAD~2 and HEAD^2?

Say first: HEAD~2 walks two first-parent steps back (the same as HEAD^^); HEAD^2 selects the second parent of HEAD, which only exists on a merge commit.

Proof: git rev-parse HEAD^2 fails on a non-merge commit but resolves to the merged branch's tip on a merge.

Follow-up: How do you list only the commits on a branch that another branch does not have?

Ignoring and Attributes

L1: You added a file to .gitignore but Git still tracks it. Why?

Say first: .gitignore only affects untracked paths, and this file was already committed, so the ignore rule does not apply to it.

Proof: git status still shows edits to the file; git rm --cached <path> untracks it while keeping it on disk.

Follow-up: Does git rm --cached remove the file from earlier commits too?

L1: What is the difference between .gitignore and .gitattributes?

Say first: .gitignore decides which untracked paths Git ignores; .gitattributes decides how Git treats paths it does track, such as line endings, diff and merge behaviour.

Proof: git check-ignore -v explains an ignore; git check-attr -a shows the attributes on a path.

Follow-up: How do you make Git treat a file as binary so it is never line-ending-normalised or merged?

Undoing Changes

L1: When do you use git revert instead of git reset?

Say first: use revert for a commit that has been pushed or shared, because it adds a new inverse commit and leaves history intact; use reset only for commits that are still local, because it rewrites history.

Proof: git revert <sha> keeps the original commit in git log and adds a Revert "..." commit; git reset --hard removes commits from the branch.

Follow-up: What breaks if you reset and force-push a branch teammates have already pulled?

L1: What is the difference between reset --soft, --mixed and --hard?

Say first: all three move HEAD; --soft stops there (changes stay staged), --mixed also resets the index (changes become unstaged), and --hard also resets the working tree (changes are discarded).

Proof: after --soft HEAD~1 the change shows M (staged); after --hard HEAD~1 the working tree matches the target and the change is gone.

Follow-up: Which of the three can lose uncommitted work, and is it recoverable?


Branching and Merging

Branches

L1: What is a branch in Git?

Say first: a branch is a movable pointer to a single commit, stored as a small file under refs/heads/ that holds that commit's SHA.

Proof: cat .git/refs/heads/main prints one 40-character SHA; git commit advances it.

Follow-up: What does HEAD point to when you are on a branch?

L1: What is HEAD, and how does it differ from a branch?

Say first: HEAD is a pointer to the current branch (or directly to a commit when detached), while a branch is a pointer to a commit; HEAD is one level of indirection above the branch.

Proof: cat .git/HEAD shows ref: refs/heads/main on a branch, or a raw SHA when detached.

Follow-up: What is a detached HEAD and when does it happen?

Merging

L1: What is the difference between a fast-forward and a three-way merge?

Say first: a fast-forward only moves the branch pointer forward when there is no divergence, while a three-way merge builds a merge commit from the two tips and their common ancestor when both have advanced.

Proof: a fast-forward prints Fast-forward and keeps history linear; a three-way merge prints Merge made by the 'ort' strategy and creates a two-parent commit.

Follow-up: How do you force a merge commit when a fast-forward is possible?

L1: What is a merge base?

Say first: the merge base is the most recent commit that both branches share, and it is the starting point Git uses to compute what each branch changed.

Proof: git merge-base main feature prints that commit's SHA.

Follow-up: What are the two parents of a merge commit, and in what order?

Rebasing

L1: What is the difference between merge and rebase?

Say first: merge joins two branches with a merge commit and keeps the real history, while rebase replays one branch's commits onto another base to produce a linear history with new commit SHAs.

Proof: git log --graph after a merge shows a two-parent commit; after a rebase it shows one straight line with different SHAs.

Follow-up: When is it unsafe to rebase?

L1: What is the golden rule of rebasing?

Say first: never rebase commits that other people have already pulled, because rebase rewrites those commits and forces everyone else into a divergent history.

Proof: the rebased commits get new SHAs, so a teammate's clone still holds the old ones and diverges.

Follow-up: What must you do to a shared remote branch after a rebase, and why is --force-with-lease safer than --force?

Interactive Rebase

L1: What is interactive rebase used for?

Say first: it replays a range of commits through an editable todo list so you can squash, reword, reorder, edit or drop them before sharing the branch.

Proof: git rebase -i HEAD~3 opens the todo with a pick line per commit and a legend of the other verbs.

Follow-up: What is the difference between squash and fixup?

L1: What is the difference between squash and fixup in a rebase todo?

Say first: both fold a commit into the previous one, but squash combines the two commit messages while fixup keeps only the earlier message and discards the folded one's.

Proof: marking a commit fixup in the todo removes its message from the result; squash opens an editor to merge messages.

Follow-up: Why is interactive rebase unsafe on a shared branch?

Conflict Resolution

L1: What causes a merge conflict?

Say first: a conflict occurs when both branches change the same lines of a file (or one edits a file the other deleted), so Git cannot decide which change to keep.

Proof: git status shows the file as UU (both modified); the file gains <<<<<<<, ======= and >>>>>>> markers.

Follow-up: In the markers, which side is above the =======?

L1: How do you resolve a conflict once Git has stopped?

Say first: edit each conflicted file to the intended content, remove all markers, git add the file, then commit the merge (or git rebase --continue).

Proof: git add replaces the three unmerged index stages with one resolved entry; git status then shows the file as staged.

Follow-up: What does git add actually change in the index when it marks a file resolved?

Cherry-Pick

L1: What does git cherry-pick do?

Say first: it copies the changes introduced by a specific commit and applies them to the current branch as a new commit, without merging the rest of the source branch.

Proof: git cherry-pick <sha> creates a new commit with the same message and change but a new SHA.

Follow-up: Why does the cherry-picked commit have a different SHA from the original?

L1: When would you cherry-pick instead of merge?

Say first: when you need one commit from a branch, not all of it, such as backporting a single fix to a release branch that must not take unreleased features.

Proof: git cherry-pick <fix-sha> onto the release branch brings only that change.

Follow-up: How do you keep the backport traceable to the original commit?


Remotes and Collaboration

Remotes

L1: What is the difference between git fetch and git pull?

Say first: git fetch downloads new commits and updates remote-tracking refs but leaves your branch and files untouched; git pull is a fetch followed by integrating the upstream into your current branch.

Proof: after git fetch, git status shows the branch as "behind"; git pull then fast-forwards or merges it.

Follow-up: What exactly is origin/main?

L1: What is origin/main, and does it show the remote's current state?

Say first: it is a local remote-tracking branch, a read-only cache of where origin's main was at your last fetch, not the remote's live state.

Proof: git branch -r lists it; it only moves when you git fetch.

Follow-up: How do you find out whether the remote has moved since you last looked?

Pushing and Pulling

L1: Your push was rejected with 'fetch first'. What does that mean and what do you do?

Say first: the remote branch has commits you do not have, so the push cannot fast-forward; you integrate the remote work with git pull (or pull --rebase), then push.

Proof: the rejection names (fetch first); after git pull --rebase origin main the push fast-forwards.

Follow-up: Why is git push --force the wrong answer here?

L1: What is the difference between git pull and git pull --rebase?

Say first: plain git pull fetches then merges, creating a merge commit when both sides moved; git pull --rebase fetches then replays your local commits on top, keeping history linear.

Proof: after --rebase, git log --oneline shows your commit above the remote's with no merge commit.

Follow-up: How do you make rebase the default for pulls?

Tags and Releases

L1: What is the difference between a lightweight and an annotated tag?

Say first: a lightweight tag is only a ref pointing at a commit; an annotated tag is its own object storing a tagger, date and message, and it can be signed.

Proof: git cat-file -t shows commit for a lightweight tag and tag for an annotated one.

Follow-up: Which should you use for a release, and why?

L1: You tagged a release and pushed, but the tag is not on the remote. Why?

Say first: a normal git push sends commits, not tags; tags must be pushed explicitly.

Proof: git push origin <tag> (or git push --tags) transfers it; git ls-remote --tags then lists it.

Follow-up: How do you delete a tag that was pushed by mistake?

Stashing

L1: What does git stash do and when would you use it?

Say first: it shelves your uncommitted changes and reverts the working tree to HEAD, so you can switch context (a hotfix, a branch change) without committing half-done work; you restore the changes later.

Proof: git stash push leaves git status clean; git stash pop brings the changes back.

Follow-up: Why might a stash not include your new file, and how do you fix that?

L1: What is the difference between git stash pop and git stash apply?

Say first: both reapply the stashed changes, but pop removes the entry from the stack while apply keeps it.

Proof: git stash list is empty after pop but still shows the entry after apply.

Follow-up: When would you deliberately choose apply?

Forks and Pull Requests

L1: What is a fork, and how does it differ from a branch?

Say first: a fork is a separate server-side copy of a repository you do not have write access to; a branch is a line of work inside one repository. You push to your fork and propose changes back with a pull request.

Proof: git remote -v on a fork clone shows origin (your fork) and usually an added upstream (the original).

Follow-up: How do you keep your fork up to date with the original?

L1: How do you keep a fork in sync with the upstream repository?

Say first: add the original as upstream, git fetch upstream, fast-forward your main to upstream/main, and push it to your fork.

Proof: git merge --ff-only upstream/main updates main with no merge commit; git push origin main publishes it.

Follow-up: What does --ff-only protect you from?


Team Workflows

Branching Strategies

L1: What is trunk-based development?

Say first: everyone integrates into one long-lived branch (main) through short-lived branches merged within a day or two, keeping main always releasable and hiding unfinished work behind feature flags.

Proof: git log --graph on main shows a mostly linear history of small, frequent merges.

Follow-up: How does GitHub flow differ from bare trunk-based development?

L1: When would you choose gitflow over trunk-based?

Say first: when you ship scheduled, versioned releases or must support several versions at once; the release/* and hotfix/* branches stabilise and patch versions while development continues.

Proof: gitflow's graph shows main, develop and release branches; trunk-based keeps one main line.

Follow-up: What is the main cost of gitflow's extra branches?

Commit Conventions

L1: What is a Conventional Commit, and why use one?

Say first: it is a commit whose subject is type(scope): summary (for example feat(api): add health endpoint), which makes history scannable and lets tooling generate changelogs and decide version bumps automatically.

Proof: git log --oneline reads like a changelog; feat maps to a minor bump and fix to a patch.

Follow-up: How is a breaking change signalled in this scheme?

L1: What makes a commit atomic, and why does it matter?

Say first: an atomic commit is one logical change that builds and passes on its own, which keeps review focused, makes git bisect precise, and lets you revert exactly one thing.

Proof: git add -p stages the hunks for one change so unrelated edits go in separate commits.

Follow-up: How do you split a working tree with two unrelated changes into two commits?

Code Review with Git

L1: How do you review a branch's changes from the command line?

Say first: list its commits with git log main..branch, see its net change with the three-dot git diff main...branch, and check it out to build and run it.

Proof: git diff main...branch matches the pull request's "Files changed" view.

Follow-up: Why the three-dot diff rather than two dots?

L1: An author force-pushed after your review. How do you see only what they changed?

Say first: git range-diff compares the old and new versions of the branch and shows a diff of the diffs, so you re-read only the commits that changed.

Proof: its output marks each commit = (unchanged), ! (reworked) or </> (one side only).

Follow-up: What does the ! marker mean in range-diff output?

Release and Versioning

L1: What do the three numbers in a semantic version mean?

Say first: MAJOR.MINOR.PATCH: MAJOR for an incompatible change, MINOR for a backward-compatible feature, PATCH for a backward-compatible fix.

Proof: a consumer can safely upgrade within the same MAJOR; a MAJOR bump warns of a breaking change.

Follow-up: How do you decide the bump from the commits in a release?

L1: How do commit types map to a version bump?

Say first: a BREAKING CHANGE forces MAJOR, any feat gives MINOR, and fix gives PATCH; you take the highest that applies across the range.

Proof: git log <lasttag>..HEAD lists the types; one feat among fixes makes it a MINOR.

Follow-up: How would you generate the changelog from the same range?


History and Recovery

Reflog and Recovery

L1: What is the reflog and what is it for?

Say first: it is a local log of every position HEAD (and each branch tip) has held, so you can recover commits made unreachable by a reset, rebase or branch delete.

Proof: git reflog lists HEAD@{n} entries; git reset --hard HEAD@{1} returns to the previous tip.

Follow-up: Is the reflog pushed to the remote or shared with teammates?

L1: You ran git reset --hard and lost commits. Are they gone?

Say first: almost certainly not; the branch pointer moved but the commits remain in the object store, and the reflog still names the old tip.

Proof: git reflog shows the pre-reset SHA at HEAD@{1}; git reset --hard HEAD@{1} restores it.

Follow-up: What is ORIG_HEAD and how does it help here?

Bisect

L1: What problem does git bisect solve, and how?

Say first: it finds the commit that introduced a regression by binary search: you mark one bad and one good commit, and it tests midpoints, halving the range each step until one commit remains.

Proof: git bisect start <bad> <good> then marking each checkout narrows to "the first bad commit" in about log2(n) steps.

Follow-up: How do you automate the marking instead of doing it by hand?

L1: How many tests does bisect need for a thousand commits, and why?

Say first: about ten, because each test halves the remaining suspect range, so the count is log2(n) rather than n.

Proof: the "roughly N steps" line drops by one per answer; 1000 is under 2^10.

Follow-up: What makes bisect land on the wrong commit despite the maths?

Rewriting History

L1: What does it mean to rewrite history in Git, and which commands do it?

Say first: it means replacing commits with new ones that have new SHAs; git commit --amend, git reset, git rebase (including -i) and git filter-repo all rewrite history.

Proof: after a rebase, git log --oneline shows new SHAs for the rewritten commits; the old ones remain only in the reflog.

Follow-up: What is the golden rule about rewriting?

L1: What is the golden rule of rebasing and rewriting?

Say first: never rewrite commits that others have already pulled; only rewrite local, unshared commits (or a branch that is yours alone).

Proof: rewriting a shared commit gives it a new id, so teammates' clones diverge on the next fetch.

Follow-up: How do you safely update a personal feature branch you already pushed?

Filter-Repo and Secrets

L1: You committed and pushed a secret. What is the first thing you do?

Say first: rotate the secret immediately; it is already exposed, and no history rewrite can recall what others have fetched. Then rewrite history to purge it.

Proof: the secret sits in every earlier commit and every clone; rotation invalidates it, git filter-repo removes it from the repo.

Follow-up: Why is deleting the file in a new commit not enough?


Internals

Object Model

L1: What are Git's object types, and what does each hold?

Say first: blob (file content), tree (a directory of names pointing at blobs and subtrees), commit (a tree plus parents and metadata), and tag (annotated-tag metadata pointing at an object).

Proof: git cat-file -t <sha> names the type; git cat-file -p HEAD shows a commit referencing a tree.

Follow-up: Where is a file's name stored, given that a blob has none?

L1: What does it mean that Git is content-addressed?

Say first: an object's id is the hash of its content, so identical content always has the same id; this gives deduplication, integrity checking and immutability.

Proof: git hash-object of a file matches its blob SHA in the tree; two identical files share one blob.

Follow-up: Why does this mean a commit cannot be edited in place?

Refs and HEAD

L1: What is a branch, really, at the storage level?

Say first: a branch is a ref: a small file under refs/heads/ containing one commit SHA, which git commit advances to the new commit.

Proof: cat .git/refs/heads/main prints a single 40-character SHA.

Follow-up: What does HEAD contain when you are on a branch?

L1: What is HEAD, and how does it differ when detached?

Say first: HEAD is a symbolic ref pointing at the current branch (ref: refs/heads/<name>); when detached it holds a raw commit SHA instead, so new commits belong to no branch.

Proof: cat .git/HEAD shows ref: refs/heads/main normally, or a bare SHA when detached.

Follow-up: How many hops does resolving HEAD to a commit take?

How Merge and Rebase Work

L1: What is a merge base, and why does merging need it?

Say first: the merge base is the most recent common ancestor of the two branches; a three-way merge compares each side's changes against it to combine them.

Proof: git merge-base A B prints it; the merge applies both sides' diffs relative to that commit.

Follow-up: How many parents does the resulting merge commit have?

L1: Why does rebasing change commit SHAs when merging does not?

Say first: rebase recreates each commit on a new parent, and a commit's SHA hashes its parent, so every replayed commit gets a new id; merge only adds a commit and rewrites none.

Proof: after a rebase git log shows new SHAs; after a merge the original commits keep theirs and a two-parent merge commit appears.

Follow-up: What does that difference mean for shared branches?

Packfiles and GC

L1: What is the difference between loose and packed objects?

Say first: loose objects are one compressed file each; packed objects are collected into a single delta-compressed packfile, which git gc produces.

Proof: git count-objects -v shows count fall to zero and in-pack rise after git gc.

Follow-up: What does delta compression save?

L1: What does git gc do?

Say first: it packs loose objects into a delta-compressed packfile, packs refs, and prunes unreachable objects past the expiry window; it also runs automatically.

Proof: after git gc, git count-objects -v shows in-pack populated and packs: 1.

Follow-up: Does gc ever delete a commit you might still need?


Advanced Tooling

Hooks

L1: What is a Git hook, and where do hooks live?

Say first: a hook is a script Git runs at a set point in its workflow (before a commit, before a push), stored as an executable in .git/hooks/ named for the event.

Proof: ls .git/hooks shows the .sample templates; renaming one to drop .sample and making it executable enables it.

Follow-up: Do hooks travel with a clone?

L1: Are client hooks a security control?

Say first: no; they are advisory, because they live in local .git/ and git commit --no-verify skips them, so real enforcement belongs on the server or in CI.

Proof: a pre-commit that blocks a pattern is bypassed by --no-verify, and the commit still lands.

Follow-up: Which hooks cannot be bypassed by the author?

Submodules

L1: What is a Git submodule, and what does the parent actually store?

Say first: a submodule is another repository embedded at a path, and the parent stores only a pinned commit SHA of it (a gitlink), not the child's files.

Proof: git ls-files --stage <path> shows mode 160000 and a commit SHA, not file blobs.

Follow-up: What happens to that folder on a plain clone?

L1: Why is a submodule folder empty after cloning, and how do you fix it?

Say first: a plain clone copies only the pointer, so the folder is empty; clone with --recurse-submodules, or run git submodule update --init --recursive afterwards.

Proof: ls on the submodule path shows nothing until the update populates it.

Follow-up: Where does --init get the URL from?

Worktrees

L1: What is a Git worktree, and how does it differ from a second clone?

Say first: a worktree is an additional working directory attached to the same repository, sharing one object store, so unlike a second clone it duplicates no history and sees the same commits instantly.

Proof: git worktree list shows multiple checkouts on different branches; a linked worktree's .git is a file pointing into the shared store.

Follow-up: Can two worktrees check out the same branch?

L1: Do worktrees share history and commits?

Say first: yes; all worktrees share one object store, so a commit in one is immediately present in the others, and only the working tree is separate.

Proof: a linked worktree's .git file points at .../.git/worktrees/<name> in the main repository.

Follow-up: What is duplicated by a worktree, if not the history?

Large Repos

L1: What is a shallow clone, and when would you use one?

Say first: a shallow clone (--depth N) fetches only the last N commits instead of all history, which speeds up CI and one-off builds that do not need the past.

Proof: git rev-list --count HEAD returns N, and git rev-parse --is-shallow-repository returns true.

Follow-up: How do you get the rest of the history later?

L1: What is the difference between a shallow clone and a partial clone?

Say first: shallow limits how many commits you fetch; partial (--filter=blob:none) keeps all commits but skips file contents until they are needed.

Proof: a partial clone shows the full commit count but reports missing blobs with rev-list --missing=print.

Follow-up: Where do the missing blobs come from when you finally read a file?

Credentials and Signing

L1: What are the two ways Git authenticates to a remote, and how do they differ?

Say first: SSH with a key pair (public key on the host, private key local), or HTTPS with a personal access token supplied by a credential helper; the remote URL's scheme decides which is used.

Proof: an SSH remote is git@host:owner/repo.git; an HTTPS remote prompts for a token that credential.helper then stores.

Follow-up: Why does an HTTPS push ask for a token rather than a password?

L1: What does a credential helper do?

Say first: it caches or stores the HTTPS token so Git does not prompt on every operation, using the platform keychain (osxkeychain, libsecret, or Git Credential Manager on Windows).

Proof: git config credential.helper names the active helper.

Follow-up: Where does the token physically live for each helper?