Comment valider le refactoring en cours?

23

J'ai donc ce gros projet qui est en train d'être refactorisé par moi. Je change beaucoup de choses, donc il n'y a aucune chance de le faire compiler bientôt. Je vis dans une branche git spéciale que j'ai nommée cleanup(qui va masterfinalement être fusionnée , bien sûr).

Le problème est que j'ai / nous avons la politique de ne jamais commettre de code non compilateur (idéalement, cela devrait également fonctionner, mais il doit au moins compiler et lier). Donc, tant que je n'ai pas terminé cette tâche énorme, je ne peux rien engager (pour examen ou pour comptabilité).
Ce n'est pas ainsi que j'aime travailler (je pense que la plupart des gens s'engagent au moins une fois par jour).

Qu'est-ce que tu penses? Y a-t-il une solution que j'envisage?
Puis-je dire plus tard à git d'agréger les commits ou quelque chose? Je pourrais vivre avec un commit non compilable tant qu'ils restent dans la cleanupbranche.

modifier

Au sujet de pousser / commettre: je suis conscient que c'est une énorme différence, mais plus tard, il y aura des révisions cassées, quand je fusionnerai mes trucs master. Donc si vous parcourez l'histoire (ou git bisect...) alors les révisions "locales" seront accessibles au monde. Donc, s'engager localement et ne pas pousser n'est pas la meilleure solution, car cela vous causera des problèmes plus tard (lorsque le sujet est fermé et oublié pendant un certain temps).

En bref: les commits locaux seront poussés à terme. L'historique global ne doit pas montrer de validations non compilables.

bitmask
la source
1
Vous pouvez collecter plusieurs validations locales en une seule validation globale.
@ Thorbjørn est-ce la recommandation de Jim ci-dessous, ou un mécanisme différent au sein de Git?
Brian
Je le crois - je ne me souviens pas de la commande exacte.
5
Vous ne refactorisez pas, vous faites quelque chose de plus grand. Après chaque refactor sur une base de code, votre code doit compiler et avoir exactement le même comportement observable. Vous voudrez peut-être changer le titre de votre question pour refléter cela, car ma réaction immédiate a été "Engagez ce que vous avez à chaque fois, tout devrait fonctionner".
David Thornley
1
@bitmask Que diriez-vous d'une réécriture?
Dave Hillier

Réponses:

21

La git merge --squashcommande vous permet de créer un seul commit au-dessus de la branche actuelle dont l'effet est identique à la fusion d'une autre branche. La commande met à jour l'arborescence de travail et met en scène les modifications dans l'index, donc tout ce que vous avez à faire ensuite est de valider:

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

La git rebase -icommande peut également écraser les validations mais nécessite plus de travail.

Jim Huang
la source
14

Une réécriture n'est pas une refactorisation

Je me rends compte que vous êtes intéressé par la façon d'utiliser Git, mais je dirais que vous devriez envisager de changer la façon dont vous effectuez les refactorings plus que la façon dont vous utilisez Git (bien que je pense que Git peut vous aider).

Martin Fowler définit le refactoring comme :

une technique disciplinée pour restructurer un corps de code existant, en modifiant sa structure interne sans changer son comportement externe.

Son cœur est une série de petits comportements préservant les transformations. Chaque transformation (appelée «refactoring») ne fait pas grand chose, mais une séquence de transformations peut produire une restructuration importante. Étant donné que chaque refactoring est petit, il est moins susceptible de mal tourner. Le système continue de fonctionner pleinement après chaque petite refactorisation, ce qui réduit les risques de panne grave d'un système pendant la restructuration.

Si vous appliquez cette méthode, vous pouvez valider (et pousser) régulièrement.

Vous pourriez dire que cela n'est pas pratique et que cela ne fonctionne pas pour quelque chose de grande échelle. C'est là que la méthode Mikado peut vous aider. Vous décomposez un grand refactoring en une série de petits refactorings en créant un graphique de dépendance. La méthode est récursive, essayez d'effectuer votre modification, elle ne casse rien, vérifiez-la, sinon annulez votre modification et notez les conditions préalables. Un par un, vous corrigez ces refactorisations prérequises jusqu'à ce que vous puissiez atteindre votre objectif de refactoring principal.

Git peut vraiment aider cette méthode. Vous pouvez conserver votre succursale locale (cassée). Au fur et à mesure que vous validez (et poussez) les sous-objectifs, vous pouvez rebaseatteindre votre branche d'objectif principale en plus des validations que vous venez de faire, jusqu'à ce qu'il ne soit plus rompu.

Dave Hillier
la source
5

Consultez la page de manuel pour git rebase, en particulier la git rebase -ivariante. Il vous permet de réorganiser, de supprimer ou de compresser un certain nombre de validations de votre historique, ce qui ressemble à ce que vous recherchez. Je l'utilise tout le temps exactement dans la situation que vous décrivez: faire de nombreux petits commits qui ne conviennent pas à la consommation publique, puis les écraser ensemble dans un seul commit de «refactoring» avant de pousser vers le référentiel partagé.


la source
3

Vous utilisez Git, donc s'engager n'implique pas forcément de pousser vos modifications ....

À mon humble avis, et en travaillant avec Git, il est parfaitement bon de valider votre travail, même s'il ne se compile pas ... car, après tout, une fois que vous avez validé vos modifications, personne n'aura le code disponible (jusqu'à ce que vous le poussiez). Bien sûr, avant de le pousser, vous devez vous assurer qu'il fonctionne bien et compiler, afin que les autres puissent récupérer et fusionner vos modifications sans aucun problème.

De plus, vous travaillez sur une branche différente de celle principale. Donc, si vous le souhaitez (et je le recommande), vous ne pousserez jamais votre branche. Une fois que vous avez terminé la refactorisation, il vous suffit de commander la branche principale, de fusionner vos modifications et de pousser la branche principale.

modifier

Dans ce cas, vous pouvez utiliser git cherry-pickou jouer avecgit rebase

Cristian
la source
Une note importante, mais j'ai considéré cela. Veuillez voir ma modification. Merci.
bitmask
Voir ma modification ci-dessus.
Cristian
Je ferais -1 si je pouvais; les commits deviendront disponibles! Les engagements locaux en cours sont excellents, mais ne les repoussez jamais; cela rend le code plus difficile à comprendre, interrompt git bissect et complique l'histoire. Rebasez ou écrasez à la place.
RJFalconer