2009-10-31 7 views
11

분산 버전 제어 (Git, Bazaar 및 Mercurial)의 Big Three는 각각 분기를 공정하게 다르게 처리합니다. 예를 들어 바자 (Bazaar)에서는 지점이 별도의 저장소 (실제로는 상위 저장소의 분기 된 사본)입니다. 파일 시스템에서 다른 브랜치가 다른 디렉토리에 있습니다. 힘내 (Git)에서는 같은 저장소에 여러 개의 브랜치가 존재할 수있다. 따라서 파일 시스템의 같은 디렉토리에 브랜치를 둘 수있다. Mercurial은 both behaviors을 지원하고, 후자는 named branches을 지원합니다.DVCS에서 다른 분기 모델의 장단점

서로 다른 분기 모델과 관련된 장단점은 무엇입니까? Bazaar의 한 지점에 대한 접근 방식, 하나의 저장소는 Git의 접근 방식보다 더 많은 부분을 아프게합니다 (예 : Bazaar의 지점을 사용하려면 먼저 지점을 만든 다음 현재 작업중인 곳에서 cd를하고 체크 아웃해야합니다). 새로운 지점, 내가 SVN에서와 같이).

+4

명명 된 분기점은 자식 분기와 매우 다릅니다. 자세한 내용은 여기를 참조하십시오. http://stevelosh.com/blog/entry/2009/8/30/a-guide-to-branching-in-mercurial/ – tonfa

+0

도 참조하십시오. 내 대답은 "힘과 의욕 - 비교 및 ​​대조", 지점도 다루고 : http://stackoverflow.com/questions/1598759/git-and-mercurial-compare-and-contrast/1599930#1599930 –

+0

남자, 항상 tonfa 내가하기 전에 나의 blog 입구를 게시하는 것을 관리한다! :) –

답변

9

Bazaar는 사용자가 설명하는 방식으로 작업 할 것을 요구하지 않습니다. 나는 실제로 이틀 전에 약 a blog post를 썼다. 하나의 작업 트리 만 사용하여 작업 할 수 있습니다. 여러 가지 분기를 전환하고 작업 트리를 떠나지 않고 새 분기를 만들 수 있습니다. 이에 대한 유용한 명령은 checkout, switch, branch --switch입니다. Bazaar에 대한 workflow 문서를 확인하면 원하는대로 거의 모든 방법으로 구성 할 수 있습니다.

+0

바자가 내가 생각했던 것보다 융통성이 있다는 것을 아는 것이 좋다. 나는 실제로 내 질문에 언급 한 문제를 해결할 수있는 귀하의 저장소 안에 "지점"디렉토리를 만드는 경우 궁금 해서요. 통찰력에 감사드립니다. – ThisSuitIsBlackNot

6

힘내 외의 다른 VCS에서 모델을 분기하는 것에 대해 많이 알지 못합니다. 모든 DVCS에서 복제를 통해 분기를 구현할 수 있다고 말하고 싶습니다 (복제를 수행하여 분기를 만듭니다). Mercurial 소위 "지사"는 (사실 내가 이해 한대로) 실제로는 레이블을 커밋합니다.은 분기로 해석되며, 때로는 모호성을 해결하기 위해 로컬 번호 매기기가 필요합니다. Mercurial "bookmarks"ar은 Git 브랜치와 아주 비슷하다고 생각합니다. 매우 다른 브랜치의 다른 개념을 가지고있는 두 DVCS는 MonotoneDarcs입니다. Subversion에서 사용하는 "복사하여 분기하는 것"은 프로젝트 이름과 분기 이름을 구분하는 경우 컨벤션인데 잘못된 생각입니다.


Git 개정판에는 커밋 된 DAG (Directed Acylclic Graph)가 있습니다. 커밋에는 부모가 있기 때문에 지시됩니다. 이것은 매우 중요한 문제입니다. 커밋 DAG의 가장자리는 커밋에서 부모 (또는 병합 커밋의 경우 두 개 이상의 부모)까지입니다. 커밋 그래프는 비순환 적입니다. 즉, 동일한 객체로 시작하고 끝나는 체인 (경로 없음)을 의미합니다.

Git glossary은의 활성 행으로 "분기"를 정의합니다. 이 아이디어는 Git에 지점을 구현 한 뒤에있다.

분기의 가장 최근의 커밋을 이라고합니다. 브랜치의 팁은 브랜치 헤드에 의해 참조되며 이는 커밋의 상징적 인 이름입니다. "branch"라는 이름의 브랜치 헤드와 같은 "loose"형태의 브랜치 헤드는 브랜치의 현재 팁에 대한 참조를 포함하는 자식 저장소 (.git 디렉토리) 내의 refs/heads/ 디렉토리의 파일입니다. SHA-1 커밋 식별자 (16 진수 문자열).

힘내에서 새 커밋을 만들 때 현재 체크 아웃 된 분기의 팁이 앞으로 이동합니다. 바꾸어 말하면 새로운 커밋은 현재 브랜치의 끝 부분에 만들어지며 브랜치 헤드는 새로운 커밋으로 넘어갑니다 (스택 맨 위로 포인터가 이동하는 방식과 다소 비슷합니다).

단일 git 저장소는 임의의 수의 분기를 추적 할 수 있지만 작업 트리 (있는 경우)는 그 중 하나 ("현재"또는 "체크 아웃"분기)와 연관됩니다. 현재 분기는 HEAD 포인터에 의해 제공됩니다. HEAD는 현재 체크 아웃 된 브랜치 (브랜치 헤드 이름)에 대한 포인터입니다 (브랜치 헤드가 브랜치의 팁에 대한 포인터 임). 현재 체크 아웃 된 경우, 예를 들어

분기 단일 LF를 포함하는 것 '마스터'이면 .git/HEAD 파일 (나타내는 HEAD)이다 ref: refs/heads/master (refs/heads/master 심볼릭 참조) 및 .git/refs/heads/master ('마스터'지점의 헤드)와 줄 것이다 종결 예를 들어, LF로 끝나는 0b127cb8ab975e43398a2b449563ccb78c437255 라인을 포함합니다. 'master'브랜치의 팁에 SHA-1 식별자가 있습니다 (즉, 현재 브랜치가 "packed"되지 않은 경우). .git/packed-refs을 살펴 봐야합니다.

"git commit"또는 "git reset"과 같이 Git 명령은 분기 헤드를 조작/변경합니다. "git checkout"과 같은 다른 명령은 HEAD (현재 분기에 대한 기호 참조)를 조작/변경합니다.

"git log branch"명령은 분기 팁, 그 부모, 그 부모 커밋의 부모 (또는 부모) 등을 의미하는 분기 팁에서 도달 할 수있는 모든 커밋을 보여줍니다. 커밋 된 DAG의 일부를 보여줍니다.

Git에서 지사 삭제는 간단히 지사 헤드를 제거하는 것을 의미합니다. 이는 일부 커밋이 "보이지 않는"즉 도달 할 수없는 프리덤 참조 (분기 및 태그)가 될 수 있음을 의미합니다. 즉, 커밋 된 시간이 가비지 수집 및 저장소에서 제거 될 수 있음을 의미합니다. 그러나 "git branch -d <branchname>"을 사용하여 브랜치를 삭제할 수 있다면 커밋이 손실되지 않는다는 것을 의미합니다. 당신은 "git branch -D <branchname>"으로 분기 삭제를 강제 할 수있다. 브랜치의 이름을 변경하는 것은 브랜치 팁의 심볼릭 참조 (상징적 인 이름) 인 브랜치 헤드의 이름을 변경하는 것입니다. 분기 이름은 커밋 개체의 아무 곳에도 저장되지 않습니다.


힘내는 분기 끝이 지적 (때) 여기서 로컬 역사 reflogs의 개념을 갖는다. 예를 들어 "git commit --amend"를 사용하여 커밋을 수정하면 분기 팁이 수정 된 커밋으로 대체되고 HEAD ^는 수정 전후의 커밋의 부모가되며 수정하기 전에 버전에 대한 reflog에 항목이 있습니다. 개정 후. "git reset"을 사용하여 히스토리를 되감다면 reflog는 되감기 전에 오래된 브랜치 팁에 대한 정보를 포함하게됩니다.

짧은 reflog에서 git 명령에 안전성과 쉬운 복구가 추가되었습니다.

관련 문제