Dzielenie postępu kodowania na znaczące zatwierdzenia bez nadmiernego obciążenia

23

Podczas pracy nad poprawką lub funkcją czasami natknęłam się na inne drobne problemy, które można poprawić w locie w ciągu kilku sekund. Kiedy robię je natychmiast, a następnie zatwierdzam gotową funkcję / poprawkę, zatwierdzenie zawiera więcej niż jedną rzecz. Na przykład "add feature X and code clean up"lub "fix bug X and improved logging". Lepiej byłoby podzielić to na dwa commity. W przypadku gdy dwie zmiany nastąpiły w tym samym pliku, nie mogę po prostu dodać jednego pliku, zatwierdzić, dodać drugi, a następnie ponownie zatwierdzić. Widzę więc następujące trzy opcje:

  1. Celowo pomijaj niepowiązane rzeczy podczas pracy nad czymś.

  2. Skopiuj plik z dwiema zmianami, przywróć go, dołącz jedną zmianę, zatwierdź, dołącz drugą zmianę, zatwierdź ponownie.

  3. Nie zmieniaj małych niepowiązanych rzeczy, ale dodaj je do listy rzeczy do zrobienia i zrób to później.

Nie bardzo lubię wszystkie trzy opcje z następujących powodów:

  1. Jakość kodu może ucierpieć, jeśli nie rozwiąże się drobnych problemów. I czuję się źle, jeśli świadomie tracę szansę na poprawę bez większego wysiłku.

  2. Zwiększa to pracę ręczną i jest podatne na błędy.

  3. Jest to dobre w przypadku niezbyt małych todos, ale dodawanie drobnego elementu do listy todo i odwiedzanie go później często trwa znacznie dłużej niż natychmiastowe naprawianie.

Jak radzisz sobie z takimi sytuacjami?

Tobias Hermann
źródło
7
Czy git nie pozwala na sprawdzanie pojedynczych wierszy zamiast całych plików?
Kilian Foth
Używam git add -pdużo, co pozwala mi interaktywnie wybierać części plików, które chcę zatwierdzić. Jeśli czyszczenie jest wystarczająco oddzielne, łatwo to zrobić. Jeśli separacja jest trudniejsza, zatwierdzam stan w gałęzi tymczasowej, a następnie ręcznie dodam zmiany do mojej faktycznej gałęzi, dopóki nie będzie żadnych różnic w gałęzi tymczasowej. Wymaga to dużo więcej pracy, ale pozwala mi sprawdzić, czy każde zatwierdzenie działa samodzielnie.
amon
1
@gnat: oczywiście nie dupe. OP nie pyta o prawidłowy rozmiar zatwierdzenia - chce robić małe zatwierdzenia. Po prostu szuka bardziej skutecznego sposobu, aby to zrobić.
Doc Brown
2
@gnat: najlepsza odpowiedź nic nie mówi (!) o tym, jak obsługiwać różne zmiany w jednym pliku i jak podzielić je na osobne zatwierdzenia.
Doc Brown

Odpowiedzi:

11

Myślę, że musisz być bardzo pragmatyczny podczas programowania. Nawet jeśli możliwe jest sformułowanie idealnego schematu, przepływu pracy lub implementacji, czasem wystarczy po prostu wykonać pracę. Oto co robię:

Używam zdolności gita do przygotowywania / zatwierdzania poszczególnych porcji i linii, gdy tylko jest to możliwe, do oddzielania niepowiązanych zmian, chociaż czasami może to powodować przejściowe problemy, jeśli separacja nie została wykonana poprawnie. Ponieważ zmiany będą sąsiadować, zwykle nie stanowi to dużego problemu, chyba że masz zasady testowania każdej pojedynczej zmiany w potoku CI.

Kiedy niezwiązana zmiana jest zbyt duża, umieszczam ją na liście rzeczy do zrobienia i zwykle biorę ją zaraz po tym, jak jest świeża w mojej głowie. Czasami może minąć dzień lub dwa, zanim wrócę do niego, zależy to od mojego obecnego zadania i toku myślenia. Czasami po prostu umieszczam TODO: obok szkodliwego kodu, jeśli nie mam gotowego dobrego rozwiązania.

Zdarza się, że rozdzielenie rzeczy jest po prostu niepraktyczne i dokonam drobnej korekty wraz z oryginalnym dziełem.

Rozmiar zmiany jest zwykle czynnikiem decydującym, kiedy wybieram trasę do przejścia, ale ostatecznie wolałbym raczej zignorować regułę przepływu pracy, niż zostawić za sobą zapach.

axl
źródło
7

Mój edytor ma wtyczkę , dzięki której umieszczanie poszczególnych części pliku jest wyjątkowo łatwe. Wyobrażam sobie, że inne edytory programistyczne mogą mieć podobne wtyczki, chociaż zawsze możesz to zrobić ręcznie git add --patch | -p. Następnie używam git stash, aby zapisać moje inne zmiany, aby przetestować moje małe zatwierdzenie w izolacji. Potem po popełnieniu robię tylko git stash popi kontynuuję od miejsca, w którym skończyłem. Właśnie do tego zostały zaprojektowane te funkcje.

Karl Bielefeldt
źródło
2

Sztuką jest nie wprowadzać zmian, chyba że jesteś przygotowany do włożenia tyle wysiłku, na ile zmiana zasługuje.

To, co zazwyczaj robię, to dodawanie do listy rzeczy do zrobienia (czasami przez dodanie komentarza do kodu, czasami w notatce na zgłoszeniu błędu, a czasem przez aktualizację kodu w oddzielnej gałęzi, wiedząc, że poprawka zostanie ostatecznie scalona). Jeśli nie ma zgłoszenia błędu dotyczącego zestawienia drobnych problemów z jakością, podnoszę jeden specjalnie do tego, więc ja i wszyscy inni możemy powiedzieć, jaki był powód tych zmian kodu po scaleniu oddziału. Nigdy nie robię po prostu zmian dla zabawy, wszystko uzyskuje identyfikowalność, więc moi koledzy nie będą zbyt zaskoczeni zmianami kodu.

Krótko mówiąc - tak, przeocz je podczas kodowania. Jeśli dodajesz funkcję, nie kusz się, aby dodać 2 funkcje, bez względu na to, jak małe. Jeśli ktoś zdecyduje się cofnąć twoją gałąź (ponieważ powiedzmy, że twoja funkcja nie jest już wymagana), stracisz również wszystkie swoje mini-poprawki. Podobnie nie chcesz wprowadzać niewielkiej „poprawki” w jakimś krytycznym kodzie, który działał poprawnie.

gbjbaanb
źródło
1
PO nie zasugerował połączenia dwóch zmian w jednym zatwierdzeniu, wręcz przeciwnie.
Doc Brown
1
@DocBrown sugeruje jednak zmieszanie 2 zmian w jedną gałąź, co może być kłopotliwe, aby później usunąć, choć oczywiście nie tak bałagan, jak 2 zmiany w jednym zatwierdzeniu.
gbjbaanb
Ok, rozumiem, co masz na myśli w ostatnim akapicie.
Doc Brown
2

TODOOpcją, z której często korzystam, jest dodawanie komentarzy, a następnie wykonywanie wielu częstych „częściowych” zatwierdzeń, za pomocą git add --patchwyboru odpowiednich części pliku. Następnie użyj, git rebase --interactiveaby zmienić kolejność i scalić częściowe zatwierdzenia w ostateczną funkcję i zatwierdzenia napraw przed ich wypchnięciem.

Utrzymuje to główne zatwierdzenie w czystości i nadal pozwala natychmiast naprawić inne znalezione problemy.

W git rebasetym kontekście nie ma nic złego, ponieważ przepisujesz tylko lokalne zatwierdzenia.

Tomek
źródło
1

Inną opcją może być „git stash” bieżących zmian. Przepływ pracy wyglądałby następująco:

  1. Rozpocznij wprowadzanie zmian związanych z funkcją A
  2. Odkryj błąd B i zdecyduj się go natychmiast naprawić
  3. Wykonaj z wiersza poleceń w repozytorium git stash (po którym kod powróci do stanu, w jakim był przed rozpoczęciem pracy nad funkcją A )
  4. W tym momencie niezatwierdzone zmiany dla funkcji A są przechowywane w „skrytce”
  5. Wprowadź niezbędne zmiany w kodzie, aby naprawić błąd B i dokonaj zmiany z powrotem w repozytorium
  6. Z linii poleceń uruchom git stash pop
  7. Twoje niezatwierdzone zmiany dla funkcji A są teraz usuwane ze skrytki i przywracane do kodu w toku wraz z (już zatwierdzoną) poprawką dla błędu B
Zach
źródło
Czy mógłbyś szerzej rozwinąć sposób działania tego przepływu pracy? Jaki jest stan repozytorium w każdym punkcie? Czy mógłbyś poprowadzić kogoś przez proces używania skrytki git?
0

Oddzielnie wprowadzaj (i zatwierdzaj) zmiany związane z poprawką. W Git Extensions jest to niezwykle łatwe. Z linii poleceń myślę, że musisz to zrobić git add -p.

Andrew Coleson
źródło