gitタグの日付を変更(またはそれに基づいてGitHubリリース)


95

私は追加しているのリリースをメインブランチの様々なコミットにタグを追加することにより、GitHubの上の私のプロジェクトに。

私のプロジェクトの1つで、年代順にコミットにタグを追加しませんでした。(私は明らかなコミットを見つけてタグ付けし、それからあまり目立たない古いコミットを見つけてタグ付けしました。)

現在、GitHubは v1.0.1 最新として表示しており、その前にv0.7.0があり、その前にv1.1.2 があります。

タグ付けされているコミットではなく、タグの作成日をリリース日として使用しているようです。タグを編集して、日付がタグ付けされているコミットと同じになるようにするにはどうすればよいですか?

gitkとGitHub間のリリースと日付のマッピング

回答:


118

警告:注釈付きタグのタグメッセージ保持されません

概要

変更が必要なタグごとに:

  1. タグを表すコミットに時間をさかのぼります
  2. タグを削除する(ローカルおよびリモート)
    • これにより、GitHubの「リリース」が下書きになり、後で削除できます。
  3. 日付をコミットの日付に設定するマジック呼び出しを使用して、同じ名前のタグを再度追加します。
  4. 日付が固定された新しいタグをGitHubにプッシュします。
  5. GitHubに移動して、現在ドラフトになっているリリースを削除し、新しいタグから新しいリリースを再作成します

コードで:

# 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

細部

Gitのタグ付け方法によると:

リリースやバージョンのバンプにタグを付けるのを忘れた場合は、いつでも遡ってタグを付けることができます。

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

そして、それは完全に使用可能ですが、タグを時系列順に並べ替える効果があり、「最新」のタグを探すビルドシステムに干渉する可能性があります。しかし、恐れはありません。ライナスはすべてを考えました:

# 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"

ただし、タグをすでに追加している場合は、上記を一緒に使用できません。そうしないとgit tag -f existingtag、gitがマージしようとすると文句を言います。

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

代わりに、ローカルでタグを削除する必要があります。

git tag -d 1.0.1

その削除をリモートでプッシュします。

git push origin :refs/tags/1.0.1

GitHubで、リリースを再読み込み(リリースは「ドラフト」としてマークされています)して、ドラフトを削除します。

次に、上記の手順に基づいてバックデートタグを追加し、最後に結果のタグをGitHubにプッシュします。

git push --tags

次に、GitHubリリース情報を再度追加します。


2
:ここではbashスクリプトを除去・gitのレポ内のすべてのタグを再追加することにありますgit tag -l | while read -r tag; do `git checkout $tag && git tag -d $tag && git push origin :refs/tags/$tag && GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag -a $tag -m"$tag"`; done; git push --tags
Phrogz

11
タグをチェックアウトしなくても、これらすべてを実行できるはずです。これは私にとってはるかに高速だったあなたのワンライナーの修正です:git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) && git tag -d $tag && git push origin :refs/tags/$tag && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a $tag -m"$tag" $COMMIT_HASH ; done && git push --tags
vmrob

2
を使用git tag -afすると-d不要になり、ローカルにとどまるので、すべてが問題ないことを確認できます-その後、次のことができますgit push --tags -f
Mr_and_Mrs_D

3
@Mr_and_Mrs_D良い提案と、この操作をワンプッシュに制限する良い方法。それを念頭に置いて、私は結果として生じる(テストされていない)ワンライナーは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
vmrob

2
:このPowerShellのgitのシェルで動作しますが、あなたは違った環境変数を設定し、2行にそれをしなければならない $env:GIT_COMMITTER_DATE="Thu Nov 11 12:21:57 2010 -0800"git tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"
roncli

18

以下は、他の回答のコメントの一部に基づくワンライナーです。

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

警告:これはアップストリームタグを核にし、注釈付きタグのメッセージを保持しません!あなたが何をしているのかを知っていることを確認し、公開リポジトリに対してこれを絶対に行わないでください!!!

それを分解するには...

# 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

シングルプッシュの使用を提案してくれた@Mr_and_Mrs_Dに感謝します。


3

他の回答を踏まえ、ここでの方法ですしますタグメッセージの最初の行を保存します

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

メッセージの保持に責任があるビットは次のとおりです:

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

head -n1古いコミットメッセージの最初の行を取ります。-n2またはに変更して、-n3代わりに2行または3行を取得できます。

1つのタグのみの日付/時刻を変更したい場合、これは、ワンライナーを分解してbashシェルで変更する方法です。

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

参照:


ありがとうございます。ただし、単一のタグを変更するコマンドで-sは、ワンライナーに存在しないフラグがあるerror: gpg failed to sign the dataため、gitの署名設定を行っていないために取得していました。そのエラーは私を少しの間失望させました。
WCH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.