Skip to content

gitattributes: aucune regle eol pour *.py — 9 blobs CRLF sur main, cause racine du conflit whole-file de #13951 #14353

Description

@jsboige

.gitattributes normalise les fins de ligne pour *.ipynb, *.lean, *.sh, .env, *.en.md, lake-manifest.json, les CSV de traduction, _quarto.yml, COURSE_CATALOG.generated.json, plusieurs README et twin_pairs.d/*.yaml — pas pour *.py. Avec core.autocrlf=false sur les machines du cluster, un outil qui écrit du CRLF dans un .py le commite tel quel, et le fichier devient « modifié des deux côtés » sur toute sa longueur au premier merge divergent.

Trouvé pendant la réparation P0 de #13951, dont c'était la cause racine.

Portée mesurée (main @ c90a0aee4)

Recensement des blobs de l'index, git cat-file blob HEAD:<path> sur les 1854 .py suivis :

État Nombre
LF pur 1845
CRLF pur 9
mixte 0

Les 9 :

MyIA.AI.Notebooks/QuantConnect/partner-course-quant-trading/examples/Crypto-MultiCanal/fix_ipynb_quotes.py
MyIA.AI.Notebooks/SymbolicAI/Argument_Analysis/argumentation_lib/_state_manager_plugin.py
scripts/lean/life_synthesize_sat.py
scripts/lean/tests/test_life_synthesize_sat.py
scripts/notebook_tools/check_lean4_wsl_repl.py
scripts/notebook_tools/tests/test_check_lean4_wsl_repl.py
scripts/tests/test_check_pr_perimeter.py
scripts/tests/test_gitleaks_allowlist.py
scripts/translation/tests/test_translation_full_mode.py

La convention de fait est déjà LF à 99,5 % : la règle ne changerait pas la pratique, elle la rendrait tenable.

Ce que ça a coûté, concrètement

Sur #13951, le premier commit a écrit scripts/tests/test_check_unaddressed_nits.py en CRLF (base 84d6a974d : CRLF 0 / LF 3754 → commit a17f1471a : CRLF 3801 / LF 3801) pendant que scripts/check_unaddressed_nits.py, resté en LF, fusionnait sans incident. Six jours plus tard le rebase produisait un conflit sur la totalité du fichier de test (marqueurs lignes 1 / 3845 / 7647), sans une seule collision sémantique. Réparation : rejeu des commits par instantané de contenu + normalisation LF, puis rebase — zéro conflit.

Le coût réel n'est pas le conflit lui-même mais ce qu'il cache : en résolvant à la main un conflit de 7600 lignes, on ne voit plus les vraies suppressions. Celle de #13951 (30 lignes de tests de main) n'a été trouvée qu'après avoir écarté le bruit CRLF.

Fix proposé

*.py text eol=lf

Effet : renormalisation des 9 fichiers ci-dessus, aucun autre. À faire en une PR dédiée qui committe la renormalisation (git add --renormalize -- '*.py') dans le même geste que la règle, sinon les 9 fichiers restent perpétuellement M dans les arbres de travail — c'est l'état décrit par #13493 pour .ipynb.

Point d'attention : la renormalisation touche 9 fichiers d'un coup ; la faire quand aucune PR ouverte ne les modifie (gh pr list --state open --json files sur ces chemins) pour ne pas déplacer le conflit ailleurs.

Note d'instrument (transposable)

git show <rev>:<path> applique la conversion working-tree et ment sur les fins de ligne : il rapportait 100 % CRLF à toutes les révisions, y compris là où od -c montrait du LF. Le recensement ci-dessus est pris avec git cat-file blob <rev>:<path>, qui rend les octets du blob. Toute mesure de fins de ligne faite avec git show est à refaire.

Voisins : #13493 (.ipynb perpétuellement M sous une règle eol=lf sans renormalisation committée), #11109 (mixte LF/CRLF sur _quarto.yml / JSON / CSV). Aucun des deux ne couvre *.py.

— lane myia-po-2026:CoursIA-2 (cycle c.884)

Activity

  1. jsboige commented on Sep 3, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2026:CoursIA-2 -- paths: .gitattributes, MyIA.AI.Notebooks/QuantConnect/partner-course-quant-trading/examples/Crypto-MultiCanal/fix_ipynb_quotes.py, MyIA.AI.Notebooks/SymbolicAI/Argument_Analysis/argumentation_lib/_state_manager_plugin.py, scripts/lean/life_synthesize_sat.py, scripts/lean/tests/test_life_synthesize_sat.py, scripts/notebook_tools/check_lean4_wsl_repl.py, scripts/notebook_tools/tests/test_check_lean4_wsl_repl.py, scripts/tests/test_check_pr_perimeter.py, scripts/tests/test_gitleaks_allowlist.py, scripts/translation/tests/test_translation_full_mode.py

    Grain: LIGHT/docs — lane myia-po-2026:CoursIA-2 — prev: MED/notebook-python #14458

  2. jsboige commented on Sep 3, 2026

    @jsboige
    OwnerAuthor

    [RELEASED] lane myia-po-2026:CoursIA-2 -- Tell c.1356 ★★★ sustained ×N+1ᵉ cas : PR #14474 OPEN (jsboige/humain, branche fix/14353-py-eol, 11 fichiers, créé 2026-09-03T12:32:43Z) porte déjà le scope verbatim (.gitattributes *.py text eol=lf + 10 fichiers .py renormalisés). Le claim c.928 est périmé — le picker l'avait flagué "TRAVAIL EN COURS : PR #14474" mais le claim a été posé sans avoir vérifié que PR #14474 = auteur humain (jsboige), pas autre lane. Aucun geste code attendu de ce cycle. — cycle c.928 (2026-09-03T18:15Z)

  3. added 2 commits that reference this issue on Sep 4, 2026
  4. jsboige commented on Sep 4, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] #14353 — myia-po-2026:CoursIA — 2026-09-04T10:55Z (retroactif : PR #14474 ouverte sur cette issue depuis le 02/09 ; le marqueur manquait pour le garde lane-claim-absent)

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions