병합 : Hg / Git vs. SVN


144

나는 종종 Hg (및 Git 및 ...)가 SVN보다 병합하는 것이 더 낫다는 것을 읽었지만 SVN이 실패한 곳 (또는 SVN이 수동 개입이 필요한 곳)을 Hg / Git이 병합 할 수있는 실제적인 예를 본 적이 없습니다. Hg / Git이 행복하게 진행되는 동안 SVN이 실패하는 위치를 나타내는 분기 / 수정 / 커밋 / ... 작업의 몇 가지 단계별 목록을 게시 할 수 있습니까? 실용적이고 예외적 인 사례는 아닙니다.

일부 배경 : SVN을 사용하여 프로젝트를 수행하는 수십 명의 개발자가 있으며, 각 프로젝트 (또는 유사한 프로젝트 그룹)는 자체 저장소에 있습니다. 릴리스 및 기능 분기를 적용하는 방법을 알고 있으므로 문제가 자주 발생하지 않습니다 (예 : 우리는 그곳에 있었지만 "한 명의 프로그래머가 팀 전체에 외상을 일으킴") 의 Joel의 문제 를 극복하는 방법을 배웠습니다. 또는 "지사를 재 통합하기 위해 2 주 동안 6 명의 개발자가 필요"). 릴리스 브랜치는 매우 안정적이며 버그 수정을 적용하는 데만 사용됩니다. 일주일 이내에 릴리스를 만들 수있을만큼 안정적인 트렁크가 있습니다. 또한 단일 개발자 또는 개발자 그룹이 작업 할 수있는 기능 분기가 있습니다. 예, 재 통합 후 삭제되므로 리포지토리가 복잡해지지 않습니다. ;)

그래서 나는 여전히 SVN에 비해 Hg / Git의 장점을 찾으려고 노력하고 있습니다. 실습 경험을 갖고 싶지만 아직 Hg / Git으로 옮길 수있는 더 큰 프로젝트가 없기 때문에 몇 개의 구성 파일 만 포함 된 작은 인공 프로젝트를 계속 사용하고 있습니다. 그리고 나는 Hg / Git의 인상적인 힘을 느낄 수있는 몇 가지 사례를 찾고 있습니다. 지금까지 나는 그것에 대해 자주 읽었지만 스스로 찾지 못했습니다.


2
정확한 중복에주의를 기울여야한다고 생각합니다 : stackoverflow.com/questions/43995/… stackoverflow.com/questions/459891/…
P Shved

11
나는 이미 첫 번째를 읽었고 다른 하나는 새 것이 었습니다. 그러나 그것들은 이미 1-2 살이었고 대부분 svn-1.5 이전 이슈 (svn은 아직 머지 트래킹이 없었습니다)에 관한 것 같습니다.
stmax

2
아래 문제를 올바르게 처리하는 다른 DVCS로 git / hg를 사용하여 Bazaar를 일괄 처리 할 수 ​​있다는 의견. 그리고 장점을 찾으려고 언급 했으므로 git / hg / bzr의 간단한 물류 이점 중 하나는 가지가 svn과 같이 전역 적이 지 않다는 것입니다. 부부 만 신청하면 67 개의 지점을 볼 필요가 없습니다. 모두 "개인"브랜치에서 작업을 수행 한 다음 뛰어난 병합 기능을 사용하여 병합이 99 %의 사례에서 작동하는지 땀없이 다시 병합합니다.
wadesworld

5
@wade : 회사 환경에서 "개인"브랜치가 유리하다고 생각하십니까? 백업이 걱정됩니다. 나는 종종 재 통합 전에 1-2 개월 동안 기능 지점을 가지고 있습니다 ..
stmax

9
@stmax : 유효한 관심사. 그러나 Subversion이있는 많은 회사 환경에서 사람들은 코드가 완벽해질 때까지 사람들이 체크인을 보류하고 동일한 노출을 갖습니다.
wadesworld

답변:


91

Subversion을 직접 사용하지는 않지만 Subversion 1.5에 대한 릴리스 정보 : 병합 추적 (기초) 에서는 Git 또는 Mercurial과 같은 전체 DAG 버전 제어 시스템 에서 병합 추적이 작동하는 방식과 다음과 같은 차이점이 있습니다 .

  • 트렁크 간 병합은 분기 간 병합과 다릅니다. 어떤 이유로 트렁크 간 병합에는 --reintegrate옵션이 필요 합니다 svn merge.

    힘내이나 의욕과 같은 분산 버전 관리 시스템에서 더이없는 기술 모든 지점이 (가있을 수 있습니다 평등하게 창조 : 트렁크 및 지점의 차이 , 사회적 차이, 비록). 어느 방향 으로든 병합하는 방법도 동일합니다.

  • 당신은 새로운 제공해야합니다 -g( --use-merge-history에) 옵션 svn logsvn blame계정으로 병합 추적을 할 수 있습니다.

    Git 및 Mercurial 병합 추적은 기록 (로그) 및 책임을 표시 할 때 자동으로 고려됩니다. Git에서는에 --first-parent머지 트래킹 정보를 "파기"하기 위해 첫 번째 부모 만 따르도록 요청할 수 있습니다 (머큐리얼에도 비슷한 옵션이 있다고 생각합니다) git log.

  • 내가 이해 한 것에서 svn:mergeinfo속성은 충돌에 대한 경로 당 정보를 저장합니다 (Subversion은 변경 세트 기반) .Git 및 Mercurial에서는 단순히 둘 이상의 부모를 가질 수있는 객체를 커밋합니다.

  • Subversion의 병합 추적에 대한 "알려진 문제" 하위 섹션에서는 반복 / 순환 / 반사 병합이 제대로 작동하지 않을 수 있음을 제안합니다. 이는 다음과 같은 이력으로 두 번째 병합이 올바른 작업을 수행하지 않을 수 있음을 의미합니다 ( 'A'는 트렁크 또는 분기 일 수 있고 'B'는 각각 분기 또는 트렁크 일 수 있음).

    * --- * --- x --- * --- y --- * --- * --- * --- M2 <-A
             \ \ /
              -* ---- M1 --- * --- * --- / <-B
    

    위의 ASCII 아트가 깨지는 경우 : 개정판 'x'에서 분기 'A'에서 분기 'B'가 생성 (포크) 된 후 나중에 분기 'A'가 개정 'y'에서 분기 'B'로 병합됩니다. 'M1'을 병합하고 마지막으로 'B'분기를 'M2'병합으로 'A'분기에 병합합니다.

    * --- * --- x --- * ----- M1-* --- * --- M2 <-A
             \ / / 
              \-* --- y --- * --- * --- / <-B
    

    위의 ASCII 아트가 깨지는 경우 : 개정판 'x'에서 분기 'A'에서 분기 'B'가 작성 (포크)되고 'y'에서 분기 'A'에 'M1'으로 병합됩니다. 'A2'지점에 'M2'로 다시 병합되었습니다.

  • Subversion은 십자 병합 의 고급 사례를 지원하지 않을 수 있습니다 .

    * --- b ----- B1--M1-* --- M3
         \ \ / /
          \ X /
           \ / \ /
            \-B2--M2-*
    

    Git은 실제로 "재귀"병합 전략을 사용하여이 상황을 잘 처리합니다. 나는 Mercurial에 대해 확신하지 못한다.

  • 에서 "알려진 문제" 한쪽 (옛 이름)의 이름을 변경하지 않고 파일 (아마도 수정 IT), 및 제 2 측면 수정 파일의 이름을 변경하는 경우 파일 이름 변경, 예와 migh하지 작업을 추적하는 병합이 경고한다.

    Git과 Mercurial은 실제로 이러한 경우를 잘 처리합니다. 이름 바꾸기 감지를 사용하는 Git , 이름 바꾸기 추적을 사용하는 Mercurial .

HTH


어떻게 든 (Markdown 파서에 오류가 있습니까?) <pre>...</pre>블록 이후 부분 은 들여 쓰기되지 않습니다 ...
Jakub Narębski

1
많은 자세한 예는 +1입니다. 나는 첫 번째 아트 아트의 예가 왜 문제를 일으킬 수 있는지 아직 이해하지 못합니다. 기능 분기를 처리하는 표준 방법처럼 보입니다. A는 트렁크이고 B는 기능 분기입니다. 매주 A에서 B로 병합 하고이 기능을 완료하면 B에서 A로 모든 것을 병합 한 다음 항상 나를 위해 일한 B를 삭제합니다. 다이어그램을 잘못 이해 했습니까?
stmax

1
위에서 주어진 예제가 실제로 Subversion에 문제가 있음을 알지 못합니다 (확인하지 않았습니다) . 이름 바꾸기와 십자 병합은 SVN에서 실제 문제입니다.
Jakub Narębski

2
재 통합 병합은 병합 할 때 가장 일반적인 경우에 도움이되는 특별한 옵션입니다. svn에서도 브랜치와 트렁크간에 기술적 인 차이가 없습니다. 나는 그것을 사용하지 않는 경향이 있으며 표준 병합 옵션을 고수합니다. 여전히 svn merge의 유일한 문제는 이동 / 이름 바꾸기를 삭제 + 추가로 처리한다는 것입니다.
gbjbaanb

--reintegrate더 이상 사용되지 않습니다.
naught101

120

나도 Subversion이 브랜치를 병합하지 못하고 Mercurial (및 Git, Bazaar 등)이 옳은 일을하는 경우를 찾고 있습니다.

SVN Book 이름이 바뀐 파일이 어떻게 잘못 병합 되는지 설명합니다 . 이것은 Subversion 1.5 , 1.6 , 1.71.8에 적용됩니다 ! 아래 상황을 재현하려고했습니다.

CD / tmp
RM - RF SVN - REPO SVN - 체크 아웃
svnadmin svn 만들기 - 저장소
svn 체크 아웃 파일 : /// tmp / svn - repo svn - checkout
CD SVN - 체크 아웃
mkdir 트렁크 브랜치
에코 '안녕, 세상!' > 트렁크 / 안녕하세요 . txt 
svn 트렁크 분기 추가
svn commit - m '초기 가져 오기.' 
svn copy '^ / trunk' '^ / branches / rename' - m '분기 생성' 
svn 스위치 '^ / trunk' . 
에코 '안녕하세요, 세계!' > 안녕하세요 . txt    
svn commit - m '트렁크에서 업데이트.' 
svn 스위치 '^ / branches / rename' . 
svn 이름을 hello로 바꿉니다 . txt hello . ko . txt 
svn commit - m '브랜치 이름 바꾸기' 
svn 스위치 '^ / trunk' . 
SVN 병합 - 재 통합 '^ / 가지 / 이름 바꾸기' 

이 책에 따르면, 병합은 깨끗하게 완료되지만 업데이트 trunk가 잊혀진 이후 이름이 바뀐 파일에 잘못된 데이터가 있어야합니다 . 대신 트리 충돌이 발생합니다 (작성 당시 데비안의 최신 버전 인 Subversion 1.6.17과 관련이 있습니다).

--- 리포지토리 URL의 차이점을 '.'으로 병합 :
hello.en.txt
   C hello.txt
충돌 요약 :
  나무 갈등 : 1

전혀 충돌이 없어야합니다. 업데이트는 파일의 새 이름으로 병합되어야합니다. Subversion은 실패하지만 Mercurial은이를 올바르게 처리합니다.

rm -rf /tmp/hg-repo
hg init /tmp/hg-repo
cd /tmp/hg-repo
echo 'Goodbye, World!' > hello.txt
hg add hello.txt
hg commit -m 'Initial import.'
echo 'Hello, World!' > hello.txt
hg commit -m 'Update.'
hg update 0
hg rename hello.txt hello.en.txt
hg commit -m 'Rename.'
hg merge

병합하기 전에 저장소는 다음과 같습니다 (from hg glog).

@ changeset : 2 : 6502899164cc
| 태그 : 팁
| 부모 : 0 : d08bcebadd9e
| 사용자 : Martin Geisler
| 날짜 : Thu Apr 01 12:29:19 2010 +0200
| 요약 : 이름을 바꿉니다.
|
| o 변경 세트 : 1 : 9d06fa155634
| / 사용자 : Martin Geisler 
| 날짜 : Thu Apr 01 12:29:18 2010 +0200
| 요약 : 업데이트.
|
변경 세트 : 0 : d08bcebadd9e
   사용자 : Martin Geisler 
   날짜 : Thu Apr 01 12:29:18 2010 +0200
   요약 : 최초 수입.

병합 결과는 다음과 같습니다.

hello.en.txt와 hello.txt를 hello.en.txt에 병합
0 개 파일 업데이트, 1 개 파일 병합, 0 개 파일 제거, 0 개 파일 미해결
(분기 병합, 커밋하는 것을 잊지 마십시오)

즉, Mercurial은 개정 1에서 변경된 사항을 개정 2 ( hello.en.txt) 의 새 파일 이름으로 병합했습니다 . 이 사건을 처리하는 것은 지원 리팩토링하기 위해 코스 필수적이며 리팩토링은 정확하게 당신이 지점에하고 싶은 것입니다 물건의 종류.


자세한 예를 보려면 +1을 누르면 키보드를 탭하여 어떤 일이 발생했는지 직접 확인할 수 있습니다. Mercurial 멍청한 놈으로서,이 예제의 hg 버전이 한 줄씩 명확한 방식으로 따르는 지 궁금합니다.
DarenW

4
@DarenW : 해당 Mercurial 명령을 추가했습니다. 더 명확 해지기를 바랍니다!
Martin Geisler

17

일반적인 이점 (오프라인 커밋, 게시 프로세스 등) 에 대해 말하지 않고 여기에 내가 좋아하는 "병합"예가 있습니다.

내가 계속 본 주요 시나리오는 두 가지 관련없는 작업이 실제로 개발 된 지점 입니다
(하나의 기능에서 시작되었지만이 다른 기능의 개발로
이어 지거나 패치에서 시작되었지만 다른 기능 개발).

기본 지점에서 두 기능 중 하나만 병합하는 방법은 무엇입니까?
또는 두 가지 기능을 자체 분기에서 어떻게 분리합니까?

어떤 종류의 패치를 생성하려고 시도 할 수 있습니다. 그 문제는 다음 사이에 존재할 수있는 기능적 종속성 이 더 이상 확실하지 않다는 것입니다 .

  • 패치에 사용 된 커밋 (또는 SVN 개정)
  • 다른 하나는 패치의 일부가 아닌 커밋

힘내 (그리고 Mercurial도 생각합니다) rebase --onto 옵션을 제안하여 브랜치의 일부를 rebase (지점의 루트를 재설정)하십시오.

에서 Jefromi의 게시물

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

v2 용 패치와 새로운 wss 기능이있는 상황을 풀 수 있습니다.

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

을 통해 다음을 수행 할 수 있습니다.

  • 모든 분기가 독립적으로 테스트되어 모든 것이 의도대로 컴파일 / 작동하는지 확인하십시오.
  • 원하는 메인 만 병합하십시오.

내가 좋아하는 다른 기능 (병합에 영향을 미침)은 커밋스쿼시 하여 (아직 다른 리포지토리로 푸시하지 않은 지점에서) 제시하는 기능입니다.

  • 더 깨끗한 역사
  • 더 일관된 커밋

이렇게하면 충돌이 줄고 병합이 훨씬 쉬워집니다.


svn에 오프라인 커밋이 없습니까? 로플? 그렇다면 어떻게 원격으로 사용을 고려할 수 있습니까?
o0 '.

@Lohoris SVN이 나왔을 때 널리 사용되는 오픈 소스 DVCS는 없었습니다. 이 시점에서 사람들이 여전히 그것을 사용하는 것이 관성이라고 생각합니다.
Max Nanasy 2013

관성 아주 나쁜 종류의 @MaxNanasy ... 여전히 그것을 선택하는 지금은 단순히 어리석은 것입니다.
o0 '.

@Lohoris Online (보다 정확하게는 중앙 집중식) 커밋은 리포지토리가 공유 로컬 서버에있을 수있는 소규모 팀에서는 그리 중요하지 않습니다. DVCS는 대부분 지리적으로 분산 된 대규모 팀 (git과 mercurial 모두 Linux 커널 코드를 관리하기위한 것)과 오픈 소스 프로젝트 (따라서 GitHub의 인기)를 위해 개발되었습니다. 관성은 팀 워크 플로의 중심에 도구를 변경하는 것의 위험과 이점을 평가하는 것으로 볼 수도 있습니다.
IMSoP

1
@Lohoris DB, 방화벽 등에 대한 나의 요점을 잘못 이해했다고 생각합니다 . 실제로 해당 코드를 먼저 실행할 수 없다면 내 홈 컴퓨터에서 커밋 할 수있는 점이 거의 없습니다. 나는 맹인으로 일할 있었지만 어딘가에서 일을 저지를 수 없다는 사실이 나를 떠나게하는 주요한 것은 아닙니다.
IMSoP

8

우리는 최근 SVN에서 GIT로 마이그레이션했으며이 같은 불확실성에 직면했습니다. GIT가 더 낫다는 일화적인 증거가 많이 있었지만 어떤 사례도 다루기가 어려웠습니다.

그래도 GIT는 SVN보다 합병이 훨씬 낫습니다. 이것은 분명히 일화 적이지만 따라야 할 표가 있습니다.

우리가 찾은 것들 중 일부는 다음과 같습니다.

  • SVN은 그렇지 않은 것처럼 보이는 상황에서 많은 트리 충돌을 일으켰습니다. 우리는 이것의 바닥에 결코 도달하지 못했지만 GIT에서는 발생하지 않습니다.
  • 더 나은 반면, GIT는 훨씬 더 복잡합니다. 훈련에 시간을 보내십시오.
  • 우리는 SVN을 Tortoise하는 데 익숙했습니다. 거북이 GIT가 좋지 않아 이로 인해 벗어날 수 있습니다. 그러나 이제는 Tortoise SVN 또는 GIT GUI를 선호하는 GIT 명령 줄을 사용합니다.

GIT를 평가할 때 다음 테스트를 수행했습니다. 이것들은 합병에있어서 GIT를 승자로 표시하지만 그렇게 많이는 아닙니다. 실제로 그 차이는 훨씬 크지 만 SVN이 잘못 처리하는 상황을 재현하지 못했습니다.

GIT vs SVN 병합 평가


5

다른 사람들은 이것의 더 이론적 인 측면을 다루었습니다. 좀 더 실용적인 관점을 빌려줄 수있을 것입니다.

저는 현재 "피처 지점"개발 모델에서 SVN을 사용하는 회사에서 일하고 있습니다. 그건:

  • 트렁크에서 작업을 수행 할 수 없습니다
  • 각 개발자는 자신의 지점을 만들 수 있습니다
  • 지점은 수행 한 작업 기간 동안 지속되어야합니다.
  • 각 작업에는 자체 지점이 있어야합니다
  • 트렁크로 병합을 승인해야합니다 (일반적으로 bugzilla를 통해).
  • 높은 수준의 제어가 필요한 경우 게이트 키퍼가 병합을 수행 할 수 있습니다.

일반적으로 작동합니다. SVN은 이와 같은 흐름에 사용될 수 있지만 완벽하지는 않습니다. 인간 행동을 방해하고 형성하는 SVN의 몇 가지 측면이 있습니다. 그것은 몇 가지 부정적인 측면을 제공합니다.

  • 보다 낮은 지점에서 분기하는 사람들에게는 꽤 많은 문제가있었습니다 ^/trunk. 이 쓰레기는 트리 전체에 정보 레코드를 병합하고 결국 병합 추적을 중단합니다. 거짓 갈등이 나타나고 혼란이 다스립니다.
  • 트렁크에서 지점으로 변경 사항을 가져 오는 것은 비교적 간단합니다. svn merge당신이 원하는 것을합니다. 변경 사항을 다시 --reintegrate병합하려면 merge 명령 이 필요합니다 . 나는이 스위치를 정말로 이해하지 못했지만 지점을 다시 트렁크에 병합 할 수 없음을 의미합니다. 이것은 죽은 지점이므로 작업을 계속하려면 새 지점을 만들어야한다는 것을 의미합니다. (참고 참조)
  • 브랜치를 생성하고 삭제할 때 URL을 통해 서버에서 작업을 수행하는 전체 업무는 사람들을 혼란스럽게하고 두려워합니다. 그래서 그들은 피합니다.
  • 분기 사이를 전환하는 것은 잘못되기 쉬우므로 분기 A를 보는 나무의 일부는 남기고 분기 B를 보는 다른 부분은 남겨 두어야합니다. 따라서 사람들은 한 분기에서 모든 작업을 수행하는 것을 선호합니다.

발생하는 경향은 엔지니어가 1 일에 지점을 만드는 것입니다. 그는 자신의 작업을 시작하고 잊어 버렸습니다. 얼마 후 상사가 와서 자신의 작품을 트렁크에 풀어줄 수 있는지 묻습니다. 재 통합은 다음을 의미하기 때문에 엔지니어는 오늘 두려워하고 있습니다.

  • 오래 살았던 지점을 트렁크로 다시 병합하고 모든 충돌을 해결하고 별도의 지점에 있었지만 관련되지 않은 관련되지 않은 코드를 공개했습니다.
  • 그의 지점을 삭제
  • 새로운 지점 만들기
  • 작업 사본을 새 지점으로 전환

... 엔지니어가 가능한 적은이 작업을 수행하기 때문에 각 단계를 수행하는 "마법의 주문"을 기억할 수 없습니다. 잘못된 스위치와 URL이 발생하면 갑자기 혼란에 빠지고 "전문가"가됩니다.

결국 모든 것이 해결되고 사람들은 단점을 해결하는 방법을 배우지 만 새로운 스타터는 모두 같은 문제를 겪습니다. 최종 현실 (내가 시작했을 때와 반대되는)은 다음과 같습니다.

  • 트렁크에 대한 작업이 없습니다
  • 각 개발자는 하나의 주요 지점을 가지고 있습니다
  • 작업을 해제해야 할 때까지 지점이 지속됩니다.
  • 티켓 버그 수정은 자체 브랜치를 얻는 경향이 있습니다.
  • 승인되면 트렁크로 다시 병합

...그러나...

  • 때로는 작업이 다른 것과 같은 지점에 있기 때문에 트렁크에 들어 가지 않아야합니다.
  • 사람들은 모든 병합 (쉽게 쉬운 것)을 피하므로 사람들은 종종 자신의 작은 거품으로 작업합니다.
  • 큰 병합은 발생하는 경향이 있으며 혼돈을 제한합니다.

고맙게도 팀은 대처하기에 충분히 작지만 확장 할 수 없습니다. 이것은 CVCS에는 아무런 문제가 없지만 DVCS만큼 병합이 중요하지 않기 때문에 매끄럽지 않다는 것입니다. "마찰 병합"은 동작을 발생 시키며 이는 "피처 브랜치"모델이 분해되기 시작 함을 의미합니다. 좋은 병합은 DVCS뿐만 아니라 모든 VCS의 기능이어야합니다.


에 따르면 거기에 지금의 --record-only문제점을 해결하는 데 사용할 수있는 스위치 --reintegrate문제를, 그리고 분명히 할 때 자동으로 재 통합을 수행하는 V1.8이 선택하는, 그리고 그것은 분기 이후 죽은 발생하지 않습니다


내가 이해하는 것처럼 --reintegrate 옵션은 기능 브랜치에 병합 할 때 충돌하는 변경 사항을 이미 해결했다고 svn에 알려줍니다. 효과적으로 패치로 취급하지 않고 모든 트렁크 개정이 분기로 병합되었음을 병합 기록에서 이미 확인한 후 전체 파일을 분기 버전으로 덮어 씁니다.
IMSoP

@IMSoP : 아마도 말이됩니다. 왜 그것이 필요한지 또는 왜 그 지점에서 추가 병합을 불가능하게했는지 설명하지 않습니다. 옵션이 문서화되지 않은 것도 도움이되지 않았습니다.
Paul S

TortoiseSVN을 통해서만 사용했으며 병합 UI에서 항상 눈에 띄게 설명되었습니다. SVN 1.8이 자동으로 올바른 전략을 선택하고 별도의 옵션이 필요하지 않다고 생각하지만 정상적인 병합 알고리즘을 수정 하여이 방법으로 재설정 된 분기를 올바르게 처리하는지 여부는 알 수 없습니다.
IMSoP

3

Subversion 1.5 이전 (실수하지 않은 경우) 전에 Subversion은 병합 기록을 기억하지 못한다는 점에서 심각한 불만을 가지고있었습니다.

VonC의 사례를 살펴 보겠습니다.

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - A - x (v2-only)
           \
             x - B - x (wss)

개정판 A와 B를 주목하십시오. 어떤 이유로 든 개정 본 B의 개정판 A에서 "wss"분기에있는 개정판 A에서 "v2 전용"분기로 변경 사항을 병합했지만 두 분기를 계속 사용했다고 가정 해보십시오. 수은을 사용하여 두 분기를 다시 병합하려고하면 개정 A 및 B 이후의 변경 사항 만 병합합니다. Subversion을 사용하면 이전에 병합하지 않은 것처럼 모든 것을 병합해야합니다.

이것은 내 경험에 의한 예입니다. 코드의 양으로 인해 B에서 A로 병합하는 데 몇 시간이 걸렸습니다. 다시 시도하는 것은 정말 어려웠을 것입니다 . 이는 1.5 이전 버전의 경우와 같습니다.

Hginit 과의 병합 동작에서 더 관련성이 높은 또 다른 차이점 : Subversion Re-education :

당신과 내가 어떤 코드를 작업하고 있다고 생각하고, 그 코드를 분기하고, 우리는 각각 별도의 작업 공간으로 가서 그 코드를 개별적으로 많이 변경하여 아주 많이 분기했다고 상상해보십시오.

우리가 합병해야 할 때 Subversion은 수정 된 코드와 수정 된 코드 인 두 가지 수정본을 모두 보려고 시도하고 하나의 거룩하지 않은 엉망으로 수정하는 방법을 추측하려고합니다. 실제로는 충돌하지 않는 "병합 충돌"페이지와 페이지를 생성하는 데 실패합니다. Subversion이 우리가 한 일을 파악하지 못한 곳입니다.

반면 Mercurial에서 별도로 작업하는 동안 Mercurial은 일련의 변경 세트를 유지하는 데 바빴습니다. 따라서 코드를 통합하려는 경우 Mercurial은 실제로 훨씬 더 많은 정보를 보유하고 있습니다. 최종 제품을보고 코드를 작성하는 방법을 추측하기보다는 우리 각자가 변경 한 사항을 알고 해당 변경 사항을 다시 적용 할 수 있습니다. 함께.

요컨대, Mercurial의 차이점 분석 방식은 서브 버전보다 우수합니다.


5
나는 hginit을 읽었습니다. 너무 나쁘다 그것은 svn.보다 hg가 더 잘하고있는 곳에 대한 더 실용적인 예를 보여주지 않습니다. 그가 보여준 간단한 예제는 아마도 svn으로도 가능할 것입니다. 실제로 이것이 제가이 질문을 연 이유입니다.
stmax

1
이것이 어떻게 말하는지에 따라, 순진한 질문이 떠 오릅니다. Mercurial의 병합 알고리즘이 Subversion에 들어가면 어떨까요? 그러면 svn이 hg만큼 좋을까요? 아니요, hg의 장점은 파일에서 행을 병합하는 낮은 수준의 텍스트가 아니라 상위 수준의 조직에 있기 때문입니다. 그것은 우리가 svn 사용자가 grok해야 할 참신한 아이디어입니다.
DarenW

@stmax : 무슨 말인지 알 수 있습니다. 그러나 Joel의 의견이나 다른 사람의 의견은 실제로 중요하지 않습니다. 한 기술이 다른 기술보다 우수하거나 (사용 사례 집합에 대해) 그렇지 않습니다. @DarenW 및 @stmax : 개인 경험에서 Hg는 분산 작업 (항상 연결되지 않음), 성능 (로컬 작업이 많음), 뛰어난 병합 알고리즘으로 강력한 직관 분기로 인해 손을,습니다. hg 롤백, 템플릿 로그 출력, hg glog, 단일 .hg 폴더 ... 계속 진행할 수 있습니다 .git 및 bazaar 이외의 것은 직선 자켓처럼 느껴집니다.
Tomislav Nakic-Alfirevic

"changesets"에 대해 인용 한 hg 의견이 다소 부정확 한 것 같습니다. SVN은 어떤 변경 사항이 병합되는지 잘 알고 있습니다 (변경 세트는 기본적으로 두 스냅 샷의 차이점이며 그 반대도 마찬가지입니다). 원하는 경우 각 변경 사항을 차례로 적용 할 수 있습니다. 확실히 "추측"할 필요는 없습니다. 그것이 "하나의 거룩하지 않은 혼란"을 초래한다면, 이는 디자인의 기본이 아닌 구현 문제입니다. 현재 아키텍처 디자인에서 해결하기 어려운 주요 문제는 파일 이동 / 복사 / 이름 바꾸기입니다.
IMSoP
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.