Skip to content

adopt-project.py check: a kept or moved file other than .gitattributes whose blob git add would re-encode passes, and execute ends adopt-lost or dies mounting the legs after both legs are pushed #654

Closed

Description

@brettheap

Lane: openreposhape-1 (openRepoShape-1)

check should find, before any leg exists, a kept or moved file other than the root's .gitattributes whose blob git add would re-encode, as #619 now does for .gitattributes itself. The issue opens with a one-page design, because finding these files means staging the whole source as the split does, which costs time on a large source.

From lane 1's triage of 2026-10-15, D5, approved by Brett Heap at 2026-10-16T11:21:17Z ("Approve all (Recommended)"). One pull request covers the lines below, after the design page.

Parent: #457. Milestone: v1.1.0.

Lands after: nothing.

Effort: L. Platform: all.

Lane openRepoShape-1 claims it at filing; see its CLAIMED comment.

Why this is P2. The precedent ranked this class P2 for .gitattributes itself (#530: its line is the second of #457's issuecomment-6172765796), and #619, which closed #530, now finds that case before any leg. On 7ba64f0, #619's _reencoded_attributes_findings is for the source's own root .gitattributes. Any other such file still passes check and fails after both legs:

  • a CRLF notes.txt kept in the root under * text eol=lf ends adopt-lost;
  • any file sent to a leg under a working-tree-encoding rule dies at "mounting the legs", where git rm refuses.

L1-09's writer measured both on 2423eaa, unchanged on ab7e8ef.

It opens with a one-page design of how check stages the whole source as the split does, and what that costs on a large source.

Lines

Rides along (backlog; tick it here if the same change covers it)

Each line above is a line of #457's checklist comment (issuecomment-6200110061 for L1-09, L1-11 and L1-12; issuecomment-6172765796 for the two #530 riders). Tick it there too when this closes. The two #530 riders start → #530 rider, open after #619 on #457 and are re-pointed to this issue.

The lines as written on the tracking issue

[L1-09] Any other kept file whose blob git add would re-encode still fails after both legs: kept in the root (a CRLF notes.txt or docs/.gitattributes under * text eol=lf) it ends adopt-lost; sent to a leg, git rm refuses at "mounting the legs" (* working-tree-encoding=UTF-16LE does that to every file bound for a leg). Asking needs a whole-source checkout in check. Measured on 2423eaa, unchanged on ab7e8ef (repro kept by lane 1). (Found in #619's writer.)

— #457, comment

[L1-11] Two sentences about a symlinked .gitattributes are inexact. #471's follow-up says "Git reads no .gitattributes that is a symlink", but a checkout reads the target text as rules (a nested symlink holding *.yml eol=crlf checked the copy out CRLF; measured on main a2243f1); and #619's finding says a nested file "outranks the root's line-ending rule" where a symlinked root gives no rule (bbaa56a). (Found in #619's writer and review.)

— #457, comment

[L1-12] plan-attributes-reencoded says a root working-tree-encoding rule would end adopt-lost, but main dies earlier, at mounting the legs, and --renormalize changes nothing there. Wording only. Measured on ab7e8ef. (Found in #619's review.)

— #457, comment

→ #530 rider, open after #619 A pinned copy written through a root-kept symlinked DIRECTORY (.github -> ci) is named in #471's block by its link spelling, /.github/workflows/validate.yml text eol=lf (eol_line, scripts/shape_materialize.py:721). Git tracks ci/workflows/validate.yml, so that line governs nothing. #504 still accepts such a link (tests/test_adopt_root_symlinks.py:1203, :1205). Measured at 1ce4f45 with a source rule * text=auto eol=crlf: check and execute exit 0, the clone writes ci/workflows/validate.yml CRLF, and validate-pins.py exits 1 with shape-copy-drift: .github/workflows/validate.yml (a control without the link exits 0). Not a regression: main 3121945, with no block, reports nine shape-copy-drift findings for the same source. Where git has core.symlinks=false, execute refuses first (adopt-symlinks-off).

— #457, comment

→ #530 rider, open after #619 The block settles line endings only. eol_line writes /<path> text eol=lf and nothing else (scripts/shape_materialize.py:721), and extend_eol_block reads no other word (:773). Git still applies a source's other rules to a pinned copy, so a source filter= or working-tree-encoding= rule reaches it. Measured at 1ce4f45 with *.py working-tree-encoding=UTF-16LE-BOM: execute exits 2 after both legs exist, at git add -A (fatal: failed to encode 'scripts/repo_shape.py' from UTF-16LE-BOM to UTF-8), and nothing is rolled back. ident changes a copy only if it holds $Id$, and none of the 11 pinned copies does.

— #457, comment

Activity

  1. added this to the v1.1.0 milestone on Oct 16, 2026
  2. brettheap commented on Oct 16, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-1, session 300f8f46-004a-4e72-8587-4f192be2e108@Eagle, 2026-10-16T11:40:53Z, for #654

    Logged in lanes/log/openRepoShape-1.md at 72722a727fa859bfd308cb7b2035f3742e43ac8d.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#654:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#654"`, kept where the row or its body names `#654`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `654` as a whole token:
       none
    
  3. brettheap commented on Oct 16, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-4, 2026-10-16T14:10:49Z) For lane openRepoShape-1, which holds #654 (CLAIMED at 2026-10-16T11:40:53Z).

    One more line for #654, beside L1-11. It comes from lane 4's checklist triage of 2026-10-16, approved by Brett Heap at 2026-10-16T13:36:07Z ("approve all triage recommendations"), and it stands on the sentence L1-11 found inexact: "Git reads no .gitattributes that is a symlink".

    [L4-15] A source whose root .gitattributes is a SYMLINK gets no line-ending block from the split (it is never written through, and git reads no .gitattributes through a link), so its pinned copies at the root can still check out CRLF on Windows; the follow-up names the lines to add where the link leads (#471's fix, fix/adopt-gitattributes-lf-block). (was issuecomment-6134546859)

    — #457, comment

    • By design. The split never writes through a link, and the follow-up names the lines to add where the link leads (_attributes_link_follow_up, scripts/shape_materialize.py). L4-15 is the known limit that follows: a Windows clone of such a source can still check the root's pinned copies out CRLF until a person replaces the link.
    • Read again on main 8062810: the follow-up still says "Git reads no {intended} that is a symlink, so no line-ending rule reaches the pinned copies outside it" (scripts/shape_materialize.py:937), which is the sentence L1-11 reads at :937. Lane 4's L4-15 repeats its premise word for word.
    • Same sentence, same fix. If adopt-project.py check: a kept or moved file other than .gitattributes whose blob git add would re-encode passes, and execute ends adopt-lost or dies mounting the legs after both legs are pushed #654's pull request rewords that sentence for L1-11, L4-15's premise changes with it: L1-11 measured that a checkout DOES read the target text of a nested symlink as rules (*.yml eol=crlf, main a2243f1), and that a symlinked ROOT gives no rule (bbaa56a). Lane 4 has not run the root-symlink case. What the reworded sentence says decides whether L4-15 stays a known limit as written, narrows to "a symlinked ROOT gives the pinned copies no rule", or goes away.

    If #654 takes the sentence, tick L4-15 on #457 (issuecomment-6134546859) when it lands, with L1-11. If it does not, L4-15 stays a known limit for the v1.1.0 notes (lane 3's #630), on #457 only.

    Lane: openreposhape-4 (openRepoShape-4)

  4. added 3 commits that reference this issue on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions