Post

Git tag

tag 기능을 이해하고 사용한다.

Git tag

📌개요

특정 커밋에 추가적인 기록을 남길 수 있는 tag를 알아본다.

📌내용

tag

Git tag는 Git 버전 관리 시스템에서 특정 커밋을 가리키는 참조 포인터다. 주로 프로젝트의 중요한 시점인 release, alpha, beta 등을 표시하기 위해 사용된다.

tag 사용 시나리오

  • 소프트웨어 release 버전 표시 (v1.0.0, v2.1.3 등)
  • 중요한 개발 이정표 (알파/베타, 주요 기능 완성)
  • 프로덕션 배포 시점 기록
  • 버그 수정을 위한 특정 시점 참조

의미 있는 버전 명명 규칙

MAJOR.MINOR.PATCH -> v2.1.3 형태로 Semantic Versioning (SemVer)을 추천한다.

  • MAJOR: 설계의 변경 또는 큰 구조적 변경
  • MINOR: 기능 추가 등 중요도가 중간 정도 되는 경우
  • PATCH: 작은 버그 수정, 문서 수정 등
  • 각 버전은 꼭 1, 2자리 제한이 아니라 관리 규칙에 따라 계속 증가할 수 있다.

예시

1
2
3
4
5
6
7
8
9
10
git tag -a v1.4.0-alpha.1 -m "Alpha release"

# 초기 개발 단계
git tag -a v0.1.0 -m "프로젝트 구성"

# 첫 안정판
git tag -a v1.0.0 -m "안정판 배포"

# 핫픽스 적용 후
git tag -a v1.0.1 -m "긴급 건 핫픽스"

주석 tag 우선 사용

가능하면 주석 태그 사용하는 것이 좋다.

예시

1
2
3
4
5
6
7
8
# 명령줄에서 큰따옴표를 닫지 않고 줄바꿈하여 작성
git tag -a v1.2.0 -m "안정화 버전 v1.2.0
- 검색 기능 추가
- 모바일 레이아웃 이슈 수정
- 의존성 업데이트"

# 자동으로 열리는 기본 에디터를 사용할 수도 있다.
git tag -a v2.1.0

특정 커밋에 tag

특정 커밋을 확인 후 해시값으로 태그를 생성할 수 있다.

1
2
3
4
5
# 커밋 해시 확인
git log

# 해시값으로 태그 생성
git tag -a v1.1.1 a1b2c3d -m "이게 짱짱 버전임"

tag 수정

Git tag는 일반적으로 수정이 불가능하다. 삭제 후 재생성해야 한다.

수정 불가 이유

태그는 특정 커밋을 가리키는 고정된 참조로 일단 생성되면 내용 변경이 불가능하다. 이는 버전 관리의 핵심 원칙 중 하나로 릴리스 버전의 무결성을 보장하기 위함이다.

  • 버전 관리의 신뢰성: 한 번 릴리스된 버전은 변하지 않아야 한다.
  • 배포 추적 용이성: 프로덕션에서 실행 중인 코드 버전을 정확히 추적 가능
  • 의존성 관리: 다른 프로젝트에서 특정 태그 버전을 의존할 때 문제 방지

삭제 후 재등록

수정이 불가하니 태그를 삭제하고 재등록해서 깔끔한 내용을 유지한다.

1
2
3
4
5
6
7
8
9
# 1. 로컬 태그 삭제
git tag -d v1.0.0

# 2. 원격 태그 삭제 (필요시)
git push origin :refs/tags/v1.0.0

# 3. 새 태그 생성
git tag -a v1.0.0 {새로운 커밋 해시} -m "수정된 메시지"
git push origin v1.0.0

강제 등록

이미 푸시된 태그를 덮어쓰거나 강제로 처리해야 하는 경우 특별히 주의해서 적용한다.

1
2
git tag -f -a v1.0.0 {커밋 해시} -m "새 메시지" # 로컬에서 강제 재설정
git push -f origin v1.0.0 # 원격 강제 푸시

tag push

단일 tag push

1
git push origin v1.0.0

모든 tag를 한 번에 push

1
git push origin --tags

push한 tags 확인

1
git ls-remote --tags origin

tag push 실패 시

태그 중복 또는 최신화가 되지 않아서 push 거절되는 경우

1
2
3
4
5
# 최신 tags 동기화
git fetch --tags

# 충돌 시 강제로 push (주의)
git push -f origin v1.0.0

CI/CD 연동 예시

Github Actions에서 특정 tag를 커밋했을 때를 가정하면 아래처럼 작성할 수 있다.

1
2
3
4
5
6
7
8
# .github/workflows/release.yml
name: Release Build

on:
	push:
		tags:
			- 'v*' # v로 시작하는 tag push될 때 실행
...

tag 장단점

장점

  • 버전 관리에 용이하다. 명확한 릴리스 포인트를 제공한다.
  • 어떤 코드가 어떤 버전으로 배포되었는지 추적할 수 있다.
  • 태그된 버전은 변경되지 않는 참조 지점을 제공하므로 안정성을 보장한다.
  • 팀원들이 특정 버전을 쉽게 확인할 수 있어서 협업 효율성에 좋다.

단점

  • 과도하게 사용 시 관리 복잡성이 증가한다.
  • 일단 생성된 태그는 이동할 수 없다.
    • 재설정을 해야 한다.
  • CI/CD 파이프라인과의 통합이 브랜치보다 덜 직관적이다.

📌고급 활용

tag 메시지 템플릿 시스템

전역 템플릿을 설정해서 일관된 tag 이력을 남길 수 있다. 특정 위치에 템플릿 파일 생성한다. 예: ~/.git-templates/tag_template

1
2
3
4
5
6
7
8
9
10
11
12
13
# [%(tag)] 릴리스 노트

## 주요 변경 사항
%(body)

## 기술적 세부사항
- 커밋 해시: %(object)
- 태그 생성일: %(taggerdate:iso8601)

## QA 체크리스트
- [ ] 스모크 테스트 통과
- [ ] 성능 테스트 완료
- [ ] 보안 검증 완료

파일 생성 후 git config 적용

1
git config --global tag.template ~/#.git-templates/tag_template 등 파일

템플릿 적용 예시

자동으로 에디터가 열릴 수 있게 명령어 실행

1
git tag -a v1.3.0 # 자동으로 템플릿 로드

에디터에 표시될 내용

1
2
3
4
5
6
7
8
9
10
11
12
13
# [v1.3.0] 릴리스 노트

## 주요 변경 사항
이곳에 변경 내용 작성

## 기술적 세부사항
- 커밋 해시: q1w2e3r4t5
- 태그 생성일: 2023-11-15T14:30:00+09:00

## QA 체크리스트
- [ ] 스모크 테스트 통과
- [ ] 성능 테스트 완료
- [ ] 보안 검증 완료

⚙️EndNote

고급 활용

  • Git 템플릿 작성 방법을 숙지하면 커스텀 태그 메시지 템플릿을 효과적으로 관리할 수 있다.
  • 자동 버전 관리 시스템을 구축하여 프로젝트 버전 관리를 자동화할 수 있다.
  • CI/CD 파이프라인 연동 시 사용하는 배포 플랫폼(GitHub Actions, GitLab CI, Jenkins 등)에 따라 구현 방식이 달라질 수 있으니 주의가 필요하다.

PR 요청 시 tag는?

태그는 본인 저장소에서 관리하기 위함이고 Fork한 원본 저장소에 PR을 하는 등의 작업에 tag는 같이 옮겨지지 않는다.

Fork 저장소에서 원본 저장소 PR 시나리오

자신의 Fork에만 태그가 있는 경우
  1. 로컬/Fork 저장소에서 태그 생성
1
2
git tag v1.0.0
git push origin v1.0.0 # 자신의 Fork에만 태그 존재
  1. 원본 저장소로 PR 생성 -> 태그는 전송되지 않음.
원본 저장소의 태그를 참조하는 경우
  1. 원본 저장소에 이미 존재하는 태그(v1.0.0)를 기반으로 작업
1
2
git fetch upstream # 원본 저장소의 태그 동기화
git checkout v1.0.0
  1. 새 커밋 후 PR 생성 -> 원본의 태그는 이동하지 않음.
    • 태그가 가리키는 커밋은 고정되어 있음.

왜 태그가 PR과 함께 전송되지 않지?

  1. 보안성: 태그는 릴리스 버전을 표시하는 중요한 참조이므로, 임의로 변경되는 것 방지.
  2. 권한 분리:
    • 일반 기여자는 브랜치로만 PR 전송 가능.
    • 태그 생성/수정은 저장소 관리자(maintainer) 권한이 필요.
  3. 버전 관리 무결성: 원본 저장소의 태그는 공식 릴리스로 간주되므로, PR을 통해 덮어쓸 수 없음.

만약 태그를 원본 저장소에 반영해야 한다면?

방법이 다양하겠지만 현실적이고 보편적인 방법 두 가지로 정리해본다.

  1. 관리자에게 요청
1
2
3
4
[요청 내용]
- 태그 이름: v1.0.0
- 대상 커밋: q1w2e3r4
- 이유: 버전 1.0.0 릴리스 준비 완료
  1. Github Releases 활용
    • PR 머지 후, 원본 저장소에서 Release 탭에서 수동으로 태그 생성
This post is licensed under CC BY 4.0 by the author.