Könnten Sie Ihre akzeptierte Antwort ändern? Die Mehrheit mag die --is-ancestorLösung.
Robert Siemer
Antworten:
51
Wenn Sie dies programmgesteuert überprüfen möchten (z. B. im Skript), können Sie überprüfen, ob git merge-base A Bes gleich ist git rev-parse --verify A(dann ist A von B aus erreichbar) oder ob dies der Fall ist git rev-parse --verify B(dann ist B von A aus erreichbar). git rev-parsewird hier benötigt, um vom Commit-Namen zum Commit SHA-1 / Commit-ID zu konvertieren.
Die Verwendung git rev-listwie in VonC Antwort ist ebenfalls möglich.
Bearbeiten: Im modernen Git gibt es explizite Unterstützung für diese Abfrage in Form von git merge-base --is-ancestor.
Wenn man von Commits über Sie fragen , ist ein Zweig Spitze , dann git branch --contains <commit>oder git branch --merged <commit>vielleicht besser nicht-programmatische Lösung sein.
Möglicherweise wäre der schnellste Weg zu git checkout -b quickcheck <more-recent-commit-ID>und dann git branch --contains <older-commit-ID>(und dann git branch -D quickcheck, um den temporären Zweig loszuwerden).
Clee
2
Zwei mögliche Ansätze, die beide viel schlechter sind als der in der Antwort von @ MattR.
JWG
6
@jwg: MattR Antwort ist besser, aber diese Antwort (und wahrscheinlich wird sie akzeptiert) ist älter als Git 1.8.0 und git merge-base --is-ancestorum 2 Jahre.
Jakub Narębski
@ JakubNarębski Fair genug, sorry.
JWG
2
In einem großen Repository (2 Millionen Commits) verglich ich die Geschwindigkeit von git branch --contains <commit>und git merge-base --is-ancestor ...: 3m40s mit 0,14s
Hagello
259
Ab Git 1.8.0 wird dies als Option unterstützt für merge-base:
Überprüfen Sie, ob der erste ein Vorfahr des zweiten ist, und beenden Sie ihn mit dem Status 0, wenn er wahr ist, oder mit dem Status 1, wenn nicht. Fehler werden durch einen Status ungleich Null angezeigt, der nicht 1 ist.
Nett! Hier ist ein Shell-Skript, das diese Antwort in etwas mit von Menschen realisierbarer Ausgabe zusammenfasst: gist.github.com/simonwhitaker/6354592
Simon Whitaker
1
Mit anderen Worten: git merge-base THING --is-ancestor OF_THING && echo yes || echo nozB:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
user1735594
2
@smarber git merge-base --is-ancestor -- commit commitarbeitet für Hashes an meiner Seite mit git2.1.4 (Debian / Devuan 7.10 Jessie) und 1.9.1 (Ubuntu 14.04 Trusty), die jetzt ziemlich alt sind. Es funktioniert sogar für Debian Wheezy, wenn Sie dies tun sudo apt-get install git/wheezy-backports.
Wenn das zuletzt angezeigte Commit mit dem ersten Commit im git rev-listBefehl identisch ist , handelt es sich um ein Commit, das vom zweiten Commit aus erreichbar ist.
Wenn das erste Commit vom zweiten nicht erreichbar ist, git rev-listsollte nichts zurückgegeben werden.
git rev-list --boundary A..B
würde vorbei enden A, wenn Aerreichbar ist von B.
Es ist das gleiche wie:
git rev-list --boundary B --not A
mit Beiner positiven und Aeiner negativen Referenz .
Es beginnt bei Bund geht zurück durch das Diagramm, bis es auf eine Revision stößt, die von erreichbar ist A.
Ich würde argumentieren, dass wenn Aes direkt erreichbar ist B, es auf sich selbst trifft (und aufgrund der --boundaryOption angezeigt wird ) A.
Dies klingt nach einem häufig genug verwendeten Anwendungsfall, bei dem ich überrascht bin, dass git noch keinen "Porzellan" -Befehl veröffentlicht hat, der genau dies tut.
Oh Mann, es sieht so aus, als müsste ich zurückgehen und an meinen Shell-Skripten arbeiten!
Lawrence I. Siden
1
Frage: Warum hat das -85e54e2...im Snippet ein Minus? auch ein möglicher Tippfehler: "... ist das gleiche wie das erste Commit ..."
sdaau
1
@sdaau -bedeutet, dass es sich um ein Boundary Commit handelt. Ich habe die Antwort bearbeitet, um dies klarer zu machen, sowie um Dokumentlinks zu aktualisieren und den Tippfehler für diese 5 Jahre alte Antwort zu korrigieren.
VonC
11
Eine andere Möglichkeit wäre, zu verwenden git logund grep.
git log --pretty=format:%H abc123 | grep def456
Dies erzeugt eine Ausgabezeile, wenn commit def456 ein Vorfahr von commit abc123 ist, oder keine andere Ausgabe.
Normalerweise können Sie das --prettyArgument weglassen , aber es ist erforderlich, wenn Sie sicherstellen möchten, dass Sie nur die tatsächlichen Commit-Hashes und nicht die Protokollkommentare usw. durchsuchen.
Das struct commit wird in vielen Kontexten verwendet. Mitglieder generationund graph_poswerden jedoch nur für Commit-Graph-bezogene Operationen verwendet und verschwenden anderweitig Speicher.
Diese Verschwendung wäre beim Übergang zur Generierungsnummer v2 stärker ausgeprägt gewesen, bei der anstelle der aktuellen 32-Bit-Generierung die 64-Bit-Generierungsnummer verwendet wird.
Da häufig auf sie zugegriffen wird, führen wir struct ein commit_graph_dataund verschieben sie auf eine commit_graph_dataPlatte.
Während die gesamte Testsuite genauso schnell läuft wie master(Serie: 26m48s , master: 27m34s, schneller um 2,87%), wurden bestimmte Befehle wie git merge-base --is-ancestorum 40% verlangsamt, wie von Szeder Gábor entdeckt .
Nach Minimierung des Commit-Slab-Zugriffs bleibt die Verlangsamung bestehen, liegt jedoch näher bei 20%.
--is-ancestor
Lösung.Antworten:
Wenn Sie dies programmgesteuert überprüfen möchten (z. B. im Skript), können Sie überprüfen, ob
git merge-base A B
es gleich istgit rev-parse --verify A
(dann ist A von B aus erreichbar) oder ob dies der Fall istgit rev-parse --verify B
(dann ist B von A aus erreichbar).git rev-parse
wird hier benötigt, um vom Commit-Namen zum Commit SHA-1 / Commit-ID zu konvertieren.Die Verwendung
git rev-list
wie in VonC Antwort ist ebenfalls möglich.Bearbeiten: Im modernen Git gibt es explizite Unterstützung für diese Abfrage in Form von
git merge-base --is-ancestor
.Wenn man von Commits über Sie fragen , ist ein Zweig Spitze , dann
git branch --contains <commit>
odergit branch --merged <commit>
vielleicht besser nicht-programmatische Lösung sein.quelle
git checkout -b quickcheck <more-recent-commit-ID>
und danngit branch --contains <older-commit-ID>
(und danngit branch -D quickcheck
, um den temporären Zweig loszuwerden).git merge-base --is-ancestor
um 2 Jahre.git branch --contains <commit>
undgit merge-base --is-ancestor ...
: 3m40s mit 0,14sAb Git 1.8.0 wird dies als Option unterstützt für
merge-base
:Von der Manpage:
Beispielsweise:
quelle
git merge-base THING --is-ancestor OF_THING && echo yes || echo no
zB:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commit
arbeitet für Hashes an meiner Seite mitgit
2.1.4 (Debian / Devuan 7.10 Jessie) und 1.9.1 (Ubuntu 14.04 Trusty), die jetzt ziemlich alt sind. Es funktioniert sogar für Debian Wheezy, wenn Sie dies tunsudo apt-get install git/wheezy-backports
.Diese Art von Operationen beruht auf dem Begriff des Revisionsbereichs, der in der SO-Frage aufgeführt ist: " Unterschied zwischen 'Git-Log-Ursprung / Master' und 'Git-Log-Ursprung / Master'. "
git rev-list
sollte in der Lage sein, von einem Commit bis zu einem anderen zurückzugehen, wenn dies erreichbar ist.Also würde ich versuchen:
(Boundary Commits werden vorangestellt
-
)Wenn das zuletzt angezeigte Commit mit dem ersten Commit im
git rev-list
Befehl identisch ist , handelt es sich um ein Commit, das vom zweiten Commit aus erreichbar ist.Wenn das erste Commit vom zweiten nicht erreichbar ist,
git rev-list
sollte nichts zurückgegeben werden.würde vorbei enden
A
, wennA
erreichbar ist vonB
.Es ist das gleiche wie:
mit
B
einer positiven undA
einer negativen Referenz .Es beginnt bei
B
und geht zurück durch das Diagramm, bis es auf eine Revision stößt, die von erreichbar istA
.Ich würde argumentieren, dass wenn
A
es direkt erreichbar istB
, es auf sich selbst trifft (und aufgrund der--boundary
Option angezeigt wird )A
.quelle
-85e54e2...
im Snippet ein Minus? auch ein möglicher Tippfehler: "... ist das gleiche wie das erste Commit ..."-
bedeutet, dass es sich um ein Boundary Commit handelt. Ich habe die Antwort bearbeitet, um dies klarer zu machen, sowie um Dokumentlinks zu aktualisieren und den Tippfehler für diese 5 Jahre alte Antwort zu korrigieren.Eine andere Möglichkeit wäre, zu verwenden
git log
undgrep
.Dies erzeugt eine Ausgabezeile, wenn commit def456 ein Vorfahr von commit abc123 ist, oder keine andere Ausgabe.
Normalerweise können Sie das
--pretty
Argument weglassen , aber es ist erforderlich, wenn Sie sicherstellen möchten, dass Sie nur die tatsächlichen Commit-Hashes und nicht die Protokollkommentare usw. durchsuchen.quelle
--pretty
ich benutze --oneline:git log --oneline ce2ee3d | grep ec219cc
funktioniert superhttps://stackoverflow.com/a/13526591/895245 erwähnt es jetzt, um es menschlicher zu machen:
quelle
git show-branch branch-sha1 commit-sha1
Wo:
quelle
Wenn Sie verwenden
git merge-base --is-ancestor
, stellen Sie sicher, dass Sie Git 2.28 (Q3 2020) verwenden.Mit Git 2.28 (Q3 2020) wurden einige Felder in "
struct commit
", die nicht immer vorhanden sein müssen, verschoben, um Platten festzuschreiben.Siehe Commit c752ad0 , Commit c49c82a , Commit 4844812 , Commit 6da43d9 (17. Juni 2020) von Abhishek Kumar (
abhishekkumar2718
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit d80bea4 , 06. Juli 2020)quelle
Aufbauend auf der Antwort von itub, falls Sie dies für alle Tags im Repository tun müssen:
quelle