Czy mogę podzielić już podzielonego przystojniaka z Gitem?

Niedawno odkryłem opcję patch git dla add i muszę powiedzieć, że jest to naprawdę fantastyczna funkcja. Odkryłem również, że duży przystojniak można podzielić na mniejsze, naciskając klawisz s, co zwiększa precyzję commita. Ale co, jeśli chcę jeszcze więcej precyzji, jeśli Split hunk nie jest wystarczająco mały?

Na przykład rozważ to już podzielone:

@@ -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;
 }

Jak mogę dodać usunięcie komentarza CSS tylko do następnego commita ? s opcja nie jest już dostępna!

Author: greg0ire, 2011-06-08

4 answers

Jeśli używasz git add -pi nawet po rozdzieleniu z s, nie masz wystarczająco małej zmiany, możesz użyć e, aby edytować łatkę bezpośrednio.

To może być trochę mylące, ale jeśli ostrożnie. postępuj zgodnie z instrukcjami w oknie edytora, które zostanie otwarte po naciśnięciu e wtedy wszystko będzie dobrze. W przypadku, gdy zacytowałeś, powinieneś zastąpić - spacją na początku tych linii:
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {

... i usuń następujący wiersz, tzn. ten, który zaczyna się od +. Jeśli następnie zapiszesz i zamkniesz edytor, tylko usunięcie komentarza CSS zostanie wystawione.

 189
Author: Mark Longair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-06 22:15:05

Powiedzmy, że Twój example.css wygląda tak:

.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;
}

Teraz zmieńmy selektory stylów w środkowym bloku, a skoro już o tym mowa, Usuń jakiś stary, komentowany styl, którego już nie potrzebujemy.

.classname {
  width: 440px;
}

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

.another {
  width: 420px;
}

To było łatwe, teraz się zaangażujmy. ale czekaj, chcę zachować logiczne oddzielenie zmian w kontroli wersji dla prostego przeglądu kodu, tak aby mój zespół i ja mogli łatwo przeszukiwać historię zmian w poszukiwaniu szczegółów.

Usunięcie starego kodu jest logicznie oddzielona od innych zmian selektora stylu. Będziemy potrzebować dwóch odrębnych commitów, więc dodajmy kilka poprawek.

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,?]?

UPS, wygląda na to, że zmiany są zbyt blisko, więc git je połączył.

Nawet próba podzielenia to przez naciśnięcie s ma taki sam wynik, ponieważ podział nie jest wystarczająco ziarnisty, aby nasze zmiany precyzji. niezmienione linie są wymagane pomiędzy zmienionymi liniami aby git mógł plaster jest automatycznie dzielony.

Więc ręcznie edytuj to przez naciśnięcie e

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

Git otworzy łatkę w wybranym przez nas edytorze.

# 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.

Przyjrzyjmy się celowi:

Jak mogę dodać usunięcie komentarza CSS tylko do następnego commita ?

Chcemy podzielić to na dwa commity:

  1. Pierwszy commit polega na usunięciu niektórych wierszy (usunięcie komentarza).

    Aby usunąć linie komentowane, po prostu zostaw je w spokoju, są już oznaczone, aby śledzić usunięcia w kontroli wersji, tak jak chcemy.

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

  2. Drugi commit to zmiana, która jest śledzona przez rejestrowanie zarówno usunięć, jak i uzupełnień:

    • Deletions (stare linie selektora usunięte)

      Aby zachować stare linie selektora (nie usuwać ich podczas tego commitu), chcemy...

      Aby usunąć" -" lines, make them '"

      ...co dosłownie oznacza zastąpienie znaku minus - spacją charakter.

      Więc te trzy linie...

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

      ...będzie (zauważ pojedynczą spacją na pierwszej z wszystkich 3 linii):


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

    • Dodatki (dodano nową linię selektora)

      Aby nie zwracać uwagi na nową linię selektora dodaną podczas tego commit, chcemy...

      Aby usunąć linie'+', usuń je.

      ...co dosłownie oznacza usunięcie całej linii:

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

      (Bonus: jeśli przypadkiem używasz vim jako swojego redaktora, naciśnij dd aby usunąć wiersz. Nano użytkownicy naciskają Ctrl+K )

Twój redaktor powinien wyglądać tak, gdy Zapisz:

# 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.

A teraz zaangażujmy się.

git commit -m "remove old code"

I dla pewności, zobaczmy zmiany z ostatniego commita.

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 {

Perfect-widać, że tylko delecje zostały uwzględnione w tym atomowym commicie. A teraz dokończmy robotę i poświęćmy resztę.

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;
 }

Wreszcie widać, że ostatni commit zawiera tylko zmiany selektora.

 35
Author: Jeff Puckett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 15:11:00

Jeśli możesz użyć gui git, pozwala to na etapowanie zmian linia po linii. Niestety nie wiem jak to zrobić z linii poleceń-a nawet czy jest to możliwe.

Inną opcją, której używałem w przeszłości, jest cofanie części zmian (zachowywanie otwartego edytora), zatwierdzanie żądanych bitów, cofanie i ponowne zapisywanie z edytora. Niezbyt eleganckie, ale robi swoje. :)


EDIT (Git-GUI usage):

Nie jestem pewien czy Git-gui jest taki sam w msysgit i Linuksie wersje, używałem tylko msysgit jeden. Ale zakładając, że jest to to samo, kiedy go uruchamiasz, są cztery panele: górny lewy panel to zmiany w katalogu roboczym, dolny lewy to zmiany w etapach, górny prawy to różnica dla wybranego pliku (czy to working dir czy stsed), a dolny prawy to opis commita (podejrzewam, że go nie potrzebujesz). Po kliknięciu pliku w prawym górnym rogu zobaczysz różnicę. Jeśli klikniesz prawym przyciskiem myszy na linii różnic, zobaczysz menu kontekstowe. Dwie opcje do uwaga to "stage hunk for commit" i "Stage line for commit". W wierszach, które chcesz zatwierdzić, wybierasz "stage line for commit" i gotowe. Możesz nawet wybrać kilka linii i etapować je, jeśli chcesz. Zawsze możesz kliknąć plik w polu staging, aby zobaczyć, co chcesz zatwierdzić.

Jeśli chodzi o zatwierdzanie, możesz użyć narzędzia gui lub Wiersza poleceń.

 9
Author: vhallac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 10:14:32

Jednym ze sposobów, aby to zrobić, jest pominięcie fragmentu, git add cokolwiek jeszcze potrzebujesz, a następnie uruchom git add ponownie. Jeśli to jedyny kawałek, będziesz mógł go podzielić.

Jeśli martwisz się o kolejność commitów, użyj git rebase -i.

 1
Author: Abizern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-14 18:11:57