Korzystając z Git, pokaż wszystkie zatwierdzenia, które są w jednej gałęzi, ale nie w innych gałęzi

465

Mam stary oddział, który chciałbym usunąć. Jednak zanim to zrobię, chcę sprawdzić, czy wszystkie zatwierdzenia dokonane w tej gałęzi zostały w pewnym momencie scalone z inną gałęzią. Dlatego chciałbym zobaczyć wszystkie zatwierdzenia dokonane w mojej bieżącej gałęzi, które nie zostały zastosowane w żadnej innej gałęzi [lub, jeśli nie jest to możliwe bez skryptu, w jaki sposób można zobaczyć wszystkie zatwierdzenia w jednej gałęzi, które nie zostały zastosowane do innego podanego oddziału?].

sircolinton
źródło
Aby wyświetlić listę brakujących zatwierdzeń między dwoma oddziałami, możesz użyć Compare-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert
Powiązane: stackoverflow.com/q/1419623/1959808
Ioannis Filippidis

Odpowiedzi:

320

Prawdopodobnie po prostu chcesz

git branch --contains branch-to-delete

Spowoduje to wyświetlenie wszystkich gałęzi, które zawierają zatwierdzenia z „gałęzi do usunięcia”. Jeśli zgłasza więcej niż tylko „odgałęzienie do usunięcia”, oddział został scalony.

Twoje alternatywy to tak naprawdę tylko lista poprawek składni. np. git log one-branch..another-branchpokazuje wszystko, co one-branchmusi mieć wszystko another-branch.

Możesz być także zainteresowany, git show-branchaby zobaczyć, co jest gdzie.

Dustin
źródło
2
+1. Zobacz także stackoverflow.com/questions/850607/…
VonC
1
Wiersz „Jeśli coś zgłasza, gałąź się scaliła” może zostać źle zinterpretowany: jeśli git branch --contains some-branchtylko zwraca some-branch, to coś zwraca, ale nie został scalony.
Zamieszanie,
5
Zauważ, że git log foo..barpokażą commits między najnowszym paskiem a najnowszym foo, ale nie brakuje innych commits z dalszej przeszłości. Aby zobaczyć wszystko w barach, ale nie w foo, powinieneś użyć rozwiązania @ jimmyorr.
Paul A Jungwirth,
555

Aby zobaczyć listę zatwierdzeń dla jednej gałęzi, ale nie innej, użyj git log:

git log --no-merges oldbranch ^newbranch

... to znaczy, pokaż dzienniki zatwierdzeń dla wszystkich zatwierdzeń na oldbranch, które nie są na newbranch. Możesz wymienić wiele oddziałów do włączenia i wyłączenia, np

git log  --no-merges oldbranch1 oldbranch2 ^newbranch1 ^newbranch2

Uwaga: w systemie Windows ^jest klawiszem Escape, więc należy go zmienić przy pomocy innego ^:

git log --no-merges oldbranch ^^newbranch
jimmyorr
źródło
2
Zauważyłem, że szuka zatwierdzeń porównania git dwóch gałęzi.
Użytkownik
25
Właśnie tego szukałem. Ale użycie tutaj ^jako prefiksu mnie zdezorientowało. W tym kontekście oznacza to wykluczenie tej gałęzi. Użycie ^sufiksu byłoby względnym odniesieniem do nadrzędnego zatwierdzenia tej gałęzi.
Joe Flynn
4
bardzo przydatne dzięki. Ciekawe, dlaczego flaga --no-scala się? Z pewnością ktoś chce zobaczyć te zobowiązania?
Max MacLeod
2
Czy chciałbyś użyć z tym gitk? Po prostu użyj gitk oldbranch ^newbranch --no-merges(Testowane z git 1.8.1.1). Uwaga dodatkowa: dla mnie ^oznacza włączenie zatwierdzenia HEAD oddziału newbranch.
Matt
2
@NazariiGudzovatyi - tak, jest: „-cherry-pick”. Istnieje ogromna liczba opcji logowania na stronie dokumentacji
romeara
91

Aby wyświetlić zatwierdzenia w oldbranch, ale nie w newbranch:

git log newbranch..oldbranch

Aby pokazać różnicę według tych zatwierdzeń (zauważ, że są trzy kropki):

git diff newbranch...oldbranch

Oto dokument z ilustracją diagramu https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges

Xuan
źródło
Zobacz komentarz Paula A Jungwirtha powyżej. Wygląda na to, że przegapisz jakieś stare zobowiązania?
Nędzna Zmienna
2
Nie jestem pewien, co oznaczają stare zobowiązania. Podwójne kropki w zasadzie prosi Gita o rozwiązanie szeregu zatwierdzeń, które są osiągalne z jednego zatwierdzenia, ale nie są osiągalne z drugiego. Oto dokument z ilustracją digram git-scm.com/book/en/v2/…
Xuan
1
i jeśli mamy na albo newbranchczy oldbranchmożemy zrobić git log ..oldbranchlub git log newbranch..odpowiednio
YakovL
Rozwiązanie jimmyorra nie działało dla mnie, ale to zrobiło to dzięki dwóm kropkom między nazwami sędziów ... Użyłem również --cherry-pickopcji, aby ukryć zatwierdzenia, które są obecne w obu gałęziach, ale mają inny skrót, ponieważ zostały wybrane z jednej gałęzi do drugiej.
flawyte
58

Dla tych, którzy wciąż szukają prostej odpowiedzi, sprawdź git cherry . Porównuje rzeczywiste różnice zamiast zatwierdzania skrótów. Oznacza to, że obsługuje zmiany, które zostały wybrane lub zmienione.

Najpierw sprawdź gałąź, którą chcesz usunąć:

git checkout [branch-to-delete]

następnie użyj git cherry, aby porównać go z główną gałęzią programistyczną:

git cherry -v master

Przykładowe dane wyjściowe:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
- 85867e38712de930864c5edb7856342e1358b2a0 Yet another message

Uwaga: -vFlaga ma zawierać komunikat zatwierdzenia wraz z skrótem SHA.

Linie z przodu „+” znajdują się w gałęzi do usunięcia, ale nie w gałęzi głównej. Ci z „-” z przodu mają równoważne zatwierdzenie w master.

Dla JUST zatwierdzeń, które nie są w master, połącz cherry pick z grep:

git cherry -v master | grep "^\+"

Przykładowe dane wyjściowe:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
Tim S.
źródło
Próbowałem tego, ale nadal raportuje, że istnieje wiele zatwierdzeń w fb (gałąź funkcji), których nie ma w mb (gałąź główna). Jednak jeśli jestem na fb i robię git diff mb, nie widzę różnic. Użyłem rebase i wszystko zgniotłem. Jestem prawie pewien, że właśnie dlatego, ale chcę mieć pewność. Jeśli tak jest, to w miarę możliwości uniknę zgniatania; Jestem w „obozie informacyjnym bez zguby”. Zastanawiam się, czy byłoby możliwe dodanie trybu wyświetlania dziennika, który może wyświetlać scalenia tak, jakby były bazami, aby utrzymać czystość historii, a jednocześnie nie utracić żadnych informacji.
Outis Von Nemo
1
Nie jestem pewien dokładnego scenariusza tutaj, ale jeśli zmiażdżyłeś wiele zatwierdzeń razem w jednym i porównujesz to do innej gałęzi, w której zatwierdzenia są osobne, to na pewno nie zadziała. W takim przypadku możesz po prostu użyć diffnarzędzia uniksowego do porównania różnych plików. Lub możesz utworzyć tymczasową gałąź i zmiażdżyć wszystkie zmiany w tym, co zrobiłeś z oryginalną gałęzią, a następnie użyć tego, co moim zdaniem będzie działać.
Tim S
50

Chociaż niektóre z zamieszczonych tutaj odpowiedzi pomogą ci znaleźć to, czego szukasz, poniższe polecenie podrzędne oddziału git jest bardziej odpowiednim rozwiązaniem dla twojego zadania.

- scalony służy do znalezienia wszystkich gałęzi, które można bezpiecznie usunąć, ponieważ gałęzie te są w pełni zawarte przez HEAD.

Podczas gdy w masterjednym można uruchomić polecenie wyliczenia gałęzi, można je bezpiecznie usunąć, na przykład:

git branch --merged
  develop
  fpg_download_links
* master
  master_merge_static

# Delete local and remote tracking branches you don't want
git branch -d fpg_download_links
git push origin :fpg_download_links
git branch -d master_merge_static
git push origin :master_merge_static

# There is also a flag to specify remote branches in the output
git branch --remotes --merged
Freddie
źródło
16

Odpowiedź Jimmyorra nie działa w systemie Windows. pomaga użyć --notzamiast tego ^tak:

git log oldbranch --not newbranch --no-merges
sebeck
źródło
4
Zgadza się, +1. Zauważ jednak, że ^jest obsługiwane w systemie Windows, ale musi być uciekł, która w systemie Windows, to (kolejny) ^: git log oldbranch ^^newbranch --no-merges.
VCC,
3
Mówiąc dokładniej, działa w systemie Windows w konsoli Powershell, ale wymaga dodatkowego „^” w CMD.
Rod
7

Jeśli jest to jedna (pojedyncza) gałąź, którą należy sprawdzić, na przykład jeśli chcesz, aby gałąź „B” została całkowicie scalona z gałęzią „A”, możesz po prostu wykonać następujące czynności:

$ git checkout A
$ git branch -d B

git branch -d <branchname> ma pewność, że „Oddział musi zostać w pełni połączony w HEAD”.

Uwaga : powoduje to usunięcie gałęzi B, jeśli zostanie scalona z A.

Jakub Narębski
źródło
3

Możesz użyć tego prostego skryptu, aby zobaczyć zatwierdzenia, które nie zostały scalone

#!/bin/bash
# Show commits that exists only on branch and not in current
# Usage:
#   git branch-notmerge <branchname>
#
# Setup git alias
#   git config alias.branch-notmerge [path/to/this/script]
grep -Fvf <(git log --pretty=format:'%H - %s') <(git log $1 --pretty=format:'%H - %s')

Możesz także użyć narzędzia git-wtf , które wyświetli stan gałęzi

manRo
źródło
0

Wystarczy użyć, git cherryaby wybrać wszystkie zatwierdzenia w oddziale, newFeature42na przykład:

git cherry -v master newFeature42

Mꜳltus
źródło
-5

Zacznij tworzyć żądanie ściągnięcia za pośrednictwem usługi hostingowej git, której używasz. Jeśli gałąź została całkowicie scalona z gałęzią podstawową, nie będzie można utworzyć nowego PR.

Nie musisz właściwie wysyłać żądania ściągnięcia, po prostu użyj pierwszego kroku, w którym wybierasz gałęzie.

Na przykład na GitHub:

Nie ma nic do porównania

Nie można utworzyć PR dla oddziałów, które zostały scalone.

To nie używa git w wierszu poleceń, ale często uważam, że pomocne jest używanie innych narzędzi, które masz do dyspozycji, z wyraźnym modelem mentalnym, zamiast próby zapamiętania innego tajemnego polecenia git.

pkamb
źródło