Jak dokonać refaktoryzacji w toku?

23

Mam więc ten duży projekt, który jest przeze mnie refaktoryzowany. Zmieniam wiele rzeczy, więc nie ma szans, aby wkrótce się skompilowało. Mieszkam w specjalnej gałęzi git, którą nazwałem cleanup(do której master, oczywiście, ostatecznie się połączy ).

Problem polega na tym, że ja / my mamy politykę, aby nigdy nie popełniać niekompilującego się kodu (najlepiej powinien również działać, ale musi przynajmniej kompilować i łączyć). Tak więc, dopóki nie skończę tego wielkiego zadania, nie jestem w stanie niczego popełnić (do przeglądu lub do księgowości).
Nie tak lubię pracować (uważam, że większość ludzi angażuje się przynajmniej raz dziennie).

Co myślisz? Czy istnieje rozwiązanie, które przeoczam?
Czy mogę później powiedzieć gitowi, aby agregował zatwierdzenia lub coś takiego? Mógłbym żyć z niepełniącymi kompilacji zobowiązaniami, o ile pozostają w cleanupoddziale.

Edytować

Do tematu pchania / angażowania się: zdaję sobie sprawę, że to ogromna różnica, ale później będą zmiany wersji, kiedy scalę swoje rzeczy master. Jeśli więc przejrzysz historię (lub git bisect...), wówczas wersje „lokalne” będą dostępne dla całego świata. Zatem tylko lokalne popełnianie, a nie pchanie, nie jest najlepszym rozwiązaniem, ponieważ spowoduje później kłopoty (gdy temat zostanie zamknięty i zapomniany przez pewien czas).

W skrócie: lokalne zatwierdzenia zostaną ostatecznie wypchnięte. Historia globalna nie powinna pokazywać zatwierdzeń niekompilujących.

maska ​​bitowa
źródło
1
Możesz zebrać wiele lokalnych zatwierdzeń w jednym globalnym zatwierdzeniu.
@ Thorbjørn to zalecenie Jima poniżej, czy inny mechanizm w Git?
Brian
Tak mi się wydaje - nie pamiętam dokładnego polecenia.
5
Nie refaktoryzujesz, robisz coś większego. Po każdym refaktoryzacji w bazie kodu kod powinien się skompilować i mieć dokładnie takie same obserwowalne zachowanie. Możesz zmienić tytuł pytania, aby to odzwierciedlić, ponieważ moją natychmiastową reakcją było: „Zaangażuj się w to, co masz, kiedy wszystko powinno działać”.
David Thornley,
1
@bitmask Co powiesz na przepisanie?
Dave Hillier

Odpowiedzi:

21

git merge --squashKomenda pozwala stworzyć pojedynczy popełnić na początku bieżącego oddziału, którego efekt jest taki sam jak łączenie inny oddział. Polecenie aktualizuje działające drzewo i ustawia zmiany w indeksie, więc wszystko, co musisz zrobić, to zatwierdzić:

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

git rebase -iKomenda może zgnieść zobowiązuje, ale wymaga więcej pracy.

Jim Huang
źródło
14

Przepisanie nie jest refaktoryzacją

Zdaję sobie sprawę, że jesteś zainteresowany sposobem korzystania z Git, ale twierdzę, że powinieneś rozważyć zmianę sposobu dokonywania refaktoryzacji bardziej niż sposobu korzystania z Git (chociaż myślę, że Git może ci pomóc).

Martin Fowler definiuje refaktoring jako :

zdyscyplinowana technika restrukturyzacji istniejącego kodu, zmieniająca jego wewnętrzną strukturę bez zmiany jego zachowania zewnętrznego.

Jego sercem jest seria drobnych zachowań zachowujących transformacje. Każda transformacja (zwana „refaktoryzacją”) niewiele robi, ale sekwencja transformacji może spowodować znaczną restrukturyzację. Ponieważ każde refaktoryzacja jest niewielka, prawdopodobieństwo niepowodzenia jest mniejsze. System jest w pełni sprawny po każdym małym refaktoryzacji, co zmniejsza ryzyko poważnego uszkodzenia systemu podczas restrukturyzacji.

Jeśli zastosujesz tę metodę, możesz zatwierdzać (i wypychać) regularnie.

Możesz argumentować, że jest to niepraktyczne i że nie działa w przypadku czegoś na dużą skalę. Tutaj może pomóc metoda Mikado . Rozkładasz duże refaktoryzacje na serię małych refaktoryzacji, tworząc wykres zależności. Metoda jest rekurencyjna, spróbuj dokonać zmiany, nic nie złamie, sprawdź, w przeciwnym razie cofnij zmianę i zanotuj warunki wstępne. Jeden po drugim naprawiasz te wstępne refaktoryzacje, aż osiągniesz swój główny cel refaktoryzacji.

Git może naprawdę pomóc w tej metodzie. Możesz zachować swój lokalny (zepsuty) oddział. Kiedy zatwierdzasz (i popychasz) cele cząstkowe, możesz rebaserozwinąć główny cel do celu, który właśnie wykonałeś, dopóki nie zostanie on już złamany.

Dave Hillier
źródło
5

Sprawdź stronę podręcznika dla git rebase, szczególnie jej git rebase -iwariantu. Pozwala na ponowne uporządkowanie, usunięcie lub zgniecenie dowolnej liczby zmian w historii, co brzmi jak to, czego szukasz. Używam go cały czas dokładnie w opisanej sytuacji: tworzenie wielu małych zatwierdzeń, które nie nadają się do publicznej konsumpcji, a następnie zgniatanie ich razem w jednym zatwierdzeniu „refaktoryzującym” przed przekazaniem do wspólnego repozytorium.


źródło
3

Używasz Git, więc zatwierdzanie niekoniecznie oznacza pchanie twoich zmian ...

IMHO i współpracując z Gitem, dobrze jest zlecić swoją pracę, nawet jeśli się nie skompiluje ... ponieważ w końcu po zatwierdzeniu zmian nikt nie będzie miał dostępnego kodu (dopóki go nie wypchniesz). Oczywiście, zanim go wypchniesz, musisz upewnić się, że działa dobrze i kompiluje, aby inni mogli pobrać i scalić twoje zmiany bez żadnych problemów.

Pracujesz także nad gałęzią inną niż główna. Więc jeśli chcesz (i polecam to), nigdy nie będziesz naciskać na swój oddział. Po zakończeniu refaktoryzacji po prostu sprawdź gałąź master, scal zmiany i wciśnij gałąź master.

Edytować

W takim przypadku możesz używać git cherry-picklub bawić sięgit rebase

Cristian
źródło
Ważna uwaga, ale zastanowiłem się nad tym. Proszę zobaczyć moją edycję. Dziękuję Ci.
maska ​​bitowa
Zobacz moją edycję powyżej.
Cristian
Zrobiłbym -1, gdybym mógł; zobowiązania będą dostępne! Lokalne zobowiązania w toku są świetne, ale nigdy ich nie forsuj; utrudnia to zrozumienie kodu, przerywa dzielenie git i komplikuje historię. Rebase lub squash zamiast tego.
RJFalconer