1 Tag란?
Tag는 특정 커밋에 붙이는 이름표다. 주로 릴리스 버전을 표시할 때 사용한다.
A --- B --- C --- D --- E
↑ ↑
v1.0.0 v2.0.0
브랜치와 달리 태그는 한번 붙이면 움직이지 않는다. 특정 시점의 스냅샷을 영구적으로 기록하는 용도다.
2 Tag의 두 가지 종류
2.1 Lightweight Tag
단순히 커밋에 이름만 붙인다. 내부적으로 커밋 해시를 가리키는 포인터일 뿐이다.
성공 시 아무 출력도 없다. git tag 로 확인한다.
2.2 Annotated Tag (권장)
태그 자체가 Git 객체로 저장되며, 작성자, 날짜, 메시지 등의 메타데이터를 포함한다.
성공 시 아무 출력도 없다. git show v1.0.0 으로 메타데이터를 확인할 수 있다:
tag v1.0.0
Tagger: Kwangmin Kim <user@example.com>
Date: Mon Jan 15 14:30:00 2024 +0900
첫 번째 정식 릴리스
commit abc1234 (HEAD -> main, tag: v1.0.0)
Author: Kwangmin Kim <user@example.com>
Date: Mon Jan 15 14:00:00 2024 +0900
feat: 첫 번째 릴리스 기능 완성
Annotated Tag에는 tagger(태그 작성자), 날짜, 태그 메시지가 커밋 정보 위에 표시된다. Lightweight Tag는 이 정보가 없다.
2.3 비교
| 항목 | Lightweight | Annotated |
|---|---|---|
| 메타데이터 | 없음 | 작성자, 날짜, 메시지 |
| Git 객체 | 아님 (포인터만) | 독립적인 Git 객체 |
| 서명 가능 | 불가 | GPG 서명 가능 |
| 용도 | 임시 마킹 | 릴리스 버전 |
릴리스 용도로는 항상 Annotated Tag를 사용하는 것이 좋다. 누가, 언제, 왜 태그를 만들었는지 기록이 남는다.
3 Tag 관리 명령어
3.1 태그 목록 확인
v0.1.0
v1.0.0
v1.1.0
v2.0.0
알파벳순으로 정렬된다.
v1.0.0
v1.1.0
v2.0.0
v1.1.0
v1.0.0
v0.1.0
-creatordate (마이너스 기호)는 최신순 정렬이다. 최신 릴리스를 먼저 확인하고 싶을 때 유용하다.
3.2 태그 삭제
Deleted tag 'v1.0.0' (was abc1234)
To https://github.com/username/repo.git
- [deleted] v1.0.0
3.3 태그와 관련된 커밋 확인
f432109 feat: 검색 기능 추가 e123456 feat: 대시보드 개선 d789012 fix: 결제 버그 수정
# 현재 커밋에서 가장 가까운 태그 확인
git describe
v1.0.0-3-gabc1234
`v1.0.0` 태그 이후 3개의 커밋이 있고, 현재 HEAD는 `abc1234` 해시임을 나타낸다. 현재 커밋이 태그와 일치하면 태그 이름만 출력된다:
v1.0.0
4 태그를 원격에 Push
태그는 기본적으로 git push에 포함되지 않는다. 명시적으로 push해야 한다.
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/username/repo.git
* [new tag] v1.0.0 -> v1.0.0
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/username/repo.git
* [new tag] v0.1.0 -> v0.1.0
* [new tag] v1.0.0 -> v1.0.0
* [new tag] v1.1.0 -> v1.1.0
[new tag] 줄이 push된 각 태그마다 나타난다.
--follow-tags 는 커밋을 push할 때 해당 커밋에 연결된 Annotated Tag만 함께 push한다. Lightweight Tag는 push되지 않는다.
5 태그로 체크아웃
특정 태그의 코드를 확인하거나 해당 시점으로 돌아갈 때 사용한다.
Note: switching to 'v1.0.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you make, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
HEAD is now at abc1234 feat: 첫 번째 릴리스 기능 완성
detached HEAD 상태라는 경고와 함께 해당 커밋으로 이동한다.
Switched to a new branch 'hotfix/v1.0.1'
git checkout v1.0.0을 하면 “Detached HEAD” 상태가 된다. 이 상태에서 커밋하면 브랜치에 속하지 않는 커밋이 생긴다. 작업이 필요하면 반드시 새 브랜치를 만들어야 한다.
6 Semantic Versioning (SemVer)
태그 이름에 사용하는 버전 번호 규칙이다. 대부분의 소프트웨어 프로젝트에서 사용한다.
v MAJOR . MINOR . PATCH
↑ ↑ ↑
주요 부가 패치
| 버전 | 변경 시점 | 예시 |
|---|---|---|
| MAJOR | 하위 호환이 깨지는 변경 | v1.0.0 → v2.0.0 |
| MINOR | 하위 호환되는 새 기능 추가 | v1.0.0 → v1.1.0 |
| PATCH | 하위 호환되는 버그 수정 | v1.0.0 → v1.0.1 |
예시:
v0.1.0 → 초기 개발 (불안정)
v1.0.0 → 첫 정식 릴리스
v1.1.0 → 새 기능 추가 (기존 기능 유지)
v1.1.1 → 버그 수정
v2.0.0 → 기존 API 변경 (하위 호환 깨짐)
추가 레이블:
v1.0.0-alpha → 알파 버전 (내부 테스트)
v1.0.0-beta → 베타 버전 (외부 테스트)
v1.0.0-rc.1 → 릴리스 후보 1
7 GitHub Releases
GitHub에서는 태그를 기반으로 Release를 생성할 수 있다. Release에는 릴리스 노트, 바이너리 파일 등을 첨부할 수 있다.
7.1 GitHub에서 Release 만들기
- 저장소 페이지 → Releases → Create a new release
- Choose a tag → 기존 태그 선택 또는 새 태그 입력
- Release title 입력 (예: “v1.0.0 - 첫 번째 릴리스”)
- Release notes 작성
- 필요시 바이너리 파일 첨부
- Publish release 클릭
7.2 CLI로 Release 만들기
8 실전 워크플로우
9 요약
| 명령어 | 동작 |
|---|---|
git tag v1.0.0 |
Lightweight 태그 생성 |
git tag -a v1.0.0 -m "msg" |
Annotated 태그 생성 |
git tag |
태그 목록 확인 |
git show v1.0.0 |
태그 상세 정보 |
git push origin v1.0.0 |
태그 원격에 push |
git push origin --tags |
모든 태그 push |
git tag -d v1.0.0 |
로컬 태그 삭제 |
git push origin --delete v1.0.0 |
원격 태그 삭제 |
git checkout v1.0.0 |
태그 시점으로 이동 |