Subversion보다 Mercurial에서 분기 및 병합이 더 쉬운 이유는 무엇입니까?


92

Subversion 또는 CVS에서 여러 가지 병합을 분기로 처리하는 것은 경험해야 할 일 중 하나 일뿐입니다. Mercurial (그리고 아마도 다른 분산 시스템)에서 브랜치와 병합을 추적하는 것이 지나치게 쉬웠지만 그 이유는 모르겠습니다. 다른 사람이 알고 있습니까?

내 질문은 Mercurial을 사용하면 Subversions / CVS의 중앙 저장소와 유사한 작업 방식을 채택 할 수 있으며 모든 것이 잘 작동한다는 사실에서 비롯됩니다. 동일한 브랜치에서 여러 병합을 수행 할 수 있으며 커밋 번호와 태그 이름이있는 종이 조각이 끝없이 필요하지 않습니다.

최신 버전의 Subversion에는 브랜치에 대한 병합을 추적 할 수있는 기능이 있으므로 동일한 정도의 번거 로움을 느끼지 않지만 그 쪽에서 거대하고 중요한 개발이었으며 여전히 개발 팀이 수행하는 모든 작업을 수행하지는 않습니다. 하는 것을 좋아합니다.

모든 작동 방식에 근본적인 차이가 있어야합니다.

답변:


115

Subversion (및 CVS)에서는 저장소가 가장 중요합니다. git과 mercurial에는 실제로 같은 방식으로 저장소의 개념이 없습니다. 여기서 변화는 중심 주제입니다.

+1

CVS / SVN의 번거 로움은 이러한 시스템이 변경의 부모 역할을 기억 하지 못한다 는 사실에서 비롯 됩니다. Git과 Mercurial에서는 커밋에 여러 자식이있을 수있을뿐만 아니라 여러 부모도있을 수 있습니다!

즉, 쉽게 그래픽 도구 중 하나를 사용하여 관찰 할 수 있습니다 gitk또는 hg view. 다음 예제에서 브랜치 # 2는 커밋 A의 # 1에서 분기되었으며 이후 한 번 병합되었습니다 (M에서 커밋 B와 병합 됨).

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

A와 B에는 두 명의 자녀가있는 반면 M에는 두 명의 부모가 있습니다. 이러한 관계는 저장소에 기록 됩니다. 이제 분기 # 2의 관리자가 분기 # 1의 최신 변경 사항을 병합하려고한다고 가정 해 보겠습니다. 다음과 같은 명령을 실행할 수 있습니다.

$ git merge branch-1

도구는 기본 이 B 라는 것을 자동으로 인식합니다. 왜냐하면 # 2 팁의 조상 인 커밋 M에 기록되었고 B와 C 사이에 발생한 모든 것을 병합해야하기 때문입니다. CVS는이 정보를 기록하지 않습니다. , 버전 1.5 이전의 SVN도 마찬가지입니다. 이러한 시스템에서 그래프는 다음과 같습니다.

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

여기서 M은 A와 B 사이에 일어난 모든 일에 대한 거대한 "분쇄 된"커밋이며 M 위에 적용됩니다. 증서가 완료된 후에는 M 위치에 대한 흔적이 남지 않습니다 (잠재적으로 사람이 읽을 수있는 주석 제외). 에서도의 유래 않았다 얼마나 많은 역사를 훨씬 더 꿰 뚫을 만들기 - 함께 붕괴되었다 커밋.

하나는 병합 기지 (첫 번째 병합시 무엇인지 파악하는 하나는 : 설상가상으로, 두 번째 병합을 수행하는 것은 악몽이되고 있다알고 처음부터 병합이되었다는!), 그 후 현재 M 위에 A..B를 재생하지 않도록 도구에 정보를 제공합니다.이 모든 것은 긴밀한 협업으로 작업 할 때 충분히 어렵지만 분산 환경에서는 불가능합니다.

(관련된) 문제는 "X에 B가 포함되어 있습니까?"라는 질문에 답할 방법이 없다는 것입니다. 여기서 B는 잠재적으로 중요한 버그 수정입니다. 따라서 해당 정보 는 병합 시간에 알려 지므로 커밋에 해당 정보를 기록하면 안됩니다 !

추신. -SVN 1.5+ 병합 녹음 기능에 대한 경험이 없지만 워크 플로는 분산 시스템보다 훨씬 더 인위적인 것 같습니다. 이것이 사실이라면 아마도 위의 의견에서 언급했듯이 변경 사항 자체가 아닌 저장소 구성에 중점을 두었 기 때문일 것입니다.


6
SVN 1.5+는 실제로 포함 된 병합 된 커밋, 즉 AB를 나열하는 병합 커밋 M에 SVN 속성을 넣습니다. 그래서 당신은 같은 정보를 가지고 있습니다.
Simon D

거의. 기술적으로 SVN의 병합 추적은 Git이 "체리 피킹 (cherry-picking)"이라고 부르는 것과 유사하며 사용자가 더 쉽게 사용할 수 있도록 추가 마법을 제공합니다. 병합 할 때 Git, Hg 및 Bzr이 수행하는 것과 의미 상 다릅니다. DAG ( eagain.net/articles/git-for-computer-scientists )에 대해 신경 쓰지 않는 한 실제로는 큰 차이가 없다고 생각합니다 .
데미안 디데 렌

2
+100 버튼이 없습니다. 감사.
Charlie Flowers

나는 당신이 말하는 SVN 1.5 기능이 svn:mergeinfo속성 의 사용이라고 가정 합니까?
MatrixFrog 2011 년

@MatrixFrog : 예, 이것이 바로 그 일 svn:mergeinfo입니다.
sleske

12

Subversion (최소 버전 1.4 이하)은 병합 된 항목을 추적하지 않기 때문입니다. Subversion의 경우 병합은 기본적으로 모든 커밋과 동일하지만 Git과 같은 다른 버전 제어에서는 병합 된 내용이 기억됩니다.


7

이미 제공된 답변에 영향을받지 않고 Hg는 변경 사항을 병합 할 때 더 많은 정보를 사용하기 때문에 우수한 병합 기능을 제공했습니다 ( hginit.com ).

예를 들어 함수를 약간 변경 한 다음 다른 곳으로 이동하면 Subversion은 해당 단계를 실제로 기억하지 못하므로 병합 할 때 새 함수가 갑자기 갑자기 나타났다고 생각할 수 있습니다. . Mercurial은 기능 변경, 기능 이동 등을 별도로 기억하는 반면, 해당 기능도 약간 변경하면 Mercurial이 변경 사항을 성공적으로 병합 할 가능성이 훨씬 더 높습니다.

물론 마지막으로 병합 된 내용 (여기에 제공된 대부분의 답변에서 다룬 요점)을 기억하는 것도 큰 승리입니다.

그러나 Subversion 1.5+는 Subversion 속성의 형태로 추가 병합 정보를 저장하기 때문에 두 가지 개선 사항 모두 의문의 여지가 있습니다. 해당 정보를 사용할 수 있으므로 Subversion 병합이 Hg 또는 Git만큼 성공적으로 병합을 구현할 수없는 분명한 이유가 없습니다. 그래도 그럴지는 모르겠지만 Subversion 개발자가이 문제를 해결하기 위해가는 길에있는 것 같습니다.


4

부분적으로는 Subversion이 수정의 절대 타임 라인과 함께 중앙 서버에 대한 아이디어를 가지고 있기 때문이라고 생각합니다. Mercurial은 진정으로 배포되며 절대 타임 라인에 대한 언급이 없습니다. 이를 통해 Mercurial 프로젝트는 하위 프로젝트별로 기능 및 테스트주기를 추가하기 위해 더 복잡한 분기 계층 구조를 형성 할 수 있지만, 이제 팀은 업데이트를 누르고 완료 할 수 없기 때문에 병합을 훨씬 더 적극적으로 유지해야합니다. .


3

Subversion (및 CVS)에서는 저장소가 가장 중요합니다. git과 mercurial에는 실제로 같은 방식으로 저장소의 개념이 없습니다. 여기서 변화 는 중심 주제입니다.

나는 당신이 어떻게 구현할 것인지에 대해 많이 생각하지 않았지만 (쓴 경험과 많은 독서를 기반으로) 내 인상은이 차이가 비 저장소 기반 시스템에서 병합 및 분기를 훨씬 쉽게 만드는 것입니다.


1

Subversion에 대한 경험이 있지만 TortoiseSVN의 병합 화면이 끔찍하게 복잡하다는 것을 말할 수 있습니다. 다행히도 그들은 당신이 제대로하고 있는지 볼 수 있도록 드라이 런 버튼을 포함합니다. 합병증은 병합하려는 항목의 구성에 있습니다. 일단 병합을 설정하면 병합은 일반적으로 잘 진행됩니다. 그런 다음 모든 충돌을 해결 한 다음 병합 된 작업 복사본을 저장소에 커밋해야합니다.

Mercurial이 병합 구성을 더 쉽게 만들 수 있다면 Subversion보다 병합이 100 % 더 쉬워 질 것이라고 말할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.