내부 데이터 모델은 근본적으로 다릅니다.
기본적으로 SVN에서는 지점의 내역을 볼 때 해당 지점에서 발생한 일만 볼 수 있습니다. 따라서 브랜치에서 브랜치 B
로 병합 할 때 브랜치 A
히스토리에는 브랜치 이후 A
명시 적으로 작성된 모든 변경 사항이 포함 된 하나의 큰 커밋이 포함됩니다 B
.
SVN의 첫 번째 버전에서 분기 B
를 분기로 A
다시 B
병합해야하는 경우 동일한 개정을 두 번 병합하지 않도록 병합하려는 분기의 개정 범위를 수동으로 지정해야 했습니다. 영리한 개발자는 물론 'Merged in B : 1234'와 같은 커밋 메시지를 사용합니다.
SVN 1.5는 "고정"되었습니다. 그러나 병합이 기본적으로 적용되는 방식은 변경되지 않았습니다. A
SVN에 1234 개정판이 병합되었음을 알리고 SVN이 올바른 개정판 범위를 자동으로 선택할 수 있도록 일부 메타 데이터를 추가했습니다 .
그러나이 솔루션은 기본적으로 병합 된 내용 추적을 기본적으로 지원하지 않는 데이터 모델에 대한 해결 방법입니다.
두 가지를 병합하는 것은 비교적 간단한 예입니다. 그러나 이보다 복잡한 시나리오를 이미징
A
에서 분기 를 trunk
만들고 여기에 몇 가지 커밋을 만듭니다.
- 여기
B
에서 브랜치 를 A
만들고 커밋을 몇 개 만듭니다.
- 몇 가지 커밋을
trunk
만들고A
- 병합
B
에trunk
- 병합
A
에B
- 병합
A
에trunk
- 병합
B
에 trunk
(이 실제로 아무것도 안)
메타 데이터 모델을 사용하여 올바르게 처리하는 것은 매우 복잡합니다 (SVN이 실제로이 시나리오를 올바르게 처리하는지 여부를 알지 못하므로 테스트하려는 경향이 없습니다).
자식 에서이 시나리오를 처리하는 것은 매우 간단합니다.
git에서는 커밋 할 때마다 해당 커밋을 나타내는 내부 객체에 이전 헤드에 대한 참조가 포함됩니다. 브랜치를 병합하면 커밋에 병합되는 모든 브랜치의 이전 헤드에 대한 참조가 포함됩니다 (git에서 한 번에 여러 브랜치를 병합 할 수 있습니다)
따라서 git에서 단일 커밋의 히스토리를 검사하면 모든 히스토리를 볼 수 있고 분기 된 시점, 병합 된 시점 및 분기와 병합 사이의 분기 히스토리를 볼 수 있습니다.
따라서 부분적으로 병합 된 지점에서 병합 할 때 이미 병합 된 항목과 그렇지 않은 항목을 결정하는 것은 매우 간단합니다.
Mercurial에 대한 경험이 없지만 내부 작업이 git과 유사하다고 생각합니다.
기본적으로 SVN의 경우 분기를 저렴하게 만드는 것이 디자인 목표였습니다. 그러나 git에서는 병합을 저렴하게 만드는 것이 디자인 목표였습니다.
마지막으로 SVN을 마지막으로 사용했을 때 병합을 처리 할 수 없었습니다. 병합은 한 지점에서 파일 이름이 바뀌고 다른 지점에서 수정되었습니다.