Graphics Programming

UE4 플러그인의 소스 컨트롤 본문

Season 2

UE4 플러그인의 소스 컨트롤

minseoklee 2020. 1. 11. 19:00

UE4에서 프로젝트를 진행하면 이런저런 플러그인을 쓰게 된다. 엔진에 내장된 것도 있고, 구매하는 것도 있고, 직접 만드는 것도 있다.

플러그인의 소스 컨트롤을 메인 프로젝트의 소스 컨트롤과 묶어서 프로젝트 저장소에서 플러그인 수정도 관리하는 게 가장 직관적이고 관리하기도 편하다. 하지만 여러가지 이유로 다른 저장소를 파서 별도의 테스트 프로젝트에서 플러그인을 개발하고, 플러그인만 메인 프로젝트로 복사해올 수도 있다.

  • UE4의 설계 의도상 어떤 프로젝트에 있는 플러그인 폴더만 복사해서 다른 프로젝트에 붙여넣어도 제대로 동작해야 한다. 그리고 이렇게 옮긴 플러그인이 제대로 작동해야 모듈화가 제대로 되어있다는 뜻이기도 하다.
  • 프로젝트가 거대할 경우 이터레이션(컴파일/쿠킹/패키징/테스트 사이클)이 굉장히 길어진다. 작은 테스트 프로젝트에서 플러그인을 개발하면 이터레이션이 훨씬 짧아진다.
  • 메인 프로젝트의 개발 히스토리와 분리하여 플러그인의 개발 히스토리만 따로 관리할 수 있다.

내가 만든 플러그인을 퍼포스와 깃에서 이런 식으로 관리했는데 나름 잘 먹혔다.

플러그인 프로젝트와 메인 프로젝트의 디렉토리가 이렇다 가정하고 글을 진행하겠다.

MyPluginDev
 Binaries/
 Content/

 Plugins/MyPlugin/...
 Source/

└ MyPluginDev.uproject

프로젝트 저장소: myproject
MyProject
 Binaries/
 Content/

 Plugins/MyPlugin/...
 Source/

└ MyProject.uproject

퍼포스

같은 디팟 안에 플러그인용 메인라인 스트림을 따로 만들거나, 아예 별도의 디팟을 만들 수도 있다. 인프라팀이 퍼포스를 관리해서 개발팀에 권한이 없으면 새로운 디팟을 만들지 못할 수도 있지만, 어차피 브랜치 매핑을 쓸 거라 상관없다.

메인 프로젝트에 플러그인 v1.1까지 통합된 상태에서 v1.2까지 개발을 완료했다고 가정하자.

플러그인 스트림 (//MyDepot/MyPluginDev/...)
CL-10011: v1.1 release
CL-10012: Bug fix
CL-10013: Implement something
CL-10014: Optimize something
CL-10015: v1.2 release

이런 경우 P4V에서 //MyDepot/MyPluginDev/Plugins/MyPlugin/... 와 //MyDepot/MyProject/Plugins/MyPlugin/... 사이에 브랜치 매핑을 생성하고 Merge/Integrate 기능을 통해 머지하면 된다. 메인 프로젝트에 통합했더니 미처 생각치 못한 문제가 생겨서 메인 프로젝트의 스트림에서 플러그인을 핫픽스해야 할 경우, 브랜치 매핑의 방향만 바꿔서 반대로 머지한다.

퍼포스를 쓸 때는 P4V라는 GUI 툴만 쓰고 커맨드라인은 거의 안 써서 p4 명령어로 하는 방법은 모르겠지만 깃보다는 단순할 것 같다. 깃은 통합하기가 보다 복잡하다.

퍼포스에서 위와 같이 잘 쓰고 있었는데 이제 팀에서 버전 관리를 깃으로 한다는 통지가 내려졌다. 일단 깃 저장소를 따로 파고 git-p4를 써서 플러그인 스트림의 히스토리를 그대로 가져왔다. 이제 두 저장소 사이에서 플러그인 폴더만 머지해야 하는 상황이 되었는데, 깃의 머지는 두 브랜치 간에 커밋을 대조해서 머지하는 것이지 두 폴더 사이를 머지한다는 개념이 없어서 고심하다가 이런 방법을 택했다.

플러그인 저장소: myplugin
프로젝트 저장소: myproject
둘 다 master 브랜치를 기준으로 머지하고, 로컬 변경이 없다고 가정한다.

myplugin의 플러그인을 myproject에 통합하기
// 한 번만
git remote add myplugin <플러그인 저장소>

// 머지용 브랜치가 남아있으면 삭제
git branch -D myplugin-merger

// 현재 브랜치 안 건드리면서 myplugin 정보 최신화
git fetch myplugin master

// 로컬 master를 리모트 master에 맞춤 (패스트 포워드 잘 되었다고 가정)
git checkout master
git pull origin master

// 머지용 브랜치 생성
git checkout -b myplugin-merger master

// 현재 플러그인 폴더 삭제 후 플러그인 저장소의 플러그인 폴더를 가져옴
git rm -r MyPluginDev/Plugins/MyPlugin
git read-tree --prefix=MyProject/Plugins/MyPlugin/ -u myplugin/master:MyPluginDev/Plugins/MyPlugin
git add -u
git commit -m "커밋 메시지"

// 머지용 브랜치를 리모트에 올린다. 풀 리퀘스트를 통해 myplugin-merger를 master에 머지
// (아니면 로컬에서 알아서 머지하고 master를 바로 업데이트)
git push origin myplugin-merger

myproject 저장소에서 플러그인을 핫픽스해서 myplugin에 통합하는 것도 비슷하게 진행한다.

myproject의 플러그인을 myplugin에 통합하기
// 한 번만
git remote add myproject <플러그인 저장소>

git branch -D myproject-merger
git fetch myproject master
git checkout master
git pull origin master
git checkout -b myproject-merger master
git rm -r MyPluginDev/Plugins/MyPlugin
git read-tree --prefix=MyPluginDev/Plugins/MyPlugin/ -u myproject/master:MyProject/Plugins/MyPlugin
git add -u
git commit -m "커밋 메시지"

// 이번에는 위와 다르게 로컬에서 머지하고 master를 바로 업데이트한다고 가정
git checkout master
git merge --ff-only myproject-merger
git push origin master

퍼포스에서는 브랜치 매핑을 만들어 놓고 Merge/Integrate만 누르면 되던 것이 더럽게 복잡해졌는데 더 편한 방법이 생각나지 않는다. -.-

Comments