Zeigen Sie mit Git alle Commits an, die sich in einem Zweig befinden, aber nicht in den anderen.

465

Ich habe einen alten Zweig, den ich löschen möchte. Zuvor möchte ich jedoch überprüfen, ob alle für diesen Zweig vorgenommenen Festschreibungen zu einem bestimmten Zeitpunkt in einem anderen Zweig zusammengeführt wurden. Daher möchte ich alle Commits für meinen aktuellen Zweig sehen, die nicht auf einen anderen Zweig angewendet wurden [oder, wenn dies ohne einige Skripte nicht möglich ist, wie sieht man alle Commits in einem Zweig, die nicht angewendet wurden? zu einem anderen gegebenen Zweig?].

Sircolinton
quelle
Um fehlende Commits zwischen zwei Zweigen aufzulisten, können Sie compare-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert
Siehe auch
Ioannis Filippidis

Antworten:

321

Sie wollen wahrscheinlich nur

git branch --contains branch-to-delete

Dadurch werden alle Zweige aufgelistet, die die Commits von "Branch-to-Delete" enthalten. Wenn mehr als nur "Branch-to-Delete" gemeldet wird, wurde der Zweig zusammengeführt.

Ihre Alternativen sind wirklich nur Rev-List-Syntax-Dinge. zB git log one-branch..another-branchzeigt alles was one-branchman haben muss alles another-branchhat.

Sie könnten auch interessiert sein git show-branch, um zu sehen, was wo ist.

Dustin
quelle
1
Die Zeile "Wenn etwas gemeldet wird, wurde der Zweig zusammengeführt" kann falsch interpretiert werden: Wenn git branch --contains some-branchnur zurückgegeben wird some-branch, wird etwas zurückgegeben, aber es wurde nicht zusammengeführt.
Verwirrung
5
Beachten Sie, dass git log foo..bardie Commits zwischen dem neuesten und dem neuesten Balken angezeigt werden, jedoch keine anderen Commits, die in der Vergangenheit fehlen. Um alles in der Leiste zu sehen, aber nicht in foo, sollten Sie die Lösung von @ jimmyorr verwenden.
Paul A Jungwirth
556

Verwenden Sie git log, um eine Liste der Commits in einem Zweig anzuzeigen, jedoch nicht in einem anderen:

git log --no-merges oldbranch ^newbranch

... das heißt, Commit-Protokolle für alle Commits auf oldbranch anzeigen, die nicht auf newbranch sind. Sie können mehrere Zweige zum Ein- und Ausschließen auflisten, z

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

Hinweis: Unter Windows ^ist ein Escape-Schlüssel vorhanden, daher muss er mit einem anderen Escape-Schlüssel maskiert werden ^:

git log --no-merges oldbranch ^^newbranch
Jimmyorr
quelle
2
Ich fand es auf der Suche nach Git-Vergleichs-Commits von zwei Zweigen.
Benutzer
25
Genau das habe ich gesucht. Aber die Verwendung ^als Präfix hier hat mich verwirrt. In diesem Zusammenhang bedeutet dies, diesen Zweig auszuschließen. Die Verwendung ^als Suffix wäre ein relativer Verweis auf das übergeordnete Commit dieses Zweigs.
Joe Flynn
4
sehr nützlich danke. Ich bin gespannt, warum das Flag --no-merges notwendig ist. Sicher will man diese Commits auch sehen?
Max MacLeod
2
Möchten Sie gitk damit verwenden? Einfach verwenden gitk oldbranch ^newbranch --no-merges(Getestet mit Git 1.8.1.1). Randnotiz ^bedeutet für mich inklusive HEAD Commit of Branch newbranch.
Matt
2
@ NazariiGudzovatyi - ja, es gibt: "-cherry-pick". Es gibt eine RIESIGE Anzahl von Optionen für die Anmeldung auf der Dokumentationsseite
Romeara
91

So zeigen Sie die Commits in Oldbranch, aber nicht in Newbranch:

git log newbranch..oldbranch

Um den Unterschied durch diese Commits anzuzeigen (beachten Sie, dass es drei Punkte gibt):

git diff newbranch...oldbranch

Hier ist das Dokument mit einer Diagrammillustration https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges

Xuan
quelle
Siehe den Kommentar von Paul A Jungwirth oben. Es scheint, dass dies einige alte Verpflichtungen verpassen wird?
Elende Variable
2
Ich bin mir nicht sicher, was alte Commits bedeuten. Die doppelten Punkte fordern Git grundsätzlich auf, eine Reihe von Commits aufzulösen, die von einem Commit aus erreichbar sind, von einem anderen jedoch nicht erreichbar sind. Hier ist das Dokument mit einer Digramm-Illustration git-scm.com/book/en/v2/…
Xuan
1
und wenn wir entweder sind newbranchoder oldbranch, was wir tun können git log ..oldbranchoder git log newbranch..jeweils
YakovL
Jimmyorrs Lösung hat bei mir nicht funktioniert, aber diese hat dank der zwei Punkte ..zwischen den Namen der Schiedsrichter funktioniert . Ich habe auch die --cherry-pickOption verwendet, um Commits auszublenden, die in beiden Zweigen vorhanden sind, aber einen anderen Hash haben, da sie von einem Zweig zum anderen ausgewählt wurden.
Fehler
58

Für diejenigen, die noch nach einer einfachen Antwort suchen, schauen Sie sich git cherry an . Es vergleicht tatsächliche Unterschiede anstelle von Commit-Hashes. Das bedeutet, dass Commits berücksichtigt werden, die von Kirschen gepflückt oder neu gegründet wurden.

Überprüfen Sie zuerst den Zweig, den Sie löschen möchten:

git checkout [branch-to-delete]

Verwenden Sie dann Git Cherry, um es mit Ihrem Hauptentwicklungszweig zu vergleichen:

git cherry -v master

Beispielausgabe:

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

Hinweis: Das -vFlag soll die Festschreibungsnachricht zusammen mit dem SHA-Hash enthalten.

Zeilen mit dem '+' vor befinden sich in der zu löschenden Verzweigung, nicht jedoch in der Hauptverzweigung. Diejenigen mit einem '-' vor haben ein gleichwertiges Commit im Master.

Kombinieren Sie für NUR die Commits, die nicht im Master enthalten sind, Cherry Pick mit Grep:

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

Beispielausgabe:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
Tim S.
quelle
Ich habe dies versucht, aber es wird immer noch berichtet, dass es in der fb (Feature-Zweig) viele Commits gibt, die nicht in der mb (Hauptzweig) enthalten sind. Wenn ich jedoch in der fb bin und ein git diff mb mache, sehe ich keine Unterschiede. Ich habe Rebase benutzt und alles zerquetscht. Ich bin mir fast sicher, warum das so ist, aber ich möchte nur sicher sein. Wenn dies der Fall ist, werde ich es vermeiden, wenn möglich zu quetschen. Ich bin im "No Lost Info Camp". Ich frage mich, ob es möglich wäre, einen Protokollanzeigemodus hinzuzufügen, in dem Zusammenführungen angezeigt werden können, als wären sie Rebases, um den Verlauf sauber zu halten und dennoch keine Informationen zu verlieren.
Outis Von Nemo
1
Sie sind sich Ihres genauen Szenarios hier nicht sicher, aber wenn Sie mehrere Commits zu einem zusammengefasst haben und dies mit einem anderen Zweig vergleichen, in dem die Commits getrennt sind, funktioniert dies definitiv nicht. In diesem Fall möchten Sie möglicherweise nur das Unix- diffDienstprogramm verwenden, um die verschiedenen Dateien zu vergleichen. Oder Sie können eine temporäre Verzweigung erstellen und alle Commits in dieser Form quetschen, ähnlich wie Sie es mit der ursprünglichen Verzweigung getan haben, und diese dann verwenden, was meiner Meinung nach funktionieren würde.
Tim S
50

Während einige der hier veröffentlichten Antworten helfen, das zu finden, wonach Sie suchen, ist der folgende Unterbefehl von git branch eine geeignetere Lösung für Ihre Aufgabe.

--merged wird verwendet, um alle Zweige zu finden, die sicher gelöscht werden können, da diese Zweige vollständig in HEAD enthalten sind.

Während masterman den Befehl ausführen kann, um die Zweige aufzulisten, kann man sicher entfernen, wie folgt:

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
quelle
16

Jimmyorrs Antwort funktioniert nicht unter Windows. es hilft zu verwenden --notanstatt ^wie folgt:

git log oldbranch --not newbranch --no-merges
sebeck
quelle
4
Das ist richtig, +1. Beachten Sie, dass ^dies unter Windows unterstützt wird, jedoch maskiert werden muss, was unter Windows (ein anderes) ist ^: git log oldbranch ^^newbranch --no-merges.
VonC
3
Um genau zu sein, funktioniert es in Windows in der Powershell-Konsole, erfordert jedoch ein zusätzliches "^" in CMD.
Rod
7

Wenn es sich um einen (einzelnen) Zweig handelt, den Sie überprüfen müssen, z. B. wenn dieser Zweig 'B' vollständig mit Zweig 'A' zusammengeführt werden soll, können Sie einfach Folgendes tun:

$ git checkout A
$ git branch -d B

git branch -d <branchname> hat die Sicherheit, dass "Der Zweig muss vollständig in HEAD zusammengeführt werden."

Achtung : Dadurch wird der Zweig B tatsächlich gelöscht, wenn er mit A zusammengeführt wird.

Jakub Narębski
quelle
3

Mit diesem einfachen Skript können Sie Commits anzeigen, die nicht zusammengeführt werden

#!/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')

Sie können auch das Tool git-wtf verwenden , das den Status von Zweigen anzeigt

manRo
quelle
0

Verwenden Sie einfach git cherry, um alle Commits in der Filiale auszuwählen, newFeature42zum Beispiel:

Git Cherry -v Master NewFeature42

Mꜳltus
quelle
-5

Start , um einen Pull - Request zu erstellen über den git - Hosting - Service Sie verwenden. Wenn der Zweig vollständig mit dem Basiszweig zusammengeführt wurde, können Sie den neuen PR nicht erstellen.

Sie müssen die Pull-Anforderung nicht tatsächlich stellen, sondern verwenden nur den ersten Schritt, in dem Sie Zweige auswählen.

Zum Beispiel auf GitHub:

Es gibt nichts zu vergleichen

Für zusammengeführte Zweige kann keine PR erstellt werden.

Dies verwendet kein Git in der Befehlszeile, aber ich finde es oft hilfreich, die anderen Tools, die Ihnen zur Verfügung stehen, mit einem klaren mentalen Modell zu verwenden, anstatt zu versuchen, sich an einen anderen arkanen Git-Befehl zu erinnern.

pkamb
quelle