태그 보관물: branching

branching

git에서 12 개의 라이브러리에 대해 버전 관리를 수행하는 방법은 모두 병렬로 작동했습니다. 가지고 있습니다. 새로운

우리는 프로젝트를 수행하고 있지만 프로젝트간에 많은 코드를 재사용하고 공통 코드를 포함하는 많은 라이브러리를 가지고 있습니다. 새로운 프로젝트를 구현함에 따라 일반적인 코드를 제외하고 라이브러리에 넣는 더 많은 방법을 찾습니다. 라이브러리는 서로 의존하고 프로젝트는 라이브러리에 의존합니다. 각 프로젝트 및 해당 프로젝트에 사용 된 모든 라이브러리는 참조하는 모든 라이브러리의 동일한 버전을 사용해야합니다. 소프트웨어를 출시하면 몇 년 동안, 때로는 수십 년 동안 버그를 수정하고 새로운 기능을 추가해야 할 것입니다. 우리는 약 12 ​​개의 라이브러리를 보유하고 있으며, 변경 사항은 종종 2 개 이상의 프로세스를 삭감했으며, 여러 팀이 여러 프로젝트를 동시에 진행하여 이러한 라이브러리를 모두 동시에 변경합니다.

우리는 최근에 git으로 전환하고 각 라이브러리와 각 프로젝트에 대한 리포지토리를 설정했습니다. 우리는 숨김을 공통 저장소로 사용하고, 기능 분기에서 새로운 작업을 수행 한 다음 풀 요청을 작성하고 검토 후에 만 ​​병합합니다.

프로젝트에서 다루어야 할 많은 문제는 여러 라이브러리와 프로젝트의 특정 코드를 변경해야합니다. 여기에는 종종 라이브러리 인터페이스의 변경이 포함되며 일부는 호환되지 않습니다. (이것이 비린 것처럼 들린다면 : 우리는 하드웨어와 인터페이스하고 일반 인터페이스 뒤에 특정 하드웨어를 숨 깁니다. 거의 다른 공급 업체의 하드웨어를 통합 할 때마다 현재 인터페이스가 예상하지 못한 경우가 발생하여이를 개선해야합니다.) 예, 프로젝트를 상상 P1라이브러리를 사용하여 L1, L2하고 L3. L1또한 사용 L2하고 L3, 그리고 L2용도 L3뿐만 아니라. 종속성 그래프는 다음과 같습니다.

   <-------L1<--+
P1 <----+  ^    |
   <-+  |  |    |
     |  +--L2   |
     |     ^    |
     |     |    |
     +-----L3---+

이제이 프로젝트를위한 기능의 변화를 필요로 상상 P1하고 L3있는의 인터페이스를 변경 L3. 이제 프로젝트를 추가 P2하고 P3이러한 라이브러리를 참조 믹스,에. 모든 인터페이스를 새로운 인터페이스로 전환하고 모든 테스트를 실행하고 새로운 소프트웨어를 배포 할 여유가 없습니다. 대체 대안은 무엇입니까?

  1. 새로운 인터페이스를 구현 L3
  2. 풀 요청을 L3하고 검토를 기다립니다
  3. 변경 사항을 병합
  4. 의 새로운 릴리스를 만들 L3
  5. 새 릴리스를 P1참조 하여 기능에 대한 작업을 시작한 L3다음 P1기능 분기 에 기능을 구현하십시오.
  6. 풀 요청을하고이를 검토하고 병합합니다.

(방금 전환 L1하고 L2새로운 릴리스 로 전환하는 것을 잊어 버렸습니다 .이 부분을 고수 할 곳조차 알지 못합니다. 왜냐하면 병렬로 수행해야하기 때문입니다 P1…)

이는 지루하고 오류가 발생하기 쉽고이 기능을 구현하는 데 오랜 시간이 걸리므로 독립적 인 검토가 필요하며 (검토하기가 훨씬 더 어려워 짐) 전혀 확장되지 않으며 비즈니스를 중단시킬 수 있습니다. 우리는 아무 일도하지 않습니다.

그러나 너무 많은 오버 헤드없이 새로운 프로젝트에서 새로운 기능을 구현할 수있는 프로세스를 만들기 위해 분기 및 태깅을 어떻게 사용합니까?



답변

여기에 명백한 것을 언급하지만 언급 할 가치가 있습니다.

일반적으로 git repos는 독립적 인 경향이 있기 때문에 lib / 프로젝트마다 조정됩니다. 프로젝트를 업데이트하고 나머지는 신경 쓰지 않습니다. 그것에 따라 다른 프로젝트는 적합하다고 생각 될 때마다 단순히 lib를 업데이트합니다.

그러나 사례는 상관 된 구성 요소에 따라 크게 달라 지므로 일반적으로 하나의 기능이 많은 구성 요소에 영향을줍니다. 그리고 전체는 번들로 패키지되어야합니다. 기능 / 변경 / 버그를 구현하려면 종종 여러 라이브러리 / 프로젝트를 한 번에 적용해야하므로 모두 동일한 리포지토리에 배치하는 것이 좋습니다.

이것에 대한 장점 / 단점이 있습니다.

장점 :

  • Tracability : 지점은이 기능 / 버그와 관련된 모든 프로젝트 / lib에서 변경된 모든 것을 보여줍니다.
  • 번들링 : 태그를 선택하기 만하면 모든 소스를 얻을 수 있습니다.

단점 :

  • 합병 : … 한 번의 프로젝트로 이미 어려움을 겪는 경우가 있습니다. 서로 다른 팀이 공유 지점에서 작업하면서 영향을 미칠 준비를하십시오.
  • 위험한 “oops”요소 : 한 직원이 실수를해서 저장소를 엉망으로 만들면 모든 프로젝트와 팀에 영향을 줄 수 있습니다 .

가격이 그만한 가치가 있는지 아는 것은 당신에게 달려 있습니다.

편집하다:

다음과 같이 작동합니다.

  • 기능 X를 구현해야합니다
  • 지점 만들기 feature_x
  • 모든 개발자는이 브랜치에서 작업하고 패러렐 리 작업을 할 것입니다. 아마도 프로젝트 / lib와 관련된 전용 디렉토리에서
  • 완료되면 검토하고 테스트하고 패키지화하십시오.
  • 그것은 마스터에 다시 … 그리고 이것은 그동안 때문에 힘든 부분 일 수있다 병합 feature_y하고 feature_z도 추가되었을 수 있습니다. “팀 간”병합이됩니다. 이것이 심각한 단점입니다.

단지 기록을 위해 : 이것은 대부분의 경우 나쁜 생각이며 병합 단점은 일반적으로 종속성 관리 / 적절한 기능 추적을 통해 얻는 것보다 높기 때문에 신중하게 수행해야한다고 생각합니다.


답변

찾고있는 솔루션은 git 서브 모듈과 함께 사용되는 종속성 관리 도구입니다.

다음과 같은 도구 :

  • 메이븐
  • 개미
  • 작곡가

이러한 도구를 사용하여 프로젝트의 종속성을 정의 할 수 있습니다.

서브 모듈이 최소 버전 > 2.xx 이상이어야 하거나 호환 가능한 버전 범위를 나타내는 = 2.2. * 또는 특정 버전 <2.2.3 미만을 나타낼 수 있습니다 .

패키지 중 하나의 새 버전을 릴리스 할 때마다 버전 번호로 태그를 지정할 수 있습니다. 이렇게하면 특정 버전의 코드를 다른 모든 프로젝트로 가져올 수 있습니다


답변

서브 모듈

한 의견에서 제안한 것처럼 하위 모듈git 시도해보십시오 .

프로젝트를 할 때 P1세 가지 서브 모듈을 의미 L1, L2그리고 L3, 실제로 세 저장소에서 특정 커밋에 대한 참조를 저장 : 사람들이있는 작업 각 라이브러리의 버전 이 프로젝트 .

따라서 여러 프로젝트가 여러 하위 모듈과 함께 작동 할 수 있습니다 . 프로젝트 가 새 버전을 사용하는 동안 P1이전 버전의 라이브러리 L1를 참조 할 수 있습니다 P2.

새 버전을 제공하면 어떻게됩니까 L3?

  • 새로운 인터페이스를 구현 L3
  • 커밋, 테스트 , 풀 요청, 검토, 병합, … (이를 피할 수 없음)
  • 보장 L2과 함께 작품을 L3커밋, …
  • L1새로운 작업을 보장 L2
  • P1모든 라이브러리의 새 버전에서 작동 하는지 확인 하십시오.
    • 내부 P1의의 로컬 작업 복사본 L1, L2그리고 L3, 당신이 관심있는 변화를 fetche.
    • git add L1 L2 L3모듈에 대한 새로운 참조를 커밋하기 위해 커밋 변경
    • 에 대한 풀 요청 P1, 테스트, 검토, 풀 요청, 병합 …

방법론

이는 지루하고 오류가 발생하기 쉽고이 기능을 구현하는 데 오랜 시간이 걸리므로 독립적 인 검토가 필요하며 (검토하기가 훨씬 더 어려워 짐) 전혀 확장되지 않으며 비즈니스를 중단시킬 수 있습니다. 우리는 아무 일도하지 않습니다.

예, 다음을 변경하기 때문에 독립적 인 검토 가 필요합니다 .

  • 도서관
  • 그것에 의존하는 라이브러리
  • 여러 라이브러리에 의존하는 프로젝트

당신은 쓰레기를 제공하기 때문에 사업을 중단 하시겠습니까? (실제로는 아닐 수도 있습니다). 그렇다면 테스트를 수행하고 변경 사항을 검토해야합니다.

적절한 git 툴을 사용하면 gitk각 프로젝트에서 사용하는 라이브러리 버전을 쉽게 확인할 수 있으며 필요에 따라 독립적으로 업데이트 할 수 있습니다. 서브 모듈은 상황에 적합하며 프로세스 속도를 늦추지 않습니다.

이 과정의 일부 를 자동화 하는 방법을 찾을 수도 있지만 위의 단계 대부분에는 인간의 두뇌가 필요합니다. 시간을 줄이는 가장 효과적인 방법은 라이브러리와 프로젝트를 쉽게 발전시키는 것입니다. 코드베이스가 새로운 요구 사항을 정상적으로 처리 할 수 ​​있다면 코드 검토가 더 간단 해지고 시간이 거의 걸리지 않습니다.

(편집)
당신을 도울 수있는 또 다른 한가지는 그룹 관련 코드 리뷰이다. 모든 변경 사항을 커밋하고 변경 사항을 사용하는 모든 라이브러리 및 프로젝트에 변경 사항을 전파 할 때까지 풀 요청을 합산하기 전에 (또는 변경하기 전에) 기다립니다. 전체 종속성 체인에 대해 더 큰 검토를 마칩니다. 각 지역 변경이 작은 경우 시간을 절약하는 데 도움이 될 수 있습니다.


답변

그래서 내가 이해하는 것은 P1의 경우 L3 인터페이스를 변경하고 싶지만 L3 인터페이스에 의존하는 다른 P2 및 P3이 즉시 변경되기를 원한다는 것입니다. 이것은 이전 버전과의 호환성의 일반적인 경우입니다. 이 이전 버전과의 호환성 유지 에 대한 좋은 기사가 있습니다.

이 문제를 해결할 수있는 몇 가지 방법이 있습니다.

  • 이전 인터페이스를 확장 할 수있을 때마다 새 인터페이스를 작성해야합니다.

또는

  • 얼마 후 이전 인터페이스를 폐기하려면 여러 버전의 인터페이스를 사용할 수 있으며 모든 종속 프로젝트가 이동하면 이전 인터페이스를 제거합니다.

답변

내가 당신의 문제를 올바르게 받고 있다면 :

  • 4 개의 상호 관련 모듈 (P1 및 L1 ~ L3)이 있습니다.
  • L1에서 L3에 영향을 미치는 P1을 변경해야합니다.
  • 4 개를 모두 함께 변경해야하는 경우 프로세스 실패로 계산됩니다.
  • 1 씩 1 씩 변경해야하는 경우 프로세스 실패로 계산됩니다.
  • 변경해야하는 청크를 미리 식별해야하는 경우 프로세스 실패로 계산됩니다.

따라서 목표는 P1과 L1을 한 번에 수행 한 다음 한 달 후에 L2와 L3을 다른 곳에서 수행하는 것입니다.

자바 세계에서 이것은 사소한 것이며 아마도 작동하는 기본 방법입니다.

  • 분기를 적절하게 사용하지 않고 모든 것이 하나의 저장소에 들어갑니다.
  • 모듈은 모두 동일한 디렉토리 트리에 있다는 사실이 아니라 버전 번호를 기반으로 maven에 의해 컴파일되고 서로 링크됩니다.

따라서 디스크의 다른 디렉토리에있는 P1의 사본에 대해 컴파일하는 경우 컴파일되지 않는 L3 용 로컬 디스크의 코드를 컴파일 할 수 있습니다. 운 좋게도 그렇게하지 않습니다. 소스 코드가 아닌 컴파일 된 jar 파일에 대해 이야기를 컴파일 / 링크하기 때문에 Java가이를 간단하게 수행 할 수 있습니다.

C / C ++ 세계 에서이 문제에 대한 기존의 널리 사용되는 솔루션을 알지 못하며 언어를 바꾸고 싶지 않다고 생각합니다. 그러나 동등한 일을하는 파일을 만들면 쉽게 해킹 될 수 있습니다.

  • 버전 번호가 포함 된 알려진 디렉토리에 설치된 라이브러리 + 헤더
  • 적절한 버전 번호를 위해 모듈 당 디렉토리로의 컴파일러 경로 변경

maven에서 C / C ++ 지원을 사용할 수도 있지만 대부분의 C 개발자는 당신이 그렇게하면 이상하게 당신을 볼 것입니다 …


답변

간단한 해결책이 있습니다 : 전체 저장소에서 릴리스 브랜치를 잘라 내고 모든 수정 사항을 활발하게 출시 된 모든 릴리스로 병합하십시오 (git에서 명확한 경우가 가능해야 함).

모든 대안은 시간이 지남에 따라 프로젝트가 성장함에 따라 끔찍한 혼란을 초래할 것입니다.


답변