git 태그 (또는이를 기반으로 한 GitHub 릴리스)의 날짜 변경


95

메인 브랜치의 다양한 커밋에 태그를 추가하여 GitHub의 프로젝트에 릴리스 를 추가 하고 있습니다.

내 프로젝트 중 하나에서 시간 순서대로 커밋에 태그를 추가하지 않았습니다. (명백한 커밋을 찾아서 태그를 지정한 다음 덜 분명하고 오래된 커밋을 찾아서 태그를 지정했습니다.)

이제 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

완벽하게 사용할 수 있지만, "최신"태그를 찾는 빌드 시스템을 망칠 수있는 시간순으로 태그를 배치하는 효과가 있습니다. 그러나 두려워하지 마십시오. Linus는 모든 것을 생각했습니다.

# 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
다음은 git 저장소의 모든 태그를 제거하고 다시 추가하는 bash 스크립트입니다.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
같을

2
이것은 PowerShell 용 git shell에서 작동하지만 환경 변수를 다르게 설정하고 두 줄로 설정해야합니다. $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등으로 수정할 수 있습니다 .

하나의 태그에 대한 날짜 / 시간을 변경하려는 경우 다음과 같이 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 datagit에 대한 서명을 설정하지 않았기 때문에 얻었 습니다. 그 오류로 인해 잠시 멈췄습니다.
wch
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.