Comment gérer les changements de format de code répandus dans un référentiel git

Nous avons un projet avec environ 500 000 lignes de code, gérées avec git, la plupart datant de plusieurs années. Nous allons apporter une série de modifications pour rendre l’ancien code conforme aux normes et aux meilleures pratiques actuelles de la communauté de développeurs, en ce qui concerne les conventions de dénomination, la gestion des exceptions, l’indentation, etc.

Vous pouvez penser à quelque chose entre jolie impression et refactoring bas niveau / mécanique.

Ce processus est susceptible de toucher presque chaque ligne de code de la base de code (~ 85%), et certaines lignes seront sujettes à cinq modifications. Tous les changements sont censés être sémantiquement neutres.

  • Existe-t-il un moyen de rendre les modifications transparentes pour git blame, etc.? En examinant le code dans un mois, nous verrons comment la logique a été introduite, pas celle dans laquelle l’indentation ou la capitalisation a été modifiée?
  • Quelle est la meilleure façon de tirer des fusions à partir de fourches n’ayant pas subi ce processus? Mon projet actuel serait de faire en sorte qu’un script clone le repository repéré, lui applique le processus automatisé et sa base, les diffère, puis applique le diff. Mais j’aimerais avoir une réponse plus propre.
  • Y a-t-il d’autres problèmes de ce genre que je ne vois pas et, si oui, que peut-on faire pour les atténuer? Je pense que Git Bect, etc. devrait être correct, git log, etc. Si vous traversez la grande ligne de partage, ça gênera à moins que vous soyez prudent, et git diff sera sans espoir, mais je ne suis pas convaincu sharepoint la douleur.
  • Je ne sais pas comment gérer au mieux certaines des modifications les plus invasives que vous décrivez, mais …

    L’option -w de git blame , git diff et autres permet à git d’ignorer les modifications des espaces, ce qui vous permet de voir plus facilement les différences réelles.

    Je recommanderais de faire ces évolutions, étape par étape, dans un référentiel Git central (central comme dans “référence publique” pour tous les autres référentiels à suivre):

    • échancrure
    • méthodes de réordonnancement
    • puis renommer
    • puis …

    Mais pas “indentation-reordering-renaming -…- un géant commet”.

    De cette façon, vous donnez à Git une chance raisonnable de suivre les changements à travers les modifications de refactoring.

    De plus, je n’accepterais aucune nouvelle fusion (tirée d’un autre repository) qui n’aurait pas appliqué le même refactoring avant de pousser son code.
    Si l’application du processus de formatage apporte des modifications au code récupéré, vous pouvez le rejeter et demander que le repository à distance soit d’abord conforme aux nouvelles normes (du moins en tirant de votre repo avant de poursuivre).

    Vous aurez également besoin d’un mergetool qui permette d’ignorer les espaces de manière agressive. p4merge le fait et est téléchargeable gratuitement.

    Cette question a une bonne solution pour cela. Utilisez brièvement git filter-branch .

    J’ai utilisé moi-même ce code:

    git filter-branch --tree-filter "git diff-tree --name-only --diff-filter=AM -r --no-commit-id \$GIT_COMMIT | grep '.*cpp\|.*h' | xargs ./emacs-script" HEAD

    Quel ./emacs-script est un script que j’ai écrit en utilisant emacs pour changer le style de code, il suffit d’appeler indent-region sur chaque fichier.

    Ce code fonctionne correctement s’il n’y a pas de fichier supprimé ou supprimé du référentiel. Sur cette situation, l’utilisation de --ignore-unmatch peut être utile, mais je n’en suis pas certain.