Module 9 — Collaboration Workflows

Updated 7 September 2026

Module 9 — Collaboration Workflows. Git gives a team mechanics; a workflow gives it manners. This module covers the human layer built on Modules 5–8: feature branches, pull requests and review, forks, and the branching-model debate (Git Flow vs GitHub Flow vs trunk-based) that every team — and many interviews — eventually litigates. Almost nothing here is a new Git command; everything here is how teams arrange the commands you already know.

🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)

Before you start. You need Module 8 completed, with the bakery.git bare remote and both clones (kitchen, kitchen-laptop2) on disk — the exercises simulate a full team flow against them, offline. Concepts assumed fresh: --no-ff merges and three-dot diffs (Module 6), upstream tracking and multi-remote setups (Module 8).

Part A — The feature-branch workflow

A1. The shape almost every team shares

Underneath every named methodology sits one shared skeleton: main is sacred, work happens on branches. main must always be releasable — nobody commits to it directly; it moves only by merging reviewed branches. Each unit of work (feature, fix, experiment) gets its own short-lived branch, named descriptively (feature/PAY-231-refund-retry — Module 5's convention capstone), pushed early so it is visible and backed up, merged when reviewed, deleted when merged. The cycle you are about to run is, with a web UI on top, the daily loop of most software teams on earth.

🧪 Exercise 9.1 — a feature's whole life, part one: branch, work, publish
bash
cd ~/git-course/kitchen              # on main
git switch -c feature/holiday-menu
echo "stollen: december only" > stollen.txt
git add stollen.txt && git commit -m "Add stollen to holiday menu"
git push -u origin feature/holiday-menu
Expected result — click to reveal
plain text
Switched to a new branch 'feature/holiday-menu'
[feature/holiday-menu 5eca2dd] Add stollen to holiday menu
 1 file changed, 1 insertion(+)
 create mode 100644 stollen.txt
To /home/aisha/git-course/bakery.git
 * [new branch]      feature/holiday-menu -> feature/holiday-menu
branch 'feature/holiday-menu' set up to track 'origin/feature/holiday-menu'.

What to read out of it: nothing new mechanically — Module 5's switch -c, Module 2's commit, Module 8's push -u — and that is the point: a "workflow" is sequencing, not new commands. The push matters even before the work is done: a published branch is visible to the team (no surprise duplicated effort), backed up off your laptop (Module 1's trap defused), and ready to become a pull request at any moment. main has not moved and cannot be broken by anything happening here.

A2. Keeping the branch current while main moves

While your branch lives, main receives other people's merges. The longer you drift from it, the bigger the eventual conflict (Module 6's fleet lesson). The standard hygiene: periodically merge main into your feature branch — the same git merge, pointed the other way. Conflicts, if any, get resolved on your branch, at your pace, leaving main pristine — and the final merge back becomes trivial because you already did the hard part. (Rebasing the branch instead is the tidier alternative many teams prefer — Module 10 adds it; the merge version below is always correct.)

🧪 Exercise 9.2 — main moves; you catch up
bash
cd ~/git-course/kitchen              # simulate the team: land something on main
git switch main
echo "gingerbread: december only" > gingerbread.txt
git add gingerbread.txt && git commit -q -m "Add gingerbread note" && git push -q
git switch feature/holiday-menu      # back on your feature
git merge main --no-edit             # bring main's progress IN
git log --oneline -3
Expected result — click to reveal
plain text
959ac14 Merge branch 'main' into feature/holiday-menu
d41c33a Add gingerbread note
5eca2dd Add stollen to holiday menu

What to read out of it (your earlier commands also print their usual Switched to branch… and Merge made by the 'ort' strategy. lines, elided here — the log listing is the point; gingerbread sits between the two because log orders by date across both parents): the merge commit's auto-message says the direction plainly — Merge branch 'main' **into** feature/holiday-menu; compare with Module 6's messages, which had no "into" clause because the target was the default. Your branch now contains everything main has, so a merge back can no longer conflict on today's content. On a real team you would do this whenever main moves meaningfully, and always just before opening review — reviewers should see your change against current reality, not last Tuesday's.

🎯 Interview questions — Part A

🎯 "What is the Git Workflow?" — asked verbatim in GeeksforGeeks' 70+ Git Interview Questions, updated Jul 2026

Two legitimate readings, worth handling both. The individual workflow is the edit→stage→commit→push loop from Modules 2 and 8: change files, git add, git commit, git push, with pull/fetch bringing others' work in. The team workflow wraps that loop in process: clone or update, branch from main per unit of work, commit and push the branch, open a pull request, pass review and CI, merge to main, delete the branch. Named models (Git Flow, GitHub Flow, trunk-based) are variations in how many long-lived branches exist and how releases are cut.

The details that separate candidates: an average answer recites edit-add-commit-push. A strong answer notices the question's ambiguity, gives the loop and the team cycle, and states the invariant all team workflows protect: main stays releasable, so integration happens through reviewed branch merges rather than direct commits. Tying each step to its enforcement mechanism — protected branches for "nobody commits to main", required checks for "CI passes before merge" — shows you have worked inside the process, not just read about it.

Part B — Pull requests and review

B1. What a pull request actually is

A pull request (GitLab: merge request) is not a Git object — no PR exists anywhere in .git (Module 1's layer-separation, now concrete). It is a host construct: a proposal saying "merge branch X into branch Y," wrapped in machinery Git itself does not provide — a discussion thread, line-by-line review comments, approval state, CI results, and a merge button with policy attached. The diff a PR shows is one you already own: git diff main...feature — the three-dot, merge-base-to-tip form (Module 6 D2), what this branch contributes, not what main did meanwhile.

The merge button typically offers three strategies, and choosing is a team decision you can now reason about: merge commit (--no-ff, Module 6 — preserves the branch bubble and gives one revertable node), squash (all branch commits collapsed into a single new commit on main — clean history, feature-branch commits discarded), and rebase (branch commits replayed individually onto main, no merge commit — Module 10 teaches the mechanics and the caveats). Protection rules complete the picture: a protected branch refuses direct pushes, force-pushes, and merges that lack required approvals or passing checks — the enforcement layer for everything Part A called "sacred."

Real-world analogy — the editor's desk at a newspaper

A journalist never types straight into tomorrow's front page. They file a draft (the branch), and an editor's desk (the PR) is where it is read, marked up, argued over, fact-checked (CI), and finally approved for print (merge). The paper's masthead rule — nothing prints unedited — is not a suggestion; the print room physically rejects unapproved copy (protected branch).

Where the analogy stops working. An editor rewrites your copy and prints; the byline blurs who wrote what. A PR merge preserves exact authorship and history — every commit keeps its author (Module 3), the reviewer approves but does not silently alter, and requested changes go back to the author to make. Also: newspapers print once; a merged PR's branch can be reverted as a unit (Module 7's -m 1) — the press has an undo, provided the team chose merge commits over fast-forwards.

🧪 Exercise 9.3 — play both roles: reviewer, then merger
bash
cd ~/git-course/kitchen              # REVIEWER hat: what does this PR propose?
git switch main
git log --oneline main..feature/holiday-menu     # the commits it brings
git diff --stat main...feature/holiday-menu      # the PR diff (three-dot!)
git merge --no-ff feature/holiday-menu --no-edit # the "merge button"
git push -q
git push origin --delete feature/holiday-menu    # the "delete branch" button
git branch -d feature/holiday-menu
git branch --merged main                         # cleanup audit: safe to delete
Expected result — click to reveal
plain text
959ac14 Merge branch 'main' into feature/holiday-menu
5eca2dd Add stollen to holiday menu
 stollen.txt | 1 +
 1 file changed, 1 insertion(+)
Merge made by the 'ort' strategy.
 stollen.txt | 1 +
 1 file changed, 1 insertion(+)
To /home/aisha/git-course/bakery.git
 - [deleted]         feature/holiday-menu
Deleted branch feature/holiday-menu (was 959ac14).
* main
  sourdough

What to read out of it: the review commands show exactly what a host renders — the commit list (including your catch-up merge from 9.2; squash-merging would collapse such noise, which is much of its appeal) and the three-dot diff: one file — and note that because you caught the branch up in 9.2, even the two-dot form would agree right now; on a stale branch that skipped 9.2, the two-dot form would have dragged gingerbread into view (Module 6's Ticket 3 bug), which is why the three-dot habit is the one to build. The --no-ff merge is the button-press; the two deletions are the post-merge tidy. git branch --merged main is the audit that makes cleanup safe: every branch it lists is fully contained in main — deleting those pointers strands nothing (--no-merged lists the dangerous ones).

Now imagine this at 500 hosts. The PR is where DevOps attaches all its gates, because it is the last moment before code becomes shared truth: CI runs, linters, security scans, license checks, deploy previews — as required status checks that the merge button enforces. This inverts the quality model: instead of finding problems on main after the fact, main becomes unable to receive them. When you design a pipeline, "what must be true before merge?" is the highest-leverage question you own — and it is configured on the host's protection rules, not in Git.

🎯 Interview questions — Part B

🎯 "What are the benefits of using a pull request in a project?" — asked verbatim in Interview Coder, Sep 2025 and GeeksforGeeks, updated Jul 2026

A PR centralizes everything that should happen between "code written" and "code shared": human review (line comments, requested changes, approvals), automated verification (CI, linters, scanners as required checks that gate the merge), discussion that becomes a permanent, searchable record of why a change happened, and policy enforcement via protected branches — no direct pushes, no merging without approvals. Net effect: main stays releasable, knowledge spreads (reviewers learn the codebase), and every change has an audit trail linking code, conversation, and checks.

The details that separate candidates: an average answer says "code review before merging." A strong answer covers all four layers (review, automation, record, enforcement) and adds the operational nuances: the PR diff is three-dot (contribution-only) so reviewers see the right thing; merge-strategy choice (merge/squash/rebase) decides what history main accumulates; and small PRs are a reviewability feature — review quality collapses with diff size, so PR sizing is workflow design, not preference. Mentioning that a PR is a host construct, not a Git object, shows precise layering.

🎯 "Why is it considered to be called git 'pull request' as 'push request'?" — asked verbatim in Interview Coder's 90+ Git questions, Sep 2025

Because of who acts. You are not pushing your changes into the target branch — you lack (and should lack) the right to write there. You are requesting that the maintainers pull your branch into theirs: the action, when approved, is performed by the receiving side, integrating from your branch. The name is honest about authority: proposer proposes, owner integrates. It predates the button — in pre-platform kernel-style workflows, git request-pull (Module 1's trivia, now meaningful) generated exactly this message: "please pull from my repository at this address."

The details that separate candidates: an average answer shrugs "GitHub named it that." A strong answer explains the direction-of-action logic, connects it to the permission model (contributors get no write access to main — the whole security posture of open source), and lands the historical anchor (request-pull, mailing-list workflows). This apparently-trivial question is really testing whether you understand who has authority over what in distributed collaboration — answer it that way.

🎯 "What command helps us know the list of branches merged to master?" — asked verbatim in Interview Coder's 90+ Git questions, Sep 2025

git branch --merged master (or main) — lists branches whose tips are reachable from that branch: their work is fully contained, so deleting them loses nothing. Its complement git branch --no-merged master lists branches with unmerged commits — the ones branch -d would refuse (Module 5's seatbelt, same reachability test). Remote-side audit: git branch -r --merged origin/main. Typical cleanup: git branch --merged main | grep -v main | xargs git branch -d — with -d, never -D, so the seatbelt still catches mistakes.

The details that separate candidates: an average answer names the flag. A strong answer explains the underlying test — reachability in the commit graph, the same relation powering -d's safety and fast-forward detection — and the operational caveat that makes seniors pause: a squash-merged branch is not detected as merged (its commits were never merged, only their content re-recorded as a new commit), so squash-heavy teams cannot trust --merged for cleanup and rely on the host's branch-deletion automation instead. That one caveat is worth the whole answer.

Part C — Forks: collaboration without shared write access

C1. A fork is a server-side copy you own

The PR flow in Part B assumes everyone can push branches to the shared repository. Open source cannot assume that — thousands of strangers cannot have push access to anything. The fork solves it: a host-side copy of the repository under your account, where you have full push rights. You clone your fork, work on branches there, push to your fork, and open PRs from your fork's branch to the original's main. The original's maintainers never granted you anything; you never needed them to. Keeping oriented requires exactly the two-remote pattern Module 8 D2 promised: origin = your fork (push there), upstream = the original (fetch from there to stay current).

A fork is not a Git concept — it is git clone performed by the host, onto the host, plus a UI relationship. Which means you can simulate one on your disk with a bare clone, and understand the whole dance offline:

🧪 Exercise 9.4 — the fork dance, simulated end to end
bash
cd ~/git-course
git clone --bare bakery.git bakery-fork.git      # "the host copies the repo to your account"
git clone bakery-fork.git kitchen-contributor    # you clone YOUR fork
cd kitchen-contributor
git remote add upstream ~/git-course/bakery.git  # the original project
git remote -v
git switch -c feature/spice-guide                # contribute on a branch
echo "cardamom pairs with cinnamon" > spices.txt
git add spices.txt && git commit -q -m "Add spice pairing guide"
git push -u origin feature/spice-guide           # push to YOUR fork only
git fetch upstream                               # stay current with the original
git branch -r
Expected result — click to reveal
plain text
Cloning into bare repository 'bakery-fork.git'...
done.
Cloning into 'kitchen-contributor'...
done.
origin	/home/aisha/git-course/bakery-fork.git (fetch)
origin	/home/aisha/git-course/bakery-fork.git (push)
upstream	/home/aisha/git-course/bakery.git (fetch)
upstream	/home/aisha/git-course/bakery.git (push)
branch 'feature/spice-guide' set up to track 'origin/feature/spice-guide'.
 * [new branch]      main       -> upstream/main
  origin/HEAD -> origin/main
  origin/feature/spice-guide
  origin/main
  upstream/main

What to read out of it (routine Switched to… / push-progress lines elided): two remotes, two photo namespaces (origin/* = your fork, upstream/main = the original), and your feature branch pushed only to the fork — the original repository was never written to, which is the entire security model. From here, a real host's "open pull request" offers yourfork:feature/spice-guide → original:main. Staying current is git fetch upstream + git merge upstream/main on your branches (never commit to your fork's main — keep it a clean mirror of upstream's, so every PR starts from truth). Every mechanic here is Module 8; the fork only rearranged who owns which copy.

🎯 Interview questions — Part C

🎯 "What is the Difference Between a Fork and a Clone?" — asked verbatim in GeeksforGeeks' 70+ Git Interview Questions, updated Jul 2026

A clone is a Git operation: a full local copy of a repository on your machine, wired to the source as origin — how anyone gets code to work on. A fork is a host platform operation: a server-side copy of someone else's repository created under your account, giving you a place you may push when you cannot push to the original. They compose rather than compete: the open-source flow is fork (on the host) → clone your fork (locally) → branch, commit, push to the fork → PR from fork to original. The fork also keeps a host-level link to its parent, which is what makes cross-repository PRs and "sync fork" buttons possible.

The details that separate candidates: an average answer says "fork is on GitHub, clone is local." A strong answer states the reason forks exist — write-access economics: maintainers grant nobody push rights, yet accept contributions from anyone — and describes the two-remote working setup (origin = fork, upstream = original, fetch upstream/push origin) that makes fork-based work sane. Precision bonus: a fork is not a Git object or command — plain Git can emulate it with any second copy you can push to, which is also why the same flow works on every host.

Part D — Choosing a branching model

D1. The three named models

Every named model answers one question differently: how does code travel from a keyboard to a release? Git Flow (Driessen, 2010) is the heavyweight: permanent main (production) and develop (integration) branches, plus feature/* off develop, release/* for stabilization, and hotfix/* off main — built for explicitly versioned software where multiple releases live in parallel. GitHub Flow is the lightweight default this module has been teaching: one permanent branch, short feature branches, PR, merge, deploy — built for continuously delivered services. Trunk-based development goes furthest: everyone integrates to main ("trunk") at least daily — branches live hours, not weeks, or vanish entirely in favor of direct small commits — with unfinished work hidden behind feature flags (runtime toggles) instead of long branches; it is the model the DORA research associates with elite delivery performance.

Worth quoting in interviews: Git Flow's own author added a reflection to the original post in 2020 — for continuously delivered web software he now points teams to simpler flows like GitHub Flow, while standing by Git Flow for explicitly versioned, multi-version-supported software. The model wars have a truce line, drawn by release model.

ModelPermanent branchesBranch lifetimeBuilt forCost
Git Flowmaindevelop (+ release/hotfix lanes)Days–weeksVersioned releases; several supported versions at onceCeremony; long-lived divergence; slow integration
GitHub Flowmain onlyHours–daysContinuous delivery of services; PR-centric teamsNeeds real CI and deploy automation on main
Trunk-basedmain onlyHours (or none)High-frequency integration; elite CD; monoreposDemands feature flags, strong tests, mature team discipline

D2. How to actually choose

Let the release model decide, not fashion. Shipping a service continuously, one production version at a time? GitHub Flow — moving toward trunk-based as CI strength and flag infrastructure grow. Shipping versioned artifacts customers install and you must patch in parallel (a CLI, firmware, an on-prem product)? Git Flow's release and hotfix lanes earn their ceremony. Migrating between models is cheap in Git terms (branches are pointers) and expensive in habit terms — so choose for your delivery reality, write it down, and enforce the invariants with protection rules rather than memos. The one metric that predicts pain regardless of model: integration latency. Whatever you call your workflow, branches that live longer diverge further, conflict harder, and review worse (Modules 6 and 9, unified). Every model is, at heart, a policy for keeping that number small.

🎯 Interview questions — Part D

🎯 "What is a Git workflow model, and can you name a few?" — asked verbatim in WeCreateProblems' 100+ GIT Interview Questions, 2026

A workflow model is a team's agreed pattern for branches and integration — which branches exist permanently, where work happens, how code reaches release. The named ones: Git Flow (main + develop + feature/release/hotfix lanes; for versioned, multi-version software), GitHub Flow (main + short PR'd feature branches; for continuously delivered services), GitLab Flow (GitHub Flow plus environment or release branches as a middle path), trunk-based development (daily-or-faster integration to main, feature flags over long branches), and the forking workflow (contribution without write access — the open-source layer that composes with any of the above).

The details that separate candidates: an average answer names two or three models. A strong answer states the selection criterion — release model: continuous delivery favors light flows, parallel supported versions justify Git Flow — citing the Git Flow author's own 2020 guidance to that effect, and names the shared invariant (releasable main, enforced by protection rules) plus the shared enemy (integration latency: long-lived branches hurt in every model). Mentioning feature flags as the technology that lets trunk-based hide unfinished work signals current, practiced knowledge rather than blog recall.

Part E — Production practice

E1. Symptom → cause → diagnosis → fix

SymptomWhat is really happeningWhat to runThe fix
PR shows files/commits the author never touchedThe branch is stale — the "changes" are main's movement viewed two-dot, or an outdated basegit diff --stat main...feature locally — the honest contributionUpdate the branch from main (merge, or rebase — Module 10); the PR diff recalculates
remote: error: GH006: Protected branch update failed (or similar direct-push refusal)Branch protection doing its job — direct pushes to main are policy-forbiddenRead the refusal; check the repo's protection rulesBranch, push, PR — the intended path; never ask for a protection exception you don't truly need
git branch --merged misses branches everyone agrees were mergedThey were squash-merged: content landed as a new commit, their commits were never mergedgit diff main branch — the endpoint diff is empty once the content landed (three-dot still shows the contribution); git cherry main branch also flags equivalent patchesTrust the host's merged-state + auto-delete, not graph reachability, on squash-heavy teams
Fork's PRs keep including old, unrelated commitsThe fork's main drifted — commits were made on it instead of branches, or it's months behind upstreamgit log --oneline upstream/main..main on the fork cloneReset fork main to upstream/main (it should be a pure mirror), branch from there; never commit to fork main
Review turnaround is days; PRs pile up unreviewedPRs too large and/or review not treated as first-class work — process, not GitMeasure PR size and time-to-first-review over a monthSlice work smaller (stacked/short PRs), set review SLAs, make review count as delivery
Two teammates unknowingly build the same feature for a weekBranches unpushed or unnamed meaningfully — no visibilitygit branch -r — what is the team actually working on?Push branches on day one, name by ticket, open draft PRs early as broadcast

E2. Capstone — four tickets

Ticket 1 — "Design the workflow for a new 8-person platform team." Continuous deployment to one production environment, strong CI already in place. Recommend a model and its enforcement.

Worked answer: GitHub Flow with trunk-based ambitions. Concretely: protected main (no direct pushes, no force-push, required CI checks, one approval); feature/<ticket>-<slug> branches capped informally at ~2 days of life; PRs opened as drafts on day one for visibility; squash-merge as the default button (clean main history; the team accepts losing branch-internal commits) or merge-commit if per-feature revertability (revert -m 1, Module 7) matters more — make that choice explicitly and write it down. Deploy from main on merge. As flag infrastructure matures, shrink branch lifetime toward trunk-based rather than "adopting" it by decree. Justify with the module's one metric: every element above is a lever on integration latency.

Ticket 2 — "We ship an on-prem product; HQ says use GitHub Flow like the SaaS teams." Your product ships quarterly versions 4.x and 5.x, both under support contracts. Push back or comply?

Worked answer: push back, with the release-model argument. GitHub Flow assumes one production version that continuously advances; you support parallel versions needing independent patches — precisely the case Git Flow's author still endorses his model for (2020 note, citable). You need at minimum: long-lived release/4.x and release/5.x branches, hotfixes branched from and merged back into the affected release lines (and forward-ported to main — state the merge direction explicitly in the runbook), and tags for every shipped build (Module 12). Full Git Flow's develop branch is negotiable — many versioned-product teams run "GitHub Flow + release branches" (GitLab Flow's shape) and skip the ceremony. The interview-grade close: workflow follows release model; HQ's mandate optimizes for a delivery reality you do not have.

Ticket 3 — "Open-source our internal SDK and accept outside contributions safely." Legal approved; maintainers worry about drive-by code and secret leakage via PRs.

Worked answer: fork-based contribution as the security boundary: outside contributors get zero write access — they fork, push to their fork, open cross-repo PRs; maintainers alone merge. Layer the protections: protected main with required maintainer review; CI for fork PRs configured to not expose secrets (host platforms run fork PRs without secret access by default — verify, don't assume, and require approval-to-run-CI for first-time contributors); a CONTRIBUTING.md defining branch naming, commit style (Module 2's conventions), and DCO/CLA sign-off if legal requires attribution chains; CODEOWNERS so sensitive paths demand specific reviewers. Internally nothing changes — employees can keep the shared-repo flow; the two models compose in one repository. The mental model to state: forks turn "who may write?" from a trust decision into an architecture.

Ticket 4 — "The metrics say our workflow is failing." Average branch age: 16 days. Merge conflicts: weekly, hour-long. PRs: 40+ files typical. Review turnaround: 3 days. Management wants "better Git training." Diagnose properly.

Worked answer: the numbers describe an integration-latency problem, not a skills problem — training on conflict resolution treats the symptom (Module 6's fleet lesson, escalated to org level). The causal chain: big work items → big branches → long life → divergence → conflicts and unreviewable PRs → slow review → longer life. Break it at the source: slice work so a branch is mergeable in ≤2 days (vertical slices, stacked PRs for genuinely large features); merge main into open branches daily until then; cap PR size socially (and dashboards make it visible); set a same-day first-review norm — review latency compounds branch age. Keep one training item only: the three-dot diff habit, so reviews at least look at the right changes while sizes shrink. Present it as physics, not blame: every workflow model is a policy for keeping integration latency small, and 16-day branches mean the policy, not the people, failed.

E3. Documentation reference

TopicOfficial sourceWhat it covers
Branching workflows (concepts)Git Book §3.4 — Branching WorkflowsLong-running vs topic branches
Distributed workflowsGit Book §5.1 — Distributed WorkflowsCentralized, integration-manager (forks), dictator models
Pull requestsAbout pull requests — GitHub DocsPR anatomy, review, merge strategies
GitHub FlowGitHub flow — GitHub DocsThe lightweight PR-centric model, step by step
ForksAbout forks — GitHub DocsFork relationships, syncing, cross-repo PRs
Git Flow (original)A successful Git branching model — nvieThe 2010 model, plus the author's 2020 reflection
Trunk-based developmenttrunkbaseddevelopment.comThe model, feature flags, release strategies

E4. Self-assessment

Answer each aloud, from memory, before moving on. Every one is answered on this page.

  1. State the one invariant every team workflow protects, and the two host features that enforce it.
  2. Walk a feature's full lifecycle, command by command, from switch -c to the post-merge cleanup.
  3. Which direction do you merge to keep a feature branch current, and why does it make the final merge easier?
  4. A PR is "not a Git object" — what does that mean concretely, and which diff form does a PR display?
  5. Merge commit vs squash vs rebase on the merge button: what does main's history look like after each?
  6. Why does git branch --merged lie on squash-heavy teams?
  7. What problem do forks solve that branches cannot? Name the two remotes and the direction of fetch/push for each.
  8. Why should a fork's main never receive direct commits?
  9. Give the one-line purpose of Git Flow's develop, release/*, and hotfix/* branches.
  10. What criterion chooses between Git Flow and GitHub Flow — and what did Git Flow's author say in 2020?
  11. What is trunk-based development's answer to "where does unfinished work live, if not on branches?"
  12. Define integration latency and explain why it is the unifying metric behind Modules 6 and 9.

E5. Sources

Interview questions in this module were captured verbatim from: Interview Coder — 90+ Common Git Interview Questions (Sep 20, 2025), GeeksforGeeks — Top 70+ Git Interview Questions (updated Jul 30, 2026), and WeCreateProblems — 100+ GIT Interview Questions (2026). A corpus note: published questions on named branching models (Git Flow vs trunk-based specifically) are surprisingly rare as verbatim standalone items — the topic appears inside broader workflow answers — so Part D carries the closest published question, and its answer covers the comparison interviews actually probe. Technical claims were verified against the sources in E3 (including the nvie 2020 author reflection, fetched and confirmed); all commands and outputs were executed on Git 2.43.0 on Linux against the Module 8 bare-remote setup. Hashes will differ on your machine.

🗒️ Cheat sheet — Module 9

Command / conceptWhat it does / means
git switch -c feature/<ticket>-<slug> → work → git push -u origin <branch>Start and publish a unit of work; main untouched
git merge main (while on the feature)Catch the branch up; resolve conflicts on your side, at your pace
git log main..feature · git diff --stat main...featureReview a "PR" locally: its commits · its true contribution (three-dot)
git merge --no-ff <feature> → delete remote + local branchThe merge button and its cleanup, by hand
git branch --merged main · --no-merged mainSafe-to-delete audit · branches still carrying unmerged work (squash caveat!)
git clone <your-fork>git remote add upstream <original>The fork working setup: push to origin, fetch from upstream
git fetch upstreamgit merge upstream/mainKeep fork-based work current with the original project
Protected branch · required checksHost-enforced: no direct/force pushes; CI + approvals gate the merge
Merge strategies: merge commit / squash / rebaseBubble + one-revert unit / one clean commit, branch history discarded / linear replay (Module 10)
Git Flow · GitHub Flow · trunk-basedmain+develop+lanes for versioned ships · main+PR branches for CD · daily-or-faster integration with feature flags

Key concepts: main is sacred and always releasable; it moves only by reviewed merges — enforced by protection rules, not memos · a workflow is sequencing of commands you already know · keep branches current by merging main in; review against current reality · a PR = host construct: three-dot diff + review + checks + policy; not in .git · squash breaks --merged detection · forks = write-access architecture: origin (yours, push) + upstream (theirs, fetch); fork main stays a mirror · choose models by release model — continuous delivery → light flows; parallel versions → Git Flow lanes · the universal enemy: integration latency.

Next: Module 10 — Rewriting History — every workflow above eventually wants tidier history: rebase, interactive rebase, cherry-pick, and the golden rule that keeps rewriting safe. The merge-vs-rebase debate you have been promised since Module 6 gets settled there.
Spotted a mistake or want something added? Send me a note.