Git - wie man das erste Commit eines bestimmten Zweigs findet

91

Im folgenden Beispielbaum:

A-B-C-D-E (master branch)
    \
     F-G-H (xxx branch)

Ich suche nach F - dem ersten Commit im xxx-Zweig. Ich denke, dass es möglich ist mit:

git log xxx --not master

und das zuletzt aufgeführte Commit sollte F sein. Ist es die richtige Lösung oder gibt es einige Nachteile?

Ich weiß, dass es ähnliche Fragen zum Stapelüberlauf gab, aber niemand hat eine solche Lösung vorgeschlagen, und ich bin mir nicht sicher, ob ich es richtig mache.

user2699113
quelle
Mögliches Duplikat von stackoverflow.com/questions/6058308/…
nyzm

Antworten:

108
git log master..branch --oneline | tail -1

Wobei "Zweig" Ihr spezifischer Zweigstellenname ist. Der Punkt-Punkt gibt Ihnen alle Commits an, die der Zweig hat, den der Master nicht hat. tail -1Gibt die letzte Zeile der vorherigen Ausgabe zurück.

konyak
quelle
3
Dies funktioniert nur, wenn `branch`` existiert. Wie würden Sie es tun, wenn der Zweig gelöscht wird?
Oz123
2
Der @ Oz123-Zweig kann durch eine beliebige Referenz ersetzt werden, z. B. HEAD oder sha1 oder tag. Aber natürlich brauchen Sie eine Referenz.
Zitrax
3
Gibt mir nicht das, was ich erwartet hatte. Mein Zweig (alter) wurde bereits wieder zum Master zusammengeführt, was bedeutet, dass alle Commits in xxx bereits im Master sind. Trotzdem - ich muss wissen, welches Commit das erste in diesem Zweig war - oder tatsächlich - ich muss die Geschichte der Commits dieses Zweigs allein untersuchen - es ist mir egal, ob sie auf Master sind oder nicht.
Motti Shneor
1
@MottiShneor Je nachdem, wie Sie zusammengeführt haben, könnte das schwierig sein. Wenn Sie einen schnellen Vorlauf durchgeführt haben, ist es so, als ob der Zweig nie existiert hätte. Andernfalls könnte Sie diese Antwort interessieren, in der verschiedene Möglichkeiten zum Auffinden des Verzweigungspunkts aufgeführt sind. Sobald Sie Ihren Verzweigungspunkt haben, kann der SHA ihn ersetzen master. Solange Ihre Verzweigung nicht gelöscht wurde, git log <sha>..branch --oneline | tail -1sollten Sie dennoch die gewünschten Ergebnisse erhalten.
ND Geek
1
Sie können verwenden --reverse, um die Protokolle mit Farben usw. rückwärts zu lesen
Dominik
8

Sie sollten die merge-baseFunktionalität verwenden, mit der genau dies gelöst werden soll:

git merge-base remotes/origin/<branch> develop 
Fabrizio Stellato
quelle
Ich denke nicht, dass dies funktionieren wird, wenn Sie zum ursprünglichen Gabelpunkt zurückkehren möchten. Wenn Sie die Zusammenführung zu <branch> zusammenführen, ist die Zusammenführungsbasis neuer als der ursprüngliche Gabelpunkt.
Alexander Mills
5
Dies würde auch nicht auf F verweisen, sondern auf ein Commit im Hauptzweig (obwohl es in der Zeichnung von OP schwer zu erkennen ist, scheint es B oder C zu sein).
RomainValeri
4
git cherry master -v | head -n 1
Nelu
quelle
1

Wenn Ihr Zweig (der alte) wieder mit dem Master zusammengeführt wird, wird das erwartete Ergebnis nicht angezeigt. Ich habe das Python-Skript verwendet, um die ID für das Festschreiben des ersten Zweigs zu finden.

git rev-list - erster übergeordneter Änderungssatz

- Erster Elternteil folgt nur dem ersten übergeordneten Commit, wenn ein Merge-Commit .

Iterieren Sie die Änderungssätze vom obigen Befehl, bis der übergeordnete Zweig gefunden wurde.

def status_check(exec_command, exec_dir=None, background=False):
    if exec_dir:
        os.chdir(exec_dir)
    res = subprocess.Popen(exec_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if not background:
        result = res.communicate()
    return result



def findNewBranchCommits(changeset=None):
    cmd = "git rev-list --first-parent "+ changeset
    rev_list = status_check(cmd,self.module_dir)
    rev_list = str(rev_list[0]).split('\n')
    rev_list = list(filter(None, rev_list))
    for x in rev_list:                      # Iterate until branch base point
        rev_cmd = "git branch --contains " + x
        rev_cmd = status_check(rev_cmd,self.module_dir)
        rev_cmd = str(rev_cmd[0]).split('\n')
        if(len(rev_cmd) > 2): 
            print "First Commit in xxx branch",x
            break

findNewBranchCommits(changeset)
Nayagam
quelle
0
git cherry master -v | tail -1   

Dies gibt Ihnen jedoch nur das erste Commit für Zweig xxx, das sich nicht im Master befindet, nicht das erste Commit für Zweig xxx. Letzteres wäre schwierig, wenn der Zweig xxx einmal oder mehrmals gelöscht und / oder neu erstellt worden wäre. In diesem Fall könnten Sie Folgendes versuchen:

git reflog | grep checkout | grep xxx | tail -1   
Doc Unid
quelle
3
Wolltest du head -n 1stattdessen schreiben tail -1? tail -1Gibt das letzte Commit anstelle des ersten zurück.
Nelu
-1

git rev-list --ancestry-path $(git merge-base master xxx)..xxx | tail -1

Hochzeiten
quelle
In meinem Repo zeigt dies das 1. Commit seit dem letzten Zusammenführen vom Master in Zweig xxx, nicht das 1. Commit von Zweig xxx.
jk7