Jaka jest korzyść z dwuetapowego procesu zatwierdzania git (etapowego)?

174

Uczę się git i zauważyłem, że ma on dwuetapowy proces zatwierdzania:

  1. git add <files>
  2. git commit

Pierwszy krok polega na wprowadzeniu poprawek do tak zwanego „obszaru przejściowego” lub „indeksu”.

Interesuje mnie, dlaczego podjęto tę decyzję projektową i jakie są jej zalety?

Jako użytkownik git robisz to, czy po prostu używasz git commit -a?

Pytam o to, ponieważ pochodzę z bzr (Bazaar), który nie ma tej funkcji.

thomasrutter
źródło
3
+1 za zapytanie. Używam Tortoise SVN, który ma takie samo podejście i nigdy nie rozumiem dlaczego.
DPD,
3
Miejsce inscenizacji nie jest takie niezwykłe. Odpowiednikiem, powiedzmy, TFS byłoby zaznaczenie lub odznaczenie pola obok pliku przed zalogowaniem. Tylko sprawdzone pliki zostaną zatwierdzone. Różnica w przypadku Git polega na tym, że jeśli go używasz git add -p, możesz wybrać zatwierdzenie jednego fragmentu pliku bez popełniania kolejnego fragmentu tego samego pliku .
Kyralessa
Odkryłem, że ten link podsumowuje większość odpowiedzi tutaj i dodaje kilka innych przypadków użycia, aby uzasadnić potrzebę inscenizacji.
Veverke
2
Odpowiedzi na to pytanie już
udzieliłem
1
Nie zapomnij git statusi prawdopodobnie git push.
Mimo

Odpowiedzi:

83

Podziel pracę na osobne zatwierdzenia. Prawdopodobnie wiele razy otworzyłeś plik, aby napisać poprawkę jednowierszową, ale jednocześnie zauważyłeś, że formatowanie było niepoprawne, część dokumentacji można ulepszyć lub inną niepowiązaną poprawkę. W przypadku innych RCS musisz to zapisać lub zapisać w pamięci, dokończyć poprawkę, którą przyszedłeś, zatwierdzić, a następnie powrócić, aby naprawić inne rzeczy (lub stworzyć zatwierdzenie typu ball-of-mud z niepowiązanymi rzeczami) . Dzięki Git naprawiasz to wszystko naraz, a etap + zatwierdzasz pojedynczą linię osobno za pomocą git add -ilub git-gui.

Nie psuj wersji. Pracujesz nad skomplikowaną modyfikacją. Więc próbujesz różnych rzeczy, z których niektóre działają lepiej niż inne, inne, które psują. Za pomocą Git możesz robić rzeczy, gdy modyfikacja poprawia sytuację, i checkout(lub poprawiać trochę więcej), gdy modyfikacja nie działa. Nie będziesz musiał polegać na funkcji cofania edytora, możesz checkoutcałe repo zamiast po prostu plik po pliku i wszelkie błędy na poziomie pliku (takie jak usunięcie pliku, który nie został zatwierdzony lub zapisanie + zamknięcie po zła modyfikacja) nie prowadzi do utraty dużej ilości pracy.

l0b0
źródło
3
Pochodzący z DVCS (bzr), który nie ma tej funkcji, który brzmi bardzo podobnie do tego, co obecnie osiągam dzięki kombinacji liberalnego użycia buforów „cofania” mojego edytora, polecenia „przywróć <plik>” i selektywnych zatwierdzeń („ commit <plik> "). Wygląda na to, że ta funkcja git może być bardziej metodyczna.
thomasrutter
1
W odniesieniu do „innych RCS” niekoniecznie jest to prawdą. W rzeczywistości możesz osiągnąć te same funkcje w Mercurial za pomocą łatek .
Lucio Paiva,
1
@ l0b0, o twoim drugim punkcie. Jeśli było tylko jednoetapowe zatwierdzenie, mógłbyś właśnie zatwierdzić zmiany (których używasz z git add) bezpośrednio jako zatwierdzenie. Jeśli dowiedziałeś się, że zrobiłeś coś złego, po prostu usunąłeś zatwierdzenie i wróciłeś do tego, gdzie byłeś, zanim dokonałeś zatwierdzenia. Dzięki koncepcji inscenizacji nie tylko to robisz, ale zwiększasz złożoność?
alpha_989,
Twoja pierwsza uwaga ma sens, chociaż do tej pory jej nie wykorzystałem. Teoretycznie dlaczego nie możesz zrobić czegoś git add -iz zatwierdzeniem na jednym etapie? Wystarczy wybrać kilka plików (lub wierszy w plikach) związanych z pojedynczą funkcją i wykonać zatwierdzenie. Potem wrócisz i zrobisz drugie zatwierdzenie związane z inną funkcją ..
alpha_989
@ thomasrutter, Z twojego oświadczenia wynika, że ​​sugerujesz, że obszar przejściowy tworzy „ręczne punkty cofania”. W VIM z permanentnym cofaniem możesz bardzo niezawodnie uzyskać nieograniczoną historię. Jest to również śledzone automatycznie w git-branchsposób typowy ( jovicailic.org/2017/04/vim-persistent-undo ). Ponadto historia cofania jest automatycznie śledzona za każdym razem, gdy przejdziesz do trybu normalnego. Zmniejsza to więc twoje psychiczne obciążenie związane z tworzeniem „ręcznych punktów cofania”. Dlaczego używanie edytorów „cofania” buforów nie jest tak metodyczne?
alpha_989,
65

Jedną z korzyści dla mnie jest możliwość stopniowego „dodawania” plików. Przed zatwierdzeniem sprawdzam każdy plik. Po przejrzeniu pliku dodaję go. Kiedy ja git statuslub git diff, git pokazuje mi tylko te pliki, które zostały zmodyfikowane i nie zostały jeszcze dodane. Po przejrzeniu wszystkich plików i dodaniu ich mogę zatwierdzić.

Więc tak, uważam, że miejsce postoju jest bardzo pomocne.

I nie, nigdy nie używam git commit -a. Jednak często używam git add -u. W ten sposób mogę nadal wizualizować, co należy popełnić.

David
źródło
2
Dokładnie. Zaletą jest znacznie dokładniejsza kontrola dokładnie tego, co robisz.
Josh K
co się stanie, jeśli wykonasz jeden plik wiele razy? czy „scala” się w strefie przeciwności?
m4l490n
21

Korzyści są dość proste: daje pełną kontrolę nad tym, które pliki chcesz zatwierdzić. W tym przypadku możesz użyć, git add -paby kontrolować, które wiersze chcesz zatwierdzić.

Rein Henrichs
źródło
2
Zawsze zastanawiałem się, jak to zrobić. Chciałbym, żeby był plik .gitignorelines, abyś mógł wprowadzić lokalne zmiany w poszczególnych liniach, które mogłyby przetrwać zatwierdzenia i pozostać nienaruszone.
alex grey
3
@ReinHenrichs, pomyśl o plikach konfiguracyjnych, które wymagają zmiany przez każdego programistę.
Ian
1
@Ian Czyli część pliku zmienia się rzadko i jest udostępniana, a część pliku zmienia się często, w niekompatybilny sposób, i nie jest udostępniana? Wspieranie tej fałszywej więzi zdecydowanie brzmi jak funkcja antyfunkcyjna.
Rein Henrichs
1
@ReinHenrichs, tak i jest bardzo powszechne, gdy plik zawiera nazwę serwera bazy danych, a każdy programista ma własną bazę danych.
Ian
4
@Ian Twój problem naprawdę istnieje, ponieważ masz plik, który ma być konfiguracją aplikacji, zawiera także konfigurację specyficzną dla komputera / urządzenia. Wszystkie znane mi systemy konfiguracji pozwalają na podzielenie tego na wiele plików. Na przykład masz swój, app.confktóry zawiera rzeczy, które chcesz udostępnić, a następnie ten, db.confktóry właśnie umieściłeś na liście .gitignore. Problem rozwiązany. Jeśli używasz czegoś zastrzeżonego, powinieneś naprawdę spróbować uzyskać coś tak prostego. Lub przeprowadź go przez preprocesor w zdarzeniu przed kompilacją. Wiele rozwiązań.
Aidiakapi
1

Jedną z korzyści, które lubię, jest możliwość dokonania części zmiany. Tj. Za pomocą git add -e. Nie wykonuję tak często, jak powinienem, a polecenie git add -e pozwala mi w pewnym stopniu rozwikłać moje zmiany.

leed25d
źródło