issue→브랜치 네이밍 규칙 — 접두어·이슈 번호·충돌

에이전트에게 “이슈 열고 브랜치 파서”만 맡기면 제멋대로인 이름·이슈 링크 누락·이미 있는 브랜치에 덮어쓰기가 나기 쉽습니다. 사람에게 팀 브랜치 컨벤션을 기대하듯, 에이전트에도 접두어 · 이슈 번호 · 충돌 시 절차를 Rule·Done 정의에 고정하는 편이 안전합니다.

이 글의 축은 셋뿐입니다. 접두어는? · 이슈 번호는? · 충돌 시? agent-pr-body는 PR 본문, agent-patch-commits는 커밋 쪼개기입니다. 여기서는 issue → branch 이름만 다룹니다. 요금·플랜·제휴·창작 후기는 없습니다.

근거는 Git — git-check-ref-format(ref 이름 규칙), GitHub Docs — Linking a pull request to an issue, GitHub Docs — Creating a pull request, 그리고 팀이 흔히 쓰는 type/issue-slug 브랜치 관행입니다.

접두어는?

한 줄 답: 접두어는 변경 종류를 사람이 한눈에 보게 두는 짧은 토큰입니다. 팀이 쓰는 목록을 고정하고, 에이전트는 그 목록 밖 접두어를 만들지 않게 하십시오.

실무에서 자주 쓰는 접두어(공개 관행·관용; 제품 요금 아님):

접두어뜻언제
feat/기능 추가새 동작·API·UI
fix/버그 수정깨진 동작 복구
chore/잡무의존성·설정·CI 튜닝(기능 아님)
docs/문서만README·가이드·주석성 문서
refactor/동작 동일 리팩터구조만 정리
test/테스트만커버리지·픽스처
ci/CI/CD워크플로·파이프라인

형식 예(팀이 하나 고르면 됩니다):

# Pattern A — type + issue + slug
feat/123-add-login-rate-limit
fix/456-null-ptr-on-empty-list

# Pattern B — issue-first (some teams)
123-feat-add-login-rate-limit

# Pattern C — GitHub-style issue word
issue/123-add-login-rate-limit

에이전트에 줄 한 줄:

Branch name = <allowed-prefix>/<issue-number>-<kebab-slug>
Allowed prefixes: feat, fix, chore, docs, refactor, test, ci
Slug: lowercase ASCII, hyphens only, max ~50 chars, no spaces.
Do not invent prefixes outside the allowlist.

하지 말 것:

  • Feature/, FIX/, 한글·공백·언더스코어 남발 → 사람·도구마다 파싱이 어긋납니다. 소문자 + 하이픈을 기본으로 둡니다.
  • temp/, wip/, agent/만 있는 이름 → 이슈·종류가 사라져 리뷰·정리가 어렵습니다.
  • 접두어를 생략한 just-fixing → 검색·필터·자동화 훅이 약해집니다.

Git ref 제약(git-check-ref-format): 공백·연속 ..·제어 문자·일부 특수문자(~^:?*[\\)는 피합니다. #를 브랜치 이름에 넣는 팀은 드물고, 셸·URL에서 불편하니 번호만 숫자로 넣는 편이 흔합니다.

이슈 번호는?

한 줄 답: 브랜치에 트래커 이슈 번호를 숫자로 넣고, PR 본문·커밋에서는 GitHub가 인식하는 링크 키워드로 이슈를 연결합니다. 번호 없는 “감으로 지은” 브랜치는 에이전트 Done 조건에서 탈락시키십시오.

위치권장이유
브랜치 이름feat/123-short-sluggit branch·CI 필터·로컬 검색에 번호가 보임
PR 제목feat: … (#123) 또는 팀 템플릿사람 리뷰·알림에 이슈가 보임
PR 본문 / 커밋Fixes #123 / Closes #123 / Resolves #123GitHub linking keywords로 머지 시 이슈 종료·연결
이슈 없음chore/no-issue-bump-deps 등 명시적 예외 토큰“번호 깜빡”과 “이슈 없는 잡무”를 구분

복붙 규칙:

If the task cites an issue URL or #N:
  1. Extract N as digits only for the branch segment.
  2. Never put literal "#" in the branch name.
  3. In the PR body, include "Fixes #N" (or Closes/Resolves) when the PR should close it.
If no issue exists:
  Stop and ask, OR use the team’s no-issue prefix token — do not invent a fake number.

주의: GitHub는 기본 브랜치로 머지되는 PR의 키워드로 이슈를 닫습니다. 브랜치 이름만으로는 자동 close가 되지 않습니다. 에이전트에게 “브랜치에 번호 넣었으니 끝”이 아니라 PR 본문 키워드까지 Done에 넣으십시오.

이슈 여러 개면: 주 이슈 하나만 브랜치에 넣고, 나머지는 PR 본문에 Related to #A, #B로 적는 편이 충돌·이름 길이 면에서 낫습니다.

충돌 시?

한 줄 답: 같은 이름이 로컬·원격에 이미 있으면 덮어쓰거나 force-push하지 말고, 존재 확인 → 재사용 여부 판단 → 접미사로 새 이름 순으로 가십시오.

충돌이 나는 대표 경우:

상황증상에이전트 행동
로컬에 동일 이름git branch에 이미 있음 / git checkout -b 실패기존 브랜치가 같은 이슈면 재사용·리베이스 정책 따르기. 다른 작업이면 새 이름
원격에 동일 이름git ls-remote --heads origin <name>에 있음남의 진행 중일 수 있음 → 새 이름 또는 사람 확인. -f push 금지
슬러그만 겹침feat/123-login vs fix/123-login접두어가 다르면 허용(팀이 허용할 때). 같은 type+번호면 슬러그·접미사로 구분
동시 에이전트두 세션이 같은 이슈로 동시에 브랜치 생성feat/123-slug-<short-id> 또는 -2 접미사. 한 PR로 합칠지는 사람 결정

점검 순서(복붙):

Before creating a branch named NAME:
  [ ] git show-ref --verify --quiet refs/heads/NAME
  [ ] git ls-remote --heads origin NAME
  If either exists:
    - Same issue + abandoned → ask human before reset
    - Same issue + active → checkout existing; do not recreate
    - Different work or unclear → use NAME-2 or NAME-<yyyymmdd> or NAME-<agent-short>
  Never: git push --force to “win” a name collision
  Never: delete someone else’s remote branch to free the name

이름 접미사 예:

feat/123-add-login-rate-limit
feat/123-add-login-rate-limit-2
feat/123-add-login-rate-limit-20260924

한 줄 정리: 허용 접두어 + 이슈 숫자 + kebab 슬러그로 만들고, 존재하면 재사용하거나 접미사를 붙이며, force로 이름을 뺏지 마십시오.

FAQ

브랜치에 #123을 넣어도 되나?

가능은 하지만 셸·URL·일부 도구에서 이스케이프가 필요합니다. 숫자 123만 넣고, #123은 PR·커밋 메시지에 두는 관행이 흔합니다.

Conventional Commits 타입과 접두어를 같게?

맞춰 두면 검색이 편합니다(feat/ 브랜치 → feat: 커밋). 필수는 아니지만 에이전트 규칙에 “브랜치 접두어 = 커밋 type”을 적으면 일관됩니다. 자세한 커밋 쪼개기는 agent-patch-commits를 보십시오.

이슈 없이 핫픽스면?

팀이 정한 예외(hotfix/ + 타임스탬프, 또는 chore/no-issue-…)만 허용하고, 가짜 이슈 번호 생성은 금지하십시오. 가능하면 먼저 이슈를 연 뒤 브랜치를 만듭니다.

main에서 바로 커밋하게 두면?

이슈→브랜치 규칙을 우회합니다. Done 조건에 “작업 브랜치 ≠ default branch”를 넣으십시오.

출처 (Sources)