# 스마트 병합

> Use the UnityYAMLMerge tool to merge scene and prefab files in a semantically correct way.

**UnityYAMLMerge** 툴을 사용하여 씬과 프리팹 파일을 구문상 올바르게 병합할 수 있습니다. 이 툴은 커맨드 라인에서 접근할 수 있으며 타사 버전 관리 소프트웨어에서도 사용할 수 있습니다.

## Unity에서 스마트 병합 설정

버전 관리 프로젝트 설정(메뉴: **Edit** > **Project Settings** > **Version Control**)의 **Mode** 필드에서 타사 버전 관리 툴(예: Perforce, PlasticSCM)을 선택하면 **Smart Merge**가 표시됩니다. 이 메뉴의 옵션은 다음과 같습니다.

* **Off**: 스마트 병합 없이 환경 설정에서 설정된 디폴트 병합 툴만을 사용합니다.
* **Premerge**: 스마트 병합을 활성화하고 클린 병합을 허용합니다. 언클린 병합은 파일의 base, mine, theirs 버전의 사전 병합 버전을 생성합니다. 그 후 기본 병합 툴과 함께 사용합니다.
* **Ask**: 스마트 병합을 사용하지만 충돌이 발생하면 사용자가 처리할 수 있도록 다이얼로그를 보여 줍니다(이 옵션이 디폴트 설정입니다).

## 타사 툴과 함께 사용하도록 UnityYAMLMerge 설정

UnityYAMLMerge 툴은 Unity 에디터에 내장되어 있습니다. Unity가 표준 위치에 설치되어 있을 경우 UnityYAMLMerge의 경로는 다음과 같습니다.

```
C:\Program Files\Unity\Editor\Data\Tools\UnityYAMLMerge.exe

or

C:\Program Files (x86)\Unity\Editor\Data\Tools\UnityYAMLMerge.exe
```

Windows에서는 위와 같으며

```
/Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge
```

Mac OSX에서는 위와 같습니다(폴더에 접근하려면 Finder에서 *Show Package Contents* 커맨드를 사용해야 합니다).

UnityYAMLMerge에는 해결되지 않은 충돌 또는 알려지지 않은 파일의 처리 방법을 지정하는 기본 폴백 파일이 내장되어 있습니다(mergespecfile.txt 파일, Tools 폴더에 존재). 또한 이 파일은 파일 확장자를 기반으로 병합 툴을 자동으로 선택하지 않는 버전 관리 시스템(예: Git)의 주요 병합 툴로 사용할 수 있습니다. 가장 일반적인 툴은 mergespecfile.txt에 이미 기본적으로 나열되어 있지만, 이 파일을 편집하여 새 툴을 추가하거나 옵션을 변경할 수 있습니다.

UnityYAMLMerge는 스탠드얼론 툴로써 커맨드 라인에서 실행할 수 있습니다(인수 없이 실행하면 전체 사용법을 볼 수 있습니다). 일반적인 버전 관리 시스템의 설정 지침은 아래와 같습니다.

### P4V

1. Preferences > Merge로 이동합니다.
2. \_Other application\_을 선택합니다.
3. *Add* 버튼을 클릭합니다.
4. 확장자 필드에 `.unity`를 입력합니다.
5. 애플리케이션 필드에 UnityYAMLMerge 툴의 경로를 입력합니다(위 참조).
6. 인수 필드에 `merge -p %b %1 %2 %r`을 입력합니다.
7. 저장을 클릭합니다.

이후 동일한 절차를 따라 `.prefab` 확장자를 추가합니다.

### Git

`.git` 또는 `.gitconfig` 파일에 다음 텍스트를 추가합니다.

```
	[merge]
	tool = unityyamlmerge

	[mergetool "unityyamlmerge"]
	trustExitCode = false
	cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
```

### Mercurial

`.hgrc` 파일에 다음 텍스트를 추가합니다.

```
	[merge-patterns]
	**.unity = unityyamlmerge
	**.prefab = unityyamlmerge

	[merge-tools]
	unityyamlmerge.executable = <path to UnityYAMLMerge>
	unityyamlmerge.args = merge -p --force $base $other $local $output
	unityyamlmerge.checkprompt = True
	unityyamlmerge.premerge = False
	unityyamlmerge.binary = False
```

### SVN

`~/.subversion/config` 파일에 다음을 추가합니다.

```
	[helpers]
	merge-tool-cmd = <path to UnityYAMLMerge>
```

### TortoiseGit

1. Preferences > Diff Viewer > Merge Tool로 이동한 후 **Advanced** 버튼을 클릭합니다.
2. 팝업에서 확장자 필드에 `.unity`를 입력합니다.
3. **External Program** 필드에 다음을 입력합니다.

```
	<path to UnityYAMLMerge> merge -p %base %theirs %mine %merged
```

이후 동일한 절차를 따라 `.prefab` 확장자를 추가합니다.

### PlasticSCM

1. Preferences > Merge Tools로 이동한 후 **Add** 버튼을 클릭합니다.
2. **External** 병합 툴을 선택합니다.
3. **Use with files that match the following pattern**을 선택합니다.
4. `.unity` 확장자를 추가합니다.
5. 다음 커맨드를 입력합니다.

```
	<path to UnityYAMLMerge> merge -p "@basefile" "@sourcefile"  "@destinationfile" "@output"
```

이후 동일한 절차를 따라 `.prefab` 확장자를 추가합니다.

### SourceTree

1. Tools > Options > Diff로 이동합니다.
2. Merge Tool 드롭다운에서 **Custom**을 선택합니다.
3. **Merge Command** 필드에 UnityYAMLMerge의 경로를 입력합니다.
4. **Arguments** 필드에 `merge -p $BASE $REMOTE $LOCAL $MERGED`를 입력합니다.

## mergerules.txt 설정

UnityYAMLMerge의 파일 병합 방식을 커스터마이즈하려면 mergerules.txt 파일을 설정합니다. 이 파일은 Unity 설치 경로의 `Editor/Data/Tools` 폴더에서 사용할 수 있습니다. 각종 설정 옵션은 다음과 같습니다.

### 배열

배열 설정 섹션은 지정된 경로를 배열(키 값이 있는 "set" 배열 또는 키 값이 없는 "plain" 배열)로 처리하도록 UnityYAMLMerge에 지시합니다. 모든 배열의 기본값은 하이브리드 모드를 수행하고 일부 알려진 휴리스틱스에 맞추는 것입니다.

* \<mode>는 "set" 또는 "plain" 중 하나입니다.

#### 예제(기본 mergerules 파일을 따름)

```
[arrays]
set *.GameObject.m_Component *.fileID
set *.Prefab.m_Modification.m_Modifications target.fileID target.guid propertyPath
plain *.MeshRenderer.m_Materials
plain *.Renderer.m_Materials
```

### 제외

제외 설정 섹션에는 병합에서 제외할 경로가 나와 있습니다. 양쪽을 모두 수정한 경우에는 충돌로 간주되고 사용자가 입력할 수 있도록 표시됩니다.

* \<mode>는 "include", "exclude", "includeIfContains", "excludeIfContains" 중 하나입니다.

#### 예제(기본 mergerules 파일을 따름)

```
[exclusions]
exclude *.MeshRenderer.m_Materials.*
exclude *.SpriteRenderer.m_Materials
exclude *.SpriteRenderer.m_Color
include *.ParticleSystem.InitialModule
exclude *.ParticleSystem.*
exclude *.ParticleSystem.InitialModule.*
#excludeDepend *.MonoBehaviour m_Script ^m_
excludeIfContains *.MonoBehaviour.* x y z
excludeIfContains *.MonoBehaviour.* r g b
```

### 비교

비교 섹션에서는 사용자 설정에 따라 무시할 수 있는 플로트 값들 간의 미미한 차이를 고려합니다. 이를 활성화하면 상대적인 부동 소수점 비교를 통해 상대 오차가 처리됩니다. 비교는 다음과 같은 방법으로 설정할 수 있습니다.

* "float" \<비교할 플로트 값> (엡실론을 머신 엡실론과 가까운 기본값으로 설정함)
* "float" \<비교할 플로트 값> \<상대 비교값과 절대 컷오프>
* "float" \<비교할 플로트 값> \<상대 비교값> \<절대 비교 컷오프>

상대 비교값은 엡실론, 그리고 플로트의 상대 오차 크기에 따라 비교가 스케일되는 방식을 결정합니다. 절대 비교 컷오프는 플로트 비교가 그래프의 0에서 절대에서 상대로 전환되는 지점을 결정합니다.

**참고**: 비교값은 플로트 엡실론(대략 0.00000011921)과 1.0 사이여야 합니다.

#### 예제

```
[comparisons]
float *.Transform.m_LocalPosition.x 0.0000005
float *.Transform.m_LocalPosition.y 0.0000005
float *.Transform.m_LocalPosition.z 0.0000005
float *.Transform.m_LocalRotation.x 0.00005 0.001
float *.Transform.m_LocalRotation.y
float *.Transform.m_LocalRotation.z 0.00005 0.001
float *.Transform.m_LocalRotation.w
```
