SVN보다 Git에서 어떻게 병합하는 것이 더 좋습니까?


400

분산 버전 제어 시스템이 빛나는 주된 이유 중 하나가 SVN과 같은 기존 도구보다 훨씬 더 잘 병합된다는 소식을 몇 군데에서 들었습니다. 이것은 실제로 두 시스템의 작동 방식이 본질적으로 다르거 나 Git / Mercurial과 같은 특정 DVCS 구현이 SVN보다 똑똑한 병합 알고리즘을 가지고 있습니까?


나는 여전히 위대한 대답을 읽음으로써 완전한 대답을 얻지 못했습니다. 재 게시 - stackoverflow.com/questions/6172037/...
ripper234


모델에 따라 다릅니다. 간단한 경우 svn은 단일 개발 브랜치를 푸시 / 병합 / 풀 / 푸시하면 git처럼 2-way merge를 실수로 호출하지 않기 때문에 종종 더 좋습니다. 참조 : svnvsgit.com
Erik Aronesty

답변:


556

왜 Subversion에서보다 DVCS에서 병합이 더 좋은지에 대한 주장은 주로 Subversion에서 분기 및 병합이 어떻게 작동했는지에 근거한 것입니다. 1.5.0 이전의 Subversion 은 브랜치가 병합 된시기에 대한 정보를 저장하지 않았으므로 병합을 원할 때 병합해야하는 개정 범위를 지정해야했습니다.

그렇다면 Subversion 병합은 왜 빨랐 습니까?

이 예를 깊이 생각해보십시오.

      1   2   4     6     8
trunk o-->o-->o---->o---->o
       \
        \   3     5     7
b1       +->o---->o---->o

b1의 변경 사항을 트렁크 에 병합 하려면 트렁크가 체크 아웃 된 폴더에 서있는 동안 다음 명령을 실행합니다.

svn merge -r 2:7 {link to branch b1}

… 변경 사항을 b1로컬 작업 디렉토리 에 병합하려고 시도합니다 . 그런 다음 충돌을 해결하고 결과를 테스트 한 후 변경 사항을 커밋합니다. 수정 트리를 커밋하면 다음과 같습니다.

      1   2   4     6     8   9
trunk o-->o-->o---->o---->o-->o      "the merge commit is at r9"
       \
        \   3     5     7
b1       +->o---->o---->o

그러나 버전 트리가 커질 때 subversion에 병합 된시기와 대상에 대한 메타 데이터가 없기 때문에 버전 범위를 지정하는이 방법은 빠르게 사라집니다. 나중에 일어날 일에 대해 숙고하십시오.

           12        14
trunk  …-->o-------->o
                                     "Okay, so when did we merge last time?"
              13        15
b1     …----->o-------->o

이것은 Subversion이 가지고있는 리포지토리 디자인의 문제입니다. 브랜치를 만들려면 트렁크의 복사본을 보관할 리포지토리에 새 가상 디렉터리 를 만들어야 하지만 언제 어디서 무엇에 관한 정보도 저장하지 않습니다. 일이 다시 합쳐졌습니다. 때로는 불 합병 한 병합 충돌이 발생할 수 있습니다. 더 나쁜 것은 Subversion이 기본적으로 양방향 병합을 사용했기 때문에 두 분기 헤드가 공통 조상과 비교되지 않은 경우 자동 병합에 약간의 제한이 있습니다.

이 Subversion을 완화하기 위해 이제 분기 및 병합을위한 메타 데이터가 저장됩니다. 그것은 모든 문제를 올바르게 해결할 것입니까?

그리고, 그런데, Subversion은 여전히 ​​엉망입니다 ...

Subversion과 같은 중앙 집중식 시스템에서 가상 디렉터리는 빨라집니다. 왜? 모든 사람이 볼 수있는 액세스 권한이 있기 때문에 ... 쓰레기 실험적인 사람도 있습니다. 실험하고 싶지만 모든 사람과 이모 실험을보고 싶지 않은 경우 분기가 좋습니다 . 이것은 심각한인지 소음입니다. 더 많은 가지를 추가할수록 더 많은 쓰레기를 볼 수 있습니다.

저장소에 공용 지점이 많을수록 다른 지점을 모두 추적하기가 더 어려워집니다. 따라서 지점이 아직 개발 중이거나 실제로 죽은 경우 중앙 집중식 버전 제어 시스템에서 말하기 어려운 질문이 있습니다.

대부분 내가 본 것으로부터 조직은 기본적으로 하나의 큰 지점을 사용하도록 기본 설정합니다. 테스트 및 릴리스 버전을 추적하기가 어려우며 분기에서 오는 좋은 점이 있기 때문에 부끄러운 일입니다.

그렇다면 Git, Mercurial 및 Bazaar와 같은 DVCS가 분기 및 병합에서 Subversion보다 나은 이유는 무엇입니까?

이유는 매우 간단한 이유가 있습니다. 분기는 일류 개념 입니다. DVCS 에는 가상 디렉터리 가 의도적으로 설계 되어 있지 않으며 , 저장소는 저장소 동기화 (즉, pushpull ) 와 함께 간단하게 작동하기 위해 필요한 DVCS의 하드 개체입니다 .

DVCS로 작업 할 때 가장 먼저해야 할 일은 리포지토리 (git 's clone, hg 's clone및 bzr 's branch) 를 복제하는 것 입니다. 복제는 개념적으로 버전 관리에서 분기를 만드는 것과 같습니다. 일부는 이것을 분기 또는 분기 라고 부릅니다 (후자는 종종 같은 위치에있는 분기를 가리키는 데 사용 되기는하지만). 모든 사용자는 자체 저장소를 실행하므로 사용자 별 분기가 진행됩니다.

버전 구조는 트리 가 아니라 그래프 입니다. 보다 구체적으로, 유향 비순환 그래프 (DAG, 사이클이없는 그래프를 의미). 각 커밋에 하나 이상의 부모 참조 (커밋이 기반으로 한 것)가있는 것을 제외하고는 DAG의 세부 사항을 다루지 않아도됩니다. 따라서 다음 그래프는 이로 인해 개정판 사이의 화살표를 반대로 표시합니다.

병합의 매우 간단한 예는 다음과 같습니다. 호출 된 중앙 저장소 origin와 사용자 Alice가 저장소를 시스템에 복제 한다고 상상해보십시오 .

         a…   b…   c…
origin   o<---o<---o
                   ^master
         |
         | clone
         v

         a…   b…   c…
alice    o<---o<---o
                   ^master
                   ^origin/master

복제하는 동안 발생하는 모든 수정 사항은 고유 한 식별 가능한 해시 ID로 확인 된 그대로 수정 사항이 Alice에 복사되고 원본 분기의 위치를 ​​표시합니다.

그런 다음 Alice는 리포지토리에서 작업하면서 자체 리포지토리에 커밋하고 변경 사항을 적용하기로 결정합니다.

         a…   b…   c…
origin   o<---o<---o
                   ^ master

              "what'll happen after a push?"


         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                   ^origin/master

해결책은 다소 간단합니다. origin리포지토리에서 수행해야 할 유일한 것은 모든 새 개정을 가져 와서 분기를 최신 개정으로 이동하는 것입니다 (git은 "fast-forward"라고 부릅니다).

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                             ^origin/master

위에서 설명한 유스 케이스 는 아무것도 병합 할 필요조차 없습니다 . 따라서 3 방향 병합 알고리즘은 모든 버전 제어 시스템에서 거의 동일하므로 문제는 실제로 알고리즘 병합과 관련이 없습니다. 문제는 무엇보다 구조에 관한 것 입니다.

그렇다면 실제 병합 이있는 예를 보 시겠습니까?

위의 예는 매우 간단한 사용 사례이므로 더 일반적인 방법이지만 훨씬 더 많이 꼬아 놓을 수 있습니다. origin세 가지 개정으로 시작한 것을 기억 하십니까? 글쎄, 그들을 한 사람은 그를 Bob 이라고 부를 수 있으며, 스스로 작업하고 자신의 저장소에 커밋했습니다.

         a…   b…   c…   f…
bob      o<---o<---o<---o
                        ^ master
                   ^ origin/master

                   "can Bob push his changes?" 

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

이제 Bob은 변경 사항을 origin저장소로 직접 푸시 할 수 없습니다 . 시스템이이를 감지하는 방법은 Bob의 수정본이에서 수정 origin되지 않는지 확인하는 것입니다 (이 경우에는 그렇지 않음). 밀어 붙이려 고 시도하면 시스템은 " 어 .. 밥이 그렇게 할 수 없을 까봐 두렵습니다 ."

따라서 Bob은 변경 사항을 가져 pull와서 변경해야합니다 (git 's ; 또는 hg 's pullmerge; 또는 bzr 's merge). 이것은 2 단계 프로세스입니다. 먼저 Bob은 새 개정을 가져와야합니다. 그러면 개정판이 origin저장소 에서있는 그대로 복사됩니다 . 그래프가 갈라지는 것을 볼 수 있습니다.

                        v master
         a…   b…   c…   f…
bob      o<---o<---o<---o
                   ^
                   |    d…   e…
                   +----o<---o
                             ^ origin/master

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

풀 프로세스의 두 번째 단계는 분기 팁을 병합하고 결과를 커밋하는 것입니다.

                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+
                             ^ origin/master

희망 병합은 (당신이 그들을 예상되는 경우 수동으로 자식의 두 단계를 할 수있는 충돌로 실행되지 않습니다 fetchmerge). 나중에 수행해야 할 작업은 해당 변경 사항을 다시 (으)로 푸시 origin하는 것입니다. 병합 커밋은 origin리포지토리 에서 최신 버전의 직접적인 후손이므로 빨리 병합됩니다 .

                                 v origin/master
                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

                                 v master
         a…   b…   c…   f…       1…
origin   o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

라는 자식과 HG에 병합하는 또 다른 옵션이 있습니다 REBASE 최신 변경 후 밥의 변화를 이동 which'll는. 이 답변이 더 이상 장황하게되기를 원하지 않기 때문에 대신 git , mercurial 또는 bazaar 문서 를 읽도록하겠습니다 .

독자를위한 연습으로 관련된 다른 사용자와 어떻게 작동하는지 알아보십시오. Bob의 경우 위의 예제와 유사하게 수행됩니다. 모든 개정 / 커밋은 고유하게 식별 가능하기 때문에 리포지토리 간 병합이 생각보다 쉽습니다.

각 개발자 사이에 패치를 보내는 문제도 있습니다. Subversion의 고유 한 문제는 git, hg 및 bzr에서 고유하게 식별 가능한 수정으로 완화되었습니다. 누군가 자신의 변경 사항을 병합 (예 : 병합 커밋)하고 팀의 다른 모든 사람이 중앙 리포지토리로 푸시하거나 패치를 보내서 소비 할 수 있도록 보내면 병합에 대해 걱정할 필요가 없습니다. . Martin Fowler는 이러한 방식으로 무차별 통합을 수행 합니다.

Subversion과 구조가 다르기 때문에 대신 DAG를 사용하면 시스템뿐만 아니라 사용자도보다 쉽게 ​​분기 및 병합을 수행 할 수 있습니다.


6
나는 당신의 분기 == 소음 주장에 동의하지 않습니다. 리드 개발자가 사람들에게 큰 기능에 사용할 브랜치를 알려줘야하기 때문에 많은 브랜치가 사람들을 혼동하지 않습니다. 따라서 두 명의 개발자가 브랜치 X에서 작동하여 "비행 공룡"을 추가 할 수 있고, 3 명은 Y를 사용하여 "던질 수 있습니다" 사람들의 자동차 "
Mr. Boy

16
John : 그렇습니다. 적은 수의 가지에 대해서는 소음이 적고 다루기 쉽습니다. 그러나 50 개 이상의 브랜치 및 태그 등을 목격 한 후 다시 돌아 오거나 대부분의 경우 활성 여부를 알 수없는 명확한 경우가 있습니다. 도구를 제외하고 사용성 문제; 왜 저장소에 모든 것들이 흩어져 있습니까? 적어도 p4에서 (사용자의 "작업 공간"은 기본적으로 사용자 별 분기이므로) git 또는 hg는 업스트림을 푸시 할 때까지 변경 사항을 모든 사람에게 알리지 않는 옵션이 있습니다. 변경 사항이 다른 사람과 관련이있을 때주의하십시오.
Spoike

24
나는 "너무 많은 실험적인 브랜치도 노이즈 논증, @Spoike"를 얻지 못한다. 우리는 모든 사용자가 자신의 폴더를 가지고있는 "Users"폴더를 가지고있다. 다른 사용자의 폴더를 무시하면 (어쨌든 왜 신경 써야합니까?) 노이즈가 보이지 않지만 SVN에서 병합하는 것은 빨라지지 않습니다 (그리고 나는 자주, 아니, 작지 않습니다) Git과 Mercurial의 합병은 우수하고 훌륭하게 지적했다.
John Smithers

11
svn에서는 비활성 브랜치를 쉽게 죽일 수 있습니다. 사람들이 사용하지 않는 가지를 제거하지 않으므로 혼란을 일으키는 것은 하우스 키핑의 문제 일뿐입니다. Git에 많은 임시 브랜치를 쉽게 넣을 수 있습니다. 내 직장에서는 표준 디렉토리 외에 "임시 지점"최상위 디렉토리를 사용합니다. "공식"코드 행이 유지되는 지점 디렉토리를 어지럽히는 대신 개인 브랜치 및 실험 브랜치가 있습니다. 기능 분기 사용).
Ken Liu

10
이것은 v1.5에서 subversion이 적어도 git can뿐만 아니라 병합 할 수 있다는 것을 의미합니까?
Sam

29

역사적으로 Subversion은 병합 정보를 저장하지 않았기 때문에 양방향 양방향 병합 만 수행 할 수있었습니다. 여기에는 일련의 변경 사항을 적용하여 트리에 적용하는 것이 포함됩니다. 병합 정보를 사용하더라도 여전히 가장 일반적으로 사용되는 병합 전략입니다.

Git은 기본적으로 3 웨이 병합 알고리즘을 사용하는데, 병합되는 헤드의 공통 조상을 찾고 병합의 양쪽에 존재하는 지식을 사용합니다. 이를 통해 Git은 충돌을 피할 수 있습니다.

Git에는 정교한 이름 변경 찾기 코드도있어 도움이됩니다. 그것은 하지 않습니다 변경 집합을 저장하거나 추적 정보를 저장 - 각 커밋하고 온 디스크 스토리지가 더이보다 복잡하다 (필요에 따라 사용하는 휴리스틱은 이름을 바꾸고 코드의 움직임을 찾을에서 그냥 파일의 상태를 저장하지만, 인터페이스 로직 레이어에 표시하여 추적을 노출하지 않습니다).


4
svn에 병합 충돌이 있지만 git은 그렇지 않은 예가 있습니까?
Gqqnbig

17

간단히 말해 병합 구현은 SVN 보다 Git 에서 더 잘 수행됩니다 . 1.5 이전에는 SVN이 병합 조치를 기록하지 않았으므로 SVN이 기록하지 않은 정보를 제공해야하는 사용자의 도움없이 향후 병합을 수행 할 수 없었습니다. 1.5에서는 더 나아졌으며 실제로 SVN 스토리지 모델은 Git의 DAG보다 약간 더 우수합니다. 그러나 SVN은 병합 정보를 다소 복잡한 형태로 저장하여 병합 작업이 Git보다 훨씬 많은 시간이 소요되었습니다. 실행 시간에서 300의 요인을 관찰했습니다.

또한 SVN은 이동 된 파일의 병합을 돕기 위해 이름 변경을 추적한다고 주장합니다. 그러나 실제로는 여전히 복사 및 별도의 삭제 작업으로 저장하며 병합 알고리즘은 수정 / 이름 바꾸기 상황, 즉 한 지점에서 파일이 수정되고 다른 지점에서 이름이 바뀌는 상황에서 여전히 넘어집니다. 병합됩니다. 이러한 상황에서는 여전히 가짜 병합 충돌이 발생하며 디렉토리 이름을 바꾸는 경우에도 수정 사항이 자동으로 손실됩니다. (SVN 사람들은 수정 사항이 여전히 역사에 있지만 지적해야 할 병합 결과가 아닌 경우 큰 도움이되지 않는다고 지적하는 경향이 있습니다.

반면에 Git은 이름 변경을 추적하지는 않지만 (병합시) 사실 이후에 이름을 알아 내고 마술처럼합니다.

SVN 병합 표현에도 문제가 있습니다. 1.5 / 1.6에서는 원하는대로 자동으로 트렁크에서 브랜치로 병합 할 수 있지만 다른 방향으로의 병합을 공지해야하고 ( --reintegrate) 브랜치를 사용할 수없는 상태로 두었습니다. 훨씬 나중에 그들은 실제로 그렇지 않다는 것을 알았고 , a) 자동으로 알아낼 --reintegrate 있고, b) 양방향으로 반복되는 병합이 가능하다는 것을 알았습니다 .

그러나이 모든 후에 (IMHO는 그들이하는 일에 대한 이해가 부족하다는 것을 보여줍니다), 나는 사소한 분기 시나리오에서 SVN을 사용하는 것이 매우주의를 기울여야하며 이상적으로 Git의 생각을 보려고합니다. 병합 결과.

SVN 지점의 글로벌 가시성으로 인해 답변에서 얻은 다른 점은 병합 기능과 관련이 없지만 유용성에는 관련이 없습니다. 또한 'Git 상점은 변경되지만 SVN 상점 (다른 것)은 대체로 중요하지 않습니다. Git은 개념적으로 각 커밋을 별도의 트리 ( tar 파일 과 같은 )로 저장 한 다음, 일부 휴리스틱을 사용하여 효율적으로 저장합니다. 두 커밋 사이의 변경 사항을 계산하는 것은 스토리지 구현과 별개입니다. 사실 Git은 히스토리 DAG를 SVN이 병합 정보보다 훨씬 간단한 형식으로 저장합니다. 후자를 이해하려는 사람은 내가 의미하는 바를 알게 될 것입니다.

요컨대, Git은 SVN보다 수정본을 저장하기 위해 훨씬 간단한 데이터 모델을 사용하므로 표현 => 실질적으로 더 나은 병합에 대처하는 대신 실제 병합 알고리즘에 많은 에너지를 넣을 수 있습니다.


11

다른 답변에서 언급되지 않았으며 실제로 DVCS의 가장 큰 장점 중 하나는 변경 사항을 적용하기 전에 로컬로 커밋 할 수 있다는 것입니다. SVN에서 변경 사항이 있었을 때 체크인하고 싶었고 누군가가 이미 같은 지점에서 커밋을 수행했기 때문에 커밋 svn update하기 전에 수행해야했습니다 . 이 수단 내 변경 및 다른 사람의 변경은 이제 서로 혼합되지 않도록하고, 방법은 (와 같은 병합 중단에 없다 git reset거나 hg update -C돌아갈 것을 약속 더 있기 때문에,). 병합이 사소한 것이 아니라면 병합 결과를 정리하기 전에 기능에 대한 작업을 계속할 수 없습니다.

그러나 어쩌면 그것은 너무 멍청한 사람들에게 별도의 가지를 사용하기에 유리한 것일 수도 있습니다 (정확하게 기억한다면 SVN을 사용한 회사에서 개발에 사용 된 하나의 가지만 있었음).


10

편집 : 이것은 주로 질문 의이 부분 을 해결 하는 것입니다.
이것은 실제로 두 시스템의 작동 방식에 본질적인 차이가 있거나 Git / Mercurial과 같은 특정 DVCS 구현이 SVN보다 똑똑한 병합 알고리즘을 가지고 있습니까?
TL; DR-이러한 특정 도구에는 더 나은 알고리즘이 있습니다. 분산되는 것은 몇 가지 워크 플로우 이점이 있지만 병합 장점과 직교합니다.
편집 종료

수락 된 답변을 읽었습니다. 그냥 잘못되었습니다.

SVN 병합은 고통스럽고 번거로울 수 있습니다. 그러나 실제로 1 분 동안 어떻게 작동하는지 무시하십시오. Git이 유지하거나 SVN이 유지하지 않거나 도출 할 수 없다는 정보는 없습니다 . 더 중요한 것은, 버전 관리 시스템의 별도 (일부 부분적인) 사본을 유지하여 더 많은 실제 정보를 제공 할 이유가 없습니다. 두 구조는 완전히 동일합니다.

"일부 영리한 일"을하고 싶다고 가정하자 Git은 "더 낫다". 그리고 당신은 SVN에 체크인되어 있습니다.

SVN을 동등한 Git 형식으로 변환하고 Git에서 수행 한 다음 여러 커밋을 사용하여 추가 분기를 사용하여 결과를 확인하십시오. SVN 문제를 Git 문제로 전환하는 자동화 된 방법을 상상할 수 있다면 Git은 근본적인 이점이 없습니다.

하루가 끝나면 모든 버전 관리 시스템에서

1. Generate a set of objects at a given branch/revision.
2. Provide the difference between a parent child branch/revisions.

또한 병합하기 위해서는 알고있는 것이 유용합니다 (또는 중요).

3. The set of changes have been merged into a given branch/revision.

Mercurial , Git 및 Subversion (현재는 원래 svnmerge.py를 사용)은 세 가지 정보를 모두 제공 할 수 있습니다. DVC로 근본적으로 더 나은 것을 보여주기 위해 SVN / 중앙 집중식 VC에서는 사용할 수없는 Git / Mercurial / DVC에서 사용할 수있는 네 번째 정보를 지적하십시오.

그들이 더 나은 도구가 아니라고 말하는 것은 아닙니다!


1
예, 제목이 아니라 세부 사항으로 질문에 답변했습니다. svn과 git은 동일한 정보에 액세스 할 수 있으므로 (실제로는 svn에 더 많은 정보가 있음) svn은 git의 모든 작업을 수행 할 수 있습니다. 그러나 그들은 다른 디자인 결정을 내렸으므로 실제로는 그렇지 않습니다. DVC / 중앙 집중식 증거는 git을 중앙 집중식 VC로 실행하고 (아마도 일부 규칙이 적용됨) svn 분산을 실행할 수는 있지만 완전히 짜증납니다. 그러나 이것은 대부분의 사람들에게 너무 학문적입니다 .git 및 hg는 svn보다 분기하고 병합하는 것이 좋습니다. 그것은 도구를 선택할 때 정말로 중요합니다 :-).
Peter

5
버전 1.5까지 Subversion 필요한 모든 정보를 저장 하지 않았습니다 . 1.5 이후 SVN을 사용하면 저장된 정보가 다릅니다. Git은 병합 커밋의 모든 부모를 저장하고 Subversion은 이미 어떤 개정이 브랜치에 병합되었는지 저장합니다.
Jakub Narębski

4
svn 저장소에서 다시 구현하기 어려운 도구는 git merge-base입니다. git을 사용하면 "버전 x에서 브랜치 a와 b가 분리됩니다"라고 말할 수 있습니다. 그러나 svn은 "파일이 foo에서 bar로 복사되었습니다"를 저장하므로 휴리스틱을 사용하여 copy to bar가 프로젝트 내에서 파일을 복사하는 대신 새 브랜치를 생성하고 있는지 확인해야합니다. 트릭은 svn의 개정이 개정 번호 기본 경로로 정의된다는 것 입니다. 대부분의 경우 "트렁크"라고 가정 할 수 있지만 실제로 분기가 있으면 물립니다.
Douglas Douglas

2
Re : "git이 보관하거나 파생 할 수있는 정보는 svn도 보관하지 않거나 파생 할 수 없습니다." -SVN이 언제 병합되었는지 기억하지 못한다는 것을 알았습니다. 트렁크에서 지점으로 작업을 가져오고 앞뒤로 이동하려면 병합이 어려워 질 수 있습니다. Git에서 리비전 그래프의 각 노드는 어디에서 왔는지 알고 있습니다. 부모는 최대 2 명이며 일부 지역 변경 사항이 있습니다. SVN보다 더 많은 것을 병합 할 수 있다고 Git을 신뢰합니다. SVN에서 병합하고 분기를 삭제하면 분기 히스토리가 손실됩니다. GIT를 병합하고 분기를 삭제하면 그래프가 그대로 유지되고 "blame"플러그인이 유지됩니다.
Richard Corfield 2016 년

1
git과 mercurial에 필요한 모든 정보가 로컬에있는 경우가 아닌가 svn은 정보를 도출하기 위해 로컬 및 중앙 데이터를 모두 조사해야합니까?
Warren Dew

8

SVN은 파일을 추적하고 Git은 내용 변경을 추적 합니다 . 한 클래스 / 파일에서 다른 클래스 / 파일로 리팩토링 된 코드 블록을 추적하기에는 영리합니다. 그들은 소스를 추적하기 위해 완전히 다른 두 가지 접근 방식을 사용합니다.

나는 아직도 SVN을 많이 사용하지만 Git을 몇 번 사용했는지 매우 기쁘게 생각합니다.

시간이 있다면 좋은 읽을 거리 : Git을 선택한 이유


그것은 내가 읽은 것입니다. 그리고 그것은 제가 믿고 있던 것이지만 실제로는 작동하지 않습니다.
Rolf

힘내 파일의 내용을 추적, 변경 내용으로 만 표시
Ferrybig

6

Joel의 블로그 (슬프게도 마지막 기사)에있는 기사를 읽으십시오. 이것은 Mercurial에 관한 것이지만 실제로 Git과 같은 Distributed VC 시스템의 장점에 대해 이야기합니다.

분산 버전 제어를 통해 분산 부분은 실제로 가장 흥미로운 부분이 아닙니다. 흥미로운 부분은 이러한 시스템이 버전이 아닌 변경의 관점에서 생각한다는 것입니다.

여기 에서 기사를 읽으 십시오 .


5
그것은 내가 여기에 게시하기 전에 생각했던 기사 중 하나였습니다. 그러나 "변화 측면에서 생각한다"는 매우 모호한 마케팅 용어입니다 (Joel의 회사는 현재 DVCS를 판매 함을 기억하십시오)
Mr. Boy

2
나는 그것이 모호하다고 생각했다. 나는 항상 변경 세트가 버전 (또는 개정판)의 핵심 부분이라고 생각했다.
Spoike

실제로 "변경 측면에서 생각하는"시스템에 대해서는 Darcs
Max

@Max : 물론, 푸시가 밀려 올 때 Git은 Darcs가 실제로 합병 할 때 Subversion만큼 고통스러운 곳을 제공합니다.
tripleee

Git의 세 가지 단점은 a) 사람들이 분기하고 병합 할 가능성이 거의없는 문서 관리와 같은 이진에는 좋지 않습니다 .b) 모든 것을 복제하려고한다고 가정합니다 .c) 복제본에도 모든 기록 클론 팽창을 유발하는 바이너리를 자주 변경하는 경우. 중앙 집중식 VCS가 이러한 사용 사례에 훨씬 적합하다고 생각합니다. Git은 특히 병합 및 분기를위한 정기적 인 개발에 훨씬 좋습니다.
locka
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.