자식 브랜치의 태그를 다른 커밋으로 옮기려면 어떻게해야합니까?


858

마스터 브랜치에서 다음 v0.1과 같은 태그를 만들었습니다 .

git tag -a v0.1

그러나 릴리스 0.1의 마스터로 병합 해야하는 변경 사항이 여전히 있음을 깨달았습니다. 그러나 이제 내 v0.1태그가 잘못된 커밋에 붙어 있습니다 (Post-it Note 유추를 호출하기 위해). 마스터에서 가장 최근의 커밋에 붙어 있기를 원하지만 대신 마스터에서 두 번째로 최근 커밋에 붙어 있습니다.

마스터에서 가장 최근의 커밋으로 어떻게 옮길 수 있습니까?

답변:


1199

-f옵션을 사용하여 다음을 수행하십시오 git tag.

-f
--force

    Replace an existing tag with the given name (instead of failing)

어노테이션이없는 태그 대신 어노테이션이있는 태그를 작성하기 위해 -f함께 사용할 수 -a있습니다.

  1. 푸시하기 전에 리모컨의 태그를 삭제하십시오

    git push origin :refs/tags/<tagname>
    
  2. 가장 최근의 커밋을 참조하도록 태그를 교체하십시오.

    git tag -fa <tagname>
    
  3. 태그를 원격 원점으로 미십시오

    git push origin master --tags
    

90
당신이이 일을함으로써, 너무 밀어 넣기 전에 모든 원격에서 태그를 삭제하는 좋은 아이디어가 될 수 있습니다 : git push origin :refs/tag/<tagname>다음 할 git tag -fa <tagname>다음과 git push origin master --tags. 그렇지 않으면 ^ 및 {} 문자가 추가되어 리모컨의 심판 목록에 이상한 것들이 생길 수 있습니다. 이것을 지적 해준 codebasehq.com의 Dan에게 감사한다.
eedeep

47
@eedeep : 사소한 수정-대신 :refs/tag/<tagname>해야합니다 :refs/tags/<tagname>.
벤 호킹

8
이것은 컴퓨터에서 코드를 푸시하지 않은 경우에만 작동합니다. 당신이 가지고 있다면, 가장 좋은 대답은 아마도 번거롭지 않은 가치가 있기 때문에 '세계에 많은 숫자가 있습니다'입니다.
Chris Huang-Leaver 13:25에

33
태그를 이미 푸시 한 경우에도 여전히 강제 푸시로 원격 태그를 업데이트 할 수 있습니다git push -f origin <tagname>
rc_luke

11
여기와 문서에서 언급되지 않은 것은 새 메시지가 제공되지 않으면 실제로 태그 메시지를 이동한다는 것입니다.
Twonky

259

보다 정확하게는 태그를 강제로 추가 한 다음 --tags 및 -f 옵션을 사용하여 푸시해야합니다.

git tag -f -a <tagname>
git push -f --tags

171

리모컨이 호출 origin되고 master지점에서 작업중인 경우 요약하면 다음 과 같습니다.

git tag -d <tagname>
git push origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git push origin <tagname>
  • 1 행은 로컬 환경에서 태그를 제거합니다.
  • 2 행은 원격 환경에서 태그를 제거합니다.
  • 3 행은 다른 커밋에 태그를 추가합니다
  • 라인 4는 변경 사항을 리모컨으로 푸시합니다

또한 4 행을 교환 git push origin --tags하여 모든 변경 사항을 로컬 변경 사항의 태그로 푸시 할 수 있습니다 .

@ stuart-golodetz, @ greg-hewgill, @eedeep, @ ben-hocking 답변, 답변 아래 댓글 및 내 답변 아래 NateS 의견을 기반으로합니다.


87

로 삭제 git tag -d <tagname>한 다음 올바른 커밋에서 다시 작성하십시오.


3
@eedeep : Greg의 반응이 실제로 공정하기에 더 낫다고 생각합니다.
스튜어트 Golodetz 1

간단하게 유지하십시오. 삭제하고 다시 한 번 수행하십시오.
ooolala

1
이것은 단순성으로 받아 들여지는 대답이어야합니다. 또한 -f force를 과도하게 사용하지 않습니다.
chinnychinchin

48

Git을 사용할 때 몇 가지를 피하려고합니다.

  1. 내부 지식 (예 : 심판 / 태그) 사용 문서화 된 Git 명령 만 사용하려고 시도하고 .git 디렉토리의 내부 내용에 대한 지식이 필요한 것을 사용하지 마십시오. 즉, Git을 Git 개발자가 아닌 Git 사용자로 취급합니다.

  2. 필요하지 않은 경우 힘을 사용합니다.

  3. 지나친 것들. (분기 및 / 또는 많은 태그를 푸시하여 원하는 위치에 하나의 태그를 얻습니다.)

Git 내부에 대한 지식없이 로컬 및 원격으로 태그를 변경하는 비폭력 솔루션입니다.

소프트웨어 수정 프로그램에 궁극적으로 문제가있어서 업데이트 / 다시 릴리스해야 할 때 사용합니다.

git tag -d fix123                # delete the old local tag
git push github :fix123          # delete the old remote tag (use for each affected remote)
git tag fix123 790a621265        # create a new local tag
git push github fix123           # push new tag to remote    (use for each affected remote)

github샘플 원격 이름, fix123샘플 태그 이름 및 790a621265샘플 커밋입니다.


26

여기에 내가 필요로하는 다른 형태의 명령을 남길 것입니다. 움직일
태그가있었습니다 v0.0.1.2.

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

그리고:

$ git push --tags --force

좋은, 감사합니다, 2 개의 단순하고 간단한 명령
Sérgio

10

다른 방법 :

원격 저장소에서 태그를 이동하십시오 (필요한 경우 HEAD를 다른 것으로 교체하십시오).

$ git push --force origin HEAD:refs/tags/v0.0.1.2

변경 사항을 다시 가져옵니다.

$ git fetch --tags

이것은 다른 답변보다 "트랜잭션"입니다.
Justin M. Keyes

9

하나의 태그를 다른 커밋으로 옮기는 별칭.

샘플에서 해시 e2ea1639로 커밋을 이동하려면 다음을 수행하십시오 git tagm v0.1 e2ea1639.

푸시 된 태그의 경우을 사용하십시오 git tagmp v0.1 e2ea1639.

두 별칭 모두 원래 날짜와 메시지를 유지합니다. 당신이 사용 git tag -d하면 원래 메시지를 잃어 버렸습니다.

.gitconfig파일 에 저장하십시오

# Return date of tag. (To use in another alias)
tag-date = "!git show $1 | awk '{ if ($1 == \"Date:\") { print substr($0, index($0,$3)) }}' | tail -2 | head -1 #"

# Show tag message
tag-message = "!git show $1 | awk -v capture=0 '{ if(capture) message=message\"\\n\"$0}; BEGIN {message=\"\"}; { if ($1 == \"Date:\" && length(message)==0 ) {capture=1}; if ($1 == \"commit\" ) {capture=0}  }; END { print message }' | sed '$ d' | cat -s #"

### Move tag. Use: git tagm <tagname> <newcommit> 
tagm = "!GIT_TAG_MESSAGE=$(git tag-message $1) && GIT_COMMITTER_DATE=$(git tag-date $1) && git tag-message $1 && git tag -d $1 && git tag -a $1 $2 -m \"$GIT_TAG_MESSAGE\" #"

### Move pushed tag. Use: git tagmp <tagname> <newcommit> 
tagmp = "!git tagm $1 $2 && git push --delete origin $1 && git push origin $1 #"

1

주석이 달린 태그를 이동하려면 대상 커밋 만 변경하고 주석 메시지와 기타 메타 데이터는 보존하십시오.

moveTag() {
  local tagName=$1
  # Support passing branch/tag names (not just full commit hashes)
  local newTarget=$(git rev-parse $2^{commit})

  git cat-file -p refs/tags/$tagName | 
    sed "1 s/^object .*$/object $newTarget/g" | 
    git hash-object -w --stdin -t tag | 
    xargs -I {} git update-ref refs/tags/$tagName {}
}

사용법 : moveTag <tag-to-move> <target>

위의 기능은 teerapap / git-move-annotated-tag.sh 를 참조하여 개발되었습니다 .


1
더 이상 필요하지 않은 것 같습니다 : git tag -f -a my_tag이미 이전 메시지의 메시지를 유지합니다 (git 버전 2.11.0).
Matthijs Kooijman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.