web-dev-qa-db-fra.com

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

J'ai récemment découvert l'option patch de git dans la commande add, et je dois dire que c'est vraiment une fonctionnalité fantastique. J’ai aussi découvert qu’un gros morceau pouvait être divisé en petits mecs en frappant le s clé, ce qui ajoute à la précision du commit. Mais que se passe-t-il si je veux encore plus de précision, si le morceau divisé n'est pas assez petit?

Par exemple, considérons 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_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Comment puis-je ajouter la suppression de commentaire CSS uniquement à la prochaine validation? L'option s n'est plus disponible!

177
greg0ire

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

Cela peut être un peu déroutant, mais si vous soigneusement suivez les instructions de la fenêtre d'édition qui sera ouverte après avoir appuyé sur e alors tout ira bien. Dans le cas que vous avez cité, vous voudriez remplacer le - avec un espace au début de ces lignes:

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

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

225
Mark Longair

Disons votre example.css ressemble à ça:

.classname {
  width: 440px;
}

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

form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
  width: 300px;
}

.another {
  width: 420px;
}

Maintenant, changeons les sélecteurs de style dans le bloc du milieu et pendant que nous y sommes, supprimons un vieux style commenté 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 des modifications dans le contrôle de version pour une revue de code pas à pas et pour que mon équipe et moi puissions facilement rechercher l'historique des validations à la recherche de détails.

La suppression de l'ancien code est logiquement séparée de l'autre changement de sélecteur de style. Nous allons avoir besoin de deux commits distincts, ajoutons donc des morceaux 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_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

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

Oups, on dirait que les changements sont trop proches, alors git les a regroupés.

Même en essayant de diviser en appuyant sur s a le même résultat car la division n'est pas assez granulaire pour que nos changements de précision. Des lignes inchangées sont nécessaires entre les lignes modifiées pour que git puisse scinder automatiquement le patch.

Alors, modifions 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_distributor + 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'objectif:

Comment puis-je ajouter la suppression de commentaire CSS uniquement à la prochaine validation?

Nous voulons scinder cela en deux commits:

  1. Le premier commit implique la suppression de quelques lignes (suppression de commentaires).

    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 qui est suivi en enregistrant les suppressions et les ajouts:

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

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

      Pour supprimer les "-" lignes, créez-les ""

      ... ce qui signifie littéralement remplacer le moins - signes avec un caractère espace.

      Donc, ces trois lignes ...

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

      ... deviendra ( remarque l'espace unique à la première des trois lignes):


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

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

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

      Pour supprimer les lignes '+', supprimez-les.

      ... ce qui signifie littéralement supprimer la ligne entière:

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

      (Bonus: Si vous utilisez vim comme éditeur, appuyez sur dd supprimer une ligne. Nano utilisateurs appuient 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_distributor + 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 commettons.

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 <[email protected]>
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_distributor + label {

Parfait - vous pouvez voir que seules les suppressions ont été incluses dans ce commit atomique. Maintenant, finissons le travail et engageons le reste.

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <[email protected]>
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_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Enfin, vous pouvez voir que la dernière validation n'inclut que les modifications de sélecteur.

51
Jeff Puckett

Si vous pouvez utiliser git gui, cela vous permet d’organiser les modifications ligne par ligne. Malheureusement, je ne sais pas comment le faire depuis la ligne de commande - ni même si c'est possible.

Une autre option que j'ai utilisée par le passé consiste à annuler une partie du changement (garder l'éditeur ouvert), à valider les bits que je veux, à annuler et à enregistrer de nouveau dans l'éditeur. Pas très élégant, mais fait le travail. :)


EDIT (utilisation de git-gui):

Je ne sais pas si le git-gui est le même dans les versions msysgit et linux, je n’ai utilisé que celui de msysgit. Mais en supposant qu'il en soit de même, lorsque vous l'exécutez, il y a quatre volets: le volet en haut à gauche représente les modifications de votre répertoire de travail, les modifications en bas à gauche, les différences en haut, le diff du fichier sélectionné (que ce ou mis en scène), et en bas à droite est pour la description de la commit (je suppose que vous n'en aurez pas besoin). Lorsque vous cliquez sur un fichier dans le coin supérieur droit, 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 "morceau d'étape pour le commit" et "ligne d'étape pour le commit". Vous continuez de sélectionner "ligne d'étape pour la validation" 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 êtes sur le point de valider.

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

9
vhallac

Une façon de le faire est de sauter le morceau, git add tout ce dont vous avez besoin, puis exécutez git add encore. Si c'est le seul morceau, vous pourrez le scinder.

Si l'ordre des commits vous inquiète, utilisez simplement git rebase -i.

1
Abizern