Comment puis-je exécuter un code sur formatter ma source sans modifier l'histoire git?

voix
-2

Je suis en train de formater un repo entier à l' aide d' un outil de mise en forme de code. Ce faisant, je veux conserver des informations sur qui a commis quelle ligne, de sorte que les commandes comme git blamemontrent toujours les informations correctes. Par cela, je veux dire qu'il doit montrer l'auteur qui a édité précédemment chaque ligne (avant qu'il ne soit mis en forme).

Il y a la commande filtre-branche git qui vous permet d'exécuter une commande sur chaque révision du départ des prises en pension depuis le début du temps.

git filter-branch --tree-filter '\
  npx prettier --write src/main/web/app/**/**.{js, jsx} || \
  echo Error: no JS files found or invalid syntax' \
  -- --all

Il faudra toujours courir ce et vraiment je ne se soucient pas du passé. Je veux juste formater la branche principale aller de l' avant sans changer la propriété de chaque ligne. Comment puis-je faire ceci? J'ai essayé de jouer avec le rev-listà la fin et d' autres types de filtrage , mais il ne fonctionne toujours pas. Il doit y avoir un moyen de formater le code de base tout en préservant les informations sur l'auteur pour chaque ligne.

Créé 27/11/2018 à 15:13
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
1

Ce que vous essayez de faire est impossible. Vous ne pouvez pas, à un moment donné dans le temps, changer une ligne de code, mais ont rapport git que le changement le plus récent de cette ligne de code est quelque chose qui est arrivé avant ce moment.

Je suppose un outil de contrôle de source pourrait soutenir l'idée d'un « changement sans importance », où vous marquez un commettras comme cosmétique et l' analyse de l' histoire serait ignorer que commettent. Je ne sais pas comment l'outil vérifiera que le changement était vraiment esthétique, et sans une certaine forme d'application de l' outil la fonction serait certainement être mal utilisé entraînant l' introduction de bugs potentiellement cachés dans commits « sans importance ». Mais vraiment les raisons pour lesquelles je pense que c'est une mauvaise idée sont ici académiques - la ligne de fond est, git ne dispose pas d' une telle fonctionnalité. (Je ne peux pas penser à un outil de contrôle de code source qui fait.)

Vous pouvez modifier la mise en forme à l'avenir. Vous pouvez conserver la visibilité des changements passés. Vous pouvez éviter que l'histoire de l'édition. Mais vous ne pouvez pas faire tous les trois en même temps, vous allez devoir décider lequel sacrifice.

Il y a en fait deux bas-côtés à la réécriture de l'histoire, par la voie. Vous avez parlé du temps de traitement, donc nous allons regarder cette première:

Comme vous l' avez remarqué, la façon simple de le faire avec filter-branchserait beaucoup de temps. Il y a des choses que vous pouvez faire pour l' accélérer (comme lui donnant un arbre pour son disque virtuel de travail), mais il est un tree-filteret il implique le traitement de chaque version de chaque fichier.

Si vous avez fait une pré-traitement, vous pourriez être un peu plus efficace. Par exemple, vous pourriez être en mesure de prétraiter tous BLOBdans la base de données et créer un mappage (où TREEcontient BLOBX, le remplacer par BLOBY), et ensuite utiliser un index-filterpour effectuer les substitutions. Cela éviterait toute la caisse et ajouter des opérations, et il éviterait reformater à plusieurs reprises les mêmes fichiers de code. Alors que gagner beaucoup d'E / S. Mais il est une chose non négligeable à mettre en place, et pourrait encore prendre du temps.

(Il est possible d'écrire un outil plus spécialisé basé sur ce même principe, mais personne n'a écrit autant que je sache un. Il existe un précédent que les outils plus spécialisés peuvent être plus rapides que filter-branch...)

Même si vous venez à une solution qui fonctionnera assez vite, gardez à l'esprit que la réécriture de l'histoire perturbera tous vos refs. Comme toute réécriture de l'histoire, il sera nécessaire pour tous les utilisateurs de la mise en pension de mettre à jour leurs clones - et quelque chose de ce balayage, la façon dont je recommande de le faire est, jeter les clones avant de commencer la réécriture et re-clone après.

Cela signifie aussi si vous avez quelque chose qui dépend de commettre les ID, qui sera également brisé. (Cela pourrait inclure les infrastructures de construction, ou de la documentation de presse, etc .; selon les pratiques de votre projet.)

Ainsi, une ré-écriture de l'histoire est une solution assez radicale. Et d'autre part, il semble aussi drastique de supposer que le formatage du code est impossible simplement parce qu'il n'a pas été fait du jour 1. Donc, mon conseil:

Ne le reformatage dans un commit. Si vous avez besoin d'utiliser git blame, et il vous RAPPELLE le commit où reformatage a eu lieu, puis un suivi en exécutant à git blamenouveau sur le reformater parent Engageons.

Ouais, il suce. Pour un moment. Mais un morceau d'histoire donnée tend à devenir moins important à mesure qu'il vieillit, donc à partir de là que vous venez de laisser le problème diminue peu à peu dans le passé.

Créé 27/11/2018 à 15:56
source utilisateur

voix
0

Il doit y avoir un moyen de formater le code de base tout en préservant les informations sur l'auteur pour chaque ligne.

Une chose que vous pouvez faire est de ramifier de certains commettent plus tôt, reformater le code, puis rebasage masterà votre succursale. Cela préserverait l' auteur pour tous les changements qui sont venus après tout ce que vous commettez commencer.

Donc, c'est l'idée, mais il y a des grandes raisons pour lesquelles vous ne devriez pas le faire:

  1. Rebasage une branche commune est une mauvaise idée. Le fait que vous vous souciez même de préserver la paternité des changements signifie probablement qu'il ya un certain nombre de personnes qui travaillent activement sur le code. Si vous allez rebasage la branche principale, puis chaque fourchette ou clone de votre repo va avoir une branche de maître avec l'histoire ancienne, et qui est lié à la confusion et la douleur à moins que vous êtes très attention à la gestion du processus et de faire certains que tout le monde est conscient de ce que vous faites et met à jour de façon appropriée leurs copies. Une meilleure approche serait sans doute de ne pas changer la base maître, mais au lieu de fusionner les commits de maître dans votre branche. Ensuite, que tout le monde commencer à utiliser la nouvelle branche au lieu de master.

  2. Les conflits de fusion. Dans reformater l'ensemble codebase, vous allez probablement apporter des modifications à un grand nombre de lignes dans presque tous les fichiers. Lorsque vous fusionnez les commits suivantes, que ce soit par l' intermédiaire rebaseou merge, vous aurez probablement un grand nombre de conflits à résoudre. Si vous prenez l'approche que je propose ci - dessus et de fusionner commits de maître dans votre nouvelle branche au lieu de rebasage, alors il sera plus facile de résoudre ces conflits d'une manière ordonnée parce que vous pouvez fusionner quelques commits à la fois jusqu'à ce que vous êtes pris vers le haut.

  3. Solution incomplète. Vous allez devoir savoir où dans l'histoire que vous souhaitez insérer votre opération de reformatage. Le plus en arrière vous allez, plus vous préservez la paternité des changements, mais plus de travail , il sera de fusionner les modifications ultérieures. Ainsi , vous aurez probablement encore jusqu'à la fin avec beaucoup de code où votre reformatage Commit est le dernier changement.

  4. Avantage limité. Vous ne fait perdre l' information de l' auteur dans git- il est juste que les outils présentent généralement seulement qui a fait le changement le plus récent. Mais vous pouvez toujours revenir en arrière et regarder commits avant et creuser à travers toute l'histoire de tout morceau de code, y compris qui fait. Donc , la seule chose que l' insertion de votre opération reformater dans l'histoire achète vraiment est la commodité de voir qui a changé un morceau de code sans l'étape supplémentaire de revenir à une version antérieure commit.

  5. Il est malhonnête. Lorsque vous réécrivez l'histoire d'une branche, vous modifiez un enregistrement de fait de la façon dont le code a changé au fil du temps, et qui peut créer des problèmes réels. Imaginons que votre reformatage n'est pas tout à fait comme sans conséquence que vous voulez dire qu'il soit, et à faire le reformatage vous créez en fait un bug. Disons, par exemple, que vous introduisez un espace blanc supplémentaire dans une chaîne multi-ligne constante. Quelques semaines plus tard, quelqu'un remarque enfin le problème et va chercher la cause, et il semble que le changement a été fait un an et il y a la moitié (parce que c'est où vous avez inséré votre reformatage dans l'histoire). Mais le problème semble nouveau - il ne se présente pas dans la construction livré il y a deux mois, donc ce que le diable se passe?

  6. Avantage diminue au fil du temps. Alors que le développement continue, les changements que vous essayez de difficile de ne pas couvrir seront couverts par quelques autres changements quand même, et vos reformatage changements seraient également remplacées par ces nouveaux changements. Au fil du temps et le développement marche sur, le travail que vous faites pour enterrer vos changements de reformatage ne signifie pas grand - chose.

Si vous ne voulez pas que votre nom apparaître comme l'auteur de chaque ligne dans votre projet, mais vous ne voulez pas vivre avec les problèmes décrits ci - dessus, alors vous voudrez peut - être vous revoir l' approche. Une meilleure solution pourrait être d'aborder le reformatage en équipe: mettre tout le monde sur l'équipe d'accord pour exécuter le formatter sur un fichier qu'ils changent, et de faire le bon formatage d' une exigence dans tous les examens de code à l' avenir. Au fil du temps, votre équipe couvre la majeure partie du code, et les informations de l' auteur sera la plupart du temps approprié puisque chaque fichier qui obtient reformaté allait être changé de toute façon. Vous pouvez éventuellement finir avec un petit nombre de fichiers qui ne sont jamais reformatés parce qu'ils sont très stables et ne nécessitent pas des mises à jour, et vous pouvez choisir de les reformater (car ayant des fichiers mal formatés vous fait des noix) ou non (parce que personne ne travaille vraiment dans les fichiers de toute façon).

Créé 27/11/2018 à 18:53
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more