๊ฒ์ ๊ฐ๋ฐ ๋ฐ ๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ ๋ฒ์ ๊ด๋ฆฌ(P4) ์๋ฒฝ ๊ฐ์ด๋: P4PORT/P4CLIENT ํ๊ฒฝ ์ค์ , ํด๋ผ์ด์ธํธ ์ํฌ์คํ์ด์ค(Workspace/View Mapping), ์์
๋๊ธฐํ(sync), ๋ณ๊ฒฝ ๋ชฉ๋ก(Changelist), ์ฒดํฌ์์(edit/add/delete), ์ปค๋ฐ(submit), ๋์ฉ๋ ๋ฐ์ด๋๋ฆฌ ๋
์ ์ ๊ธ(exclusive lock), ์คํธ๋ฆผ(Streams) ๋ฐ ์ธ๋ฆฌ์ผ/์ ๋ํฐ ์ค๋ฌด ์ํฌํ๋ก์ฐ
## 1. ์ฌ์ ์๊ฑด & ์์คํ
์๊ตฌ์ฌ์ (Prerequisites & Installation)
### ๐ป ์์คํ
์ค์น ๋ฐ ์คํ ์๊ตฌ์ฌ์ (System Requirements)
| ํญ๋ชฉ | ์ต์ ์ฌ์ (Minimum) | ๊ถ์ฅ ์ฌ์ (Recommended) | ์ฐธ๊ณ ๋ฐ ๋น๊ณ |
| :--- | :--- | :--- | :--- |
| **์ด์์ฒด์ (OS)** | Windows 10/11, macOS, Linux (RHEL, Ubuntu) | Windows 11, Ubuntu 22.04 LTS, macOS Sonoma | ๊ฒ์ ๊ฐ๋ฐ ํ๊ฒฝ(Unreal/Unity)์์๋ Windows ํ์ค |
| **CPU** | 2 ์ฝ์ด ์ด์ | 8 ์ฝ์ด ~ 16 ์ฝ์ด ์ด์ | ์๋ง ๊ฐ ํ์ผ์ ๋ณ๋ ฌ ์ฒดํฌ์์ ๋ฐ ํด์ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฌ |
| **๋ฉ๋ชจ๋ฆฌ (RAM)** | 2 GB ์ด์ | 8 GB ~ 32 GB ์ด์ | ๋๊ท๋ชจ ๊ฒ์ ํ๋ก์ ํธ(์์ญ~์๋ฐฑ GB ์์
) ๋๊ธฐํ ์ ํ์ |
| **๋์คํฌ (Storage)** | 1 GB ์ด์์ ์ฌ์ ๊ณต๊ฐ | 100 GB ~ 1 TB ์ด์์ ์ด๊ณ ์ NVMe SSD | ๋์ฉ๋ 3D ๋ชจ๋ธ(FBX), ํ
์ค์ฒ(PSD/TGA), ๋น๋ ๋ฐ์ด๋๋ฆฌ ๋ณด๊ด |
| **๋คํธ์ํฌ / ํ๋กํ ์ฝ** | P4 CLI / P4V (Helix Visual Client) ์ต์ ๋ฒ์ | ์ฌ๋ด Helix Core ์๋ฒ ํฌํธ (๊ธฐ๋ณธ: `1666` ๋๋ `ssl:1666`) | 1Gbps ~ 10Gbps ๊ณ ์ ์ฌ๋ด LAN ํ๊ฒฝ ๊ถ์ฅ |
---
### ๐ ํด๋ผ์ด์ธํธ ์ค์น ๋ฐ ํ์ ํ๊ฒฝ๋ณ์ ์ค์
Perforce๋ ํฐ๋ฏธ๋ CLI(`p4`)์ ๊ณต์ GUI ํด๋ผ์ด์ธํธ์ธ **P4V**๋ฅผ ๋ชจ๋ ์ง์ํฉ๋๋ค.
#### โ OS๋ณ P4 CLI ์ค์น
```bash
# ๐ง Ubuntu / Debian (Perforce ๊ณต์ ํจํค์ง ์ ์ฅ์ ๋ฑ๋ก)
wget -qO - https://package.perforce.com/perforce.pubkey | sudo apt-key add -
echo "deb http://package.perforce.com/apt/ubuntu jammy release" | sudo tee /etc/apt/sources.list.d/perforce.list
sudo apt update
sudo apt install -y helix-cli
# ๐ macOS (Homebrew)
brew install perforce
# ๐ช Windows (๊ณต์ Helix Core Visual Client ์ค์น ์ p4 CLI ์๋ ํฌํจ)
winget install Perforce.P4V
```
#### โก ํ์ ์ฐ๊ฒฐ ํ๊ฒฝ๋ณ์ ์ค์
```bash
# [1] Helix Core ์๋ฒ ์ฃผ์ ์ง์ (ํธ์คํธ๋ช
:ํฌํธ๋ฒํธ ๋๋ ssl:ํธ์คํธ:ํฌํธ)
export P4PORT=ssl:p4.luckytech.com:1666
# Windows CMD: set P4PORT=ssl:p4.luckytech.com:1666
# PowerShell: $env:P4PORT="ssl:p4.luckytech.com:1666"
# [2] ์ฌ์ฉ์ ๊ณ์ ๋ช
๋ฐ ์ํฌ์คํ์ด์ค ์ด๋ฆ ์ง์
export P4USER=sulucky
export P4CLIENT=sulucky_workstation_main
# [3] ์๋ฒ ์ฐ๊ฒฐ ์ํ ๋ฐ ์ธ์ฆ ํ์ธ
p4 trust -y # SSL ์ง๋ฌธ ์ ๋ขฐ ๋ฑ๋ก (SSL ์ ์ ์ ์ต์ด 1ํ)
p4 login # ๋น๋ฐ๋ฒํธ ์
๋ ฅํ์ฌ ํฐ์ผ ๋ฐ๊ธ
p4 info # ํ์ฌ ์ฐ๊ฒฐ๋ ์๋ฒ ์ ๋ณด ๋ฐ ๋ด ์ํฌ์คํ์ด์ค ์ํ ์์ฝ ์ถ๋ ฅ
```
---
## 2. Perforce ๋ฉํ ๋ชจ๋ธ: ๋ํฌ(Depot) vs ์ํฌ์คํ์ด์ค (Architecture)
Git์ด ๋ชจ๋ ๋ณ๊ฒฝ ์ด๋ ฅ์ ๋ก์ปฌ์ ํต์งธ๋ก ๋ณต์ ํ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, **Perforce Helix Core**๋ ๊ธฐ๊ฐ๋ฐ์ดํธ(GB)~ํ
๋ผ๋ฐ์ดํธ(TB) ๋จ์์ ๋๊ท๋ชจ ๊ฒ์ ๋ฐ์ด๋๋ฆฌ ์์
์ ์ฒ๋ฆฌํ๊ธฐ ์ํด **์ค์ ์ง์คํ ์คํธ๋ฆฌ๋ฐ ๊ตฌ์กฐ**๋ฅผ ์ฑํํฉ๋๋ค.
### ๐ ๋ํฌ, ๋ทฐ ๋งคํ, ์ํฌ์คํ์ด์ค ์ํคํ
์ฒ (ASCII Diagram)
```text
[ Helix Core Central Server ] (์ค์ ์๋ฒ)
โโโ //depot/ (์ค์ ๋ํฌ)
โโโ //depot/main/Source/ (C++ ์์ค์ฝ๋)
โโโ //depot/main/Content/ (์ธ๋ฆฌ์ผ 3D ๋ชจ๋ธ, ํ
์ค์ฒ, ์ฌ์ด๋: 500GB+)
โโโ //depot/main/Config/
โ
โผ [ View Mapping (์ ํ์ ๋งคํ ํํฐ๋ง) ]
โ //depot/main/... //sulucky_ws/...
โผ
[ Local Client Workspace ] (๊ฐ๋ฐ์ ๋ก์ปฌ PC: C:\Projects\MyGame)
- ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ํ์ผ์ ์ฝ๊ธฐ ์ ์ฉ(Read-Only: ์ฐ๊ธฐ ๋ฐฉ์ง ์ ๊ธ ์ํ)
- ์์
ํ ํ์ผ๋ง ๋ช
์์ ์ผ๋ก ์ฐ๊ธฐ ๊ถํ์ ์ด์ด ์ฒดํฌ์์ (p4 edit)
โ
โผ [ Changelist (์์์ ๋ณ๊ฒฝ ๋ฌถ์) ]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Changelist #1024 (Pending) โ
โ - //depot/main/Content/Characters/Hero.uasset (edit) โ
โ - //depot/main/Content/Textures/Hero_Albedo.png (edit) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ p4 submit (์์์ ์ปค๋ฐ)
โผ
[ ์ค์ ์๋ฒ์ ์ ๊ท ๊ธ๋ก๋ฒ ์ฒด์ธ์ง๋ฆฌ์คํธ #1025๋ก ์๊ตฌ ๊ธฐ๋ก ์๋ฃ ]
```
### ๐งฉ Git vs Perforce ํต์ฌ ๋ฉํ ๋ชจ๋ธ ๋น๊ต
| ๋น๊ต ํญ๋ชฉ | Git (๋ถ์ฐ VCS) | Perforce Helix Core (์ํฐํ๋ผ์ด์ฆ VCS) |
| :--- | :--- | :--- |
| **๋์ฉ๋ ํ์ผ ์ฒ๋ฆฌ** | ๋๊ท๋ชจ ๋ฐ์ด๋๋ฆฌ ์ ์ฅ ์ LFS ํ์, ์๋ ๊ธ๊ฐ | **GB ๋จ์ ๋์ฉ๋ ํ์ผ ์์ญ๋ง ๊ฐ๋ฅผ ์ด๊ณ ์ ์ฒ๋ฆฌ (๊ฒ์ ์
๊ณ ํ์ค)** |
| **๋ก์ปฌ ํ์ผ ์์ ๋ฐฉ์** | ๋ก์ปฌ ํ์ผ ์ธ์ ๋ ์์ ๋กญ๊ฒ ์์ ๊ฐ๋ฅ | **๊ธฐ๋ณธ Read-Only ์ํ โ ์์
์ `p4 edit` ์ฒดํฌ์์ ํ์** |
| **๋ฐ์ด๋๋ฆฌ ํ์ผ ์ ๊ธ** | ๋ถ๊ฐ๋ฅ (๋์ ์์ ํ ๋จธ์ง ์คํจ) | **๋
์ ์ ๊ธ(`+l`)์ผ๋ก ๋ค๋ฅธ ์ฌ๋์ ๋์ ์์ ์์ฒ ์ฐจ๋จ** |
| **์ปค๋ฐ ๋จ์** | ๋ก์ปฌ Commit โ ์๊ฒฉ Push | **์ฒด์ธ์ง๋ฆฌ์คํธ(Changelist) ๋จ์๋ก ์ค์ ์๋ฒ์ ์ฆ์ Submit** |
| **๋ธ๋์นญ ๋ฐฉ์** | ๊ฐ๋ฒผ์ด ๋ก์ปฌ ๋ธ๋์น ํฌ์ธํฐ | **์คํธ๋ฆผ(Streams) ๊ธฐ๋ฐ ๊ฐ์์ ํ์ดํ๋ผ์ธ ๋ธ๋์นญ** |
---
## 3. [์ด๋ณด์ 1๋จ๊ณ] 3๋ถ ํฌ๋ก์๋: ์ํฌ์คํ์ด์ค ์ค์ & ์ฒซ Submit (Hello World)
### โ ํด๋ผ์ด์ธํธ ์ํฌ์คํ์ด์ค ์์ฑ (`p4 client`)
๋ก์ปฌ ํด๋์ ์๋ฒ ๋ํฌ(Depot) ๊ฒฝ๋ก๋ฅผ ์ฐ๊ฒฐํ๋ ๋ทฐ ๋งคํ(View Mapping)์ ๊ตฌ์ฑํฉ๋๋ค:
```bash
# ๊ธฐ๋ณธ ํ
์คํธ ์๋ํฐ๋ก ์ํฌ์คํ์ด์ค ์ค์ ์ด๊ธฐ
p4 client
```
์ค์ ํ์ผ์ด ์ด๋ฆฌ๋ฉด ๋ค์ ํญ๋ชฉ์ ์์ฑํ๊ณ ์ ์ฅํฉ๋๋ค:
```text
Client: sulucky_workstation_main
Owner: sulucky
Root: /Users/sulucky/workspace/mygame # Windows: D:\Projects\MyGame
View:
//depot/main/... //sulucky_workstation_main/...
```
---
### โก ์ต์ ํ์ผ ๋๊ธฐํ (Sync)
```bash
# ์๋ฒ์ ์ต์ ๋ฆฌ๋น์ ํ์ผ๋ค์ ๋ก์ปฌ ๋๋ ํ ๋ฆฌ๋ก ๋ค์ด๋ก๋
p4 sync
# ์ถ๋ ฅ: //depot/main/README.md#1 - added /Users/sulucky/workspace/mygame/README.md
```
---
### โข ํ์ผ ์ถ๊ฐ, ์์ ๋ฐ ์ ์ถ (Add, Edit & Submit)
```bash
cd /Users/sulucky/workspace/mygame
# [1] ์ ๊ท ํ
์คํธ ํ์ผ ์์ฑ ๋ฐ P4์ ์ถ๊ฐ ๋ฑ๋ก (p4 add)
echo "Perforce ๊ฒ์ ๊ฐ๋ฐ ํ๋ก์ ํธ ์์!" > intro.txt
p4 add intro.txt
# ์ถ๋ ฅ: //depot/main/intro.txt#1 - opened for add
# [2] ํ์ฌ ์ด๋ ค ์๋ ๋ณ๊ฒฝ ๋ชฉ๋ก ํ์ธ
p4 opened
# ์ถ๋ ฅ: //depot/main/intro.txt#1 - add default change (text)
# [3] ์๋ฒ์ ์ฒด์ธ์ง๋ฆฌ์คํธ ์ ์ถ (p4 submit)
p4 submit -d "ํ๋ก์ ํธ ์๊ฐ ํ
์คํธ ํ์ผ ์ ๊ท ๋ฑ๋ก"
# ์ถ๋ ฅ:
# Submitting change 1001.
# Locking 1 files ...
# add //depot/main/intro.txt#1
# Change 1001 submitted.
```
---
### โฃ ๊ธฐ์กด ํ์ผ ์์ ์: ๋ฐ๋์ `p4 edit` ๋จผ์ ์คํ!
```bash
# ๋ก์ปฌ ํ์ผ์ด Read-Only๋ก ์ ๊ฒจ ์์ผ๋ฏ๋ก, ์์ ์ ๋ฐ๋์ p4 edit์ผ๋ก ์ฐ๊ธฐ ๊ถํ์ ํ์ด์ผ ํจ!
p4 edit intro.txt
# ์ถ๋ ฅ: //depot/main/intro.txt#1 - opened for edit
# ๋ด์ฉ ์์
echo "์๋ก์ด ํจ์น ๋
ธํธ ์ถ๊ฐ" >> intro.txt
# ์์ ์ฌํญ ์ปค๋ฐ
p4 submit -d "์๊ฐ ํ์ผ ๋ด์ฉ ์
๋ฐ์ดํธ"
# Change 1002 submitted.
```
---
## 4. [2๋จ๊ณ] ํต์ฌ ๊ธฐ๋ฅ: ์ผ์ ์์
& ๋ณ๊ฒฝ ๋ชฉ๋ก ๊ด๋ฆฌ (Changelists & Shelve)
### ๐ป ํ์ ํ์ผ ์ํ ์ ์ด ๋ช
๋ น์ด
```bash
# [1] ํ์ผ ์์ ์ค๋น (์ฒดํฌ์์ - ์ฐ๊ธฐ ๊ถํ ํ์ฑํ)
p4 edit <file>
# [2] ์ ๊ท ํ์ผ ์ถ๊ฐ
p4 add <file>
# [3] ํ์ผ ์ญ์ (์๋ฒ์์ ์ญ์ ์์ฝ)
p4 delete <file>
# [4] ์์
์ทจ์ (์์ ์ ๋ฒ๋ฆฌ๊ณ ์๋ฒ ์ต์ ๋ณธ์ผ๋ก ์์ ๋ณต๊ตฌ)
# ํ์ผ ๋ด์ฉ์ด ์์ ๋์ง ์์๋ค๋ฉด ์๋์ผ๋ก ๋ซํ
p4 revert <file>
# ๋ด์ฉ์ด ์์ ๋์์ด๋ ๊ฐ์ ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ํ๊ธฐํ๊ณ ๋กค๋ฐฑ (-a ๋๋ ๋ฌด์กฐ๊ฑด ๋๋๋ฆฌ๊ธฐ)
p4 revert -k <file> # ๋ก์ปฌ ํ์ผ์ ๋จ๊ธฐ๊ณ P4 ์ด๋ฆฐ ์ํ๋ง ์ทจ์
p4 revert <file> # ๋ก์ปฌ ์์ ๋ฒ๋ฆฌ๊ณ ์๋ณธ์ผ๋ก ๋ฎ์ด์ฐ๊ธฐ
# [5] ๋ด๊ฐ ํ์ฌ ์์ ์ค์ธ ๋ชจ๋ ํ์ผ ๋ชฉ๋ก ํ์ธ
p4 opened
```
---
### ๐ฆ ๋ฒํธ ๋งค๊ฒจ์ง ๋ณ๊ฒฝ ๋ชฉ๋ก (Numbered Changelist) ์์ฑ
์ฌ๋ฌ ์์
์ ๋์์ ์งํํ ๋, ํน์ ๋ฒ๊ทธ ์์ ํ์ผ๋ค๋ง ํ๋์ ์ฒด์ธ์ง๋ฆฌ์คํธ๋ก ๋ฌถ์ด ๊ด๋ฆฌํฉ๋๋ค:
```bash
# ์ ๊ท ์ฒด์ธ์ง๋ฆฌ์คํธ ์์ฑ (๋ํํ ์๋ํฐ ์คํ)
p4 change
```
```text
Change: new
Description:
[BUG-104] ํ๋ ์ด์ด ์บ๋ฆญํฐ ์ ํ ์ ๋๋ฉ์ด์
๊ธ๋ฆฌ์น ์์
Files:
//depot/main/Source/PlayerController.cpp
//depot/main/Content/Anims/Jump.uasset
```
์ ์ฅ ์ `Change 1005 created.`์ ๊ฐ์ด ๋ฒํธ๊ฐ ๋ฐ๊ธ๋ฉ๋๋ค.
```bash
# ํน์ ์ฒด์ธ์ง๋ฆฌ์คํธ๋ง ๋จ๋
์ ์ถ
p4 submit -c 1005
```
---
### ๐ก๏ธ ๋ณ๊ฒฝ ์ฌํญ ์์ ๋ณด๊ด (Shelve / Unshelve)
์์
๋์ค ๊ธํ ํซํฝ์ค๋ฅผ ํด์ผ ํ๊ฑฐ๋, ๋๋ฃ์๊ฒ ๋ด ์์
์ฝ๋๋ฅผ ์๋ฒ์ ์ฌ๋ ค ๋ฆฌ๋ทฐ๋ฐ๊ณ ์ถ์ ๋ ๋ก์ปฌ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ฒ์ ์์ ๋ณด๊ดํจ์ ์
ธ๋ธ(Shelve)ํฉ๋๋ค:
```bash
# [1] ๋ฒํธ ๋งค๊ฒจ์ง ์ฒด์ธ์ง๋ฆฌ์คํธ์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ฒ์ ์
ธ๋ธ (๋ฐฑ์
)
p4 shelve -c 1005
# ์ถ๋ ฅ: Shelving files for change 1005 ...
# [2] ๋ก์ปฌ ์์
ํ์ผ์ ์์ ํ๊ฒ ๋๋๋ฆฌ๊ณ ๋ค๋ฅธ ์์
์ํ
p4 revert -c 1005 //...
# [3] ๋์ค์ ๋๋ ๋๋ฃ PC์์ ํด๋น ์์
๋ณต์ (Unshelve)
p4 unshelve -s 1005
```
---
## 5. [2๋จ๊ณ] ํต์ฌ ๊ธฐ๋ฅ: ๋ฐ์ด๋๋ฆฌ ๋
์ ์ ๊ธ (Exclusive Locking: `+l`)
๊ฒ์ ๊ฐ๋ฐ์์ **3D ๋ชจ๋ธ(FBX), ํ
์ค์ฒ(PNG/PSD), ์ธ๋ฆฌ์ผ ๋ธ๋ฃจํ๋ฆฐํธ(`.uasset`), ์ ๋ํฐ ํ๋ฆฌํน(`.prefab`)** ๋ฑ์ ๋ ์ฌ๋์ด ๋์์ ๊ณ ์น๋ฉด ๋ณํฉ(Merge)์ด ๋ถ๊ฐ๋ฅํ์ฌ ์์
๋ฌผ์ด ์ ์ค๋ฉ๋๋ค.
Perforce์ **๋ฐฐํ์ ์ ๊ธ(Exclusive Lock: `+l`)** ์์ฑ์ ์ฌ์ฉํ๋ฉด ํ ์ฌ๋์ด `p4 edit`ํ๋ ์๊ฐ ๋ค๋ฅธ ์ฌ๋์ ์์ ์ ์์ฒ ์ฐจ๋จํฉ๋๋ค.
### โ ํ์ผ ํ์
์ `+l` (Exclusive Lock) ๋ถ์ฌ
```bash
# ํ์ผ ์ถ๊ฐ ์ ๋ฐฐํ์ ์ ๊ธ ๋ฐ์ด๋๋ฆฌ ํ์
์ง์
p4 add -t binary+l Characters/Monster.uasset
# ์ด๋ฏธ ๋ฑ๋ก๋ ํ์ผ์ ํ์
์ ๋ฐฐํ์ ์ ๊ธ์ผ๋ก ๋ณ๊ฒฝ
p4 edit -t binary+l Weapons/Sword.fbx
p4 submit -d "๋ฌด๊ธฐ ๋ชจ๋ธ์ ๋
์ ์ ๊ธ ํ์
๋ถ์ฌ"
```
### โก ์ ์ญ ํ์ผ ํ์
๋งคํ ๊ท์น ์ค์ (`p4 typemap`)
๊ด๋ฆฌ์๊ฐ ์๋ฒ ์ ์ญ์์ ํน์ ํ์ฅ์๋ ๋ฌด์กฐ๊ฑด ๋
์ ์ ๊ธ์ด ๋๋๋ก ๊ฐ์ ํฉ๋๋ค:
```bash
p4 typemap
```
```text
TypeMap:
binary+l //depot/.../*.uasset
binary+l //depot/.../*.umap
binary+l //depot/.../*.fbx
binary+l //depot/.../*.psd
binary+l //depot/.../*.blend
```
> **ํจ๊ณผ**: ์ด์ ์ด๋ค ์ํฐ์คํธ๊ฐ `Monster.uasset`์ ๋ํด `p4 edit`์ ์คํํ๋ ์๊ฐ, ๋ค๋ฅธ ํ์์ "Monster.uasset is locked by artist_kim"์ด๋ผ๋ ๊ฒฝ๊ณ ์ ํจ๊ป ์์ ์ ์์ํ ์ ์๊ฒ ๋ฉ๋๋ค.
---
## 6. [3๋จ๊ณ] ์ค๋ฌด ์์ฉ: ์คํธ๋ฆผ(Streams) ๋ธ๋์นญ ์ํฌํ๋ก์ฐ (Streams)
Helix Core์ **์คํธ๋ฆผ(Streams)**์ ๋ณต์กํ ๋ธ๋์น ๊ฐ์ ๊ด๊ณ์ ์ฝ๋ ๋ณํฉ ํ๋ฆ์ ์๊ฐ์ ์ธ ์ปจํ
์ด๋๋ก ๊ตฌ์กฐํํ ๋ชจ๋ ํ์ดํ๋ผ์ธ์
๋๋ค.
### ๐ ์คํธ๋ฆผ ํ๋ฆ ์์น (Merge Down, Copy Up)
```text
[ Mainline Stream ] (์์ ํ๋ ํ๋ก๋์
๋ฉ์ธ ์ค๊ธฐ: //stream/main)
โฒ โ
Copy Up โ โ Merge Down
(์ํฅ ๋ณต์ฌ) โ (ํํฅ ๋ณํฉ)
โ โผ
[ Development Stream ] (๊ธฐ๋ฅ ๊ฐ๋ฐ ์ค๊ธฐ: //stream/dev)
```
- **Merge Down (ํํฅ ๋ณํฉ)**: ๋ฉ์ธ๋ผ์ธ์ ์ต์ ๋ณ๊ฒฝ ์ฌํญ์ ํญ์ ๋จผ์ ๊ฐ๋ฐ ๋ธ๋์น๋ก ๋ด๋ ค๋ฐ์ ์ถฉ๋์ ํด๊ฒฐ.
- **Copy Up (์ํฅ ๋ณต์ฌ)**: ์๋ฒฝํ ๊ฒ์ฆ๋๊ณ ์์ ํ๋ ์ฝ๋๋ง ๋ฉ์ธ๋ผ์ธ์ผ๋ก ์ฌ๋ฆผ.
```bash
# [1] ํํฅ ๋ณํฉ (Mainline โ Dev)
p4 merge -S //stream/dev
p4 resolve -am # ์ถฉ๋ ์๋ ํด๊ฒฐ (ํ
์คํธ ์์ ๋ณํฉ)
p4 submit -d "๋ฉ์ธ๋ผ์ธ ์ต์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ๋ฐ ๋ธ๋์น๋ก ๋ณํฉ"
# [2] ์ํฅ ๋ณต์ฌ (Dev โ Mainline)
p4 copy -S //stream/dev
p4 submit -d "๊ฐ๋ฐ ์๋ฃ๋ ๊ธฐ๋ฅ ๋ฉ์ธ๋ผ์ธ์ผ๋ก ๋ฆด๋ฆฌ์ฆ ๋ณต์ฌ"
```
---
## 7. [3๋จ๊ณ] ์ค๋ฌด ์์ฉ: ๋ฆฌ๋น์ ์ง์ ์ & ํ์ผ ์ถ์ (Revisions & Diff)
### ๐ท๏ธ P4 ๋ฆฌ๋น์ ์ง์ ์(Revision Specifier) ๋ฌธ๋ฒ
| ์ง์ ์ ๋ฌธ๋ฒ | ์๋ฏธ ๋ฐ ์ค๋ช
| ์ฌ์ฉ ์์ |
| :--- | :--- | :--- |
| **`#head`** | ์ ์ฅ์์ ๊ฐ์ฅ ์ต์ ๋ฆฌ๋น์ | `p4 sync file.cpp#head` |
| **`#have`** | ๋ด ๋ก์ปฌ ์ํฌ์คํ์ด์ค๊ฐ ํ์ฌ ๋ณด์ ํ ๋ฆฌ๋น์ | `p4 diff file.cpp#have` |
| **`#<number>`** | ํน์ ๋ฆฌ๋น์ ๋ฒํธ (1๋ถํฐ ์์) | `p4 diff file.cpp#3` |
| **`@<changelist>`**| ํน์ ์ฒด์ธ์ง๋ฆฌ์คํธ ์์ ์ ์ํ | `p4 sync //depot/...@1020` |
| **`@<date>`** | ํน์ ๋ ์ง/์๊ฐ ์์ ์ ์ํ | `p4 sync //depot/...@2026/10/10` |
```bash
# [1] ํ์ผ์ ๋ณ๊ฒฝ ํ์คํ ๋ฆฌ ๋ฐ ๋๊ฐ ์์ ํ๋์ง ํ์ธ
p4 filelog Content/Characters/Hero.uasset
# [2] ํ์ผ ๋ผ์ธ๋ณ ์์ฑ์ ์ถ์ (Git blame๊ณผ ๋์ผ)
p4 annotate -u Source/GameEngine.cpp
# [3] ๋ด ๋ก์ปฌ ์์ ๋ณธ๊ณผ ์๋ฒ ์ต์ ๋ณธ์ ์ฐจ์ด์ diff
p4 diff -du Source/Player.cpp
```
---
## 8. ์ค๋ฌด ์ฃผ์์ฌํญ & ๊ฒ์ ์์ง ์ฐ๋ ๋ชจ๋ฒ ์ฌ๋ก (Best Practices)
### โ ๏ธ ์ด๋ณด์๊ฐ ๊ฐ์ฅ ํํ ๊ฒช๋ 5๋ ์ค์ ๋ฐ ํด๊ฒฐ์ฑ
| ์ฆ์ ๋ฐ ๋ฌธ์ ์ | ์์ธ ๋ถ์ | ํ์คํ ํด๊ฒฐ ๊ฐ์ด๋ |
| :--- | :--- | :--- |
| **P4 ์ธ๋ถ์์ ํ์ผ ์์ ํ ํ์ผ์ด ์ฌ์ ํ Read-Only** | `p4 edit`์ ์คํํ์ง ์๊ณ ์๋ํฐ๋ ํด์์ ๊ฐ์ ์ ์ฅํจ | **`p4 reconcile`** (๋๋ `p4 status`)๋ฅผ ์คํํ์ฌ ์คํ๋ผ์ธ ๋ณ๊ฒฝ ์ฌํญ์ P4 ์์
๋ชฉ๋ก์ ์๋ ๋ฐ์ |
| **Submit ์ `File is out of date` ์๋ฌ ๋ฐ์** | ๋ด๊ฐ ์์
ํ๋ ๋์ ๋ค๋ฅธ ์ฌ๋์ด ์ ๋ฆฌ๋น์ ์ ๋จผ์ ์ฌ๋ฆผ | **`p4 sync`** โ **`p4 resolve`** (์ถฉ๋ ํด๊ฒฐ) โ ๋ค์ **`p4 submit`** |
| **๋๋ฃ๊ฐ ํ์ผ์ ๋ฝ(`+l`) ๊ฑธ์ด๋๊ณ ํด๊ทผ/ํด๊ฐ ๊ฐ** | ๋
์ ์ ๊ธ์ด ์ ์ง๋์ด ๋ค๋ฅธ ์์
์๊ฐ ๋ธ๋กํน๋จ | ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ๊ฐ์ ์ ๊ธ ํด์ : `p4 unlock -f //depot/.../file.uasset` |
| **๋ถํ์ํ ์์ ํ์ผ์ด P4์ ๋๋ add ๋จ** | `.p4ignore` ํ์ผ ๋๋ฝ | ์ํฌ์คํ์ด์ค ๋ฃจํธ์ `.p4ignore` ํ์ผ ์์ฑ ํ `P4IGNORE=.p4ignore` ์ค์ |
| **์ํฌ์คํ์ด์ค๋ฅผ ์๋ชป ์ญ์ ํ์ฌ ํ์ผ ์ ์ฒด๊ฐ ์ฌ๋ผ์ง** | `p4 client -d` ์ ๋ก์ปฌ ํ์ผ ๋๊ธฐํ ์ต์
ํผ๋ | ์ ์ํฌ์คํ์ด์ค๋ฅผ ๋ง๋ค๊ณ `p4 sync -f`๋ก ๊ฐ์ ์ฌ๋๊ธฐํ |
---
### ๐ฎ ์ธ๋ฆฌ์ผ ์์ง / ์ ๋ํฐ ์ ์ฉ `.p4ignore` ํ
ํ๋ฆฟ
ํ๋ก์ ํธ ๋ฃจํธ์ `.p4ignore` ํ์ผ์ ์์ฑํ๊ณ ํ๊ฒฝ๋ณ์๋ก ๋ฑ๋กํฉ๋๋ค:
```bash
p4 set P4IGNORE=.p4ignore
```
```ini
# .p4ignore - Unreal Engine & Unity ํ์ค ์ ์ธ ๋ชฉ๋ก
# ์ธ๋ฆฌ์ผ ์์ง (Unreal Engine 5)
Binaries/
Build/
DerivedDataCache/
Intermediate/
Saved/
.vscode/
.vs/
*.sln
*.vcxproj
# ์ ๋ํฐ (Unity)
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
[Mm]emoryCaptures/
*.csproj
*.unityproj
```
์๊ฒฌ ๋ฐ ์ง๋ฌธ
0์์ง ๋ฑ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋๊ธ์ ๋จ๊ฒจ๋ณด์ธ์!
๋๊ธ ์์
๋๊ธ ์ญ์