Tag 가 순간을 핀, release 는 metadata 있는 tag
Branch 는 움직이고 tag 는 안 움직여. Tag 는 특정 commit 하나의 이름, 한 번 설정되면 pointer 영원히 안 바뀜. 사용 사례는 release: ship 한 commit 에 v2.4.0 tag, 그 후 영원히 누구나 git checkout v2.4.0 으로 정확히 그 release 시점 production 자리. 복구할 가치 있는 모든 순간에 같음: 고객이 'v2.3.7 에서' 버그 재현하면 초 단위로 거기 자리 잡음.
중요한 tag 타입 둘. Lightweight tag (git tag v2.4.0) 는 그냥 pointer 파일 — commit 의 이름, metadata 없음. Annotated tag (git tag -a v2.4.0 -m "Release 2.4.0") 는 author, 날짜, 메시지, (선택적) GPG 서명 있는 full Git object. 실제 release 엔 항상 annotated. 서명이 인가된 사람한테서 release 왔는지 확인, 메시지가 audit trail 일부, git describe 가 annotated tag 로 v2.4.0-12-g3f4a5d6 같은 사람 읽을 수 있는 commit ID 생성.
git push --tags 가 tag 를 remote 로. 많은 사람이 놀람 — plain git push 는 tag 포함 안 함. git config --global push.followTags true 박으면 push 되는 commit 가리키는 tag 가 일반 push 따라옴. git tag -d <name> 이 local tag 삭제, git push origin --delete <name> 가 remote tag 삭제. 조심: remote tag 삭제는 거의 옳지 않음, 이미 pull 한 사람 누구나 그 tag 여전히 가짐.
GitHub 의 'Releases' 기능은 annotated tag + UI: release note, 다운로드 가능한 자산 (tarball, binary), pre-release flag. CLI 에서 gh release create v2.4.0 --notes "...", 또는 tag push 후 web UI. Semantic-release 도구 + Conventional Commits 와 결합하면 release 가 merge 의 자동 부수 효과 — 팀이 다시는 손으로 release note 안 씀.