Czy mogę podzielić już podzielony przystojniak za pomocą git?


204

Niedawno odkryłem patchopcję git dla tego addpolecenia i muszę powiedzieć, że to naprawdę fantastyczna funkcja. Odkryłem również, że duży kawałek można podzielić na mniejsze kawałki, naciskając sklawisz, co zwiększa precyzję zatwierdzenia. Ale co, jeśli chcę jeszcze większej precyzji, jeśli podzielony przystojniak nie jest wystarczająco mały?

Weźmy na przykład ten podzielony przystojniak:

@@ -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 zatwierdzenia? Ta sopcja nie jest już dostępna!

Odpowiedzi:


253

Jeśli używasz, git add -pa nawet po podzieleniu s, nie masz wystarczająco małej zmiany, możesz ebezpośrednio edytować łatkę.

Może to być nieco mylące, ale jeśli dokładnie wykonasz instrukcje w oknie edytora, które zostanie otwarte po naciśnięciu e, wszystko będzie w porządku. W przypadku, który zacytowałeś, chciałbyś zastąpić -spacją na początku tych wierszy:

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

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


9
Fajne rozwiązanie! Widziałem to, ale źle zrozumiałem ... Myślałem, że zmiany zostaną również usunięte z działającego drzewa.
greg0ire

7
Rzeczywiście, nie jest to bardzo oczywiste z tekstu pomocy. Właściwie to często go używam, ponieważ myślę, że git naprawdę zachęca cię, aby każde zatwierdzenie było jak najbardziej precyzyjne i piękne :)
Mark Longair

27
Zauważ, że naprawdę musisz go zastąpić spacją . Próbowałem tego, sądząc, że mogę po prostu usunąć -postacie, a Git narzekał, że moja łatka nie ma zastosowania.
Ryan Lundy,

3
Zgaduję, że powodem, dla którego usuwasz linie za pomocą „-” i zamieniasz „+” na spację, jest to, że tworzysz łatkę, w której te linie za pomocą „-” zostały już usunięte, a linie za pomocą „ + zostały już dodane (w oku łatki). Lub inny sposób patrzenia na to, czy faktycznie wykonujesz akcję reprezentowaną przez te znaki (-, +) (dodawanie linii lub usuwanie jej). Tylko pozostałe wiersze z „-s” i „+” są zapisywane jako zmiany, a reszta to „tylko jak plik”.
atomictom

3
@Filype: Obawiam się, że nie wiem, dlaczego tak się stało - jeśli działałeś git add -pi edytowałeś przystojniak e, powinno to wpływać tylko na to, co jest ustawione, a nie na działające drzewo.
Mark Longair

60

Powiedzmy, że Twój example.csswygląd wygląda następująco:

.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 gdy już nad tym pracujemy, usuńmy niektóre skomentowane style, których 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 popełnijmy. Ale poczekaj, chcę zachować logiczną separację zmian w kontroli wersji dla prostej krokowej weryfikacji kodu, aby mój zespół i ja mogli z łatwością przeszukiwać historię zatwierdzeń w celu znalezienia szczegółów.

Usunięcie starego kodu jest logicznie oddzielone od innej zmiany selektora stylu. Będziemy potrzebować dwóch różnych zatwierdzeń, więc dodajmy przystawki do poprawki.

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 podzielił je na części.

Nawet próba podzielenia go przez naciśnięcie sdaje ten sam wynik, ponieważ podział nie jest wystarczająco szczegółowy, aby wprowadzić zmiany precyzji. Niezmienne linie są wymagane między zmienionymi liniami, aby git mógł automatycznie podzielić łatkę.

Więc niech Ręcznie edycję naciskające

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

git otworzy łatkę w naszym wybranym 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 zatwierdzenia?

Chcemy podzielić to na dwa zatwierdzenia:

  1. Pierwsze zatwierdzenie obejmuje usunięcie niektórych wierszy (usunięcie komentarza).

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

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

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

    • Usunięcia (stare linie wyboru zostały usunięte)

      Aby zachować stare linie wyboru (nie usuwaj ich podczas tego zatwierdzania), chcemy ...

      Aby usunąć linie „-”, wykonaj je ”

      ... co dosłownie oznacza zastąpienie -znaków minus znakiem spacji .

      Te trzy linie ...

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

      ... stanie się ( zwróć uwagę na pojedynczą spację na pierwszym z wszystkich 3 wierszy):


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

    • Dodatki (dodano nową linię wyboru)

      Aby nie zwracać uwagi na nową linię selektora dodaną podczas tego zatwierdzenia, 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 używasz vima jako edytora, naciśnij, ddaby usunąć linię. Użytkownicy Nano naciśnij Ctrl+ K)

Twój edytor powinien wyglądać tak po zapisaniu:

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

Teraz popełnijmy.

git commit -m "remove old code"

I dla pewności zobaczmy zmiany od ostatniego zatwierdzenia.

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <jeff@jeffpuckett.com>
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 {

Idealnie - widać, że tylko usunięcia zostały zawarte w tym zatwierdzeniu atomowym. Teraz zakończmy zadanie i dokonaj reszty.

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <jeff@jeffpuckett.com>
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 możesz zobaczyć, że ostatnie zatwierdzenie zawiera tylko zmiany selektora.


1
Bonus # 2: Jeśli używasz VIM jako edytora, musisz dwukrotnie nacisnąć „d” na klawiaturze, aby usunąć wiersz: D
Alexxus

3
Ponadto, zamiast usuwania dodanych wierszy nie chcesz dodawać, można wymienić +z #. Rezultat jest taki sam, ale może nie czujesz się komfortowo z usunięciem (i nie możesz cofnąć) lub chcesz poeksperymentować przed zapisaniem.
ob-ivan

I to dlatego, że vim jest r #ponad plus xD
aksh1618

Celem jest „Jak mogę dodać usunięcie komentarza CSS tylko do następnego zatwierdzenia?”, Ale kroki są naprawdę mylące co do jego osiągnięcia. (Chcemy „dodać” tylko „usunięcie” kilku wierszy do następnego zatwierdzenia.) Zatem samo usunięcie lub dodanie jest bardzo mylące. Stwierdzenie, co zostało osiągnięte na każdym etapie, pomoże wyjaśnić.
ahnbizcad

9

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

Inną opcją, z której korzystałem w przeszłości, jest wycofanie części zmiany (pozostawienie edytora otwartego), zatwierdzenie żądanych bitów, cofnięcie i ponowne zapisanie z edytora. Niezbyt elegancki, ale wykonuje pracę. :)


EDYCJA (użycie git-gui):

Nie jestem pewien, czy git-gui jest taki sam w wersjach msysgit i Linux, użyłem tylko jednego msysgit. Ale zakładając, że jest tak samo, po uruchomieniu są cztery panele: górny lewy panel to zmiany katalogu roboczego, dolny lewy to zmiany etapów, prawy górny to diff dla wybranego pliku (czy to reż. lub wyreżyserowane), a dolny prawy to opis zatwierdzenia (podejrzewam, że nie będziesz go potrzebować). Po kliknięciu pliku w prawym górnym rogu zobaczysz różnicę. Jeśli klikniesz prawym przyciskiem linię różnicową, zobaczysz menu kontekstowe. Dwie opcje do odnotowania to „stage hunk for commit” i „stage stage for commit”. Ciągle wybierasz „linię etapu do zatwierdzenia” w liniach, które chcesz zatwierdzić, i gotowe. Możesz nawet wybrać kilka linii i ustawić je, jeśli chcesz.

Jeśli chodzi o zatwierdzanie, możesz użyć narzędzia GUI lub wiersza polecenia.


Twoja druga propozycja jest dość oczywista, ale pierwsza jest interesująca, czy mógłbyś podać więcej szczegółów? Zainstalowałem, git-guiale nie mam pojęcia, jak osiągnąć to, co opisujesz.
greg0ire

czołgi dużo! To działa! Byłem nawet w stanie wybrać linie, które chciałem ustawić na scenie i zindeksować je jednym kliknięciem.
greg0ire

0

Jednym ze sposobów na to jest pominięcie fragmentu, git addcokolwiek jeszcze potrzebujesz, a następnie git addponowne uruchomienie . Jeśli jest to jedyny fragment, będziesz mógł go podzielić.

Jeśli martwisz się kolejnością zatwierdzeń, po prostu użyj git rebase -i.


Właśnie tego próbowałem, a przystojniak w moim pytaniu jest jedynym, gdy git add -pznów biegnę , ale nie mogę go podzielić. Rozumiem: Stage this hunk [y,n,q,a,d,/,e,?]?a następnie naciśnięcie „s” drukuje pomoc. BTW, miałeś na myśli add patch, nie patch add? Czy jest git patchwtyczka, którą powinienem zainstalować?
greg0ire

Czy popełniłeś zainscenizowane przystojniaki, zanim ponownie to uruchomiłeś? I nie, Mercurial ma wtyczki, Git nie.
Abizern

Nie, nie zrobiłem tego, chcę, aby były w tym samym zatwierdzeniu (ale myślę, że jeśli twoje rozwiązanie działa, mogę użyć --amend, aby to osiągnąć). Dam temu szansę.
greg0ire

Jak powiedziała moja odpowiedź → git rebase -i. Który jest bardziej elastyczny niżcommit --amend
Abizern
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.