Skip to main content

SVN merge 기능 검토

· 6 min read

SVN에 있는 merge 기능 중에 이해가 잘 되지 않는 부분이 있어서 몇가지 간단하게 검토해 보았다.

 

환경

나의 경우엔 개발 산출물이 누적되는 trunk가 있고 release만을 위한 branch가 존재하는 상태.

Trunk에서 특정 revision을 release branch에 반영하거나 patch로 사용할 수 있어야 했다.

이런 환경에서 궁금했던 내용은 아래와 같다.

 

1. Two tree merge가 가능한가?

Windows에서 많이 사용되는 TortoiseSVN에는 two tree merge 라는 기능이 존재하는데 command 로는 어떻게 처리해야 할지 알 수가 없었다.

간단하게도 아래와 같은 형태의 command를 실행하면 가능하다.

svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]

이미 release branch에서 checkout 한 working copy가 존재하는 상태에서 trunk의 특정 revision을 branch에 반영하고자 했다.

(Working copy 없이 repository 내에서만 처리하고 싶었으나 copy, reintegrate 외에는 그런 기능이 없었기 때문에 부득이하게 working copy를 사용)

위와 같은 형태로 Source1은 branch를 Source2는 trunk를 가리키게 하고 target을 wc로 정하니 문제없이 merge가 가능.

물론 특정 revision을 명시할 수 있어야 했고 이것도 가능.

 

2. 특정 revision을 merge 한다는 것은 해당 revision에 대한 변경사항만 반영하는 것인가?

참조 문서 상으로 @REV의 형태는 1:REV를 의미한다고 한다. 그러므로 @REV 형태로 command를 사용하면 REV에 맞춰서 sync 한다는 의미와 같다.

c (cherry-picking)나 r (revision) 옵션을 사용할 경우 cherry-pick을 한다고 하는데 문서에는 지정하는 revision들의 change-set 만 merge하게 된다고 한다.

그래서 1부터 10까지 한 줄에 하나씩 기록해서 commit 한 revision 10짜리 file을 준비해서,

branch는 trunk의 revision 3을 우선 반영했다. (File은 1, 2, 3이 세 줄에 걸쳐 기록된 상태)

여기서 branch에 trunk의 revision 5를 cherry-pick 하려고 해봤다.

이 때 revision 5의 change-set은 revision 4와 5의 차이가 될 것이라 생각했고 (5가 추가된 상태), merge가 된다면 File에는 1, 2, 3, 5가 기록될거라 예상했다.

하지만 결과는 conflict.

Unified-diff 상으로는 revision 5의 change-set은 4대신 4 + 줄바꿈 + 5 였는데, branch에서 가지고 있는 File은 4가 없기 때문에 merge를 못하는 것이 아닌가 싶다.

Conflict이 발생하는 것으로 봐서는 cherry-pick은 특정 revision 까지가 아니라 (sync가 아니라) revision의 변경사항만 반영하는 것이 맞는 것으로 판단된다.

 

3. 그럼 특정 revision을 patch로 활용하는게 가능한가?

Cherry-pick을 사용하는 이유가 특정 revision에 bug-fix 등이 되어있을 때 그 부분만 가져오기 위해서라고 하는데 한 파일에 대한 revision 차이가 클 경우 conflict이 발생할 가능성이 클 것 같다.

Conflict을 제거하기 위해 --accept theirs-conflict 옵션을 사용해 봤는데 재밌는 결과를 볼 수 있었는데,

위의 과정처럼 branch와 branch의 wc에는 1, 2, 3 까지만 파일에 기록되어 있는 상태에서 trunk의 revision 9 (1부터 9까지 기록된 상태)를 merge 해봤더니

conflict은 물론 없었지만 (발생시 저장소 파일을 선택하게 했으므로) merge 된 파일에는 1부터 9까지 기록되어 있었다.

정리하면 revision 9 까지의 변경이력을 모두 merge 했다는 의미인데 만약 중간의 어떤 revision이 문제점을 갖고 있다면 그 문제까지 merge 될 것이다.

Conflict이 발생하지 않는다면 patch로 활용하는게 가능할 것으로는 생각되는데 conflict 발생시 처리에 대한 것은 여전히 의문으로 남는다.

수작업으로 resolve 한다면 어떻게든 되겠으나 자동화까지 생각했을 때 다른 대안도 마련해야 할 듯.

 

참조

1. SVN merge

2. Advanced Merging