894 Stimmen

Herausfinden, aus welchem Zweig eine Git-Übertragung stammt

Gibt es eine Möglichkeit, herauszufinden, aus welchem Zweig ein Commit stammt, wenn man seine SHA-1 Hash-Wert?

Bonuspunkte gibt es, wenn Sie mir sagen können, wie man dies mit Ruby Grit erreichen kann.

19 Stimmen

Die folgenden Methoden sind pragmatische, nützliche und funktionierende Wege, um ableiten a Wahrscheinlich Antwort, aber beachten Sie, dass in Git die Frage selbst ein Missverständnis ist: Commits kommen nicht aus Zweigen. Zweige kommen und gehen, sie bewegen sich, nur Commits repräsentieren die wirkliche Repo-Historie. Das soll aber nicht heißen, dass die unten genannten Lösungen schlecht sind. Nur wissen keine von ihnen gibt eine vollständig vertrauenswürdige Antwort, was in Git absichtlich nicht möglich ist. (Ein einfacher Fall sind gelöschte Verzweigungen: Ich verzweige, ich übertrage zweimal, ich führe in eine andere Verzweigung zusammen, ich lösche die erste Verzweigung. Woher "kommt" die Übergabe?

2 Stimmen

Ich habe einen Fall, in dem ich explizit eine Tiefe 1 flachen Klon aus einem Tag ziehen. Es ist billig und einfach und effizient ... und bis jetzt tat alles, was ich wollte schön. Jetzt, wo ich wissen möchte, auf welchem Zweig das Tag war, bin ich aufgeschmissen, zumindest für dieses Detail. Man kann nicht immer nach Hause gehen, lol

1170voto

Cascabel Punkte 449595

Es stimmt zwar, dass Dav die Informationen nicht direkt speichert, aber das bedeutet nicht, dass man sie nicht herausfinden kann. Hier sind ein paar Dinge, die Sie tun können.

Zweige finden, in denen die Übergabe stattfindet

git branch -a --contains <commit>

Dies zeigt Ihnen alle Zweige an, die den angegebenen Commit in ihrer Historie haben. Natürlich ist dies weniger nützlich, wenn der Commit bereits zusammengeführt wurde.

Suche in den Reflogs

Wenn Sie in dem Repository arbeiten, in dem der Commit gemacht wurde, können Sie in den Reflogs nach der Zeile für diesen Commit suchen. Reflogs, die älter als 90 Tage sind, werden von git-gc beschnitten, d.h. wenn der Commit zu alt ist, werden Sie ihn nicht finden. Das heißt, Sie können dies tun:

git reflog show --all | grep a871742

um Commit a871742 zu finden. Beachten Sie, dass Sie die abgekürzten 7 ersten Ziffern der Übergabe verwenden MÜSSEN. Die Ausgabe sollte in etwa so aussehen:

a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite

was anzeigt, dass die Übergabe auf dem Zweig "completion" erfolgte. Die Standardausgabe zeigt abgekürzte Commit-Hashes an. Achten Sie also darauf, nicht nach dem vollständigen Hash zu suchen, sonst werden Sie nichts finden.

git reflog show ist eigentlich nur ein Alias für git log -g --abbrev-commit --pretty=oneline Wenn Sie also mit dem Ausgabeformat herumspielen wollen, um verschiedene Dinge für grep verfügbar zu machen, ist das Ihr Ausgangspunkt!

Wenn Sie nicht in dem Repository arbeiten, in dem der Commit gemacht wurde, können Sie in diesem Fall bestenfalls die Reflogs untersuchen und herausfinden, wann der Commit zum ersten Mal in Ihr Repository eingeführt wurde; mit etwas Glück haben Sie den Zweig gefunden, in den er committed wurde. Dies ist etwas komplizierter, da Sie nicht gleichzeitig den Commit-Baum und die Reflogs durchgehen können. Sie müssen die Reflog-Ausgabe parsen und jeden Hash daraufhin untersuchen, ob er den gewünschten Commit enthält oder nicht.

Eine nachfolgende Zusammenführungsübergabe finden

Dies hängt vom Arbeitsablauf ab, aber bei guten Arbeitsabläufen werden Übertragungen auf Entwicklungszweige vorgenommen, die dann zusammengeführt werden. Sie könnten dies tun:

git log --merges <commit>..

um Merge-Commits zu sehen, die den angegebenen Commit als Vorgänger haben. (Wenn der Commit nur einmal zusammengeführt wurde, sollte der erste Commit derjenige sein, nach dem Sie suchen; andernfalls müssen Sie wohl mehrere untersuchen). Die Nachricht über die Zusammenführung sollte den Namen des Zweiges enthalten, der zusammengeführt wurde.

Wenn Sie sich darauf verlassen wollen, sollten Sie die --no-ff Option zu git merge um die Erstellung von Merge-Commits zu erzwingen, auch im Fall des Schnellvorlaufs. (Seien Sie aber nicht zu eifrig, das könnte bei übermäßigem Gebrauch zu Verwirrung führen). VonCs Antwort auf eine verwandte Frage wird dieses Thema in hilfreicher Weise erläutert.

5 Stimmen

+1. Das schiere Fehlen von Informationen zu diesem speziellen Thema lässt die Frage aufkommen, ob es sich tatsächlich um ein Problem handelt? Zweige können sich jederzeit ändern, umbenannt oder gelöscht werden. Kann sein git describe reicht aus, da (kommentierte) Tags als aussagekräftiger angesehen werden können als Zweige.

9 Stimmen

Ich stimme definitiv zu - Zweige sollen leicht und flexibel sein. Wenn Sie einen Arbeitsablauf einführen, in dem diese Informationen wichtig werden, können Sie die --no-ff Option, um sicherzustellen, dass es immer einen Merge-Commit gibt, so dass Sie immer den Weg eines bestimmten Commits verfolgen können, während er zu Master zusammengeführt wird.

0 Stimmen

Siehe meine Antwort die auf Seths Perl-Skript verweist, für eine interessante Implementierung dieses Suchalgorithmus.

258voto

khichar.anil Punkte 4219

Dieser einfache Befehl funktioniert wie ein Zauberspruch:

git name-rev <SHA>

Zum Beispiel (wenn Testzweig ist der Name der Verzweigung):

git name-rev 651ad3a
251ad3a remotes/origin/test-branch

Selbst dies funktioniert bei komplexen Szenarien, wie z. B.:

origin/branchA/
              /branchB
                      /commit<SHA1>
                                   /commit<SHA2>

Hier git name-rev commit<SHA2> gibt zurück. ZweigstelleB .

14 Stimmen

Ich fand git name-rev --name-only <SHA> ist nützlicher, um nur den Namen des Zweigs zu erhalten. Meine Frage ... Kann es in jedem Fall mehr als einen Zweig zurückgeben?

7 Stimmen

Wenn Sie nur den Zweignamen und die Ausnahmen suchen wollen, können Sie folgenden Befehl verwenden: git name-rev --refs="refs/heads/*" --name-only <SHA>

2 Stimmen

Leider funktioniert dies nur für eine kurze Zeit nach der Zusammenführung, bevor die Referenz in den Müll wandert. Dies ist die gleiche Einschränkung wie bei der Methode "Search the reflogs" in der Antwort von @Cascabel. Wie VonC bereits erwähnt hat, ist die einzige Möglichkeit, diese Informationen zu erhalten, wenn Ihr Arbeitsablauf das Speichern in einer Git-Notiz oder einem kommentierten Tag für jeden Merge vorsieht.

51voto

Eugen Konkov Punkte 18206

Zum Beispiel, um festzustellen, dass c0118fa Die Zusage kam von redesign_interactions :

* ccfd449 (HEAD -> develop) Require to return undef if no digits found
*   93dd5ff Merge pull request #4 from KES777/clean_api
|\
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| *   a435005 Merge branch 'redesign_interactions' into clean_api
| |\
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event

Sie sollten laufen:

git log c0118fa..HEAD --ancestry-path --merges

Und scrollen Sie nach unten, um den letzten zusammenführen verpflichten. Das heißt:

commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date:   Sat Oct 1 00:54:18 2016 +0300

    Merge branch 'redesign_interactions' into clean_api

Update

Oder nur einen Befehl:

git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1

9 Stimmen

Dies war die einzige Lösung, die das gewünschte Ergebnis brachte. Den Rest habe ich ausprobiert.

1 Stimmen

Beachten Sie, dass dies nur funktioniert, wenn die Zusammenführungszusammenfassungen die in den Zusammenführungen verwendeten Zweignamen enthalten, was normalerweise der Fall ist. Jedoch git merge -m"Any String Here" werden die Informationen über den Quell- und Zielzweig unkenntlich gemacht.

0 Stimmen

@qneill: Nein, die Zusammenführung hat immer Informationen über zusammengeführte Zweige: Merge: f6b70fa d58bdcb . Sie können Ihren Merge Commit nach Belieben benennen. Ich werde keine Materie haben

50voto

VonC Punkte 1117238

Update Dezember 2013:

sschuberth Kommentare

git-what-branch (Perl-Skript, siehe unten) scheint nicht mehr gepflegt zu werden. git-when-merged ist eine in Python geschriebene Alternative, die für mich sehr gut funktioniert.

Sie basiert auf " Zusammenführungs-Commit finden, der einen bestimmten Commit enthält ".

git when-merged [OPTIONS] COMMIT [BRANCH...]

Finden Sie heraus, wann ein Commit in einen oder mehrere Zweige zusammengeführt wurde.
Finden Sie den Merge-Commit, der die COMMIT in die angegebene(n) BRANCHE(n).

Suchen Sie insbesondere nach dem ältesten Commit in der First Parent History von BRANCH die die COMMIT als Vorfahre.


Originalantwort September 2010:

Sebastien Douche nur getwittert (16 Minuten vor dieser SO-Antwort):

git-was-verzweigen : Herausfinden, auf welchem Zweig sich eine Übertragung befindet oder wie sie zu einem bestimmten Zweig gelangt ist

Dies ist eine Perl-Skript de Seth Robertson Das scheint sehr interessant zu sein:

SYNOPSIS

git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...

ÜBERBLICK

Teilen Sie uns (standardmäßig) den frühesten kausalen Pfad von Commits und Merges mit, der dazu geführt hat, dass der angeforderte Commit in einen benannten Branch gelangt ist. Wenn ein Commit direkt auf einem benannten Zweig gemacht wurde, ist das natürlich der früheste Pfad.

Mit dem frühesten kausalen Pfad ist der Pfad gemeint, der nach der Commit-Zeit am frühesten in einen benannten Zweig übergegangen ist (außer --topo-order angegeben ist).

PERFORMANCE

Wenn viele Zweige (z.B. Hunderte) den Commit enthalten, kann das System sehr lange brauchen (für einen bestimmten Commit im Linux-Baum brauchte es 8 Sekunden, um einen Zweig zu erkunden, aber es gab über 200 Kandidatenzweige), um den Pfad zu jedem Commit aufzuspüren.
Auswahl eines bestimmten --reference-branch --reference tag zu untersuchen, wird hundertmal schneller sein (wenn Sie Hunderte von Kandidatenzweigen haben).

BEISPIELE

 # git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4
 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path:
   v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May  5 08:59:37 2005)
   v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May  3 18:27:24 2005)
   v2.6.12-rc3-461-g84e48b6 is on master
   v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n
   [...]

Dieses Programm berücksichtigt nicht die Auswirkungen der Rosinenpickerei bei den gewünschten Übertragungen, sondern nur die Zusammenführungsoperationen.

5 Stimmen

git-what-branch scheint nicht mehr gepflegt zu werden. git-when-merged ist eine in Python geschriebene Alternative, die für mich sehr gut funktioniert.

0 Stimmen

@sschuberth danke für dieses Update. Ich habe Ihren Kommentar in die Antwort aufgenommen, um ihn besser sichtbar zu machen.

26voto

phyatt Punkte 17614

khichar.anil abgedeckt das meiste davon in seiner Antwort.

Ich füge nur das Kennzeichen hinzu, das die Tags aus der Liste der Revisionsnamen entfernt. Dies gibt uns:

git name-rev --name-only --exclude=tags/* $SHA

0 Stimmen

Im zweiten Satz scheint etwas zu fehlen.

2 Stimmen

Das hat mir geholfen, denn sonst hätte ich in der Ausgabe eine Markierung statt einer Verzweigung erhalten

2 Stimmen

Das war genau der Grund, warum ich hierher gekommen bin. Danke fürs Teilen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X