Jak sprawdzić, których zatwierdzeń w jednej gałęzi nie ma w drugiej?

180

Mam dwie gałęzie develi next. W wersji deweloperskiej mam mniej lub bardziej dużą liczbę zatwierdzeń. Niektóre z zatwierdzeń są niezwykle przydatne next. Dodałem także kilka zatwierdzeń do następnego, które są scalane do devel.

Teraz chciałbym zobaczyć, czego brakuje next, więc mogę szczegółowo przetestować zmiany, zanim je wprowadzę next. Moje pytanie brzmi teraz, jak mogę zobaczyć, które zmiany są w grze, devela nie w następnej?

Sascha Effert
źródło
Twój tytuł jest nieco mylący, ponieważ chcesz porównać końcówki obu gałęzi. a ja przyszedłem tutaj szuka rozwiązania dwa porównania specyficznego (różne) popełnia dwóch oddziałów
thebugfinder
Duplicate ?: stackoverflow.com/questions/1710894/…
reinierpost

Odpowiedzi:

210

Rzadko używane polecenie git cherrypokazuje zatwierdzenia, które nie zostały jeszcze wybrane. Dokumentacja dla git cherryjest tutaj , ale krótko mówiąc, powinieneś być w stanie zrobić:

git checkout devel
git cherry next

... i zobacz wyjście trochę w ten sposób:

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

Commity zaczynające się od +będą tymi, których jeszcze nie wybrałeś next. W tym przypadku wybrałem jak dotąd tylko jedną rewelacyjną zmianę. Możesz chcieć dodać -vparametr do git cherrypolecenia, aby wyświetlał również wiersz tematu każdego zatwierdzenia.

Mark Longair
źródło
Świetnie, tego potrzebowałem. Fajnie byłoby też otrzymać krótki opis testów, ale mogę to napisać.
Sascha Effert
29
Nie musisz git checkout devel, po prostu możesz to zrobić git cherry next devel.
Robin Winslow,
21
„Może chcesz dodać -v ? Wiśnia bez -vjest jak lsbez -la. ; -J
Slipp D. Thompson
1
I nie znałbyś sposobu cherryna zaznaczenie lub wykluczenie równoważnych zatwierdzeń, prawda? cherrywydaje się być poleceniem wodno-kanalizacyjnym, ale nie oferuje wielu opcji. To, w czym obecnie jestem, git cherrydaje mi fałszywe alarmy, ale @ sehe git log --cherry-pickpoprawnie wyklucza wcześniej wybrane / ponownie bazowane zatwierdzenia.
Slipp D. Thompson,
Dokumentacja zawiera konkretny przykład: git-scm.com/docs/git-cherry#_concrete_example
ams
107

Możesz także użyć

git log --left-right --graph --cherry-pick --oneline devel...next

Aby uzyskać listę miłe z rzeczywistych różnych zatwierdzeń nie dzielonych między gałęziami.

Słowem operacyjnym jest --cherry-pick

--cherry-pick

Pomiń każde zatwierdzenie, które wprowadza tę samą zmianę co inne zatwierdzenie po „drugiej stronie”, gdy zbiór zatwierdzeń jest ograniczony symetryczną różnicą. Na przykład, jeśli masz dwie gałęzie, A i B, zwykłym sposobem na wyświetlenie wszystkich zatwierdzeń tylko po jednej stronie jest użycie --left-right, jak w powyższym przykładzie w opisie tej opcji. Pokazuje jednak zatwierdzenia, które zostały wybrane z innej gałęzi (na przykład „trzecie miejsce na b” może zostać wybrane z gałęzi A). Dzięki tej opcji takie pary zatwierdzeń są wykluczane z wyniku.

Aktualizacja Jak wspomniano w komentarzu, dodano najnowsze wersje git --cherry-mark:

--cherry-mark

Podobnie jak --cherry-pick (patrz poniżej), ale równoważne zatwierdzenia oznaczaj znakiem = zamiast je pomijać, a nierównomierne znakami +.

sehe
źródło
1
To nie zadziałało dla mnie. Moja wersja gita nie zna jednej linii, dlatego ją usunąłem. Potem musiałem wymienić rozwój i następny i zadziałało. Bardzo dobrze!
Sascha Effert
@SaschaEffert: nie musiałeś przełączać między rozwijaniem a następnym (zauważ TRZY kropki, a nie DWIE). To powiedziawszy, sprawy mogą wyglądać inaczej, jeśli użyjesz starożytnej wersji git (?), Ale w takim przypadku powinieneś otrzymać błąd analizy obrotów w trzech kropkach.
sehe
2
Dla zabawy ustaliłem, że składnia "..." (różnica symetryczna) została dodana w lipcu 2006 r. , A jej dokumentacja została zaktualizowana w czerwcu 2008 r . Radość z open source!
sehe
1
'gls --first-parent --cherry-mark --left-only develop ... next', gdzie gls jest moim aliasem dziennika git z całym ładnym formatowaniem. zaznaczenie wiśni pokazuje zarówno wybrane, jak i niezebrane zatwierdzenia w fazie rozwoju, ale oznacza je inaczej.
angularsen,
1
dodaj --no-łączy, może lepiej
MervynYang,
51

Możesz spróbować wykonać podzbiory dziennika git:

git log --oneline devel ^next
Bryan Buckley
źródło
4
To jest moim zdaniem najlepsze rozwiązanie (odpowiedź @ sehe pokazuje również zmiany w kolejnych, które nie są w fazie rozwoju - w kontekście PO ich nie ma, ale w moim są - użycie --left-onlybyłoby lepsze). Jednak można to nieco ulepszyć, dodając, --no-mergesaby pominąć wszelkie zatwierdzenia scalające (np. Jeśli funkcja lub gałąź poprawki została scalona (osobno) zarówno do wersji devel, jak i następnej). Ściśle mówiąc, rozwiązywanie konfliktów podczas fuzji może powodować inne różnice, ale zwykle tak nie jest. Tę --no-mergesopcję można z powodzeniem zastosować także do innych odpowiedzi.
Alex Dupuy
27

Co powiesz na

git log next..devel

Wynik jest podobny do odpowiedzi Byrana (inna kolejność zatwierdzeń), ale obie nasze odpowiedzi spowodują zmiany w różnych gałęziach, pokazując raczej, co jest w jednej gałęzi, a nie w drugiej.

justingordon
źródło
4
Możesz również pominąć drugą gałąź, jeśli aktualnie jesteś na tej gałęzi. iegit log next..
jmaxyz
btw „git log next..devel” różni się od „git log devel..next”
Eugene Kaurov
1

Aby uzyskać listę zatwierdzeń, które nie zostały zintegrowane z gałęzią wydania (dalej), możesz użyć:

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

Sprawdź listę git-rev-list, aby uzyskać więcej informacji.

Mihai
źródło
w poleceniu tej odpowiedzi brakuje właściwych gałęzi, o których mowa, tj.next...devel
Alex Dupuy
@AlexDupuy Yah, to dość niedorzeczna odpowiedź. Ponieważ nie jest to również najprostsza odpowiedź i nie wyjaśnia, dlaczego takie podejście byłoby lepiej, jestem -1 -ing go.
Slipp D. Thompson,
-1

@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:

  1. Utwórz plik poprawki lub pliku różnic z repozytorium git i zastosuj go do innego innego repozytorium git
Gabriel Staples
źródło
Musiałem dziś odwołać się do tej odpowiedzi, ale nie mogłem jej szybko znaleźć. Na szczęście miał głos przeciw, który pomógł mi znaleźć to łatwiejsze, więc proste kliknięcie ikony pucharu z nagrodami w prawym górnym rogu ekranu pokazało, gdzie ostatnio straciłem 2 punkty, i kliknięcie tego sprowadziło mnie z powrotem tutaj, gdzie mogę teraz odwołaj się tutaj do mojej własnej odpowiedzi! Miejmy nadzieję, że nie dostaję już głosów przeciw, ale dla przeciwnika, dzięki za usługę, która przypadkowo mi pomogła!
Gabriel Staples