자식 리포지토리에서 단일 프로젝트 또는 여러 프로젝트 중에서 선택 하시겠습니까?


223

git대부분의 프로젝트를 모듈화 한 환경 에서는 저장소 당 하나의 프로젝트 또는 저장소 디자인 문제당 여러 프로젝트에 직면하고 있습니다. 모듈화 된 프로젝트를 생각해 보자.

myProject/
   +-- gui
   +-- core
   +-- api
   +-- implA
   +-- implB

오늘 우리는 저장소 당 하나의 프로젝트를 가지고 있습니다. 그것은 자유를 준다

  • release 개별 구성 요소
  • tag 개별 구성 요소

그러나 branch종종 분기 api는에 동일한 분기 가 필요 core하고 다른 구성 요소가 필요 하기 때문에 구성 요소에 번거 롭습니다 .

release개별 구성 요소를 원할 경우 리포지토리 디자인 당 여러 프로젝트 를 활용하여 비슷한 유연성을 얻을 수 있습니다 .

어떤 경험이 있으며 이러한 문제를 어떻게 / 왜 해결 했습니까?


1
나는 지금 매우 비슷한 문제가 있습니다. 다른 버전의 프로젝트를 출시해야하므로 서로 다른 저장소에 있어야합니다. 이것은 관리해야 할 악몽입니다. 하위 디렉토리 만 분기하는 방법이 있다면 좋을 것입니다.
Andrew T Finnell

1
각 모듈에는 별도의 버전 번호가 있어야합니다. 그리고 우리는을 사용 git-describe합니다.
linquize



Bit ( bitsrc.io )와 Lerna ( github.com/lerna/lerna )가 언급되지 않은 것을보고 놀랐습니다 ! 자세한 내용은 여기를 참조하십시오 : hackernoon.com/…
Yoni

답변:


199

one project per repository위에서 설명한 방식 에는 세 가지 주요 단점이 있습니다 . 이들은 실제로 별개의 프로젝트라면 사실이 아니지만, 소리가 하나에서 다른 것으로 바뀌면 종종 다른 것으로 변경해야하기 때문에 이러한 문제를 과장 할 수 있습니다.

  1. 버그가 도입 된 시점을 발견하기가 더 어렵습니다. git bisect리포지토리를 하위 리포지토리로 분할 할 때 와 같은 도구 를 사용하기가 훨씬 어려워집니다. 그것은이다 가능한 그것은 훨씬 어렵이 위기의 시대에 버그 사냥을 의미만큼이나 쉬운 일이 아니다.
  2. 기능의 전체 기록을 추적하는 것은 훨씬 어렵습니다. 히스토리 트래버 싱 명령 git log은 손상된 저장소 구조를 사용하여 히스토리를 의미있게 출력하지 않습니다. 하위 모듈 이나 하위 트리 또는 다른 스크립트 가능한 메소드를 통해 유용한 출력을 얻을 수 있지만 관심있는 모든 커밋을 입력 tig --grep=<caseID>하거나 git log --grep=<caseID>스캔 하는 것과 동일하지 않습니다 . 당신의 역사는 이해하기 어려워 져서 필요할 때 덜 유용하게 만듭니다.
  3. 새로운 개발자는 코딩을 시작하기 전에 Version Control의 구조를 배우는 데 더 많은 시간을 보냅니다. 모든 새로운 작업에는 픽업 절차가 필요하지만 프로젝트 저장소가 손상되면 코드 아키텍처와 함께 VC 구조도 선택해야합니다. 내 경험상, 이것은 단일 리포지토리를 사용하는 전통적인 중앙 상점에서 온 개발자에게 익숙하지 않습니다.

결국, 기회 비용 계산입니다. 한 전 고용주에서 우리는 1 차 신청서를 35 개의 다른 하위 저장소로 나누었습니다. 그 외에도 복잡한 스크립트를 사용하여 기록을 검색하고 상태 (예 : 생산 대 개발 지점)가 동일한 지 확인하고 개별적으로 또는 대량으로 배포했습니다.

너무 많았습니다. 적어도 우리에게는 너무 많습니다. 관리 오버 헤드로 인해 기능이 덜 민첩 해지고 배포가 훨씬 어려워지고 새로운 개발자를 가르치는 데 너무 많은 시간이 걸리고 결국에는 저장소를 파괴 한 이유를 간신히 기억할 수있었습니다. 아름다운 봄날, 나는 EC2에서 오후 10 시간의 클러스터 컴퓨팅 시간을 보냈습니다. 수십 번의 git filter-branch전화로 repos를 다시 정리했습니다 . 우리는 결코 뒤돌아 보지 않았습니다.


7
비 제한적인 점으로, 리포지토리 관리자로서 노트북을 20 시간 동안 할 수 없었던 일을 2 시간 안에 할 수있는 시스템에서 시간을 점심보다 저렴하게 구매하는 것보다 즐거운 일이 거의 없습니다. 때로는 인터넷을 정말 좋아합니다.
Christopher

2
개별 프로젝트를 어떻게 개별 릴리스로 릴리스 하시겠습니까? 아니면 그렇게 할 필요가 없습니까? 그것이 내가 가진 문제입니다. 당신이 프로젝트 (A)의 V1을 작성해야하고, 경우와 프로젝트 B의 V2
앤드류 T Finnell

5
은 "REPO 당 하나 개의 프로젝트"와 "복수의 repos"간 이동을 위해 자식-하위 트리 (잘 설명 고려 stackoverflow.com/a/17864475/15585 )
deterb

1
나는 일반적인 사용 사례를 위해 이것을 자동화하는 스크립트를 작성했다 : github.com/Oakleon/git-join-repos
chrishiestand

"VC 구조"란 무엇입니까?
Robert Harvey

60

Christopher 는 리포지토리 당 하나의 프로젝트 모델의 단점을 열거하는 데 매우 효과적이었습니다. 다중 저장소 접근 방식을 고려할 수있는 몇 가지 이유에 대해 이야기하고 싶습니다. 내가 작업 한 많은 환경에서 다중 저장소 접근 방식은 합리적인 해결책 이었지만 저장소 수와 절단 위치를 결정하는 것이 항상 쉬운 것은 아닙니다.

현재는 10 년이 넘는 역사를 가진 거대한 단일 리포지토리 CVS 리포지토리를 여러 git 리포지토리로 마이그레이션했습니다. 초기 결정 이후, 다른 팀의 조치를 통해 저장소 수가 증가하여 최적의 것보다 많은 것으로 생각합니다. 일부 신입 사원은 리포지토리 병합을 제안했지만 이에 반대했습니다. Wayland 프로젝트는 비슷한 경험을 가지고 있습니다. 내가 최근에 본 대화에서 한 시점에서 200 개가 넘는 git 저장소가 있었으며 그 결과 리드가 사과했습니다. 그들의 웹 사이트를 보면 , 나는 지금 그들이 5에 있다는 것을 알았습니다. 리포지토리 가입 및 분할은 관리 가능한 작업이므로 관찰해야합니다 (이유 내에서).

언제 여러 저장소를 원하십니까?

  1. 단일 저장소가 너무 커서 효율적이지 않습니다.
  2. 리포지토리가 느슨하게 연결되어 있거나 분리되어 있습니다.
  3. 개발자는 일반적으로 개발할 리포지토리 중 하나 또는 일부만 필요합니다.
  4. 일반적으로 리포지토리를 독립적으로 개발하고 가끔씩 만 동기화하면됩니다.
  5. 더 많은 모듈성을 장려하고 싶습니다.
  6. 다른 팀은 다른 리포지토리에서 작업합니다.

포인트 2와 3은 포인트 1이 유지되는 경우에만 중요합니다. 리포지토리를 분할함으로써 오프 사이트 동료가 겪는 지연을 크게 줄이고 디스크 소비를 줄이며 네트워크 트래픽을 개선했습니다.

4와 5가 더 미묘합니다. 클라이언트와 서버의 저장소를 분할하면 클라이언트와 서버 코드 간의 변경 사항을 조정하는 데 비용이 많이 듭니다. 이것은 둘 사이의 분리 된 인터페이스를 장려한다는 점에서 긍정적일 수 있습니다.

다중 리포지토리 프로젝트의 단점이 있더라도 웨이 랜드와 부스트가 떠 오릅니다. 모범 사례에 대한 합의가 아직 발전하지 않았다고 생각하며 일부 판단이 필요합니다. 여러 리포지토리 (git-subtree, git-submodule 및 기타) 작업을위한 도구는 계속 개발되고 실험 중입니다. 나의 조언은 실험적이고 실용적입니다.


7
이 답변은 "리포지토리 가입 및 분할은 관리 가능한 작업"이라는 주장을 뒷받침하는 참조를 통해 더욱 유용 할 것입니다.
와일드 카드

3
다중 저장소는 공유 코드를 변경하기가 어렵 기 때문에 모듈화에 대해서도 작동합니다. 교차 리포지토리 종속성으로 인해 통합이 더욱 어려워지고 코드를 더 쉽게 깨뜨릴 수 있습니다 (이를 확인하는 데 유용한 툴링이 있더라도) 리포지토리 외부 코드를 손상시키는 위협은 리팩토링 인터페이스를 방해하여 작업을 수행하는 가장 강력한 도구 중 하나입니다 더 모듈.
커트 J. 샘슨

MicroServices 및 DDD 디자인에 대한 모든 것이 여기에 있습니다. 공유 코드를 최소화해야합니다.
Arwin

49

우리는 GitHub의를 사용하여, 우리는 실제로 하나 개의 repo에서 여러 프로젝트를 가지고 있지만 있도록 해당 프로젝트가 / 모듈이 제대로 모듈화되어 (우리가 -api 및 -core 규칙을 사용 + 메이븐 + 정적 및 런타임 확인하고 심지어 부팅 일일은 OSGi에 갈 수도) .

무엇을 절약합니까? 여러 프로젝트에서 작은 것을 변경하는 경우 여러 풀 요청을 발행 할 필요가 없습니다. 이슈 및 위키는 중앙 집중식으로 유지됩니다.

우리는 여전히 각 모듈 / 프로젝트를 적절한 독립 프로젝트로 취급하고 CI 서버 등에서 개별적으로 빌드하고 통합합니다.


1
매우 흥미로운. 나는 이것이 github의 일반적인 모델이라고 생각합니다. 개별 컴포넌트 릴리스에 직면 한 경우 submodules전체 저장소 를 사용 하거나 릴리스 / 태그를 지정합니까?
Johan Sjöberg

서브 모듈은 필요하지만 지금은 부모에서 다운 버전입니다.
Martijn Verburg

현재 고용주에서 비슷한 전략을 사용하고 프로젝트의 최신 커밋에 대한 메타 데이터를 다양한 아티팩트 파일 (예 : 결과 git log -1 -- <project_dir>)에 패키지합니다 . 정말 대단합니다. 이 답변은 더 많은 투표를 받아야합니다.
Christopher

22

나에게 하나 이상의 저장소를 사용하는 주된 차이점은 다음 질문에 대한 답변입니다.

  • 동일한 팀에서 개발 한 여러 부품이 동일한 릴리스주기, 동일한 고객입니까? 그런 다음 하나의 저장소를 분할 할 이유가 적습니다.
  • 여러 부분 서로 크게 의존하고 있습니까? 따라서 모델, 컨트롤러 및 UI를 분리하는 것은 (서로 다른 부분 일지라도) 서로에 대한 의존성이 높기 때문에 그다지 의미가 없습니다. 그러나 2 개의 부품이 작은 의존성을 가지고 있다면 몇 년마다 바뀌는 안정적인 인터페이스로 구현되므로 2 개의 부품을 2 개의 리포지토리로 나누는 것이 좋습니다.

예를 들어, Subversion 저장소의 "품질"을 확인하는 작은 응용 프로그램 (클라이언트 전용)이 있습니다. 커맨드 라인에서 시작할 수 있고 Java 6과 잘 작동하는 핵심 구현이 있습니다. 그러나 Java 8을 Java 8의 일부로 사용하는 UI를 구현하기 시작했습니다. 일정이 다른 두 번째 저장소 (두 번째 빌드 프로세스 포함) ...

나는 위의 답변을 좋아하지만 (투표를했지만) 이것이 전체적인 이야기는 아니라고 생각합니다. 그래서 리포지토리 분할에 대한 인수도 추가하고 싶었습니다. 따라서 실제 답변 (분할시)은 중간에있을 수 있습니다 ...



0

귀하의 예에서, 저장소는 상호 의존성 측면에서 설정되어야합니다. MicroServices 및 Domain Driven Design 설계에 대한 모든 추론이 여기에 적용됩니다. 일부 경우 중복 코드가 허용되고 인터페이스 작업이 가능하며 실제로 필요한 경우가 아니라면 호환성을 유지하지 마십시오.

이제 UI는 백엔드와 독립적이어야합니다. 따라서 UI 프로젝트 저장소에는 일반적으로 UI 코드와 클라이언트 컨트롤러가 포함되어야합니다. 클라이언트 컨트롤러는 추상적 인 방식으로 서비스 컨트롤러와 연결됩니다. 서비스와 별도로 버전이 지정된 서비스 클라이언트 / api 추상화를 사용하므로 클라이언트를 손상시키지 않고 서비스를 업데이트 할 수 있습니다 (여러 개의 다른 클라이언트가있을 수 있음).

따라서 서비스 자체는 자체 저장소 여야합니다. 필자의 관점에서 볼 때이 서비스는 단일 지점 비즈니스 로직의 래퍼 일뿐입니다. 따라서 비즈니스 로직은 일반적으로이를 호스팅하는 서비스 기술과 분리되어야합니다. 반면에 리포지토리 구현은 일반적으로 비즈니스 로직에 매우 밀접하게 연결되어 있으므로 동일한 리포지토리에 통합 될 수 있습니다. 그러나 거기에서도 마일리지가 다를 수 있습니다.

물론 모든 UI를 백엔드와 동일한 소스에서 호스팅 할 수 있고 백엔드 서비스는 일반적으로 동일한 클라이언트 만 사용하는 기술 측면에서 많이 변경되지 않거나 다중 스택을 지원하지 않는 간단한 프로젝트는 더 많은 혜택을 누릴 수 있습니다. 긴밀하게 통합 된 리포지토리.

이 경우 하나의 저장소에 전체 수직을 두는 것이 좋을 것입니다. 기능 도메인이 자체 저장소에 올바르게 독립되어 있는지 확인하는 데 집중하십시오. 그러면 더 작은 리포지토리의 장점이 가장 많고 그렇지 않으면 오버 헤드가 거의 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.