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