Breadcrumbs
태그는 깃 레포지토리에서 특정 객체를 가리키는 역할을 합니다. 보통 릴리즈 버전 등 소스코드의 특별한 버전을 기록하는 데에 많이 사용됩니다. 깃 태그에 관련된 명령어들을 정리해보겠습니다.
tag
명령어를 이용하여 현재 로컬 저장소의 모든 태그를 조회할 수 있습니다.
> git tag
v1.0.0
v1.0.1
v2.0.0
v2.2.0
tag
명령어를 -l
또는 --list
옵션 및 와일드카드 패턴과 함께 사용하여 조건에 맞는 태그를 조회할 수 있습니다.
> git tag -l "v2.*"
v2.0.0
v2.2.0
show-ref
명령어를 --tags
옵션과 함께 사용하여 태그 리스트를 볼 수도 있습니다.
> git show-ref --tags
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
f3d335a2b45670624eaf84a0c9d8dccd77353e29 refs/tags/v1.0.1
ddbb5e8fb36559a5693655eb44937e424cab46f6 refs/tags/v2.0.0
904b9a448772d47c32b6eb21e00985d3bfde486a refs/tags/v2.2.0
show
명령어를 사용하여 특정 태그에 대한 정보를 볼 수 있습니다.
> git show v2.0.0
tag v2.0.0
Tagger: seizze ...
Date: Tue Dec 24 16:21:12 2019 +0900
commit 243912f247b3cfeef5c27f3be83f28c08aa7c2d3 (tag: v2.0.0)
Author: seizze ...
Date: Fri Oct 11 02:51:40 2019 +0900
Commit message
// ...
깃은 lightweight와 annotated 두 종류의 태그를 지원합니다. lightweight 태그는 단지 특정 커밋에 대한 포인터 역할만 하며, annotated 태그는 깃 데이터베이스에 완전한 객체로 저장되어 태그한 사람의 이름과 이메일, 날짜, 태그 메시지 등을 함께 저장할 수 있습니다. 그리고 GNU Privacy Guard (GPG)로 서명될 수 있습니다.
tag
명령어를 다음과 같이-a
옵션과 함께 사용하여 annotated 태그를 생성할 수 있습니다.
> git tag -a <TAG NAME> -m "<TAG MESSAGE>"
-a
, -s
, -m
중 아무 옵션도 지정하지 않으면 lightweight 태그를 생성할 수 있습니다. lightweight 태그에는 어떠한 추가적인 정보도 저장할 수 없습니다.
> git tag <TAG NAME>
특정 커밋을 지정하여 해당 커밋에 태그하려면, 커맨드 맨 뒤에 커밋 checksum의 시작 부분 일부를 지정합니다.
> git tag -a <TAG NAME> <COMMIT CHECKSUM>
lightweight 태그와 annotated 태그는 show
명령어를 이용하여 조회했을 때 다음과 같은 차이가 있습니다.
> git tag -a v2.2.1 -m "Tag message" 66b7e57
> git tag v2.2.2-lw
> git show v2.2.1
tag v2.2.1
Tagger: seizze ...
Date: Tue Dec 24 20:17:04 2019 +0900
Tag message
commit 66b7e57d4b11283078f974a7818b77e268bbc5c0 (tag: v2.2.1)
Author: seizze ...
Date: Fri Oct 11 16:57:30 2019 +0900
Commit message
// ...
> git show v2.2.2-lw
commit a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 (HEAD -> master, tag: v2.2.2-lw, origin/master)
Author: seizze ...
Date: Fri Oct 11 21:04:52 2019 +0900
Commit message
v2.2.1
라는 이름과 “Tag message”라는 태그 메시지를 가진 annotated 태그를 커밋 66b7e57
에 생성하였고, v2.2.2-lw
라는 이름의 lightweight 태그를 현재 커밋에 생성하였습니다. annotated 태그는 태그 정보와 커밋 정보를 함께 보여주지만, lightweight 태그는 태그에 대한 추가적인 정보를 저장할 수 없기 때문에 가리키고 있는 커밋에 대한 정보만 보여줍니다.
추가적으로, show-ref
명령어를 --tags
옵션과 함께 사용했을 때, --dereference
(또는 -d
) 옵션의 유무는 다음과 같은 차이점이 있습니다.
> git show-ref --tags
// ...
3b0cb630236559e57c804642ef81e0d9f80def10 refs/tags/v2.2.1
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
> git show-ref --tags --dereference
// ...
3b0cb630236559e57c804642ef81e0d9f80def10 refs/tags/v2.2.1
66b7e57d4b11283078f974a7818b77e268bbc5c0 refs/tags/v2.2.1^{}
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
show-ref
는 사실 로컬 리포지토리의 레퍼런스들을 보여주는 명령어입니다. --dereference
는 문자 그대로 태그를 dereferencing하여 태그가 가리키고 있는 내용도 보여줍니다. 이 경우 ^{}
를 뒤에 붙여서 보여줍니다.
*
연산자를 dereference operator라 하며, 이 동작을 포인터를 dereferencing한다고 부른다.이전에도 언급했듯이, 깃에서 annotated 태그는 태그하고 있는 객체의 메타데이터와 SHA-1를 포함하고 있으며, 그 자체의 메시지와 ID를 갖고있는 객체입니다. lightweight 태그는 태그 객체가 아니고, 태그한 객체를 그저 가리키고만 있습니다.
그러므로 show-ref --tags
명령어를 그냥 사용하면, 레퍼런스들을 보여주므로 annotated 태그의 경우 가리키고 있는 태그 객체의 ID(3b0cb63
)를 보여주며 lightweight 태그의 경우 객체가 아니므로 그 자체의 ID가 없고 가리키고 있는 커밋 ID(a859fc4
)를 보여줍니다.
--dereference
옵션과 함께 사용하면, 태그 객체를 dereferencing한 결과로, 태그 객체가 가리키고 있는 커밋 ID(66b7e57
)도 보여줍니다. 이는 annotated 태그에만 해당되며, lightweight 태그는 객체가 존재하지 않으므로 해당되지 않습니다(--dereference
옵션을 사용하지 않고 출력한 결과와 같습니다.).
로컬 저장소의 태그를 삭제하려면 -d
또는 --delete
옵션과 함께 사용합니다.
> git tag -d v2.2.1
Deleted tag 'v2.2.1' (was 3b0cb63)
이미 만들어진 로컬 저장소의 태그를 수정하려면, 다음과 같이 사용합니다.
> git tag -a <NEW TAG NAME> <OLD TAG NAME>^{} -m "<NEW TAG MESSAGE>"
> git tag -d <OLD TAG NAME>
기존 태그가 가리키고 있는 커밋을 가리키는 새로운 annotated 태그를 생성한다는 의미입니다. (lightweight의 경우 옵션을 지정하지 않으면 됩니다.) 예를 들어, 다음과 같이 사용합니다.
> git show-ref --tags --dereference
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
2cf8c22706d2f72bcaf95086cf4c6926bd5d24a6 refs/tags/v1.0.0^{}
f3d335a2b45670624eaf84a0c9d8dccd77353e29 refs/tags/v1.0.1
b661213fb1e00bcc80f42dcde3c72f750fa8c2e9 refs/tags/v1.0.1^{}
ddbb5e8fb36559a5693655eb44937e424cab46f6 refs/tags/v2.0.0
243912f247b3cfeef5c27f3be83f28c08aa7c2d3 refs/tags/v2.0.0^{}
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
> git tag -a v4.0.0 v2.0.0^{} -m "new tag message"
> git tag -d v2.0.0
Deleted tag 'v2.0.0' (was ddbb5e8)
> git show-ref --tags --dereference
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
2cf8c22706d2f72bcaf95086cf4c6926bd5d24a6 refs/tags/v1.0.0^{}
f3d335a2b45670624eaf84a0c9d8dccd77353e29 refs/tags/v1.0.1
b661213fb1e00bcc80f42dcde3c72f750fa8c2e9 refs/tags/v1.0.1^{}
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
71acb8920d6045e411a8679aea68b36d80c95f7d refs/tags/v4.0.0
243912f247b3cfeef5c27f3be83f28c08aa7c2d3 refs/tags/v4.0.0^{}
^{}
는 태그가 아닌 객체가 나타날 때까지 태그를 dereference한다는 뜻으로, v2.0.0^{}
는 v2.0.0
태그가 가리키고 있는 커밋 객체를 의미합니다. ^{}
를 명시하지 않으면 기존 태그가 가리키고 있던 커밋을 가리키는 새로운 태그 객체를 생성하는 것이 아니라 기존 태그 객체를 가리키는 새로운 객체(lightweight의 경우 포인터)를 생성하게 되므로 목적에 맞지 않습니다.
ls-remote
명령어는 원격 저장소의 레퍼런스들을 출력합니다. 이를 이용하여 원격 저장소의 태그 목록을 볼 수 있습니다.
> git ls-remote --tags
기본적으로 push
명령어만으로는 태그가 서버에 올라가지 않습니다. 서버에 태그를 공유하려면, 명시적으로 태그를 푸시해야 합니다.
> git push <REMOTE> <TAG NAME>
예를 들어 다음과 같이 사용합니다.
> git push origin v1.0.0
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 150 bytes | 75.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://...
* [new tag] v1.0.0 -> v1.0.0
> git ls-remote --tags
From https://...
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
2cf8c22706d2f72bcaf95086cf4c6926bd5d24a6 refs/tags/v1.0.0^{}
--tags
옵션을 이용하여 전체 태그를 한 번에 푸시할 수 있습니다.
> git push origin --tags
Enumerating objects: 2, done.
Counting objects: 100% (2/2), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 277 bytes | 277.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To https://...
* [new tag] v1.0.1 -> v1.0.1
* [new tag] v2.2.2-lw -> v2.2.2-lw
* [new tag] v4.0.0 -> v4.0.0
> git ls-remote --tags
From https://...
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
2cf8c22706d2f72bcaf95086cf4c6926bd5d24a6 refs/tags/v1.0.0^{}
f3d335a2b45670624eaf84a0c9d8dccd77353e29 refs/tags/v1.0.1
b661213fb1e00bcc80f42dcde3c72f750fa8c2e9 refs/tags/v1.0.1^{}
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
71acb8920d6045e411a8679aea68b36d80c95f7d refs/tags/v4.0.0
243912f247b3cfeef5c27f3be83f28c08aa7c2d3 refs/tags/v4.0.0^{}
--tags
옵션을 이용하여 전체 태그를 한 번에 푸시할 때 annotated와 lightweight 태그는 구분되지 않고 올라갑니다.
--follow-tags
옵션을 이용하여 커밋과 태그를 동시에 푸시할 수도 있습니다.
> git push --follow-tags
원격 저장소의 태그를 지우기 위해서는 다음 명령어들 중 하나를 사용합니다.
> git push <REMOTE> :refs/tags/<TAG NAME>
> git push <REMOTE> :<TAG NAME>
> git push <REMOTE> -d <TAG NAME>
> git push <REMOTE> --delete <TAG NAME>
예를 들어 다음과 같이 사용합니다.
> git ls-remote --tags
From https://....
44380aab1c606cfcfe5d09bf65d063a674fe1aaf refs/tags/v1.0.0
2cf8c22706d2f72bcaf95086cf4c6926bd5d24a6 refs/tags/v1.0.0^{}
f3d335a2b45670624eaf84a0c9d8dccd77353e29 refs/tags/v1.0.1
b661213fb1e00bcc80f42dcde3c72f750fa8c2e9 refs/tags/v1.0.1^{}
a859fc475db6d86b0a7e9b324c5ec3fb833f87c5 refs/tags/v2.2.2-lw
71acb8920d6045e411a8679aea68b36d80c95f7d refs/tags/v4.0.0
243912f247b3cfeef5c27f3be83f28c08aa7c2d3 refs/tags/v4.0.0^{}
> git push origin :refs/tags/v1.0.0
To https://...
- [deleted] v1.0.0
> git push origin :v1.0.1
To https://...
- [deleted] v1.0.1
> git push origin -d v2.2.2-lw
To https://...
- [deleted] v2.2.2-lw
> git push origin --delete v4.0.0
To https://...
- [deleted] v4.0.0
> git ls-remote --tags
From https://...