4 분 소요

태그란 무엇인가?

태그(Tag) 는 특정 커밋에 붙이는 고정된 이름표입니다. 이것은 “이 커밋은 중요한 순간이다”라고 표시하는 방식입니다. 예를 들어, 버전 1.0.0을 출시할 때 해당 커밋에 v1.0.0 태그를 붙이면, 언제든 그 시점의 코드를 쉽게 찾을 수 있습니다.

  • 태그는 한 번 붙이면 변하지 않습니다. 이후에 다른 커밋이 추가되어도 태그가 가리키는 커밋은 그대로 유지됩니다.
  • 태그는 브랜치와 다르게 지속적으로 이동하지 않습니다. 브랜치는 새로운 커밋이 생길 때마다 업데이트되지만, 태그는 특정 커밋에 고정됩니다.

태그와 브랜치의 차이

태그 브랜치
특정 커밋에 붙는 고정된 이름표 커밋들의 연속으로 계속 업데이트됨
한 번 붙이면 변하지 않음 새로운 커밋이 생기면 브랜치도 최신 커밋으로 이동
주로 버전이나 릴리즈 관리에 사용 기능 개발, 버그 수정 등 작업 흐름 관리에 사용

예시:

  • v1.0.0 태그: 특정 시점의 소프트웨어 릴리즈를 표시.
  • feature-login 브랜치: 로그인 기능 개발 중인 최신 작업들을 포함.

태그의 종류

Git에는 두 가지 태그가 있습니다.

1. Annotated Tag (주석 태그)

  • 특징: 작성자, 날짜, 메시지 등의 메타데이터를 포함.
  • 사용처: 릴리즈 같은 중요한 순간에 사용.
  • 생성 방법:
$ git tag -a v1.0.0 -m "Release version 1.0.0"
  • 주석 태그는 CI/CD 도구와 연동 시 유리하며, --follow-tags 옵션과 함께 사용할 수 있습니다.

2. Lightweight Tag (가벼운 태그)

  • 특징: 메타데이터 없이 단순히 특정 커밋을 가리킴.
  • 사용처: 단순한 참조가 필요할 때.
  • 생성 방법:
$ git tag v1.0.0

태그 만들기

1. 현재 커밋에 태그 달기

현재 브랜치의 최신 커밋에 태그를 붙이려면:

git tag v1.0.0

2. 특정 커밋에 태그 달기

이미 존재하는 특정 커밋에도 태그를 붙일 수 있습니다.

git tag v1.0.0 <commit-hash>
  • <commit-hash>는 태그를 달고 싶은 커밋의 해시 값입니다.

태그를 달면 해당 커밋에 영구적으로 “이름표”가 붙습니다. 커밋은 변하지 않으므로 태그도 변하지 않습니다.

3. 태그 조회

태그 목록만 조회

$ git tag

커밋과 태그 같이 조회

$ git log --oneline

커밋과 태그를 동시에 푸시하기

CI/CD 파이프라인에서는 커밋과 함께 태그를 푸시하는 것이 효율적입니다. 이를 위해 Git의 --follow-tags 옵션을 사용할 수 있습니다.

1. 커밋 만들기

$ git add .
$ git commit -m "새로운 기능 추가"

2. 주석 태그 달기

$ git tag -a v1.2.3 -m "릴리즈 버전 1.2.3"

3. 커밋과 태그 함께 푸시하기

# 전체 명령어.
$ git push --follow-tags origin <브랜치명>

# 현재 브랜치로 푸시.
$ git push --follow-tags
  • 이 명령은 <브랜치명>에 새로운 커밋과 함께 주석 태그를 원격 저장소로 보냅니다.
  • 중요: --follow-tags는 주석 태그만 포함하므로, 가벼운 태그를 사용하지 않도록 주의합니다.

이 방법을 사용하면 커밋과 태그를 한 번에 푸시할 수 있어 CI/CD 워크플로우의 조건에 맞추기 쉽습니다.

태그 푸시하기

이미 로컬에 있는 태그를 원격 저장소에 푸시하려면:

특정 태그만 푸시:

$ git push origin v1.0.0

모든 태그 푸시:

$ git push origin --tags

주의: 태그를 푸시하기 전에 해당 태그가 가리키는 커밋이 이미 원격에 있어야 합니다. 먼저 커밋을 푸시한 뒤 태그를 푸시하세요.

GitHub Actions에서 태그와 브랜치 구분하기

GitHub Actions 워크플로우를 설정할 때, 모든 푸시를 트리거로 시작하고 job 단계에서 태그인지 아닌지 조건문으로 분기할 수 있습니다.

1. 워크플로우 트리거 설정

모든 푸시 이벤트에 대해 워크플로우가 시작되도록:

on:
  push: {}  # 모든 push 이벤트 트리거

2. Job 단계에서 태그 여부로 분기

각 단계에서 현재 푸시가 태그인지 브랜치인지 확인해 작업을 분기할 수 있습니다.

jobs:
  example_job:
    runs-on: ubuntu-latest
    steps:
      - name: 코드 체크아웃
        uses: actions/checkout@v3

      - name: 브랜치 푸시 작업
        if: "!startsWith(github.ref, 'refs/tags/')"
        run: echo "이 푸시는 브랜치 푸시입니다."

      - name: 태그 푸시 작업
        if: "startsWith(github.ref, 'refs/tags/')"
        run: echo "이 푸시는 태그 푸시입니다."
  • github.ref를 통해 현재 이벤트가 태그 푸시인지 브랜치 푸시인지 확인할 수 있습니다.
  • startsWith(github.ref, 'refs/tags/') 조건은 태그 푸시를 의미합니다.
  • !startsWith(github.ref, 'refs/tags/') 조건은 브랜치 푸시를 의미합니다.

이렇게 하면 하나의 워크플로우 안에서 태그와 브랜치 푸시에 따라 다른 작업을 수행할 수 있습니다.

태그와 병합 시 동작

질문:

dev 브랜치의 커밋 A에 태그 atag를 붙이고 푸시한 후, 그 커밋을 main 브랜치로 병합하면 어떻게 될까요?

답변:

  • 태그는 커밋에 고정되어 있습니다. 즉, 태그 atag는 커밋 A에 붙어 있고, 커밋 A가 어디에 속하든 변하지 않습니다.
  • dev 브랜치에서 커밋 A에 태그를 단 후, 그 커밋을 main에 병합하면:
    • 커밋 A는 이제 main 브랜치의 히스토리에도 포함됩니다.
    • 태그 atag는 여전히 커밋 A에 붙어 있습니다.
    • 태그 자체가 새로운 브랜치에 “붙는” 것이 아니라, 커밋 A가 병합되었기 때문에 그 커밋과 함께 태그가 남아 있는 것입니다.

즉, 병합 후에도 태그 atag는 커밋 A를 계속 가리킵니다. 이로써 중요한 커밋에 대한 태그는 브랜치 변화에도 영향을 받지 않습니다.

자주 묻는 질문(Q&A)

Q1: 왜 태그와 브랜치의 차이를 알아야 하나요?
A1: 태그는 특정 시점의 상태를 고정하기 위해, 브랜치는 개발 흐름을 관리하기 위해 사용됩니다. 이 둘의 차이를 이해하면 각 상황에 적합한 도구를 선택하여 효과적으로 버전 관리할 수 있습니다.

Q2: 가벼운 태그와 주석 태그 중 어느 것을 사용해야 하나요?
A2: 중요한 릴리즈나 메타데이터가 필요한 경우 주석 태그를 사용하는 것이 좋습니다. CI/CD와 같은 자동화 도구와 연동할 때 특히 유용합니다. 단순 참조만 필요하다면 가벼운 태그도 괜찮습니다.

Q3: --follow-tags 옵션은 언제 사용하나요?
A3: 새 커밋과 함께 주석 태그를 원격 저장소에 동시에 푸시하고 싶을 때 사용합니다. 이를 통해 CI/CD 워크플로우가 태그 조건을 만족하는 커밋을 놓치지 않도록 할 수 있습니다.

Q4: 태그를 병합 시 어떻게 동작하나요?
A4: 태그는 특정 커밋에 고정되어 있으므로, 그 커밋이 어느 브랜치에 속하든 태그는 변하지 않습니다. 병합 과정에서 커밋이 다른 브랜치에 포함되더라도 태그는 그대로 유지됩니다.

결론

Git 태그는 중요한 커밋을 표시하고, 버전 관리와 CI/CD 자동화에 큰 도움을 줍니다.

  • 태그 이해: 고정된 커밋에 이름표를 붙여 중요한 시점을 기록.
  • 태그 종류: 주석 태그(메타데이터 포함)와 가벼운 태그(단순 참조).
  • 활용법: 커밋과 함께 태그를 푸시하고, 워크플로우 내에서 태그와 브랜치를 분기하여 다양한 동작을 실행.
  • 병합 시: 태그는 커밋에 고정되어 있어, 병합 후에도 변하지 않음.

태그: ,

카테고리:

업데이트:

댓글남기기