Puis-je diviser un morceau déjà divisé avec git?

J’ai récemment découvert l’option de patch de git pour la commande add , et je dois dire que c’est vraiment une fonctionnalité fantastique. J’ai également découvert qu’un gros morceau pouvait être divisé en petits morceaux en appuyant sur la touche s , ce qui ajoute à la précision de la validation. Mais que faire si je veux encore plus de précision, si le gros morceau n’est pas assez petit?

Par exemple, considérez ce morceau déjà divisé:

 @@ -34,12 +34,7 @@ width: 440px; } -/*#field_teacher_id { - display: block; -} */ - -form.table-form #field_teacher + label, -form.table-form #field_producer_dissortingbutor + label { +#user-register form.table-form .field-type-checkbox label { width: 300px; } 

Comment puis-je append la suppression des commentaires CSS uniquement à la prochaine validation? L’option n’est plus disponible!

Si vous utilisez git add -p et même après avoir fractionné avec s , vous n’avez pas assez de changements, vous pouvez utiliser e pour éditer directement le patch.

Cela peut être un peu déroutant, mais si vous suivez attentivement les instructions de la fenêtre de l’éditeur qui sera ouvert après avoir appuyé sur e, vous irez bien. Dans le cas que vous avez cité, vous voudriez remplacer le - par un espace au début de ces lignes:

 - -form.table-form #field_teacher + label, -form.table-form #field_producer_dissortingbutor + label { 

… et supprimez la ligne suivante, c’est-à-dire celle qui commence par + . Si vous enregistrez et quittez ensuite votre éditeur, seule la suppression du commentaire CSS sera effectuée.

Disons que votre example.css ressemble à ceci:

 .classname { width: 440px; } /*#field_teacher_id { display: block; } */ form.table-form #field_teacher + label, form.table-form #field_producer_dissortingbutor + label { width: 300px; } .another { width: 420px; } 

Modifions maintenant les sélecteurs de style dans le bloc du milieu, et pendant que nous y sums, supprimons un ancien style avec commentaires dont nous n’avons plus besoin.

 .classname { width: 440px; } #user-register form.table-form .field-type-checkbox label { width: 300px; } .another { width: 420px; } 

C’était facile, maintenant engageons-nous. Mais attendez, je veux maintenir une séparation logique entre les changements de contrôle de version pour une révision simple et progressive du code, et pour que mon équipe et moi-même puissions facilement rechercher l’historique des détails.

La suppression de l’ancien code est logiquement distincte de l’autre modification du sélecteur de style. Nous allons avoir besoin de deux commits distincts, alors ajoutons des astuces pour un patch.

 git add --patch 
 diff --git a/example.css b/example.css index 426449d..50ecff9 100644 --- a/example.css +++ b/example.css @@ -2,12 +2,7 @@ width: 440px; } -/*#field_teacher_id { - display: block; -} */ - -form.table-form #field_teacher + label, -form.table-form #field_producer_dissortingbutor + label { +#user-register form.table-form .field-type-checkbox label { width: 300px; } Stage this hunk [y,n,q,a,d,/,e,?]? 

Whoops, on dirait que les changements sont trop proches, donc git les a coincés ensemble.

Même en essayant de le diviser en appuyant sur s, vous obtenez le même résultat car le fractionnement n’est pas suffisamment granulaire pour nos changements de précision. Des lignes inchangées sont nécessaires entre les lignes modifiées pour que git puisse diviser automatiquement le patch.

Donc, modifions-le manuellement en appuyant sur e

 Stage this hunk [y,n,q,a,d,/,e,?]? e 

git ouvrira le patch dans notre éditeur de choix.

 # Manual hunk edit mode -- see bottom for a quick guide @@ -2,12 +2,7 @@ width: 440px; } -/*#field_teacher_id { - display: block; -} */ - -form.table-form #field_teacher + label, -form.table-form #field_producer_dissortingbutor + label { +#user-register form.table-form .field-type-checkbox label { width: 300px; } # --- # To remove '-' lines, make them ' ' lines (context). # To remove '+' lines, delete them. # Lines starting with # will be removed. # # If the patch applies cleanly, the edited hunk will immediately be # marked for staging. If it does not apply cleanly, you will be given # an opportunity to edit again. If all lines of the hunk are removed, # then the edit is aborted and the hunk is left unchanged. 

Passons en revue l’objective:

Comment puis-je append la suppression des commentaires CSS uniquement à la prochaine validation?

Nous voulons diviser ceci en deux commits:

  1. La première validation implique la suppression de certaines lignes (suppression de commentaire).

    Pour supprimer les lignes commentées, laissez-les seules, elles sont déjà marquées pour suivre les suppressions dans le contrôle de version, comme nous le souhaitons.

    -/*#field_teacher_id {
    - display: block;
    -} */

  2. Le deuxième commit est un changement, suivi par l’enregistrement des suppressions et des ajouts:

    • Suppressions (anciennes lignes de sélecteur supprimées)

      Pour conserver les anciennes lignes de sélecteur (ne les supprimez pas lors de cette validation), nous voulons …

      Pour supprimer ‘-‘ lignes, faites-les ”

      … ce qui signifie littéralement remplacer les signes moins - avec un espace personnage.

      Donc ces trois lignes …

      -
      -form.table-form #field_teacher + label,
      -form.table-form #field_producer_dissortingbutor + label {

      … deviendra ( remarquez le seul espace sur la première des 3 lignes):


      form.table-form #field_teacher + label,
      form.table-form #field_producer_dissortingbutor + label {

    • Ajouts (nouvelle ligne de sélecteur ajoutée)

      Pour ne pas faire attention à la nouvelle ligne de sélecteur ajoutée lors de cette validation, nous voulons …

      Pour supprimer les lignes ‘+’, supprimez-les.

      … qui signifie littéralement supprimer toute la ligne:

      +#user-register form.table-form .field-type-checkbox label {

      (Bonus: si vous utilisez Nano comme éditeur, le raccourci clavier pour supprimer une ligne est Ctrl + K )

Votre éditeur devrait ressembler à ceci lorsque vous enregistrez:

 # Manual hunk edit mode -- see bottom for a quick guide @@ -2,12 +2,7 @@ width: 440px; } -/*#field_teacher_id { - display: block; -} */ form.table-form #field_teacher + label, form.table-form #field_producer_dissortingbutor + label { width: 300px; } # --- # To remove '-' lines, make them ' ' lines (context). # To remove '+' lines, delete them. # Lines starting with # will be removed. # # If the patch applies cleanly, the edited hunk will immediately be # marked for staging. If it does not apply cleanly, you will be given # an opportunity to edit again. If all lines of the hunk are removed, # then the edit is aborted and the hunk is left unchanged. 

Maintenant, engageons nous.

 git commit -m "remove old code" 

Et juste pour être sûr, voyons les changements depuis le dernier commit.

 git show 
 commit 572ecbc7beecca495c8965ce54fbccabdd085112 Author: Jeff Puckett  Date: Sat Jun 11 17:06:48 2016 -0500 remove old code diff --git a/example.css b/example.css index 426449d..d04c832 100644 --- a/example.css +++ b/example.css @@ -2,9 +2,6 @@ width: 440px; } -/*#field_teacher_id { - display: block; -} */ form.table-form #field_teacher + label, form.table-form #field_producer_dissortingbutor + label { 

Parfait – vous pouvez voir que seules les suppressions ont été incluses dans cet engagement atomique. Maintenant, finissons le travail et engageons le rest.

 git add . git commit -m "change selectors" git show 
 commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9 Author: Jeff Puckett  Date: Sat Jun 11 17:09:12 2016 -0500 change selectors diff --git a/example.css b/example.css index d04c832..50ecff9 100644 --- a/example.css +++ b/example.css @@ -2,9 +2,7 @@ width: 440px; } - -form.table-form #field_teacher + label, -form.table-form #field_producer_dissortingbutor + label { +#user-register form.table-form .field-type-checkbox label { width: 300px; } 

Enfin, vous pouvez voir que la dernière validation ne comprend que les changements de sélecteur.

Si vous pouvez utiliser git gui, il vous permet de modifier les changements ligne par ligne. Malheureusement, je ne sais pas comment le faire depuis la ligne de commande – ou même si c’est possible.

Une autre option que j’ai utilisée dans le passé est d’annuler une partie de la modification (garder l’éditeur ouvert), valider les bits que je veux, annuler et ré-enregistrer à partir de l’éditeur. Pas très élégant, mais fait le travail. 🙂


EDIT (utilisation de git-gui):

Je ne suis pas sûr que le git-gui soit le même dans les versions msysgit et linux, je n’ai utilisé que celui de msysgit. Mais en supposant que ce soit la même chose, quand vous l’exécutez, il y a quatre volets: le volet supérieur gauche est votre répertoire de travail modifié, le bas à gauche correspond à vos changements d’étapes, le haut à droite est le diff pour le fichier sélectionné ou mis en scène), et en bas à droite est pour la description du commit (je suppose que vous n’en aurez pas besoin). Lorsque vous cliquez sur un fichier en haut à droite, vous verrez le diff. Si vous cliquez avec le bouton droit sur une ligne de diff, vous verrez un menu contextuel. Les deux options à noter sont “stage hunk for commit” et “stage line for commit”. Vous continuez à sélectionner “étape pour commettre” sur les lignes que vous souhaitez valider, et vous avez terminé. Vous pouvez même sélectionner plusieurs lignes et les mettre en scène si vous le souhaitez. Vous pouvez toujours cliquer sur le fichier dans la boîte de transfert pour voir ce que vous tentez de commettre.

En ce qui concerne la validation, vous pouvez utiliser l’outil graphique ou la ligne de commande.

Une façon de le faire est de sauter le morceau, d’ git add tout ce dont vous avez besoin, puis de git add . Si c’est le seul morceau, vous pourrez le séparer.

Si vous vous inquiétez de l’ordre des commits, utilisez simplement git rebase -i .