You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A .gitattributes merge driver is retroactively inert: every PR older than the declaration still conflicts #3308
Seven open PRs could not even be updated onto main today — gh pr update-branch refused each with "Cannot update PR branch due to conflicts". The conflict surface, measured across all seven:
docs/audits/impl-estimates.jsonl should never conflict. It is strictly append-only — every commit touching it is N insertions, 0 deletions — and #3256 (768e740b1) declared exactly the right thing:
docs/audits/*.jsonl merge=union
It still conflicted.
Mechanism
A .gitattributes merge-driver declaration is retroactively inert. Git reads merge attributes from the side being merged into, not from the side being merged in. A branch cut before the rule landed carries a .gitattributes without it, so the driver is never consulted.
$ git show origin/agent/T-2:.gitattributes
docs/roadmaps/roadmap.yaml merge=roadmap <- no jsonl rule
$ git merge-base --is-ancestor 768e740b1 origin/agent/T-2 ; echo $?
1 <- branch predates the declaration
$ git merge origin/main
CONFLICT (content): Merge conflict in docs/audits/impl-estimates.jsonl
The blobs themselves merge perfectly — git merge-file --union on the three stages returns rc=0, 50 rows, 0 markers, every line valid JSON. Nothing was wrong with the data or the driver; the attribute simply never bound.
This is the "declared fix that cannot fire" class. The repo has had the correct declaration since #3256 and every PR older than it kept conflicting anyway, silently, with no signal that the declaration was not in play.
Fix
scripts/ci_resolve_dirty.sh already owns this class for roadmap.yaml: it registers merge.roadmap.driverper invocation so nothing leaks into the shared .git. Bind union the same way:
git -c core.attributesFile=<tmp with `docs/audits/*.jsonl merge=union`> merge ...
core.attributesFile is the lowest-priority attribute source, so it applies only where the branch has no rule of its own — a branch that already carries the declaration is unaffected. Nothing shared is written.
Verified on #3271, whose merge had failed minutes earlier:
Activity
fix(git): a merge driver declared after a branch was cut never fires …