1. 핵심 개념
- perforce
2. 상세 내용
도입
팀원과 사이드 프로젝트로 깃허브에서 협업을 할 때 uasset, umap, 그 외 fbx, mp4 등과 같은 큰 용량의 파일을 git lfs를 사용해서 보내기로 했다. 그런 와중에 lfs의 무료 플랜 10GB bandwidth를 모두 사용해서 lfs로부터 파일을 받을 수 없게 되었다.
이와 같은 문제를 해결하기 위해 다른 대체제를 찾는 도중에 팀원이 실무에서는 언리얼 엔진과 Perforce를 사용한다면서 자신의 남는 맥북을 서버로 사용해서 리버전 컨트롤을 하기로 결정했다.
what is Perforce
Perforce P4 (formely Helix Core)는 VCS 중 하나로 언리얼과 같이 대규모 바이너리 에셋을 다루는 게임 업계에서 표준으로 사용된다고 한다.
git과 같은 VCS이지만 Git은 분산형인 반면에 p4는 서버에 모든 데이터가 집중되어 있고 클라이언트가 필요한파일을 sync해서 사용하는 점에서 그 차이가 있다.
p4에는 기존의 git과 다른 큰 장점이 있는데 Merge가 불가능한 바이너리 에셋 파일을 Merge Conflict를 사전에 봉쇄하는게 가능하도록 check-out으로 파일 Lock을 줄 수 있다는 것이다.
세팅
P4D설치->포트설정->관리자 계정 생성->방화벽 및 포트포워딩
이번 프로젝트에서는 Tailscale을 사용해서 복잡한 방화벽, 포트 설정 없이 사설망을 만들어서 Tailscale IP:1666을 통해서 팀원 간에 접속을 가능하게 했다.
p4 개념
p4는 워크스페이스 단위로 파일이 '읽기' 중인지 '수정' 중인지 관리한다.
- Workspace/Client Spec: 서버 파일을 로컬에 저장한 장소
- Root: 로컬 컴퓨터의 실제 경로
- View Mapping: 서버의 디렉터리와 로컬 위치를 매칭
- Stream: p4에서의 브랜치
- Mainline: 모든 작업이 모이는 중심 줄기.
- Development: 실험적인 작업을 하는 브랜치.
- Release: 배포를 위한 안정화 브랜치.
명령어
| 명령어 | 설명 | 비고 |
|---|---|---|
p4 sync |
서버의 최신 파일을 로컬로 가져옵니다. | Git의 pull과 유사 |
p4 edit |
파일을 수정하기 위해 체크아웃합니다. | 파일의 읽기 전용 속성이 해제됨 |
p4 add |
새로 만든 파일을 관리 대상에 추가합니다. | |
p4 delete |
파일을 삭제 예약합니다. | 로컬에서도 삭제됨 |
p4 submit |
수정한 내용을 서버에 저장(Check-in)합니다. | Git의 commit + push 합본 |
p4 revert |
수정한 내용을 취소하고 서버 상태로 되돌립니다. | |
p4 have |
현재 내가 싱크 받은 파일 목록을 확인합니다. |
p4에서는 바이너리 에셋의 충돌을 막기위해 Exclusive Checkout을 지원해주기에 게임 개발에서 매우 유용하게 사용할 수 있어보인다. 하지만 그외에 스크립트 파일은 lock하는 것보다 병렬로 개발하는 것이 더 빠르기에 다음 프로젝트에서 perforce를 사용한다면 바이너리 에셋만 따로 중앙 서버에 두고 코드 베이스는 깃에서 관리하는 식으로 병행해서 사용할 것 같다.
Stream

우선 p4에서는 깃의 branch에 대응되는 개념이 코드라인이다. 그리고 스트림은 몇 가지 기능이 추가된 코드라인이다.
- Branch: git branch와 유사하며 특정 코드라인에 영향을 미치지 않도록 코드라인을 새로 생성한다.
- Integrate: 새 코드라인이나, 작업된 변경 사항을 다른 코드라인에 적용하는 것을 의미한다.
- Merge: 충돌하는 두 개의 컨텐츠를 단일 컨텐츠로 병합한다.
- Resolve
스트림은 사용자가 파일 간 변경사항을 이동하거나, 작업하는 방법을 정의하는 규칙을 추가하여 연관된 파일을 모으는 코드라인으로 보인다.
stream flow
스트림은 부모, 자식 스트림이 있으며 분기된 스트림은 기존 스트림의 자식이 된다.
- Upstream (부모 쪽): 더 안정적인 코드 (Main 또는 Release)
- Downstream (자식 쪽): 실험적이고 변화가 많은 코드 (Development)
스트림 설정 창의 Paths 탭에서 특정 폴더나 파일에 대해 더 세부적인 경로를 정할 수 있다.
- share: 부모와 자식이 양방향으로 데이터를 주고받습니다. (기본값)
- isolate: 내 스트림에서만 수정하고, 부모에게는 보내지 않습니다. (로컬 전용)
- import: 부모나 다른 스트림의 내용을 읽기 전용으로 가져오기만 합니다. (라이브러리 등)
- exclude: 아예 흐름에서 제외합니다. (불필요한 데이터)
stream types
- Mainline: 줄기가 되는 기본 스트림 (최초 생성 시)
- Development: 기능 개발용 (부모로부터 코드를 가져오고 다시 보냄)
- Task: 자식 스트림 못만듬
- Release: 배포/안정화용 (버그 수정 위주)
- Virtual: 특정 파일만 필터링해서 보여주는 가상 스트림
merge/integrate vs copy

copy는 자식을 나에게 반영, merge는 부모를 나에게 반영
| 구분 | Copy (복사) | Merge / Integrate (병합/통합) |
|---|---|---|
| 핵심 목적 | 대상(Target)을 소스(Source)와 완전히 동일하게 만듦 | 소스의 변경 사항을 대상의 기존 작업물과 결합 |
| 충돌 처리 | 충돌이 발생하지 않음 (대상을 그냥 덮어씀) | 충돌 발생 시 수동 해결(Resolve) 필요 |
| 대상 데이터 | 대상 브랜치에만 있던 독자적인 수정 사항이 삭제됨 | 대상 브랜치의 수정 사항을 보존하면서 소스 내용 추가 |
| 사용 시점 | 브랜치를 처음 생성하거나, 특정 상태로 강제 동기화할 때 | 개발 브랜치에서 작업한 내용을 메인 브랜치에 합칠 때 |
퍼포스 GUI
- History: 왼쪽 트리에서 선택한 디팟(Depot), 스트림, 파일의 히스토리
- Files: 왼쪽 트리에서 Workspace 탭으로 갔을 때, 각 폴더에 있는 파일 목록
- Pending: 현재 작업하고자 Checkout한 파일리스트 또는 제출하기 위해 만든 체인지리스트
- Submitted: 내가 제출한 체인지리스트의 목록
- Revert: 파일을 서버에 저장되어 있는걸로 되돌림 (로컬 수정내역 리셋)
- Streams: 현재 서버의 Stream들의 목록을 볼 수 있다.
- Stream Graph: 스트림들 관의 관계 (깃 브랜치 트리 라고 생각하면 된다.)
3. 질문 및 해결 (Q&A)
4. 관련 문서 (Links)
'내일배움캠프 > TIL' 카테고리의 다른 글
| TIL260518 - VFX (0) | 2026.05.18 |
|---|---|
| TIL260515 - Unreal (0) | 2026.05.15 |
| TIL260513 - Unreal (0) | 2026.05.13 |
| TIL260512 - Unreal (0) | 2026.05.12 |
| TIL260511 - Unreal (0) | 2026.05.11 |