Git: Znajdź najnowszego wspólnego przodka dwóch gałęzi

844

Jak znaleźć najnowszego wspólnego przodka dwóch gałęzi Git?

Przetrząsać
źródło
3
Zdefiniować najnowsze: czas rzeczywisty, liczba zatwierdzeń, inne dane?
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
2
Ważne (połączenia krzyżowe): stackoverflow.com/questions/26370185/…
jub0bs
1
@CiroSantilli 新疆 改造 中心 996ICU 六四 事件 jest taki sam w każdej metryki, prawda?
JakowL,
@YakovL Nie wierzę ze względu na rozgałęzienie i ponieważ możesz ustawić dowolne daty zatwierdzenia na swoich obiektach zatwierdzenia: sama data prawdopodobnie nie jest tym, czego chcesz.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
1
@CiroSantilli 新疆 改造 中心 996ICU 六四 事件 Wydaje mi się, że może być inaczej tylko wtedy, gdy przed ostatnim wspólnym zatwierdzeniem w drzewie istnieje zatwierdzenie, które ma starszy znacznik czasu. Czy możesz podać mniej banalny przykład?
JakowL,

Odpowiedzi:

1019

Szukasz git merge-base. Stosowanie:

$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2
CB Bailey
źródło
85
Zauważ, że znajduje to najnowszego wspólnego przodka ... który moim zdaniem jest tym, czego chce pytający, więc daj +1. Po prostu to zauważam, na wypadek, gdyby ktoś tu przyszedł i próbował znaleźć najstarszego wspólnego przodka (tak jak ja) - dla którego zobacz także: stackoverflow.com/questions/1527234/…
lindes
16
@funroll: Lub skrót do tego:git log master...HEAD
CB Bailey,
17
@lindes czy najstarszy wspólny przodek nie byłby początkowym zatwierdzeniem?
Thorbjørn Ravn Andersen
8
@ ThorbjørnRavnAndersen, tak, przypuszczam, że tak ... Trudność opisu wynika z faktu, że git używa Directed Acyclic Graph, a jednak często uważa się go za drzewo, którym technicznie nie jest. Aby być bardziej ostrożnym w moim sformułowaniu, mówiłem o przypadku, w którym chcesz, aby rodzic pierwszego wystąpienia „gałęzi” rozdzielił się ... ponieważ mogą mieć wiele punktów, w których ponownie się scalili i rozdzielili, to jest to „najstarszy” z nich, ale nie tak naprawdę najstarszy przodek, który jest (myślę) zawsze początkowym zatwierdzeniem.
Lindes
5
Chociaż pytanie to dotyczy wyłącznie znalezienia wspólnego przodka dwóch gałęzi, każdy, kto chce wspólnego przodka trzech lub więcej gałęzi, powinien zauważyć, że musi przekazać --octopusflagę, aby uzyskać właściwy wynik. Oczywistym-ale-nie tak git merge-base branch1 branch2 branch3daje popełnić, ale, jak to opisano w dziale dyskusji w Dokumentach, to nie jest koniecznie wspólny przodek wszystkich trzech oddziałów.
Mark Amery
46

git diff master...feature

pokazuje wszystkie nowe zatwierdzenia twojej bieżącej gałęzi funkcji (prawdopodobnie wielokrotnego zatwierdzenia).

man git-diff dokumenty, które:

git diff A...B

jest taki sam jak:

git diff $(git merge-base A B) B

ale ...łatwiej jest pisać i zapamiętywać.

Jak wspomniał Dave , szczególny przypadek HEADmożna pominąć. Więc:

git diff master...HEAD

jest taki sam jak:

git diff master...

co wystarczy, jeśli obecna gałąź to feature.

Na koniec pamiętaj, że kolejność ma znaczenie! Robićgit diff feature...master spowoduje wyświetlenie zmian, które masternie są włączone feature.

Chciałbym, żeby więcej komend git obsługiwało tę składnię, ale nie sądzę, żeby to zrobiły. A niektóre mają nawet inną semantykę ...: Jakie są różnice między podwójnymi kropkami „..” a potrójnymi kropkami „...” w zakresach zatwierdzania Git?

Ciro Santilli
źródło
8
Lub tylko git diff master...w szczególnym przypadku różnicHEAD
Dave
„...” nie działało dla mnie w PowerShell, zabawne, że działało w konsoli git, być może repo nie zostało ukończone, git diff $ (git merge-base AB) B zrobiło, a ponieważ jestem trochę nowy w git Byłem trochę sceptyczny, że może to połączyć gałęzie :)
Moiz Ahmed
1
łał. całkiem niesamowite. a jeśli żądany oddział nie istnieje w lokalnym repozytorium, ponieważ nigdy go nie sprawdziłeś, możesz po prostu zrobićgit diff origin/branchname...
Mark Ch
25

Jak wspomniano w poprzedniej odpowiedzi, git merge-basedziała:

$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

ale jeśli myfeaturejest to bieżąca gałąź, co jest powszechne, możesz użyć use --fork-point:

$ git merge-base --fork-point develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

Ten argument działa tylko w wystarczająco aktualnych wersjach git. Niestety nie zawsze to działa i nie jest jasne, dlaczego. Proszę odnieść się do ograniczeń zanotowanych na końcu tej odpowiedzi .


Aby uzyskać pełne informacje o zatwierdzeniu, rozważ:

$ git log -1 $(git merge-base --fork-point develop) 
Acumenus
źródło
Mam git version 2.14.1.windows.1. Uruchamianie git merge-base --fork-point branch2z gałęzią (z własnymi zatwierdzeniami), która, jak wiem , rozwidliła się z bieżącej gałęzi, nie daje żadnego rezultatu, podczas gdy git merge-base branch1 branch2poprawnie pokazuje punkt rozwidlenia. Co może być problemem?
ADTC
@ ADTC Checkout, branch2a następnie uruchom git merge-base --fork-point branch1.
Acumenus
@ ADTC Użyj graficznej przeglądarki zatwierdzania, np. gitkItp., Aby zobaczyć, jak wygląda drzewo. Może dostaniesz swoją odpowiedź.
Acumenus
Nie widzę nic dziwnego w drzewie, gdy oglądam je graficznie. Potrafię prześledzić ścieżki i znaleźć wspólnego przodka, który pasuje do wyniku git merge-base branch1 branch2. Ale dziwne jest to, że --fork-pointnic nie daje. Czy potwierdziłeś, że działa on zgodnie z przeznaczeniem?
ADTC
1
Dostaję to samo, co @ ADTC. Polecenie „git log -1 $ (git merge-base --fork-point anotherBranch)” nie wyświetla żadnych wyników przy użyciu git w wersji 2.16.2.windows.1.
masinger
10

Dzięki gitkniemu możesz wyświetlić dwie gałęzie graficznie:

gitk branch1 branch2

A potem łatwo jest znaleźć wspólnego przodka w historii dwóch gałęzi.

Martin G.
źródło
6
W każdym przypadku nie wszystko można zrobić wizualnie. Istnieją powody, dla których może zaistnieć potrzeba zautomatyzowanej automatyzacji.
ADTC