Git Project: Feature Branch
Create a feature branch, produce a genuine conflict, resolve it, and merge with a graph you can explain on paper.
Build two valid lines of development, create one genuine content conflict, and merge them into a tested history whose snapshots, parent order, and resolution you can explain.
Filter incidents by severity
A feature branch adds filtering while main independently normalizes severity names. Each branch works alone; integration requires both intentions.
A merge you can prove
The final merge preserves topology, combines behavior correctly, passes tests, carries an annotated integration tag, and contains no unexplained state.
Project brief
You maintain a small command-line status board. Incidents currently store severity as low, medium, or high. Product work adds filtering on a feature branch while maintenance work changes the canonical names to info, warning, and critical on main. Both change the same mapping in src/incidents.js.
Evidence tracker
Mark a gate complete only after the named command or review proves it. Progress is saved in this browser.
Safety boundary
Disposable repository only
Create a new status-board-conflict directory. Never manufacture conflicts in valuable work.
No remote yet
This unit tests local graph reasoning. Do not add a remote, fetch, pull, or push.
No rewriting shortcuts
Do not rebase, reset, squash, or cherry-pick the required histories. The final two-parent merge topology is part of the deliverable.
No real incident data
Use fictional labels and messages only. Do not copy customer, credential, or production information.
Repository contract
src/incidents.js
Exports severity normalization and incident filtering. The deliberate conflict must occur in this file.
test/incidents.test.js
Uses the built-in node:test module and proves exact normalized labels and filter output.
README.md
Explains how to run node --test and documents the final accepted severity names.
package.json
Contains a test script using node --test; no external package or network access is required.
Use Node.js available on your machine, or adapt the same contract to a local runtime you can test. The history shape, conflict evidence, and final behavior remain mandatory.
Required graph and final behavior
* <merge> (HEAD -> main, tag: v0.1.0-integration) Merge incident severity filter
|\
| * <feature-tests> Test severity filtering
| * <feature-code> Add severity filtering
* | <main-docs> Document normalized severity names
* | <main-code> Normalize severity names
|/
* <base-model> Add incident model
* <initial> Initialize status boardBoth intentions survive
Legacy input normalizes to the new names, and filtering operates on normalized severity without mutating incidents.
npm testOne two-parent merge
Main’s maintenance tip is parent one; the exact feature tip is parent two.
git rev-list --parents -n 1 HEADSeven reachable commits
Two base, two main, two feature, and one merge commit are reachable from main.
git rev-list --count mainMilestone 1 · Build and verify the baseline
Initialize main. Create the first commit with package.json, README, implementation, and baseline tests. Create a second commit that adds an immutable incident fixture and tests all three legacy labels.
git init -b main
git add package.json README.md src/incidents.js test/incidents.test.js
git diff --cached --check
git commit -m "Initialize status board"
git add src/incidents.js test/incidents.test.js
git diff --cached
git commit -m "Add incident model"
npm test
git statusTag nothing yet. Record the second commit ID as the expected merge base. The baseline API accepts legacy labels and returns unfiltered incidents.
Milestone 2 · Build the focused feature line
git switch -c feature/incident-filter
# Add filterIncidents(incidents, severity) in src/incidents.js
git add src/incidents.js
git diff --cached
git commit -m "Add severity filtering"
# Add focused filter tests
git add test/incidents.test.js
git diff --cached --check
npm test
git commit -m "Test severity filtering"The feature implementation compares against the original low, medium, and high mapping. Preserve the exact feature tip ID in your evidence.
Milestone 3 · Advance main independently
Switch to main. Change the same mapping lines so legacy input normalizes to info, warning, and critical. Update baseline tests in the same code commit. Then update the README in a separate documentation commit.
git switch main
# Modify the overlapping severity map and baseline expectations
git add src/incidents.js test/incidents.test.js
git diff --cached
npm test
git commit -m "Normalize severity names"
# Document info, warning, and critical
git add README.md
git diff --cached --check
git commit -m "Document normalized severity names"Both branches must pass their own tests before integration. The histories now contain six commits total and match this topology:
* <main-docs> (HEAD -> main) Document normalized severity names
* <main-code> Normalize severity names
| * <feature-tests> (feature/incident-filter) Test severity filtering
| * <feature-code> Add severity filtering
|/
* <base-model> Add incident model
* <initial> Initialize status boardMilestone 4 · Predict the merge from evidence
git status
git log --oneline --decorate --graph --all
git merge-base main feature/incident-filter
git log main..feature/incident-filter --oneline
git log feature/incident-filter..main --oneline
git diff main...feature/incident-filter
BASE=$(git merge-base main feature/incident-filter)
git diff "$BASE" main -- src/incidents.js
git diff "$BASE" feature/incident-filter -- src/incidents.jsWrite a prediction before merging: the result cannot fast-forward, must create a two-parent merge commit, and should conflict in the shared severity mapping. Name which feature and main behaviors the resolution must preserve.
Milestone 5 · Trigger and resolve the real conflict
git merge --no-ff feature/incident-filter
git status
git diff --name-only --diff-filter=U
git ls-files -u -- src/incidents.js
git show :1:src/incidents.js
git show :2:src/incidents.js
git show :3:src/incidents.jsResolve src/incidents.js so legacy values normalize to main’s new names and the feature filter accepts those normalized names. Keep the function pure. Update feature tests where the expected public contract changed; do not simply choose an entire side.
git add src/incidents.js test/incidents.test.js
git diff --name-only --diff-filter=U
git ls-files -u
git diff --cached
git diff --cached --check
git grep -n -e '^<<<<<<< ' -e '^=======$' -e '^>>>>>>> '
npm testEvery marker-search match must be reviewed, the unmerged lists must be empty, and the complete staged integration must be intentional before continuing.
Milestone 6 · Create and inspect the merge commit
git commit -m "Merge incident severity filter" \
-m "Preserve normalized severity names and apply filtering after normalization."
git show --no-patch --pretty=raw HEAD
git rev-list --parents -n 1 HEAD
git diff HEAD^1 HEAD
git diff HEAD^2 HEAD
npm test
git statusThe raw commit must show two parents. Parent one is the pre-merge main documentation tip; parent two is the feature test tip. Each parent diff answers a different question about what the merge contributed relative to that side.
Milestone 7 · Tag and audit the integrated state
git tag -a v0.1.0-integration HEAD -m "Verified incident filter integration"
git show v0.1.0-integration
git rev-parse v0.1.0-integration^{}
git branch --merged main
git rev-list --count main
git statusKeep feature/incident-filter through the evidence review. You may delete it only after containment is proven and its exact tip remains reachable through the merge. The annotated tag must peel to the merge commit.
Required failure drills
Abort once
Before the successful attempt, run git merge --abort during conflict and prove main, status, and feature tip return unchanged.
Wrong-side preview
Use git restore --ours and --theirs only to inspect whole-file outcomes, then restore the conflict state or rebuild. Neither side alone is acceptable.
Fail one test intentionally
Demonstrate that keeping main’s names with feature’s old filter values fails a focused integration test, then correct the contract.
Protect the tag
Create a different local experimental tag name. Do not move v0.1.0-integration after verification.
Evidence package
- Pre-merge graph with all six commits and both branch decorations.
- Merge-base ID, unique commit lists, and both base-relative implementation patches.
- Conflict status, unmerged index entries, and base/ours/theirs file versions.
- Final cached diff, marker scan, test output, and merge message rationale.
- Raw merge commit, parent IDs, parent-relative diffs, containment proof, and seven-commit count.
- Annotated tag object, peeled merge ID, final clean status, and a short explanation of why no history was rewritten.
Self-assessment rubric: 25 points
5 · Branch construction
Exact base, feature, and main commits; focused snapshots; clean tests on both sides.
5 · Prediction
Correct merge base, unique ranges, base-relative diffs, conflict location, and topology forecast.
5 · Resolution
All three stages inspected; normalized names and filtering preserved; no mechanical side choice.
5 · Verification
Cached review, marker check, passing tests, exact parent order, and parent-relative explanations.
5 · Final audit
Seven commits, containment, annotated tag, clean status, no remote, and complete evidence package.
Automatic stop
Valuable repository use, invented conflict markers, history rewriting, real data, or unexplained lost work requires rebuilding safely.
Project checklist
- I created two valid divergent histories from one recorded merge base.
- I predicted the merge and conflict from ranges and base-relative patches.
- I inspected base, ours, and theirs before designing the combined behavior.
- I proved the resolution with staged review, marker checks, and integration tests.
- I verified two parent IDs, seven reachable commits, containment, tag target, and clean status.
Final audit commands
git status
git log --oneline --decorate --graph --all
git rev-list --count main
git rev-list --parents -n 1 HEAD
git merge-base --is-ancestor feature/incident-filter main
git diff HEAD^1 HEAD
git diff HEAD^2 HEAD
git show v0.1.0-integration
git fsck --no-reflogs --unreachablegit fsck --no-reflogs --unreachable should report no unexplained unreachable project commits. If it does, identify each object before considering the project complete.