fix(pull): allow the first fast-forward into an unborn branch #394

Merged
hexajon merged 1 commit from issue-373-fixpull-unborn-branch-misread-as-dirty-diff-index into main 2026-08-17 06:31:11 +00:00
Owner

Summary

An unborn local branch that already tracks a populated origin was misread as dirty, so madtea pull refused the first fast-forward into a fresh checkout (#373).

Root cause: the uncommitted-changes guard ran git diff-index --quiet HEAD, which errors (exit 128) on an unborn HEAD rather than signalling a diff, and the guard treated any error as dirty.

Fix: HasUncommittedChangesDir and UncommittedFilesDir now detect an unborn HEAD structurally (ADR 0031 clause 4) and judge cleanliness against the index (git diff --cached). An empty unborn index reads clean; a staged unborn index reads dirty and its files are named. Born-HEAD behavior is byte-for-byte unchanged.

Also removed a now-redundant unborn-HEAD bypass in the foreign-dirty-target guard that would have cleared a stranger's staged unborn work; it now routes through the fixed helper and stays protective.

Adds hermetic tests for the unborn cases and the first-fast-forward repro. Full gate green: build, vet, gofmt, staticcheck, govulncheck, gosec, test-race, mcp-conformance.

Closes #373

## Summary An unborn local branch that already tracks a populated origin was misread as dirty, so `madtea pull` refused the first fast-forward into a fresh checkout (#373). Root cause: the uncommitted-changes guard ran `git diff-index --quiet HEAD`, which errors (exit 128) on an unborn HEAD rather than signalling a diff, and the guard treated any error as dirty. Fix: HasUncommittedChangesDir and UncommittedFilesDir now detect an unborn HEAD structurally (ADR 0031 clause 4) and judge cleanliness against the index (`git diff --cached`). An empty unborn index reads clean; a staged unborn index reads dirty and its files are named. Born-HEAD behavior is byte-for-byte unchanged. Also removed a now-redundant unborn-HEAD bypass in the foreign-dirty-target guard that would have cleared a stranger's staged unborn work; it now routes through the fixed helper and stays protective. Adds hermetic tests for the unborn cases and the first-fast-forward repro. Full gate green: build, vet, gofmt, staticcheck, govulncheck, gosec, test-race, mcp-conformance. Closes #373
fix(pull): allow the first fast-forward into an unborn branch
Some checks failed
drift / govulncheck (pull_request) Has been skipped
drift / surface-diff (pull_request) Successful in 1m20s
drift / forgejo-smoke (pull_request) Has been skipped
ci / mcp-conformance (pull_request) Successful in 2m8s
ci / mcp-conformance (push) Successful in 31s
drift / govulncheck (push) Has been skipped
drift / surface-diff (push) Successful in 13s
drift / forgejo-smoke (push) Has been skipped
ci / gate (push) Failing after 9m31s
ci / gate (pull_request) Successful in 16m18s
d5f4d80fc5
Closes #373
hexajon deleted branch issue-373-fixpull-unborn-branch-misread-as-dirty-diff-index 2026-08-17 06:33:23 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea!394
No description provided.