it-swarm.com.de

Ändern des Datums des Git-Tags (oder der darauf basierenden GitHub-Version)

Ich füge Releases zu meinen Projekten auf GitHub hinzu, indem ich Tags zu verschiedenen Commits im Main-Zweig hinzufüge. 

In einem meiner Projekte habe ich die Tags nicht in chronologischer Reihenfolge zu den Commits hinzugefügt. (Ich fand offensichtliche Commits und markierte sie, und dann fand ich weniger offensichtlich, ältere Commits und markierten sie.)

Nun zeigt GitHub v1.0.1 als aktuell, v0.7.0 davor und v1.1.2 that

Es scheint, dass das Datum bei der Erstellung eines Tags als Veröffentlichungsdatum verwendet wird, anstelle des Commits, das markiert wird. Wie kann ich meine Tags so bearbeiten, dass ihr Datum dem Commit entspricht, das sie mit einem Tag versehen?

 mapping of releases and dates between gitk and GitHub

81
Phrogz

WARNUNG: Dadurch werden nicht Tag-Nachrichten für mit Anmerkungen versehene Tags beibehalten.

Zusammenfassung

Für jedes Tag, das geändert werden muss:

  1. Gehen Sie in der Zeit zurück zu dem Commit, das das Tag darstellt
  2. Löschen Sie das Tag (lokal und remote)
    • Dadurch wird Ihr "Release" auf GitHub zu einem Entwurf, den Sie später löschen können.
  3. Fügen Sie das gleichnamige Tag erneut mit einem magischen Aufruf hinzu, der sein Datum auf das Datum der Festschreibung setzt.
  4. Schieben Sie die neuen Tags mit festem Datum zurück in GitHub.
  5. Gehen Sie zu GitHub, löschen Sie alle jetzt entworfenen Versionen und erstellen Sie neue Versionen der neuen Tags

In Code:

# Fixing tag named '1.0.1'
git checkout 1.0.1               # Go to the associated commit
git tag -d 1.0.1                 # Locally delete the tag
git Push Origin :refs/tags/1.0.1 # Push this deletion up to GitHub

# Create the tag, with a date derived from the current head
GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag -a 1.0.1 -m"v1.0.1"

git Push --tags                  # Send the fixed tags to GitHub

Einzelheiten

Gemäß How to tag in Git:

Wenn Sie vergessen, ein Release oder einen Versions-Bump mit einem Tag zu versehen, können Sie es immer nachträglich wie folgt markieren:

git checkout SHA1_OF_PAST_COMMIT
git tag -m"Retroactively tagging version 1.5" v1.5

Und obwohl dies perfekt verwendbar ist, hat dies den Effekt, dass Ihre Tags nicht in chronologischer Reihenfolge angeordnet werden, was bei Build-Systemen, die nach dem "neuesten" Tag suchen, vermasseln kann. Aber habe keine Angst. Linus dachte an alles:

# This moves you to the point in history where the commit exists
git checkout SHA1_OF_PAST_COMMIT

# This command gives you the datetime of the commit you're standing on
git show --format=%aD  | head -1

# And this temporarily sets git tag's clock back to the date you copy/pasted in from above
GIT_COMMITTER_DATE="Thu Nov 11 12:21:57 2010 -0800" git tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"

# Combining the two...
GIT_COMMITTER_DATE="$(git show --format=%aD  | head -1)" git tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"

Wenn Sie das Tag jedoch bereits hinzugefügt haben, können Sie das Obige nicht mit git tag -f existingtag verwenden. Andernfalls beschwert sich git beim Zusammenführen:

Rammy:docubot phrogz$ git Push --tags
To [email protected]:Phrogz/docubot.git
 ! [rejected]        1.0.1 -> 1.0.1 (already exists)
error: failed to Push some refs to '[email protected]:Phrogz/docubot.git'
hint: Updates were rejected because the tag already exists in the remote.

Stattdessen müssen Sie das Tag lokal entfernen:

git tag -d 1.0.1

Drücke den Löschvorgang remote:

git Push Origin :refs/tags/1.0.1

Reload Releases auf GitHub - die Version wurde nun als "Entwurf" markiert - und der Entwurf entfernt.

Fügen Sie nun das backdated-Tag gemäß den obigen Anweisungen hinzu, und drücken Sie schließlich das resultierende Tag an GitHub:

git Push --tags

und fügen Sie dann die GitHub-Release-Informationen erneut hinzu.

101
Phrogz

Hier ist ein Einzeiler basierend auf einigen Kommentaren in der anderen Antwort:

git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$tag" $COMMIT_HASH ; done && git Push --tags --force

WARNUNG: Dadurch werden Ihre Upstream-Tags gelöscht undnichtMeldungen für kommentierte Tags beibehalten! Stellen Sie sicher, dass Sie wissen, was Sie tun, und tun Sie dies NICHT für ein öffentliches Repository !!!

Um es niederzureißen ...

# Loop over tags
git tag -l | while read -r tag
do

    # get the commit hash of the current tag
    COMMIT_HASH=$(git rev-list -1 $tag)

    # get the commit date of the tag and create a new tag using
    # the tag's name and message. By specifying the environment
    # environment variable GIT_COMMITTER_DATE before this is
    # run, we override the default tag date. Note that if you
    # specify the variable on a different line, it will apply to
    # the current environment. This isn't desired as probably
    # don't want your future tags to also have that past date.
    # Of course, when you close your Shell, the variable will no
    # longer persist.
    GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$tag" $COMMIT_HASH


done

# Force Push tags and overwrite ones on the server with the same name
git Push --tags --force

Vielen Dank an @Mr_and_Mrs_D für den Vorschlag, einen einzelnen Push zu verwenden.

15
vmrob

Aufbauend auf den anderen Antworten kann will die erste Zeile der Tag-Nachricht beibehalten

git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1) && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$COMMIT_MSG" $COMMIT_HASH ; done
git tag -l -n1           #check by listing all tags with first line of message
git Push --tags --force  #Push edited tags up to remote

Das für die Aufbewahrung der Nachrichten verantwortliche Bit ist:

COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1)

head -n1 nimmt die erste Zeile der alten Commit-Nachricht. Sie können es in -n2 oder -n3 etc ändern, um stattdessen zwei oder drei Zeilen zu erhalten.

Wenn Sie das Datum und die Uhrzeit für nur ein Tag ändern möchten, können Sie den One-Liner in Ihrer bash-Shell aufteilen:

tag=v0.1.0
COMMIT_HASH=$(git rev-list -1 $tag)
COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1)
COMMIT_DATE=$(git show $COMMIT_HASH --format=%aD | head -1)
GIT_COMMITTER_DATE=$COMMIT_DATE git tag -s -a -f $tag -m"$COMMIT_MSG" $COMMIT_HASH

Verweise:

0
weiji14