답변:
"분기이라고 주장 자유 는 그 자체로"무료 "가 아니기 때문에 자식의는"사실의 단순화이다. 후드를 살펴보면 분기가 기본적으로 커밋을 참조하기 때문에 분기가 대신 엄청나게 저렴 하다고 말하는 것이 더 정확한 주장입니다 . 여기서 "저렴함"은 오버 헤드가 적을수록 저렴합니다.
어떤 종류의 오버 헤드가 있는지 조사하여 Git이 왜 "저렴한"지에 대해 알아 보겠습니다.
git 저장소는 .git
주로 git이 사용하는 메타 데이터를 포함하는 파일이있는 디렉토리로 구성됩니다. 예를 들어 git에서 브랜치를 만들 때마다 git branch {name_of_branch}
몇 가지 일이 발생합니다.
.git/refs/heads/{name_of_branch}
.git/logs/refs/heads/{name_of_branch}
기본적으로 몇 개의 텍스트 파일이 만들어집니다. 참조를 텍스트 파일로 열면 내용이 분기가 가리키는 커밋의 id-sha가됩니다. 참고 분기가 어떤 커밋을 할 필요가 없습니다 그들이 개체의 또 다른 친절로. 브랜치와 커밋은 모두 git의 "일류 시민"이며, 한 가지 방법은 브랜치-커밋 관계를 컴포지션이 아니라 집계로 생각하는 것입니다. 분기를 제거해도 커밋은 여전히 "매달리기"로 존재합니다. 실수로 브랜치를 제거한 경우 항상 커밋을 찾 git-lost-found
거나 git-fsck --lost-found
sha-id에서 브랜치 를 발견하려고 시도 할 수 있습니다 (git가 가비지 수집을 아직 수행하지 않은 한).
git은 현재 어떤 브랜치를 추적하고 있습니까? 대답은 .git/HEAD
파일에 있으며 master
지점 에있는 경우 일종의 모양 입니다.
ref: refs/heads/master
분기를 전환하면 .git/HEAD
파일 의 참조 가 변경되고 커밋에 정의 된 내용으로 작업 영역의 내용이 변경됩니다.
에서 서브 버전 , 가지 저장소의 가상 디렉터리입니다 . 따라서 가장 쉬운 분기 방법은 원 라이너로 원격으로 수행하는 것 svn copy {trunk-url} {branch-url} -m "Branched it!"
입니다. SVN의 기능은 다음과 같습니다.
trunk
를 대상 디렉토리에 복사하십시오 .로컬로 복사하는 것은 파일을 복사하고 심볼릭 링크하는 선형 시간 작업이므로 서버에서 원격으로이 작업을 수행하려고합니다. 이것은 매우 느린 작업이지만 서버에서 수행하는 것은 일정한 시간 작업입니다. 서버에서 분기를 수행 할 때에도 서브 버전 은 분기 할 때 커밋이 필요 하지만 git은 그렇지 않습니다. 이는 중요한 차이점입니다. 그것은 SVN을 Git보다 조금 저렴하게 만드는 일종의 오버 헤드입니다.
SVN 에서 분기 를 전환 하는 명령 , 즉 svn switch
실제로 svn update
위장입니다. 가상 디렉터리 개념 덕분에이 명령은 git보다 svn에서 약간 더 유연합니다. 작업 공간의 하위 디렉토리를 전환하여 다른 저장소 URL을 미러링 할 수 있습니다. 가장 가까운 것은 사용하는 git-submodule
것이지만 그것을 사용하는 것은 의미 상 분기와 다릅니다. 불행히도 이것은 미러 할 원격 URL을 모든 작업 공간 디렉토리를 확인해야하기 때문에 Git보다 SVN에서 조금 느리게 전환하는 설계 결정입니다. 내 경험상 Git은 SVN보다 지점을 빠르게 전환합니다.
SVN의 브랜칭은 파일을 복사하고 항상 공개적으로 사용할 수 있어야하므로 비용이 발생합니다. git에서 위에서 설명한 것처럼 브랜치는 "그냥 참조"이며 로컬 리포지토리에 보관하고 재량에 게시 할 수 있습니다. 그러나 내 경험상 SVN은 예를 들어 ClearCase보다 훨씬 저렴하고 성능이 뛰어납니다.
SVN이 탈 중앙화되지 않은 것은 혼란스러운 일입니다. 소스 리포지토리에 미러링 된 여러 리포지토리를 가질 수 있지만 SVN에는 커밋에 대한 고유 식별자가 없기 때문에 여러 가지 SVN 리포지토리를 동기화하는 것은 불가능합니다 (git에는 커밋 내용을 기반으로 해시 식별자가 있습니다). 내가 개인적으로 SVN을 통해 git을 사용하기 시작한 이유 는 저장소를 시작하는 것이 git에서 훨씬 쉽고 저렴 하기 때문 입니다. 개념적으로 소프트웨어 구성 관리 측면에서 프로젝트의 각 분기 사본 (복제, 포크, 작업 공간 또는 기타)은 "분기"이며 SVN에서 새 사본을 작성하는 용어는 Git만큼 저렴하지 않습니다. 분기 "내장".
다른 예로서, Mercurial에서 , 브랜칭은 DVCS와 약간 다르게 시작되었고 명명 된 브랜치를 생성 / 파기하려면 별도의 커밋이 필요했습니다. 의욕 개발자는 개발 이후에 구현 북마크 하지만 모방 자식의 같은 분기의 모델 heads
이라고 tips
하고 branches
있는 bookmarks
수은 용어 대신에.
This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.
-모든 파일을 명시 적으로 복사하지 않는 한 SVN에서 브랜치를 만드는 것은 쉽지 않습니다.
지점의 실제 비용은 합병됩니다. Git은 다른 소스 제어 시스템보다 쉽게 사용할 수 있습니다. 스택 오버플로 질문을 참조하십시오 . SVN보다 Git에서 어떻게 병합하는 것이 더 좋습니까? .
Git에서 브랜치는 로컬 리포지토리에 대한 커밋에 대한 참조 일뿐입니다. 네트워크를 만들지 않아도 매우 저렴합니다. 꽤 자유롭지는 않지만 (명령을 입력해야 함) 가까이 있습니다.
SVN에서는 브랜칭이 특히 비싸지 않습니다. 단지 사본 일 뿐이므로 매우 저렴한 커밋입니다. SVN에는 중앙 저장소 모델이 있으므로 네트워크 액세스이지만 끔찍한 것은 아닙니다.
반면에 훌륭한 CVS에서는 분기가 매우 비쌉니다. 기본적으로 CVS 브랜치는 태그 추가를 포함하지만 CVS에서는 모든 파일에 영향을 미칩니다. 각 파일은 새 태그를 포함하도록 다시 작성됩니다. 엄청 비싸요. 그리고 저장소가 크면 너무 느립니다. 실제로, 큰 프로젝트를 진행하고 있다면, 일부 사람들은 가능하다면 지점을 만들지 않는 경향이 있습니다.
SVN의 분기는 Git만큼 무료입니다. 그것은 분기가 시작되는 위치를 알려주는 약간의 하우스 키핑 데이터 일 뿐이며 저장된 파일은 변경되지 않습니다. SVN의 '복사'는 Unix 디렉토리에 심볼릭 링크를 추가하는 것과 같습니다. SVN 브랜치는 작업 카피 변경 사항을 커밋 할 때까지 네트워크 트립을 요구하지 않습니다 (그러나 로컬에서 오프 로컬로 커밋하지 않으면 SCM이 많은 포인트는 없습니다).
Git 브랜치는 커밋 할 때 어딘가에 저장 해야하는 태그를 내부적으로 추가하는 것과 같은 하우스 키핑도 포함합니다. 전혀 큰 문제가 아니기 때문에 '무료'라고 불립니다.
일부 이전 버전 제어 시스템에서는 지점이 해당 시점의 코드의 완전한 사본 이었으므로 지점은 많은 부분을 차지 했기 때문에 '무료'(이 문맥에서 '무료'는 실제로 빠르고 쉽고 공간을 차지하지 않음을 의미합니다) 입니다. 공간이 넓어졌고, 완전히 다른 버전의 소프트웨어가 설치되어 관리하기가 쉬웠습니다. 다른 경우에는 코드의 완전한 사본이 아니지만 모든 파일을 태그에 대해 수정해야했기 때문에 느리고 고통 스럽습니다 ( '비용이 많이 드는').
"무료 / 저렴한 / 비싸다"의 또 다른 측면은 분기의 다운 스트림 결과를 처리하기 위해 개발자 리소스 측면에서 비용이 얼마나 드는지에 관한 것입니다. 즉, 분기의 변경 사항을 병합하는 프로세스입니다.
여기에서 Git 및 Mercurial과 같은 DVCS 시스템에서 브랜치를 병합하는 것이 구형 시스템보다 쉽습니다. DVCS 시스템은 그래프에서 버전의 기록을 훨씬 더 잘 추적 할 수 있기 때문입니다. 즉, 이전 브랜치 병합이 발생한 위치. 이렇게하면 병합이 더 정확 해지고 불필요한 충돌이 줄어 듭니다. ... 관련 개발자에게 주관적으로 "쉽게"또는 "무섭게"병합 할 수 있습니다.