Wie erhalte ich den neuesten Tag-Namen im aktuellen Zweig in Git?

462

Was ist der einfachste Weg, um das neueste Tag in Git zu erhalten?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

Ausgabe:

a
b
c

Sollte ich ein Skript schreiben, um die Datums- und Uhrzeitangaben jedes Tags abzurufen und zu vergleichen?

culebrón
quelle
1
zuletzt erstelltes Tag oder zuletzt nach Festschreibungsdatum geordnetes Tag? Ihre akzeptierte Antwort zeigt das zuletzt erstellte Tag. Dies könnte ein Problem sein, wenn man beschließt, vorhandene Tags zu ändern ...
Paebbels

Antworten:

412

Sie könnten einen Blick darauf werfen git describe, was etwas in der Nähe von dem tut, was Sie fragen.

JB.
quelle
194
Damit --abbrev=0sollte das nächste kommentierte Tag zurückgegeben werden
Jakub Narębski
13
Gibt das neueste Tag im aktuellen Zweig zurück.
Brittohalloran
42
Verwenden Sie, um das neueste mit Anmerkungen versehene Tag abzurufen, das nur auf das aktuelle Commit im aktuellen Zweig abzielt git describe --exact-match --abbrev=0.
Naftuli Kay
5
Diese Antwort mit Kommentaren lieferte nicht das richtige Tag für mich. @ Kilianic lieferte eine korrekte Lösung.
Herman J. Radtke III
19
git describe --tagsund vergleichen Sie com letzten Tag in Github Release-Seite
Adriano Resende
627

So erhalten Sie das neueste Tag:

git describe --tags

So erhalten Sie das neueste mit Anmerkungen versehene Tag:

git describe --abbrev=0
acassis
quelle
2
Ja, wie die Manpage für git describesagt: --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas
22
Oder einfachgit describe --tags
james_womack
5
Diese Antwort (und wahrscheinlich die anderen) stößt auf Probleme, wenn zwei Tags auf dasselbe Commit verweisen. Wenn es sich bei den Tags nicht um mit Anmerkungen versehene Tags handelt, kann git meines Erachtens nicht unterscheiden, welche der beiden zuvor erstellt wurde.
Paul Lynch
10
Dies sollte die akzeptierte Antwort sein. Vielen Dank für die Übermittlung.
Crmpicco
6
Wenn Sie das neueste Tag direkt git checkout $(git describe --abbrev=0 --tags)
auschecken
321

Gibt das Tag des letzten getaggten Commits in allen Zweigen aus

git describe --tags $(git rev-list --tags --max-count=1)
kilianc
quelle
8
oder TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ William-Pursell
Kilianc
20
Dies ist die beste Antwort. Es erhält tatsächlich Tags über alle Zweige hinweg, nicht nur über den aktuellen Zweig, wie es die aktuelle "richtige" Antwort tut.
Brittohalloran
61
Außer die Frage fragt speziell nach dem aktuellen Zweig.
michaeltwofish
3
@michaeltwofish, als ich es nicht wusste, habe ich es später herausgefunden und meine Antwort entsprechend korrigiert. Das tut mir leid.
Kilianc
3
Hinweise: Dieser Befehl gibt das "neueste" Tag zurück, auch wenn sich dieses Tag in einem anderen Zweig befindet.
Alan Zhiliang Feng
47

Um das neueste Tag zu erhalten, haben Sie folgende Möglichkeiten:

$ git für jede Referenz refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1

Natürlich können Sie das count-Argument oder das Sortierfeld nach Bedarf ändern. Es scheint, dass Sie beabsichtigt haben, eine etwas andere Frage zu stellen, aber dies beantwortet die Frage so, wie ich sie interpretiere.

William Pursell
quelle
2
Dies ist fast genau das, wonach ich gesucht habe (das neueste Tag in allen Zweigen), aber zumindest mit meiner Version von git (1.7.7.6) werden die Tags für --sort=-authordateund in derselben Reihenfolge erstellt --sort=authordate.
Larsks
3
Aha, denn was du eigentlich willst, ist --sort=-taggerdate. Für Tags authordateund committerdatesind leer (so nutzlos wie Sortierschlüssel).
Larsks
8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1ist noch besser :)
Christophe Eblé
5
Wirklich, eine vollkommen korrekte Antwort, die fast 5 Jahre alt ist, ohne Kommentar herunterzustimmen? Das ist einfach unhöflich.
William Pursell
1
Und --points-at=$SHASie erhalten das Tag für einen Commit-Hash.
Ryan
34

Wie wäre es damit?

TAG=$(git describe $(git rev-list --tags --max-count=1))

Technisch gesehen erhalten Sie nicht unbedingt das neueste Tag, sondern das neueste Commit, das mit Tags versehen ist, und das möglicherweise das ist, wonach Sie suchen.

Wincent Colaiuta
quelle
Dieser erhält nicht das neueste Tag im aktuellen Zweig, sondern für einen Zweig. Was großartig ist, denn es ist genau das, was ich brauchte. Danke Wincent.
Jasongregori
2
Wenn Sie benötigen , um Tag -Übereinstimmungsmuster erhalten Sie verwenden --tags=<pattern>in rev-list. Zum Beispiel erhalten Sie das letzte Versions-Taggit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
Wirone
1
$ (git beschreiben - enthält $ (git rev-parse HEAD))
Vaidas Zilionis
Danke, es hat funktioniert, aber ich musste --tagsgit describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati
25

Sie können Folgendes ausführen: git describe --tags $(git rev-list --tags --max-count=1)hier gesprochen: Wie erhalte ich den neuesten Tag-Namen?

xserrat
quelle
Ich begann mit der besten / akzeptierten Antwort und arbeitete mich nach unten. Dies ist die erste Antwort, die mir tatsächlich das neueste Tag gibt (nicht sicher warum, aber einfach alt git describe ...gibt ein früheres Tag zurück?!)
Jeremy Davis
Dies ist der einzige, der für mich funktioniert. Versuchte einige der --abbrev=0Antworten und sie schnitten einen Teil des Tags ab, den ich will.
Luke Davis
22

"Neueste" könnte zwei Bedeutungen in Bezug auf Git haben.

Sie könnten bedeuten, "welches Tag das späteste Erstellungsdatum hat", und die meisten Antworten hier beziehen sich auf diese Frage. In Bezug auf Ihre Frage möchten Sie Tag zurückgeben c.

Oder Sie könnten bedeuten, "welches Tag in der Entwicklungsgeschichte einem benannten Zweig am nächsten kommt", normalerweise dem Zweig, in dem Sie sich befinden HEAD. In Ihrer Frage würde dies ein Tag zurückgeben a.

Diese können natürlich anders sein:

A->B->C->D->E->F (HEAD)
       \     \
        \     X->Y->Z (v0.2)
         P->Q (v0.1)

Stellen Sie sich vor dem Entwickler tag'ed Zwie v0.2am Montag, und dann tag'ed Qals v0.1am Dienstag. v0.1ist die neuere, ist aber v0.2in der Entwicklungsgeschichte näher an HEAD, in dem Sinne, dass der Weg, auf dem sie sich befindet, an einem Punkt beginnt, der näher an HEAD liegt.

Ich denke, Sie möchten normalerweise diese zweite Antwort, näher in der Entwicklungsgeschichte. Sie können dies herausfinden, indem Sie git log v0.2..HEADfür jedes Tag etc verwenden. Dies gibt Ihnen die Anzahl der Commits auf HEAD an, da der Pfad, der bei endet, v0.2vom Pfad abweicht, dem HEAD folgt.

Hier ist ein Python-Skript, das dies tut, indem es alle Tags durchläuft, die diese Prüfung ausführen, und dann das Tag mit den wenigsten Commits auf HEAD druckt, seit der Tag-Pfad divergiert:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describemacht etwas etwas anderes, indem es von (z. B.) HEAD zurückverfolgt, um das erste Tag zu finden, das sich auf einem Pfad in der Geschichte von HEAD befindet. Sucht in git-Begriffen git describenach Tags, die über HEAD "erreichbar" sind. Es werden daher keine Tags gefunden v0.2, die sich nicht auf dem Rückweg von HEAD befinden, sondern auf einem Pfad, der von dort abweicht.

Matthew Brett
quelle
21

git describe --tags

Gibt das letzte Tag zurück, das vom aktuellen Zweig gesehen werden kann

beenhere4hours
quelle
15
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

WENN SIE MEHR ALS EINEN LETZTEN TAG BENÖTIGEN

(git beschreiben --tags gibt manchmal falsche Hashes, ich weiß nicht warum, aber für mich --max-count 2 funktioniert nicht)

Auf diese Weise können Sie eine Liste mit den neuesten 2 Tag-Namen in umgekehrter chronologischer Reihenfolge erhalten. Funktioniert perfekt mit Git 1.8.4. Für frühere Versionen von git (wie 1.7. *) Gibt es keine "tag:" - Zeichenfolge in der Ausgabe - löschen Sie einfach den letzten sed-Aufruf

Wenn Sie mehr als 2 neueste Tags möchten, ändern Sie dieses "sed 2q" in "sed 5q" oder was auch immer Sie benötigen

Dann können Sie einfach jeden Tag-Namen in eine Variable oder so analysieren.

Osten
quelle
Dies ist sehr hilfreich. Viele Entwickler werden versuchen, den Release-Prozess zu automatisieren, indem sie zum vorherigen Tag zurückkehren, wenn die Bereitstellung unterbrochen wird. Großartiges Zeug!!!
AkD
1
Um diese weiter zu gehen: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' wo in %Dden umliegenden schließt ()Zeichen, und die seds 5q Blätter 4 Zeilen vor 5 beginnen, dann druckt alle Zeichen zwischen ‚tag:` und dem ersten‘, '. Unter der Annahme, dass im Tag keine Kommas verwendet werden, funktioniert dies einwandfrei.
Cometsong
14

Was ist mit allen Vorschlägen falsch (außer der Erklärung von Matthew Brett , aktuell in diesem Antwortbeitrag)?

Führen Sie einfach einen Befehl von anderen auf jQuery Git Geschichte geliefert , wenn Sie an anderer Stelle der Geschichte und Prüfergebnis mit visueller Tagging Geschichte Darstellung (I tat das ist , warum Sie diesen Beitrag sehen):

$ git log --graph --all --decorate --oneline --simplify-by-decoration

Heutzutage führen viele Projekte Releases (und damit Tagging) in einem von der Hauptlinie getrennten Zweig durch .

Dafür gibt es starke Gründe . Schauen Sie sich einfach alle etablierten JS / CSS-Projekte an. Für Benutzerkonventionen enthalten sie binäre / minimierte Release-Dateien in DVCS. Natürlich möchten Sie als Projektbetreuer Ihren Mainline- Diff- Verlauf nicht mit nutzlosen binären Blobs verschmutzen und das Festschreiben von Build-Artefakten außerhalb der Mainline durchführen .

Da Git DAG und keine lineare Historie verwendet, ist es schwierig, die Entfernungsmetrik zu definieren, sodass wir sagen können, dass die Drehzahl meiner am nächsten kommt HEAD!

Ich beginne meine eigene Reise in (schau hinein, ich habe keine ausgefallenen Proof-Bilder in diesen langen Beitrag kopiert):

Was ist das nächste Tag in der Vergangenheit in Bezug auf die Verzweigung in Git?

Derzeit habe ich 4 vernünftige Definitionen des Abstands zwischen Tag und Revision mit abnehmender Nützlichkeit:

  • Länge des kürzesten Wegs von HEAD, um die Basis mit dem Tag zusammenzuführen
  • Datum der Zusammenführungsbasis zwischen HEADund Tag
  • Anzahl der Umdrehungen , die vom HEAD aus erreichbar, aber vom Tag aus nicht erreichbar sind
  • Datum des Tags unabhängig von der Zusammenführungsbasis

Ich weiß nicht, wie ich die Länge des kürzesten Weges berechnen soll .

Skript, das Tags nach dem Datum der Zusammenführungsbasis zwischen HEADund tag sortiert :

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort

Es ist für die meisten Projekte verwendbar.

Skript, das Tags nach der Anzahl der Umdrehungen sortiert , die über HEAD erreichbar, aber nicht über tag erreichbar sind:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

Wenn Ihre Projekthistorie seltsame Daten für Commits hat (aufgrund von Rebases oder einer anderen Neufassung der Historie oder eines Trottels, vergessen Sie, die BIOS-Batterie oder andere Magie, die Sie für die Historie ausführen, zu ersetzen), verwenden Sie das obige Skript.

Für die letzte Option ( Datum des Tags unabhängig von der Zusammenführungsbasis ), um eine Liste der Tags nach Datum sortiert zu erhalten, verwenden Sie:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

Um das aktuelle Überarbeitungsdatum bekannt zu machen, verwenden Sie:

$ git log --max-count=1

Beachten Sie, dass git describe --tagsdie Verwendung in eigenen Fällen erfolgt, jedoch nicht zum Auffinden des vom Menschen erwarteten nächsten Tags in der Projekthistorie .

HINWEIS Sie können die oben genannten Rezepte für jede Revision verwenden. Ersetzen HEADSie sie einfach durch das, was Sie möchten!

Gavenkoa
quelle
12

git describe --abbrev=0 --tags

Wenn Sie das neueste Tag nicht sehen, stellen Sie sicher, dass Sie den Ursprung abrufen, bevor Sie Folgendes ausführen:

git remote update

Walter B.
quelle
12
git tag -l ac* | tail -n1

Holen Sie sich das letzte Tag mit dem Präfix "ac" . Beispiel: Tag mit ac1.0.0oder ac1.0.5. Andere Tags genannt 1.0.0, 1.1.0werden ignoriert.

git tag -l [0-9].* | tail -n1

Holen Sie sich das letzte Tag, dessen erstes Zeichen ist 0-9. Daher werden diese Tags mit dem ersten Zeichen a-zignoriert.

Mehr Info

git tag --help # Help for `git tag`

git tag -l <pattern>

Listen Sie Tags mit Namen auf, die dem angegebenen Muster entsprechen (oder alle, wenn kein Muster angegeben ist). Wenn Sie "git tag" ohne Argumente ausführen, werden auch alle Tags aufgelistet. Das Muster ist ein Shell-Platzhalter (dh mit fnmatch (3) abgeglichen). Es können mehrere Muster angegeben werden; Wenn einer von ihnen übereinstimmt, wird das Tag angezeigt.


tail -n <number> # display the last part of a file
tail -n1 # Display the last item 

Aktualisieren

Mit git tag --help, über das sortArgument. Es wird lexicorgraphic orderstandardmäßig verwendet, wenn tag.sortkeine Eigenschaft vorhanden ist.

Die Sortierreihenfolge ist standardmäßig auf den Wert eingestellt, der für die Variable tag.sort konfiguriert ist, sofern vorhanden, oder auf eine andere lexikografische Reihenfolge. Siehe git-config (1).

Nach Google sagte jemand, dass Git 2.8.0 die folgende Syntax unterstützt.

git tag --sort=committerdate
AechoLiu
quelle
Es ist kein Wok für mich, das letzte Tag ist 2.11.174, aber dieser Druck 2.11.99, weil nicht als Versionierung
sortiert
8
git tag --sort=committerdate | tail -1
user2957741
quelle
Bitte erläutern Sie, wie dieses Code-Snippet das Problem löst, anstatt nur eine Code-Antwort zu veröffentlichen.
Arun Vinoth
5

Das Folgende funktioniert für mich, wenn Sie die letzten beiden Tags benötigen (zum Beispiel, um ein Änderungsprotokoll zwischen dem aktuellen Tag und dem vorherigen Tag zu erstellen). Ich habe es nur in Situationen getestet, in denen das neueste Tag das war HEAD.

PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`

GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`

Es passt zu meinen Bedürfnissen, aber da ich kein Git-Assistent bin, bin ich sicher, dass es weiter verbessert werden könnte. Ich vermute auch, dass es brechen wird, falls sich der Commit-Verlauf vorwärts bewegt. Ich teile nur für den Fall, dass es jemandem hilft.

Ivan Vučica
quelle
4

Mein erster Gedanke ist, dass Sie verwenden könnten git rev-list HEAD, der alle Umdrehungen in umgekehrter chronologischer Reihenfolge in Kombination mit auflistet git tag --contains. Wenn Sie eine Referenz finden, in git tag --containsder eine nicht leere Liste erstellt wird, haben Sie die neuesten Tags gefunden.

Greg Hewgill
quelle
4

Wenn Sie das letzte Tag suchen möchten, das auf einen bestimmten Zweig angewendet wurde, können Sie Folgendes versuchen:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")
Scyssion
quelle
3

Wenn Sie einen Einzeiler benötigen, der den neuesten Tag-Namen (nach Tag-Datum) für den aktuellen Zweig erhält :

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

Wir verwenden dies, um die Versionsnummer im Setup festzulegen.

Ausgabebeispiel:

v1.0.0

Funktioniert auch unter Windows.

Markus
quelle
1
Unter Linux (Debian Stretch) bekomme ich-bash: syntax error near unexpected token '('
Jeremy Davis
1
Wenn ich diesen Teil in Anführungszeichen (dh --format="%(refname:short)") einfülle und das überspringe --points-at=HEAD, funktioniert es. Mit diesem letzten Schalter wird nichts zurückgegeben, denke ich, weil mein HEADnicht markiert ist?
Jeremy Davis
@JeremyDavis, ja ich denke das liegt daran, dass dein HEADnicht markiert ist.
Markus
2

Dies ist ein alter Thread, aber es scheint, dass vielen Menschen die einfachste, einfachste und korrekteste Antwort auf die Frage von OP fehlt: Um das neueste Tag für den aktuellen Zweig zu erhalten , verwenden Siegit describe HEAD . Erledigt.

Bearbeiten: Sie können auch einen beliebigen gültigen Referenznamen angeben, auch Fernbedienungen. Das heißt, git describe origin/masterSie erfahren das neueste Tag, das vom Ursprung / Master aus erreichbar ist.

dohpaz42
quelle
Nichts garantiert, dass "das neueste Tag" von einem Zweig verarbeitet wird. Die zwei funktionierenden Lösungen sind der for-each-refBefehl ( stackoverflow.com/a/5261470/515973 ) und die Kombination von rev-listund describe( stackoverflow.com/a/7979255/515973 )
Julien Carsique
1
Dies erhält nicht das aktuellste Tag für mich.
K - Die Toxizität in SO nimmt zu.
git describe branchname --tagsfunktioniert für mich, um das neueste Tag auf Zweig (Git-Version 2.12.2) zu bekommen
Rob_M
0

Um das neueste Tag nur für den aktuellen Zweig- / Tag-Namen zu erhalten, dem der aktuelle Zweig vorangestellt ist, musste ich Folgendes ausführen

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

Filialleiter:

git checkout master

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

master-1448

Branch Custom:

git checkout 9.4

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

9.4-6

Und mein letztes Bedürfnis, das Tag +1 für das nächste Tag zu erhöhen und zu erhalten.

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
Sankarganesh Eswaran
quelle
0

Für die gestellte Frage

So erhalten Sie den neuesten Tag-Namen in der aktuellen Verzweigung

Sie wollen

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parentsagt git log, dass keine zusammengeführten Historien detailliert werden sollen , sondern --pretty=%ddass nur die Dekorationen angezeigt werden sollen, dh lokale Namen für Commits. grep -m1sagt "Nur eine Übereinstimmung", sodass Sie nur das neueste Tag erhalten.

jthill
quelle
0

Wenn Ihre Tags sortierbar sind:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1
Clintm
quelle
0

Nicht viel erwähnte nicht kommentierte Tags gegenüber kommentierten hier. 'beschreiben' funktioniert mit kommentierten Tags und ignoriert nicht kommentierte.

Dies ist hässlich, führt jedoch den angeforderten Job aus und findet keine Tags in anderen Zweigen (und nicht in dem im folgenden Beispiel im Befehl angegebenen Befehl: master).

Die Filterung sollte wahrscheinlich optimiert (konsolidiert) werden, aber auch dies scheint der Job zu sein.

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

Kritik willkommen, da ich dies jetzt nutzen werde :)

Rondo
quelle
-2

Eine andere einfache Möglichkeit, den neuesten Tag-Namen zu erhalten, ist mit

git tag | tail -1

oder

TAG=$(git tag | tail -1)

um es in einer Variablen zu speichern.

git taglistet alle verfügbaren Tags auf und gibt die allerletzte Zeile zurück, wenn das Ergebnis angezeigt wird.tail-1

Xaver
quelle
4
Ohne Sortierung ist dies ein schlechter Schachzug.
mjd2