Comment (et pourquoi!) Garder votre historique de commit Git propre

Les commits sont lun des éléments clés dun dépôt Git, et plus encore, le message de validation est un journal de vie pour le référentiel. Au fur et à mesure que le projet / référentiel évolue avec le temps (ajout de nouvelles fonctionnalités, correction de bugs, refactorisation de larchitecture), les messages de commit sont lendroit où lon peut voir ce qui a été changé et comment. Il est donc important que ces messages reflètent le changement sous-jacent dune manière courte et précise.

Pourquoi un historique de commit Git significatif est important

Que fait Git commit? Messages de commit Git sont les empreintes digitales que vous laissez sur le code que vous touchez. Tout code que vous validez aujourdhui, dans un an lorsque vous examinerez le même changement; vous seriez reconnaissant pour un message de validation clair et significatif que vous avez écrit, et il sera également simplifiez la vie de vos collègues développeurs. Lorsque les commits sont isolés en fonction du contexte, un bogue qui a été introduit par un certain commit devient plus rapide à trouver, et plus il est facile de revenir sur le commit qui a causé le bogue en premier lieu.

Lorsque nous travaillons sur un grand projet, nous avons souvent affaire à un grand nombre de pièces mobiles qui sont mises à jour, ajoutées ou supprimées. Sassurer que les messages de validation sont conservés dans de tels cas peut être délicat, en particulier lorsque le développement sétend sur plusieurs jours, semaines, voire des mois. Donc, pour simplifier leffort de maintien de la concis e historique des commit, cet article utilisera certaines des situations courantes auxquelles un développeur pourrait être confronté en travaillant sur un dépôt Git.

  • Situation 1: je dois changer le commit le plus récent
  • Situation 2: je dois modifier un commit spécifique
  • Situation 3: je dois ajouter, supprimer ou combiner des commits
  • Situation 4: mon historique de commit ne fonctionne pas sens, jai besoin dun nouveau départ!

Mais avant de plonger, voyons rapidement à quoi ressemble un workflow de développement typique dans notre hypothétique application Ruby.

Remarque: Cet article suppose que vous connaissez les bases de Git, le fonctionnement des branches, comment ajouter des modifications non validées dune branche à létape et comment valider les modifications. Si vous nêtes pas sûr de ces flux, notre documentation est un excellent point de départ.

Une journée dans la vie

Ici, nous travaillons sur un petit projet Ruby on Rails où nous besoin dajouter une vue de navigation sur la page daccueil et qui implique la mise à jour et lajout de plusieurs fichiers. Voici une description étape par étape de lensemble du flux:

  • Vous commencez à travailler sur une fonctionnalité avec la mise à jour dun fichier ; appelons-le application_controller.rb
  • Cette fonctionnalité nécessite que vous mettiez également à jour une vue: index.html.haml
  • Vous avez ajouté un partiel qui est utilisé dans la page dindex: _navigation.html.haml
  • Les styles de la page doivent également être mis à jour pour refléter le partiel que nous avons ajouté: styles.css.scss
  • La fonctionnalité est maintenant prête avec les modifications souhaitées, il est temps également de mettre à jour les tests; les fichiers à mettre à jour sont les suivants:
    • application_controller_spec.rb
    • navigation_spec.rb
  • Les tests sont mis à jour et passent comme prévu, il est maintenant temps de valider les changements!

Puisque tous les fichiers appartiennent à des territoires différents de larchitecture, nous nous engageons les changements isolés les uns des autres pour sassurer que chaque commit représente un certain contexte et est effectué dans un certain ordre. Je préfère généralement le backend – > ordre du frontend où la plupart des changements centrés sur le backend sont validés en premier, suivi par la couche intermédiaire, puis par les changements centrés sur le frontend dans les validations de la liste Git. >

Maintenant que nos modifications sont validées, nous créons une demande de fusion avec la branche. Une fois que vous avez ouvert la demande de fusion, elle est généralement examinée par votre pair avant que les modifications ne soient fusionnées dans la branche repo « s master. Voyons maintenant quelles sont les différentes situations auxquelles nous pourrions nous retrouver pendant la révision du code.

Situation 1: je dois modifier le commit le plus récent

Imaginez un cas où le réviseur a regardé styles.css.scss et a suggéré un changement. Dans un tel cas, il est très simple de faire le changement car les changements de feuille de style font partie du dernier commit sur votre branche. Voici comment nous pouvons gérer cela;

  • Vous apportez directement les modifications nécessaires à styles.css.scss dans votre branche.
  • Une fois vous avez terminé les modifications, ajoutez ces modifications à létape; exécutez git add styles.css.scss.
  • Une fois les modifications effectuées, nous devons ajouter ces modifications à notre dernier commit; exécutez git commit --amend.
    • Répartition de la commande: ici, nous « demandons à la commande git commit de modifier les modifications présentes dans étape vers le commit le plus récent.
  • Cela ouvrira votre dernier commit dans votre éditeur de texte défini par Git qui a le message de commit Add styles for navigation.
  • Puisque nous navons mis à jour que la déclaration CSS, nous navons pas besoin de modifier le message de validation.À ce stade, vous pouvez simplement enregistrer et quitter léditeur de texte que Git a ouvert pour vous et vos modifications seront reflétées dans le commit.

Puisque vous avez modifié un commit existant, ces modifications sont nécessaires pour être forcé à votre dépôt distant en utilisant git push --force-with-lease <remote_name> <branch_name>. Cette commande remplacera le commit Add styles for navigation sur le dépôt distant avec le commit mis à jour que nous venons de faire dans notre dépôt local.

Une chose à garder à lesprit lorsque vous forcez le push des branches est que si vous travaillez sur la même branche avec plusieurs personnes, la poussée forcée peut causer des problèmes aux autres utilisateurs lorsquils essaient de pousser normalement leurs modifications sur une branche distante qui a une nouvelle force de validation. Par conséquent, utilisez cette fonctionnalité à bon escient. Vous pouvez en savoir plus sur les options de poussée de Git ici.

Situation 2: je dois changer un commit spécifique

Dans la situation précédente, le correctif était plutôt simple car nous devions modifier seulement notre dernier commit Git, mais imaginez si le réviseur suggérait de changer quelque chose dans _navigation.html.haml. Dans ce cas, cest le deuxième commit à partir du haut, donc le changer ne sera pas aussi direct que dans la première situation. Voyons comment nous pouvons gérer cela:

Chaque fois quun commit est fait dans une branche, il est identifié par une chaîne de hachage SHA1 unique. Considérez-le comme un identifiant unique qui sépare un commit dun autre. Vous pouvez afficher tous les commits, ainsi que leurs hachages SHA1 dans une branche en exécutant git log. Avec cela, vous verriez une sortie qui ressemble un peu à la suivante, où les commits les plus récents sont en haut;

Cest là que la commande git rebase entre en jeu. Chaque fois que nous souhaitons éditer un commit spécifique avec git rebase, nous devons dabord rebaser notre branche en replaçant HEAD au point juste avant le commit que nous souhaitons éditer. Dans notre cas, nous devons changer le commit qui lit Page Navigation View.

Ici, notez le hachage de commit qui est juste avant le commit que nous voulons modifier; copiez le hachage et effectuez les étapes suivantes:

  • Rebase la branche pour la déplacer vers la validation avant notre validation cible; exécuter git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • Répartition des commandes: ici, nous « re exécutons Git » s rebase commande avec mode interactif avec hachage SHA1 fourni comme commit à rebase.
  • Cela exécutera la commande rebase pour Git en mode interactif et ouvrira votre éditeur de texte affichant tous vos commits qui sont venus après le commit sur lequel vous avez rebasé . Cela ressemblera un peu à ceci:

Remarquez comment chaque commit a un mot pick devant lui et dans le contenu ci-dessous, il y a tous les mots-clés possibles que nous pouvons utiliser. Puisque nous voulons éditer un commit, nous devons changer pick 4155df1cdc7 Page Navigation View en edit 4155df1cdc7 Page Navigation View. Enregistrez les modifications et quittez léditeur.

Maintenant, votre branche est rebasée au point dans le temps juste avant le commit que vous avez effectué qui incluait _navigation.html.haml. Ouvrez le fichier et effectuez les modifications souhaitées conformément aux commentaires de lexamen. Une fois que vous avez terminé les modifications, mettez-les en scène en exécutant git add _navigation.html.haml.

Puisque nous avons mis en scène les modifications, il est temps de déplacer la branche HEAD vers le commit que nous avions initialement (tout en incluant les nouvelles modifications que nous avons ajoutées), exécutez git rebase --continue, cela ouvrira votre éditeur par défaut dans le terminal et vous montrera le message de commit que nous avons édité lors du rebase; Page Navigation View. Vous pouvez modifier ce message si vous le souhaitez, mais nous le laisserons tel quel pour le moment, alors enregistrez et quittez léditeur. À ce stade, Git rejouera tous les commits qui a suivi après le commit que vous venez de modifier et maintenant la branche HEAD est de retour au commit supérieur que nous avions à lorigine, et il inclut également les nouvelles modifications que vous avez apportées à lun des commits.

Puisque nous avons à nouveau modifié un commit qui « est déjà présent dans le dépôt distant, nous devons forcer à nouveau pousser cette branche en utilisant git push --force-with-lease <remote_name> <branch_name>.

Situation 3 : Je dois ajouter, supprimer ou combiner des commits

Une situation courante est celle où vous « avez fait plusieurs commits juste pour corriger quelque chose précédemment commis. » Maintenant, réduisons-les autant que possible, en les combinant avec les commits originaux.

Tout ce que vous avez à faire est de démarrer le rebase interactif comme vous le feriez dans les autres scénarios.

Maintenant, imaginez que vous voulez combiner tous ces correctifs dans c22a3fa0c5c Render navigation partial. Il vous suffit de:

  1. Déplacez les correctifs vers le haut afin quils soient juste en dessous du commit que vous souhaitez conserver à la fin.
  2. Remplacez pick par squash ou fixup pour chacun des correctifs.

Remarque: squash garde les messages de validation dans la description. fixup oubliera les messages de validation des correctifs et conservera loriginal.

Vous vous retrouverez avec quelque chose comme ceci:

Enregistrez les modifications, quittez léditeur , et tu as fini! Voici lhistorique qui en résulte:

Comme auparavant, il ne vous reste plus quà git push --force-with-lease <remote_name> <branch_name> et les changements sont en place.

Si vous souhaitez supprimer complètement le commit de la branche, au lieu de squash ou fixup, écrivez simplement drop ou supprimez simplement cette ligne.

Évitez les conflits

Pour éviter les conflits, assurez-vous que la validation vous engage « vous déplacez vers le haut de la chronologie ne touchez pas aux mêmes fichiers touchés par les commits laissés après eux.

Conseil de pro : Corrections rapides

Si vous savez exactement quel commit vous voulez corriger, lors de la validation, vous n’avez pas à gaspiller des cycles cérébraux en pensant à de bons noms temporaires pour «Fix 1», «Fix 2»,…, « Fix 42 ».

Étape 1: Rencontrez --fixup

Après avoir mis en scène les modifications en corrigeant tout ce qui doit être corrigé, juste Git valide tous les changements comme ceci:

(Notez quil sagit du hachage du commit c22a3fa0c5c Render navigation partial)

Cela générera ce message de commit: fixup! Render navigation partial.

Étape 2: Et le compagnon --autosquash

Rebase interactif facile. Vous pouvez demander à git de placer automatiquement les fixup au bon endroit.

git rebase -i 4155df1cdc7 --autosquash

Lhistorique sera affiché comme ceci:

Prêt pour vous examinez et continuez.

Si vous « vous sentez aventureux, vous pouvez faire un rebase non interactif git rebase --autosquash, mais seulement si vous aimez vivre dangereusement, car vous » ll Je nai pas la possibilité de revoir les squashes en cours de création avant quils ne soient appliqués.

Situation 4: Mon historique de commit Git na pas de sens, jai besoin dun nouveau départ!

Si nous « Si vous travaillez sur une fonctionnalité importante, il est courant davoir plusieurs correctifs et modifications de commentaires de révision qui sont fréquemment validés. Au lieu de constamment rebaser la branche, nous pouvons laisser le nettoyage des commits jusquà la fin du développement.

Cest là que la création de fichiers de correctifs est extrêmement pratique. En fait, les fichiers de correctifs étaient le principal moyen de partager du code par e-mail tout en collaborant sur de grands projets open source avant que les services basés sur Git comme GitLab ne soient disponibles pour les développeurs. Imaginez que vous ayez une de ces branches (par exemple; add-page-navigation) où il y a des tonnes de commits qui ne traduisent pas clairement les changements sous-jacents. Voici comment créer un fichier de correctif pour tous les changements que vous avez faits dans cette branche:

  • La première étape pour créer le fichier de patch est de sassurer que votre branche a toutes les modifications présentes de master branche et na pas de conflit avec le même.
  • Vous pouvez exécuter git rebase master ou git merge master pendant que vous « re-vérifié dans la branche add-page-navigation pour obtenir toutes les modifications de master vers votre branche.
  • Maintenant, créez le fichier correctif ; run git diff master add-page-navigation > ~/add_page_navigation.patch.
    • Répartition des commandes: ici, nous utilisons la fonction de diff de Git et demandons un diff entre master branche et add-page-navigation branche, et redirige la sortie (via le symbole >) vers un fichier nommé add_page_navigation.patch chez nous er répertoire personnel (généralement ~/ dans les systèmes dexploitation * nix).
  • Vous pouvez spécifier le chemin que vous souhaitez conserver ce fichier dans et le nom et lextension du fichier peuvent être tout ce que vous voulez.
  • Une fois la commande exécutée et que vous ne voyez aucune erreur, le fichier de correctif est généré.
  • Maintenant checkout master branche; exécutez git checkout master.
  • Supprimez la branche add-page-navigation du dépôt local; exécutez git branch -D add-page-navigation. Noubliez pas que nous avons déjà des modifications de cette branche dans un fichier de patch créé.
  • Maintenant, créez une nouvelle branche avec le même nom (pendant que master est extrait); lancez git checkout -b add-page-navigation.
  • À ce stade, il sagit dune nouvelle branche et ne comporte aucune de vos modifications.
  • Enfin, appliquez vos modifications depuis le fichier de correctif; git apply ~/add_page_navigation.patch.
  • Ici, toutes vos modifications sont appliquées dans une branche et elles apparaîtront comme non validées, comme si toutes vos modifications là où cest fait, mais aucune des modifications na été réellement validée dans la branche.
  • Vous pouvez maintenant continuer et valider des fichiers individuels ou des fichiers regroupés par zone dimpact dans lordre souhaité avec des messages de validation concis.

Comme dans les situations précédentes, nous avons fondamentalement modifié toute la branche, il est donc temps de forcer le push!

Conclusion

Bien que nous ayons couvert les situations les plus courantes et les plus élémentaires qui surviennent dans un flux de travail quotidien avec Git, la réécriture de lhistorique de Git est un vaste sujet et à mesure que vous vous familiarisez avec ci-dessus, vous pouvez apprendre des concepts plus avancés sur le sujet dans la documentation officielle de Git. Happy git « ing!

Photo de pan xiaozhen sur Unsplash

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *