11. 배포 관리와 태그(Tag)
- 태그가 무엇이고 왜 배포(릴리스)에 쓰이는지 이해한다
- annotated 태그와 lightweight 태그의 차이를 안다
- 특정 커밋에 태그를 달고, 태그로 체크아웃한다
- 태그를 원격에 공유·동기화하고, 수정·삭제한다
11.1 태그란 무엇인가?
브랜치가 "계속 움직이는 이름표"였다면, 태그(Tag)는 특정 커밋에 박아두는 "움직이지 않는 이정표"입니다. 주로 "이 커밋이 버전 1.0.0이다"처럼 의미 있는 시점을 표시할 때 사용합니다.
gitGraph
commit id: "A"
commit id: "B"
commit id: "C" tag: "v1.0.0"
commit id: "D"
commit id: "E" tag: "v1.1.0"
commit id: "F" tag: "v2.0.0"
브랜치(main)는 커밋이 쌓일 때마다 계속 움직이지만, 태그는 한번 박으면 그 커밋에 영원히 고정됩니다.
- 브랜치는 커밋이 쌓일 때마다 앞으로 이동하지만, 태그는 한번 달면 그 커밋에 영원히 고정됩니다.
- "릴리스(배포)한 버전"을 기록하는 데 가장 많이 쓰입니다.
🏷️ 책갈피 비유
책(저장소)을 읽다가 중요한 페이지(커밋)에 책갈피(태그)를 꽂아둡니다. 책을 더 읽어 나가도(커밋 추가) 책갈피는 그 페이지에 그대로 있습니다. 나중에 "1장 끝부분"을 바로 펼칠 수 있죠.
11.2 버전 태그와 시맨틱 버저닝
태그 이름으로 가장 널리 쓰이는 규칙이 시맨틱 버저닝(Semantic Versioning)입니다.
v MAJOR . MINOR . PATCH v 2 . 1 . 3
| 자리 | 이름 | 언제 올리나 |
|---|---|---|
| MAJOR | 주 버전 | 기존과 호환 안 되는 큰 변경 |
| MINOR | 부 버전 | 호환되는 기능 추가 |
| PATCH | 수 버전 | 호환되는 버그 수정 |
예: v1.0.0 → 버그 수정 → v1.0.1 → 기능 추가 → v1.1.0 → 대규모 개편 → v2.0.0
v를 붙입니다(v1.0.0). GitHub의 Releases 기능도 이 태그를 기준으로 동작합니다.11.3 태그의 두 종류
Git의 태그는 두 가지입니다. 실무에서는 annotated 태그를 권장합니다.
| Annotated (주석 태그) | Lightweight (가벼운 태그) | |
|---|---|---|
| 저장 방식 | 별도 객체로 저장 | 커밋을 가리키는 이름표만 |
| 작성자/날짜 | 기록됨 | 없음 |
| 메시지 | 있음 | 없음 |
| 서명(GPG) | 가능 | 불가 |
| 용도 | 공식 릴리스(권장) | 임시·개인용 북마크 |
11.4 Annotated 태그 만들기 (권장)
-a(annotated)와 -m(메시지) 옵션을 씁니다.
# 현재 커밋(HEAD)에 annotated 태그 달기 git tag -a v1.0.0 -m "First stable release"
작성자, 날짜, 메시지가 함께 기록됩니다. 상세 정보를 확인해봅시다.
git show v1.0.0
tag v1.0.0
Tagger: Hong Gildong <hong@example.com>
Date: Mon Jun 23 15:00:00 2026 +0900
First stable release
commit a1b2c3d...
(해당 커밋 내용)
11.5 Lightweight 태그 만들기
아무 옵션 없이 이름만 주면 가벼운 태그가 됩니다.
git tag v1.0.0-beta
메시지·작성자 정보가 없어, 잠깐 표시해두는 개인 북마크 용도로 적합합니다.
11.6 태그 목록 보기
# 모든 태그 보기 git tag # 패턴으로 필터링 git tag -l "v1.*" # 태그와 메시지를 함께 보기 git tag -n
v1.0.0 v1.1.0 v2.0.0
11.7 특정(과거) 커밋에 태그 달기
깜빡하고 태그를 안 달았던 과거 커밋에도 나중에 태그를 달 수 있습니다. 커밋 해시를 지정하면 됩니다.
# 과거 커밋 해시 확인 git log --oneline
a1b2c3d (HEAD) Latest work 9f8e7d6 Release-worthy commit ← 여기에 태그를 달고 싶다 c3d4e5f Initial commit
# 해당 커밋에 태그 달기 git tag -a v0.9.0 9f8e7d6 -m "Pre-release version"
소스트리에서는 원하는 커밋을 우클릭 → "Tag..."를 선택해 이름과 메시지를 입력하면 됩니다. 어느 커밋에 다는지 그래프로 확인하며 작업할 수 있어 직관적입니다.
11.8 태그 중복 방지
이미 있는 이름으로 태그를 또 달려고 하면 Git이 막아줍니다.
git tag v1.0.0
fatal: tag 'v1.0.0' already exists
정말 덮어써야 한다면 -f(force)를 쓰지만, 이미 공유한 태그에는 위험하므로 권장하지 않습니다.
git tag -f -a v1.0.0 -m "..." # 강제 재생성 (주의)
11.9 태그 삭제
# 로컬 태그 삭제 git tag -d v1.0.0
Deleted tag 'v1.0.0' (was a1b2c3d)
원격 태그 삭제는 11.12에서 다룹니다(로컬 삭제만으로는 원격에서 사라지지 않습니다).
11.10 태그로 체크아웃하기
태그가 가리키는 시점의 코드를 그대로 보고 싶을 때:
git checkout v1.0.0 # 또는 git switch --detach v1.0.0
태그는 고정된 지점이라, 체크아웃하면 detached HEAD 상태(6장)가 됩니다. 그 버전을 기반으로 작업을 이어가려면 새 브랜치를 만드세요.
git switch -c hotfix-v1.0.0 v1.0.0 # v1.0.0 시점에서 새 브랜치 시작
11.11 태그 공유(동기화) — 원격에 올리기
git push는 태그를 자동으로 올리지 않습니다. 태그는 따로 push해야 합니다. 이걸 모르면 "분명 태그를 달았는데 GitHub에 안 보인다"고 당황하게 됩니다.특정 태그 하나만 올리기
git push origin v1.0.0
모든 로컬 태그를 한 번에 올리기
git push origin --tags
커밋과 태그를 함께 올리기
git push --follow-tags # annotated 태그만 커밋과 함께 push
GitHub에 태그를 올리면 Releases 페이지에서 그 태그를 기반으로 릴리스 노트와 다운로드 파일을 만들 수 있습니다. 이것이 오픈소스 배포의 표준 방식입니다.
원격 태그 가져오기
git fetch --tags # 원격의 모든 태그 받기
11.12 원격 태그 수정과 삭제
원격 태그 삭제
로컬에서 지워도 원격엔 남아있으므로, 원격에서도 따로 지워야 합니다.
# 로컬 삭제 git tag -d v1.0.0 # 원격 삭제 git push origin --delete v1.0.0 # 또는 git push origin :refs/tags/v1.0.0
원격 태그 수정(이동)
이미 공유한 태그를 다른 커밋으로 옮기는 것은 권장되지 않습니다. 동료가 받은 태그와 어긋나기 때문입니다(리베이스 황금률과 같은 이유). 부득이하면 로컬에서 강제 재생성 후 강제 push 합니다.
git tag -f v1.0.0 <새커밋> git push origin -f v1.0.0 # 주의: 협업 시 사전 합의 필요
11.13 태그 생성 원리 (참고)
annotated 태그는 내부적으로 .git/refs/tags/에 저장되며, 별도의 태그 객체(작성자·날짜·메시지·가리키는 커밋)를 만듭니다. lightweight 태그는 그냥 커밋 해시를 담은 파일 하나일 뿐입니다. 깊이 알 필요는 없지만, "annotated는 진짜 객체, lightweight는 단순 포인터"라는 점만 기억하면 충분합니다.
11.14 실습: 릴리스 전체 흐름
# 1. 안정 버전을 main에 병합 완료한 상태에서 git switch main # 2. annotated 태그 발행 git tag -a v1.0.0 -m "First public release" # 3. 태그 확인 git tag git show v1.0.0 # 4. 원격(GitHub)에 태그 올리기 git push origin v1.0.0 # 5. (GitHub) Releases 페이지에서 릴리스 노트 작성 # === 이후 버그 발견 → 긴급 수정 === git switch -c hotfix v1.0.0 # 출시 버전 기준 브랜치 # ... 버그 수정, 커밋 ... git switch main git merge hotfix git tag -a v1.0.1 -m "Fix critical bug" git push origin v1.0.1
11.15 이 장에서 배운 것 (요약)
- 태그 = 특정 커밋에 고정되는 이정표 (브랜치는 움직이고 태그는 고정)
- 버전 이름은 시맨틱 버저닝(
vMAJOR.MINOR.PATCH) 권장 - Annotated 태그(
-a -m, 권장) vs Lightweight 태그(이름만) - 과거 커밋에도 해시를 지정해 태그 가능
- 태그 체크아웃 시 detached HEAD → 이어 작업하려면 새 브랜치
git push는 태그를 안 올린다 →git push origin <태그>또는--tags- 원격 태그 삭제는
git push origin --delete <태그> - 태그는 옮기기보다 새 버전 발행이 안전
✍️ 확인 문제
- annotated 태그와 lightweight 태그 중 공식 릴리스에 권장되는 것은?
- 태그를 달고
git push만 했는데 GitHub에 안 보입니다. 무엇을 빠뜨렸나요? - 출시된 v1.0.0에서 버그를 그 버전 기준으로 고치려면 어떻게 시작하나요?
축하합니다! 본문 11개 섹션을 모두 마쳤습니다. 마지막으로 전체를 한 장에 정리한 부록을 확인하세요. → 99_부록-치트시트.md