@Mark Longair przytoczył to w swojej odpowiedzi tutaj , ale chciałbym dodać dodatkowe informacje.
Powiązane i odpowiadanie na pytanie, jak rozbić duże żądanie ściągnięcia (PR), zwłaszcza gdy zgniatanie twoich zatwierdzeń jest niepraktyczne ze względu na jedno lub więcej połączeń mastera z twoją gałęzią funkcji
Moja sytuacja:
zrobiłem duży feature_branchz 30 zatwierdzeniami i otworzyłem pull request (PR) na GitHub, aby go scalić master. Oddział masterzmienił tonę pode mną i otrzymał 200 zatwierdzeń, feature_branchktórych nie miałem. Aby rozwiązać konflikty, zrobiłem git checkout feature_branchi git merge masterscaliłem masterzmiany w moim feature_branch. Zdecydowałem się mergezamiast rebasena najnowszą wersję master, więc musiałem rozwiązywać konflikty tylko raz zamiast potencjalnie 30 razy (raz na każde z moich zatwierdzeń). Nie chciałem najpierw zmiażdżyć moich 30 zatwierdzeń do 1, a następnie bazować na najnowszychmasterponieważ może to wymazać historię komentarzy przeglądu GitHub w PR. Tak więc scaliłem master z moją gałęzią funkcji i rozwiązałem konflikty 1 raz. Wszystko było dobrze. Mój PR był jednak zbyt duży, aby moi koledzy mogli go przejrzeć. Musiałem to rozdzielić. Poszedłem zmiażdżyć moje 30 commits i O NIE! GDZIE ONI SĄ? WSZYSCY ZWIĄZANI Z master200 ostatnich zatwierdzeń teraz, ponieważ połączyłem mastersię z moim feature_branch! CO JA ROBIĘ?
git cherryużycie w przypadku, gdy chcesz spróbować git cherry-pickindywidualnych zatwierdzeń:
git cherry na ratunek (w pewnym sensie)!
Aby zobaczyć wszystkie zatwierdzenia, które są w środku, feature_branchale NIE w nich master, mogę zrobić:
git checkout feature_branch
git cherry master
LUB, mogę sprawdzić zatwierdzenia z DOWOLNEJ gałęzi BEZ upewnienia się, że jestem na feature_branchpierwszym, robiąc w git cherry [upstream_branch] [feature_branch]ten sposób. Ponownie, to sprawdza, które zatwierdzenia SĄ, feature_branchale NIE upstream_branch( masterw tym przypadku):
git cherry master feature_branch
Dodanie -vpokazuje również wiersze tematu wiadomości o zatwierdzeniu:
git cherry -v master
Potok do „word count” „-lines” ( wc -l) zlicza liczbę zatwierdzeń:
git cherry master | wc -l
Możesz porównać tę liczbę z liczbą zatwierdzeń pokazaną w swoim PR GithHub, aby poczuć się lepiej wiedząc, git cherryże naprawdę działa. Możesz także porównać skróty git jeden po drugim i zobaczyć, czy pasują git cherrydo GitHub. Zauważ, że git cherrynie będą się liczyć żadnych zobowiązuje korespondencji seryjnej, gdzie połączyły mastersię feature_branch, ale GitHub woli. Więc jeśli zauważysz niewielką rozbieżność w liczbie, przeszukaj stronę zatwierdzenia PR GitHub w poszukiwaniu słowa „scalanie”, a prawdopodobnie zobaczysz, że to winowajca, który się nie pojawia git cherry. Na przykład: zatwierdzenie zatytułowane „Merge branch 'master' into feature_branch” pojawi się w GitHub PR, ale nie po uruchomieniu git cherry master feature_branch. To jest w porządku i oczekiwane.
Więc teraz mam sposób, aby dowiedzieć się, które różnice mogę chcieć wybrać na świeżą gałąź funkcji, aby podzielić ten różnicę: mogę użyć git cherry master feature_branchlokalnie lub spojrzeć na zatwierdzenia w GitHub PR.
Jak zgniatanie mogłoby pomóc - gdybyśmy tylko mogli zgnieść:
Alternatywą jednak, aby podzielić moją dużą różnicę, jest zgniecenie wszystkich 30 moich zatwierdzeń w jedną, załatanie tego na nową gałąź funkcji, miękkie resetowanie zatwierdzenia poprawki, a następnie użycie git guido dodawania elementów plik po pliku, kawałek po kawałku lub linia po linii. Gdy dostanę jedną podfunkcję, mogę zatwierdzić to, co dodałem, a następnie sprawdzić nową gałąź, dodać więcej, zatwierdzić, sprawdzić nową gałąź itp., Aż moja duża funkcja zostanie podzielona na kilka podfunkcji . Problem polega na tym, że moje 30 zatwierdzeń jest przeplatanych z pozostałymi 200 zatwierdzeniami innych osób z powodu git merge mastermojego feature_branch, więc zmiana bazy jest zatem niepraktyczna, ponieważ musiałbym przesiać przez 230 zatwierdzeń, aby zmienić kolejność i zgnieść moje 30 zatwierdzeń.
Jak użyć pliku poprawki jako znacznie łatwiejszego zamiennika dla zgniatania:
Aby obejść ten problem, wystarczy po prostu uzyskać plik łatki zawierający „odpowiednik squasha” wszystkich 30 moich zatwierdzeń, załatać go na nowy rozwidlenie master(nowej gałęzi podrzędnej) i zacząć od tego w następujący sposób:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Teraz mam moją łatkę z 30 zatwierdzeniami, wszystkie zaaplikowane lokalnie, ale nie na scenie i niezatwierdzone.
Teraz użyj, git guiaby dodać pliki, fragmenty i / lub linie i rozbić swój duży PR lub „różnicę”:
Zauważ, że jeśli nie masz git gui, możesz łatwo zainstalować go w Ubuntu za pomocą sudo apt install git-gui.
Mogę teraz uruchomić git guii rozpocząć dodawanie plików, fragmentów i / lub linii (klikając prawym przyciskiem myszy w programie git GUI) i podzielić gałąź funkcji 30 commit na podgałęzie, jak opisano powyżej, wielokrotnie dodając, zatwierdzając, a następnie rozwidlając nowa gałąź funkcji i powtarzanie tego cyklu, aż wszystkie zmiany zostaną dodane do gałęzi podrzędnej, a moja funkcja z 30 zatwierdzeniami zostanie pomyślnie podzielona na 3 lub 4 funkcje podrzędne. Mogę teraz otworzyć osobny PR dla każdej z tych podfunkcji i mojemu zespołowi będzie łatwiej je przejrzeć.
Bibliografia:
- Utwórz plik poprawki lub pliku różnic z repozytorium git i zastosuj go do innego innego repozytorium git