git 하위 트리를 언제 사용합니까?


81

어떤 문제가 git subtree해결됩니까? 이 기능을 언제, 왜 사용해야합니까?

나는 그것이 저장소 분리에 사용 된다는 것을 읽었습니다 . 그러나 관련되지 않은 두 개의 저장소를 하나로 묶는 대신 두 개의 독립적 인 저장소를 만들지 않는 이유는 무엇입니까?

이 GitHub 가이드 에서는 Git 하위 트리 병합을 수행하는 방법을 설명 합니다 .

나는 그것을 사용 하는 방법 을 알고 있지만 언제 (사용 사례), , 그리고 그것이 git submodule. 다른 프로젝트 또는 라이브러리에 대한 종속성이있을 때 하위 모듈을 사용합니다.


1
"리포지토리 분리"! = "관련되지 않은 리포지토리"는 리포지토리의 종속성을 생각하고 서브 모듈을 사용하고 싶지 않습니다 (어떤 이유에서인지 투명하지 않고 커밋의 경로가 하위 모듈이 기본 git repo의 경로와 일치하지 않습니다.)
cyphar 2015 년

1
@cyphar : 당신은 둘 건가요 submodule과는 subtree다소 관련 프로젝트를 포함 동일한 목표를 달성하고, 유일한 차이점은 그 것을하는 submodule조금 덜 투명하고 업데이트 서브 모듈 수있는 두 단계의 작업과의 단점이 있다는 subtree점이다 커밋 메시지가 두 프로젝트간에 모두 섞일까요?
Lernkurve 2015 년

1
글쎄, 특정 경우에는 실제로 단점이 아닙니다. 예를 들어, subtrees가 있고 종속성에 버그가 도입 된 저장소를 양분해야하는 경우 버그를 도입 한에서 정확한 커밋 subtree 찾을 수 있습니다. 서브 모듈을 사용하면 rev'd 커밋이 submodule버그를 유발 한다는 것을 알 수 있으며 submodule메인 프로젝트에서 버그를 유발하는 커밋을 빠르게 찾고 싶다면 일종의 SOL 입니다.
cyphar 2015 년

1
다음은 git 하위 트리와 git 하위 모듈을 실제 예제와 비교하는 기사입니다. nering.dev/2016/git-submodules-vs-subtrees
8ctopus

답변:


58

실제로 두 개의 별개이지만 관련 주제가 여기 에 있기 때문에 문맥에서 '하위 트리' 라는 용어를 사용할 때 말하는 내용을 명시 적으로주의해야합니다 git.

git-subtreegit 하위 트리 병합 전략 .

TL; DR

두 하위 트리 관련 개념을 사용하면 여러 저장소를 하나에서 효과적으로 관리 할 수 ​​있습니다. 메타 데이터 만 루트 저장소에 .gitmodules 형식으로 저장되는 git-submodule 과 달리 외부 저장소를 별도로 관리해야합니다.

자세한 내용은

git 하위 트리 병합 전략 은 기본적으로 참조한 명령을 사용하는보다 수동적 인 방법입니다.

git-subtree 는보다 자연스러운 구문을 지원하는 래퍼 쉘 스크립트입니다. 이것은 실제로 여전히 일부이며 contrib일반적인 man 페이지와 함께 git에 완전히 통합되지는 않았습니다. 문서는 대신 스크립트 측면을 따라 저장됩니다.

사용 정보는 다음과 같습니다.

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' add   -P <prefix> <commit>
'git subtree' add   -P <prefix> <repository> <ref>
'git subtree' pull  -P <prefix> <repository> <ref>
'git subtree' push  -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]

나는 내 자신의 블로그 게시물을 작성할 계획을 세우고 있었기 때문에 하위 트리 주제에 대해 꽤 많은 리소스를 발견했습니다. 내가 할 경우이 게시물을 업데이트 할 것이지만 지금은 당면한 질문과 관련된 몇 가지 정보가 있습니다.

많은 당신이 찾을 수 있습니다 추구하는 어떤 이 골드 피처 블로그 에 의해 니콜라 Paolucci 관련 섹션 아래 :

서브 모듈 대신 서브 트리를 사용하는 이유는 무엇입니까?

subtree사용하는 것이 더 좋은 이유는 다음과 같습니다.

  • 간단한 워크 플로우 관리가 쉽습니다.
  • 의 이전 버전 git이 지원됩니다 ( 이전 버전 포함 v1.5.2).
  • 하위 프로젝트의 코드는 clone슈퍼 프로젝트가 완료된 직후에 사용할 수 있습니다 .
  • subtree저장소 사용자가 새로운 것을 배울 필요가 없으며 subtree종속성을 관리하는 데 사용하고 있다는 사실을 무시할 수 있습니다 .
  • subtreedoes submodules(예 :) 와 같은 새 메타 데이터 파일을 추가하지 않습니다 .gitmodule.
  • 모듈의 내용은 다른 곳에 종속성의 별도 리포지토리 복사본이 없어도 수정할 수 있습니다.

제 생각에는 단점이 허용됩니다.

  • 새로운 병합 전략 (예 :)에 대해 배워야합니다 subtree.
  • upstream하위 프로젝트에 대한 코드 기여 는 약간 더 복잡합니다.
  • 커밋에서 슈퍼 및 하위 프로젝트 코드를 혼합하지 않는 책임은 사용자에게 있습니다.

나는 이것의 많은 부분에도 동의 할 것이다. 일반적인 사용법에 대해 설명하는 기사를 확인하는 것이 좋습니다.

그가 여기 에이 접근 방식에서 생략 된 중요한 세부 사항을 언급하는 후속 작업을 작성했음을 알 수 있습니다 .

git-subtree 현재 리모컨을 포함하지 않습니다!

이 짧은 시력은 아마도 사람들이 종종 하위 트리를 다룰 때 수동으로 원격을 추가한다는 사실 때문일 수 있지만 이것은 git에도 저장되지 않습니다. 작성자는 git-subtree이미 생성 된 커밋에이 메타 데이터를 추가하기 위해 작성한 패치를 자세히 설명합니다 . 이것이 공식 git 메인 라인이 될 때까지 커밋 메시지를 수정하거나 다른 커밋에 저장하여 비슷한 일을 할 수 있습니다.

또한 이 블로그 게시물도 매우 유익합니다. 저자는 그가 호출하는 세 번째 하위 트리 메서드를 git-stree믹스에 추가합니다. 이 기사는 그가 세 가지 접근 방식을 비교하는 데 꽤 좋은 일을했기 때문에 읽을 가치가 있습니다. 그는 자신이하는 일과 싫어하는 일에 대한 개인적인 의견을 제시하고 왜 세 번째 접근 방식을 만들 었는지 설명합니다.

기타

마무리 생각

이 항목에서는 git기능이 표시를 놓쳤을 때 발생할 수있는 세분화 의 힘 과 세분화를 모두 보여줍니다 .

나는 git-submodule기여자들이 이해하기 더 헷갈 리기 때문에 개인적으로 혐오감을 쌓았다 . 또한 여러 저장소를 관리하지 않고도 쉽게 재현 가능한 환경을 용이하게하기 위해 프로젝트 내에서 모든 종속성을 관리 하는 것을 선호 합니다. git-submodule그러나 현재는 훨씬 더 잘 알려져 있으므로이를인지하고 결정을 좌우할 수있는 청중에 따라 당연히 좋습니다.


12

첫 번째 : 귀하의 질문은 강하게 의견이 많은 답변을받는 경향이 있으며 여기서 주제에서 벗어난 것으로 간주 될 수 있습니다. 그러나 나는 그 SO 정책을 좋아하지 않으며 주제에 대한 경계를 약간 바깥쪽으로 밀어 붙일 것이므로 대신 대답하고 다른 사람들도 그렇게하기를 바랍니다.

귀하가 지적한 GitHub 튜토리얼에는 장점 / 단점에 대한 관점을 제공하는 하위 트리 병합 전략을 사용하는 방법에 대한 링크 가 있습니다 .

하위 트리 병합과 하위 모듈 비교

사용의 장점 하위 트리 병합 이 있다는 것입니다 사용자로부터 적은 관리 부담이 필요 저장소의를. 그것은 나이와 함께 작동 (힘내 v1.5.2 전) 클라이언트 당신은 복제 후 코드 권리가 있습니다.

그러나 하위 모듈 을 사용하는 경우 하위 모듈 개체를 전송하지 않도록 선택할있습니다 . 하위 트리 병합에 문제가있을 수 있습니다.

또한 다른 프로젝트 를 변경 한 경우 서브 모듈 만 사용하면 변경 사항을 제출 하는 것이 더 쉽습니다 .

위의 관점은 다음과 같습니다.

나는 종종 일반 git 사용자가 아닌 사람들 (= 커미터)과 함께 일하며, 일부는 여전히 버전 제어에 어려움을 겪습니다. 하위 모듈 병합 전략을 사용하는 방법에 대해 교육하는 것은 기본적으로 불가능합니다. 여기에는 병합, 분기 및 모든 것을 하나의 워크 플로로 혼합하는 것에 대한 추가 원격 개념이 포함됩니다. 업스트림에서 당기고 업스트림으로 밀어 올리는 것은 두 단계 프로세스입니다. 가지가 이해하기 어렵 기 때문에 이것은 모두 절망적입니다.

하위 모듈을 사용하면 여전히 너무 복잡 하지만 ( sigh ) 이해하기가 더 쉽습니다. 저장소 내의 저장소 (계층 구조에 익숙 함) 일 뿐이며 평소처럼 밀고 당기는 작업을 수행 할 수 있습니다.

간단한 래퍼 스크립트를 제공하는 것이 하위 모듈 워크 플로에 대해 더 쉽습니다.

많은 하위 저장소가있는 대형 수퍼 저장소의 경우 일부 하위 저장소의 데이터를 복제하지 않도록 선택하는 점은 하위 모듈의 중요한 이점입니다. 작업 요구 사항 및 디스크 공간 사용량에 따라이를 제한 할 수 있습니다.

액세스 제어가 다를 수 있습니다. 아직이 문제가 발생하지 않았지만 다른 리포지토리에 다른 액세스 제어가 필요하여 일부 사용자를 일부 하위 리포지토리에서 효과적으로 금지하는 경우 하위 모듈 방식으로 수행하는 것이 더 쉬운 지 궁금합니다.

개인적으로 나는 무엇을 사용해야할지 결정되지 않았습니다. 그래서 나는 당신의 혼란을 공유합니다 : o]


3
이 대답은 모순에도 불구하고 내가 본 가장 강하게 주장하는 대답이며, 유일한 대답이며 자기 성취적인 예언입니다. 분노한 한숨, 다른 사람의 학습 능력에 대한 종말론 자 태도, 이것은 매우 오만한 대답입니다. 정책에 대한 귀하의 의견은 도움이 될 수있는 메타에 속할 것입니다. 이기적인 보풀이 아닌 대답 자체는 꽤 좋습니다.
vgoff 2015 년

1
@vgoff : 귀하의 비판이 정확합니다. 거만 해 보이는 것에 대해 죄송합니다. 다른 버전 제어 시스템에서 다른 사람들에게 그 시간 동안 교육을 받았지만 여전히 텍스트 파일을 수많은 .backup.<timestamp>. 나는 처음에 그것이 의견이 될 것이라는 것을 분명히 밝힌 것 같습니다. 다른 사람들은 좀 더 사실적인 통찰력을 제공 할 수 있기를 바라며, 아직 아무도 알지 못합니다.
cfi

나는 아직도 그것을 이해하지 못한다. 그것이 submodule사용 된 라이브러리를 통합하는 더 이상 사용되지 않는 오래된 방법이며 subtree새롭고 반짝이는 방법 이라고 말하는가 ?
Lernkurve 2015 년

아니요. 문서에서는 적어도 둘 중 어느 것도 사용되지 않는다고 언급하지 않습니다. 그리고 나에게 문서는 최종 결정권을 가지고 있습니다 (버그 제외). 비슷한 작업을 수행하는 것은 두 가지 다른 워크 플로입니다. 둘 다 장점과 단점이 있습니다. 나에게 자식 전문가 중 아무도 아직 대답하지 않았다는 사실은 전문가에게 차이가 무시할 만하다는 확인입니다. 아마도 하위 트리 병합 전략은 이전에 구현 된 전략이고 사람들이 read-tree(그리고 어쨌든 분기 / 병합 / 원격) 익숙하기 때문에 사용합니다 . submodules에 추가되었습니다
cfi sep. 07 2015-09-07

5

git 하위 트리가 구원 인 실제 사용 사례 :

우리 회사의 주요 제품은 높은 모듈 식이며 별도의 저장소에서 여러 프로젝트로 개발되었습니다. 모든 모듈에는 별도의 로드맵이 있습니다. 전체 제품은 콘크리트 버전의 모든 모듈로 구성됩니다.

병행하여 전체 제품의 구체적인 버전은 각 고객에 맞게 사용자 정의됩니다 (각 모듈에 대한 개별 분기). 때때로 여러 프로젝트에서 한 번에 사용자 정의해야합니다 ( cross-module customization).

맞춤형 제품에 대해 별도의 제품 수명주기 (유지 관리, 기능 분기)를 갖기 위해 git 하위 트리를 도입했습니다. 모든 사용자 정의 모듈에 대해 하나의 git-subtree 저장소가 있습니다. 우리의 커스터마이징은 모든 원본 리포지토리에서 커스터마이징 브랜치로 돌아가는 'git subtree push'입니다.

이렇게 우리는 많은 저장소와 많은 지점을 관리하지 않습니다. git-subtree는 생산성을 여러 번 향상 시켰습니다!

최신 정보

댓글에 게시 된 솔루션에 대한 자세한 내용 :

우리는 새로운 저장소를 만들었습니다. 그런 다음 클라이언트 분기가있는 각 프로젝트를 해당 새 저장소에 하위 트리로 추가했습니다. 마스터 변경 사항을 원래 리포지토리의 클라이언트 브랜치로 정기적으로 되 돌리는 젠킨스 작업이있었습니다. 우리는 기능 및 유지 관리 분기와 함께 tipical git 흐름을 사용하여 "클라이언트 저장소"로 작업했습니다.

우리의 '클라이언트'리포지토리도이 특정 클라이언트에 맞게 조정 한 스크립트를 작성했습니다.

그러나 제시된 솔루션의 함정이 있습니다.

제품의 주요 핵심 개발에서 점점 더 멀어짐에 따라 특정 클라이언트에 대한 가능한 업그레이드가 점점 더 어려워졌습니다. 우리의 경우에는 하위 트리가 이미 주 경로의 한 방법이되기 전의 프로젝트 상태가 괜찮 았으므로 하위 트리는 최소한 기본 git 흐름을 도입 할 수있는 순서와 가능성을 도입합니다.


Marek, 나는 같은 상황에 직면했고 나는 상대적으로 git에 익숙하지 않고 가능성에 허둥 대고 있습니다. 설정에 대해 더 알고 싶습니다.
goug

새로운 저장소를 만들었습니다. 그런 다음 클라이언트 분기가있는 각 프로젝트를 해당 저장소에 하위 트리로 추가했습니다. 원래 리포지토리의 변경 사항을 클라이언트 브랜치로 되 돌리는 젠킨스 작업이있었습니다. 클라이언트 리포지토리에서는 기능, 유지 관리 분기가있는 마스터에서 정상적으로 작업했습니다.
Marek Jagielski

함정은 우리가 제품의 주요 핵심 개발에서 점점 더 멀어지고 있다는 것입니다. 따라서 특정 클라이언트에 대한 가능한 업그레이드는 점점 더 어려워졌습니다. 우리의 경우에는 하위 트리가 이미 주 경로의 한 방법이되기 전의 프로젝트 상태가 괜찮 았으므로 하위 트리는 최소한 기본 git 흐름을 도입 할 수있는 순서와 가능성을 도입합니다.
Marek Jagielski

우리의 '클라이언트'리포지토리가이 특정 클라이언트에 맞게 조정 한 스크립트를 작성했던 한 가지 더.
Marek Jagielski

1
의견의 추가 정보를 답변에 통합하는 것이 좋습니다. 그들은 확실히 이것을 더 나은 대답으로 만듭니다.
James Skemp

5

기본적으로 Git-subtree는 Git-submodule 접근 방식에 대한 대안입니다. 많은 단점이 있거나 오히려 git-submodules를 사용하는 동안 매우주의해야합니다. 예를 들어 "one"repo가 ​​있고 "one"안에있는 경우 하위 모듈을 사용하여 "two"라는 또 다른 저장소를 추가했습니다. 주의해야 할 사항 :

  • "two"에서 무언가를 변경할 때 "two"내부에서 커밋하고 푸시해야합니다. 최상위 디렉토리 (즉, "one")에 있으면 변경 사항이 강조 표시되지 않습니다.

  • 알 수없는 사용자가 "하나"저장소를 복제하려고 할 때 "하나"를 복제 한 후 해당 사용자는 "2 개"저장소를 얻기 위해 하위 모듈을 업데이트해야합니다.

다음은 몇 가지 요점이며 더 나은 이해를 위해 다음 비디오를 시청하는 것이 좋습니다. https://www.youtube.com/watch?v=UQvXst5I41I

  • 이러한 문제를 극복하기 위해 하위 트리 접근 방식이 발명되었습니다. git-subtree에 대한 기본 정보를 얻으려면 https://www.youtube.com/watch?v=t3Qhon7burE를 확인하세요.

  • 하위 트리 접근 방식이 하위 모듈에 비해 더 안정적이고 실용적이라는 것을 알았습니다. :) (저는 이런 말을하는 것이 매우 초보자입니다)

건배!


2

위의 답변에 추가하려면 하위 트리 사용의 추가 단점은 하위 모듈과 비교하여 리포지토리 크기입니다.

실제 메트릭은 없지만 모듈에서 푸시가 수행 될 때마다 해당 모듈이 사용되는 모든 곳에서 상위 모듈에서 동일한 변경 사항의 복사본을 가져옵니다 (이후 해당 저장소에서 업데이트 될 때).

따라서 코드 기반이 크게 모듈화되어 있다면 상당히 빨리 추가 될 것입니다.

그러나 스토리지 가격이 항상 하락하고 있으므로 중요한 요소가 아닐 수 있습니다.


저장은 문제가 아닙니다. 엔트로피가 문제입니다 ! 예를 들어, 각각 35GB의 공통 코드베이스를 공유하는 10KB에서 100KB의 1000 개의 도구가 있습니다 (다른 소스의 방대한 수의 모듈을 포함하기 때문입니다). 서브 모듈을 사용하면 모두 약 36GB를 전송하지만 git 하위 트리에서는 1TB 이상을 전송할 수 있습니다! 또한 하위 모듈은 git gcZFS 중복 제거 (객체 팩)와 관련 하여 분명히 불공정 한 이점이 있습니다 . 따라서 AFAICS의 더 작은 코드베이스 (리포지토리 크기가 아니라 리포지토리 크기가 현명함)는 서브 모듈과 함께 이동해야하고, 더 큰 코드베이스는 monorepo와 함께 사용해야합니다. 아직 하위 트리에 대한 용도를 찾지 못했습니다.
Tino

@tino Git은 일반적인 코드로 하위 트리를 중복 제거합니다. 확인하기 위해 몇 가지 실험을 실행했습니다. 체크 아웃 된 코드의 경우 ZFS와 같은 것을 실행해야합니다. 그러나 서브 모듈은 다르지 않습니다.
Matthias
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.