포스트

[TIL] 2026-06-17 — 팀 프로젝트 레포 세팅: UE5 .gitignore·도메인 소유권·Git Flow develop 완충

[TIL] 2026-06-17 — 팀 프로젝트 레포 세팅: UE5 .gitignore·도메인 소유권·Git Flow develop 완충

Ch4 팀 프로젝트(8조 — 가구 옮기기 협동 게임)를 시작하기 전에, 코드보다 레포 표준을 먼저 잡았다. UE5용 .gitignore, 도메인별 코드 소유권, 에셋 접두사 규칙, 그리고 develop 완충 브랜치를 둔 Git Flow까지. “나중에 하면 되는 것” 같지만, 팀 작업에서 이 토대가 없으면 머지 충돌과 빌드 깨짐으로 시간을 다 잡아먹는다. 오늘 세팅하며 정리한 핵심을 남긴다.

왜 코드보다 레포 먼저인가

혼자 만드는 과제는 레포가 대충이어도 굴러간다. 하지만 6명이 동시에 같은 언리얼 프로젝트를 만지면 이야기가 다르다. 빌드 산출물이 커밋되고, 같은 파일을 둘이 고치고, 에셋 이름이 제각각이면 — 기능을 짜기도 전에 충돌 정리에 시간을 쓴다. 그래서 착수 전에 표준을 박아두는 것이 팀 리드의 첫 일이다.

1. UE5 .gitignore — 무엇을 빼고 왜

언리얼 프로젝트는 재생성되는 것원본인 것을 구분해서, 재생성되는 건 전부 git에서 제외해야 한다.

Binaries/            # 빌드하면 다시 생김
Intermediate/        # 중간 산출물
DerivedDataCache/    # 로컬 캐시
Saved/               # 로그·자동저장
*.sln                # UBT가 생성하는 솔루션
.vs/                 # IDE 찌꺼기

추적해야 하는 건 Source/(C++), Config/, Content/(에셋), *.uproject뿐이다. 특히 Binaries/·Intermediate/를 커밋하면 용량이 폭발하고 사람마다 달라 매번 충돌한다. 실제로 솔루션 파일(*.sln)도 머신마다 절대경로가 달라 자동 생성에 맡기고 제외하는 게 맞다.

2. 도메인별 코드 소유권 — 머지 충돌을 구조로 막는다

Source/ 아래를 기능 도메인으로 나누고, 각 폴더에 OWNER.txt로 담당자를 명시했다.

1
2
3
4
5
6
7
Source/TeamCarry/
├── Core/        게임모드·점수 판정       (담당 A)
├── Player/      캐릭터·이동·상호작용     (담당 B)
├── Furniture/   가구 운반·내구도         (담당 C)
├── Network/     복제·RPC                 (분산)
├── Level/       스테이지·환경            (담당 D)
└── UI/          HUD·결과 화면            (담당 E)

핵심은 “같은 파일을 두 명이 동시에 만지지 않게” 작업 영역을 미리 갈라두는 것이다. 충돌은 머지 단계에서 푸는 것보다 애초에 안 생기게 설계하는 게 싸다. 각자 자기 도메인 폴더에서 작업하면 물리적으로 겹칠 일이 줄어든다.

3. 팀 규칙: 에셋 접두사

언리얼 콘텐츠 브라우저는 파일이 수백 개로 불어난다. 접두사 규칙이 없으면 검색·정리가 지옥이 된다.

접두사종류
SM_Static MeshSM_Sofa_01
SK_Skeletal MeshSK_Mover_Default
BP_BlueprintBP_Furniture_Sofa
WBP_Widget BlueprintWBP_InGameHUD
DT_Data TableDT_FurnitureStats

이런 규칙은 모두가 지켜야 의미가 있어서, 문서로 박아두고 통합 담당이 관리한다.

4. Git Flow와 develop 완충 브랜치

처음엔 GitHub Flow(main + feat/*)로 잡았다가, develop 완충 브랜치를 둔 Git Flow로 바꿨다.

1
2
3
4
5
main    ──●───────────────────●──   발표/제출용 안정판 (release 때만 머지)
           ↑ release            ↑
develop ──●──●──●──●──●─────────●──   기본 브랜치 · 통합 완충
           │   │   │
           │ feat/* feat/* ...       develop에서 분기 → develop으로 PR

왜 완충이 필요한가

GitHub Flow는 feat가 곧장 main으로 들어간다. 단순하지만, 누군가의 머지가 main을 깨면 그 순간 전원이 깨진 main을 받게 된다. develop을 사이에 두면:

  • 매일의 통합·머지·멀티플레이 QA는 전부 develop에서 일어난다
  • main은 발표·제출처럼 안정된 시점에만 develop을 받는다
  • develop이 깨짐 위험을 흡수하는 완충 지대 역할을 한다

부트캠프 팀플처럼 동시에 여러 사람이 미완성 기능을 올리는 상황에서, “항상 보여줄 수 있는 main”을 지키려면 이 완충이 효과적이다. 대신 브랜치 흐름이 한 단계 늘어나는 비용은 있다.

5. 언리얼 Revision Control(Git) — 바이너리의 함정

언리얼 에디터에 내장된 Revision Control을 Git으로 연결했다. 여기서 중요한 함정 하나:

.uasset·.umap은 바이너리라 머지가 안 된다. Perforce와 달리 Git에는 파일 잠금(exclusive checkout)이 없어서, 두 사람이 같은 에셋을 고치면 한쪽 작업이 통째로 날아간다. 그래서:

  • 에셋 작업 전 “나 OO 맵 만진다”를 디스코드로 공유 → 사실상의 수동 잠금
  • 저장하면 가능한 빨리 커밋·푸시해 점유 시간을 줄이기

코드(.cpp/.h)는 텍스트라 머지가 되지만, 에셋은 “동시에 안 건드리기”가 유일한 방어다.

오늘 배운 것 정리

  1. 팀 레포는 코드보다 먼저다. 착수 전 .gitignore·폴더 표준·네이밍을 박아두지 않으면 충돌 정리에 시간을 다 쓴다.
  2. 충돌은 푸는 것보다 안 생기게 설계한다. 도메인별 폴더 + OWNER.txt로 작업 영역을 갈라 동시 수정 자체를 줄인다.
  3. develop 완충 브랜치의 가치. feat→develop→main 흐름에서 develop이 main 깨짐 위험을 흡수해, “항상 보여줄 수 있는 main”을 지킨다.
  4. 언리얼 에셋은 바이너리라 머지가 없다. Git엔 잠금이 없으니, 디스코드 사전 공유가 유일한 협업 방어선이다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.