헤비급 기업 커뮤니케이션, 구성 관리 및 테스트 요구 사항이 포함 된 Mercurial Repository 구조


16

나는 아직 분산 버전 관리의 타오에서 자신을 다시 교육하기 위해 고군분투하는 또 다른 Subversion 사용자입니다.

Subversion을 사용할 때 저는 프로젝트 마이너 접근 방식에 큰 관심을 보였으며 대부분의 이전 고용주와 함께 리포지토리 지점을 구성했습니다. 다음과 같이 태그 및 트렁크 :

branches-+
         +-personal-+
         |          +-alice-+
         |          |       +-shinyNewFeature
         |          |       +-AUTOMATED-+
         |          |                   +-shinyNewFeature
         |          +-bob-+
         |                +-AUTOMATED-+
         |                            +-bespokeCustomerProject
         +-project-+
                   +-shinyNewFeature
                   +-fixStinkyBug
tags-+
     +-m20110401_releaseCandidate_0_1
     +-m20110505_release_0_1
     +-m20110602_milestone
trunk

실제 소스 트리 자체에서 다음과 같은 구조를 사용합니다.

  (src)-+
        +-developmentAutomation-+
        |                       +-testAutomation
        |                       +-deploymentAutomation
        |                       +-docGeneration
        |                       +-staticAnalysis
        |                       +-systemTest
        |                       +-performanceMeasurement
        |                       +-configurationManagement
        |                       +-utilities
        +-libraries-+
        |           +-log-+
        |           |     +-build
        |           |     +-doc
        |           |     +-test
        |           +-statistics-+
        |           |            +-build
        |           |            +-doc
        |           |            +-test
        |           +-charting-+
        |           |          +-build
        |           |          +-doc
        |           |          +-test
        |           +-distributedComputing-+
        |           |                      +-build
        |           |                      +-doc
        |           |                      +-test
        |           +-widgets-+
        |                     +-build
        |                     +-doc
        |                     +-test
        +-productLines-+
        |              +-flagshipProduct-+
        |              |                 +-coolFeature
        |              |                 +-anotherCoolFeature
        |              |                 +-build
        |              |                 +-doc
        |              |                 +-test
        |              +-coolNewProduct
        +-project-+
                  +-bigImportantCustomer-+
                  |                      +-bespokeProjectOne
                  |                      +-bespokeProjectTwo
                  +-anotherImportantCustomer-+
                                             +-anotherBespokeProject

아이디어는 저장소의 구조를 사용하여 엔지니어링 팀 간의 의사 소통을 구조화하는 데 도움이되었습니다. 비즈니스의 고객 대면 부분과 다양한 기타 이해 관계자 및 도메인 전문가.

재치 : "프로젝트"디렉토리 중 하나에있는 소스 문서는 한 번만 사용됩니다 (그리고 돈을 버는 것). "productLines"디렉토리 중 하나에있는 문서는 해당 특정 라인의 제품이 판매 될 때마다 여러 번 돈을받습니다. "라이브러리"디렉토리 중 하나에있는 문서는이를 사용하는 모든 제품이 판매되는 횟수만큼 돈을 벌 수 있습니다.

비용 상각 개념을 명시 적으로 작성하고 비즈니스 전체에서 소스 문서 재사용에 대한 지원을 구축하는 데 도움이됩니다.

또한 빌드 자동화 도구가 작동 할 수있는 공통 구조가 있음을 의미합니다. (빌드 스크립트는 소스 트리에서 각 구성 요소의 빌드 방법을 지정하는 구성 파일을 찾는 "빌드"폴더를 찾습니다. 문서 생성 및 테스트에서 유사한 프로세스가 발생합니다).

중요하게도 제가 일하는 제품은 일반적으로 성능 측정 및 특성화 테스트를 실행하는 데 오랜 시간이 걸립니다. 20 내지 200 시간; 몇 GB에서 수 TB의 처리 된 테스트 결과 / 중간 데이터 (시간이 지남에 따라 성능 향상을 측정 할 수 있도록 특정 시스템 구성에 저장 및 연결되어야 함)를 생성합니다. 이 문제는 구성 관리를 중요한 고려 사항으로 만들고 일반적으로 성능 측정 및 특성 테스트를 실행하는 데 필요한 계산 리소스가 제한되어 있기 때문에 중앙 집중화에 대한 일부 요구 사항을 부과합니다. (64-128 코어의 작은 클러스터).

하나의 마지막 메모로; 지속적인 통합 시스템은 빌드를 트리거해야한다는 것을 알고 있습니다. 정적 분석; 스모크 테스트 및 단위 테스트는 트렁크가 수정 될 때마다, "태그"분기가 수정 될 때마다, 그리고 "AUTOMATED"분기 분기가 수정 될 때마다 실행됩니다. 이러한 방식으로 개별 개발자는 중요한 기능인 IMHO와 같은 개인 지사와 함께 CI 시스템을 사용할 수 있습니다.

자, 여기 내 질문이 있습니다 : Mercurial을 사용하여 위의 모든 것을 복제하고 가능한 경우 향상시킬 수 있습니까?

--편집하다:

나의 현재 생각은 전체 구조를 정의하기 위해 중앙 Subversion Repository를 사용하는 것이지만 hg를 클라이언트로 사용하여 개발자가 로컬에서 repos를 사용할 수 있도록하는 것입니다.


1
와. 이것에 대한 좋은 대답은 내가 생각하는 아주 긴 에세이가 될 것입니다.
Ed James

핵심 질문은 아마도 코드 병합이 어떻게 그리고 어디에서 진행되는지는 아마도 가장 저항이 적은 경로를 정의 할 것이기 때문이라고 생각합니다. 그렇다면 코드는 어떻게 병합됩니까?
Wyatt Barnett

일반적으로 병합은 개인 브랜치에서 프로젝트 또는 기능 브랜치로 들어온 다음 트렁크로 들어올 수 있습니다. 트렁크에 다시 통합하지 않고 너무 오랫동안 (최대 한 번의 반복) 실행하지는 않았지만 병합에 너무 많은 어려움을 겪지 않았습니다 (Win32에서 TortoiseSVN을 사용하고 있음). 어쨌든 개발 워크 플로가 아닌 사람 관리를 단순화하는 것이 목표 였지만 대부분의 작업은 트렁크에서 수행하는 경향이있었습니다. (독립적으로 활동하는 많은 개발자 한 명이 트렁크에 모든 것을 담아 개발 리더가 무슨 일이 있었는지 쉽게 추적 할 수있게 해주었습니다.)
William Payne

핵심 시스템 중 하나는 CI 시스템에 의해 구동되는 테스트, 특히 시스템 테스트 수준에 크게 의존한다는 것입니다. 이는 서로 다른 개발자들이 서로 방해하지 않는다는 확신을 심어주고 작은 반복적 사고 방식을 장려하기위한 것입니다. 또한 시스템 테스트를 실행하는 데 필요한 계산 작업이 많으면 사람들이 주로 트렁크에서 작업하는 경우 계산 리소스에 대한 경합이 줄어 들었습니다.
William Payne

답변:


10

Spoike의 답변 은 훌륭하지만 의견에 비해 너무 큰 추가 가치가 있다고 생각하는 것이 몇 가지 있습니다.

지점 조직

Mercurial을 사용하면 첫 번째 조직도 전체를 행복하게 무시할 수 있습니다. Spoke가 말했듯이, 각 리포지토리에는 고유 한 태그, 브랜치 (이름 및 익명)가 있으며 비즈니스 요구에 따라 구성 할 수 있습니다.

bespokeProjectTwo특수한 버전의 charting라이브러리 가 필요한 경우 분기 charting하고 새 기능을 추가하여에 사용하십시오 bespokeProjectTwo. 표준 charting라이브러리를 참조하는 다른 프로젝트에서는 새 기능 (및 버그)을 사용하지 않습니다 . 기본 charting라이브러리에 버그가 수정 된 경우 해당 변경 사항을 브랜치에 병합 할 수 있습니다. 다른 프로젝트에도 이러한 기능이 필요한 경우 해당 프로젝트에서 특수 분기 를 사용하도록 하거나 분기를 기본 라인으로 병합하고 분기를 닫을 수 있습니다.

또한 AUTOMATION 지점과 같은 특정 기능을 제공하기 위해 지점 이름을 구성하는 정책을 중단하는 것은 없습니다.

디렉토리 구성

Mercurial에서와 같이 소스 디렉토리를 정확하게 유지할 수없는 이유는 없습니다. 유일한 차이점은 Subversion을 사용하면 단일 모 놀리 식 (src)저장소가 있고 Mercurial을 사용하면 논리적으로 그룹화 된 저장소로 분할하는 것이 좋습니다. 소스 트리 구조에서 다음을 개별 리포지토리로 추출 할 수 있습니다.

src-+
      +-(developmentAutomation)
      +-libraries-+
      |           +-(log)
      |           +-(statistics)
      |           +-(charting)
      |           +-(distributedComputing)
      |           +-(widgets)
      +-productLines-+
      |              +-(flagshipProduct)
      |              +-(coolNewProduct)
      +-project-+
                +-bigImportantCustomer-+
                |                      +-(bespokeProjectOne)
                |                      +-(bespokeProjectTwo)
                +-anotherImportantCustomer-+
                                           +-(anotherBespokeProject)

이를 통해 모든 제품 또는 맞춤형 프로젝트 는 모든 버전의 라이브러리 조합을 사용할 수 있습니다. 제품 또는 프로젝트의 특정 버전에 사용되는 라이브러리를 쉽게 관리 할 수있는 수은 하위 저장소 를 살펴보십시오 .

워크 플로우

Spoike의 제안 된 워크 플로 (개발자가 축복받은 저장소에서 가져 오기, 로컬에서 작업, 끌어 오기 요청을 발행하고 마지막으로 통합자가 변경 사항을 가져 와서 병합)에 대한 대안은 연속 통합 시스템을 중개자로 사용하는 것입니다.

이전과 마찬가지로 개발자는 축복받은 저장소에서 가져와 로컬에서 작업하지만 완료되면 축복받은 저장소에서 다시 끌어 와서 축복받지 못한 저장소로 넘어갑니다. 축복되지 않은 리포지토리에 대한 변경 사항은 (수동 또는 자동으로) 검토되고 승인 된 경우에만 축복 된 리포지토리로 이동됩니다.

이는 통합자가 변경 만 수락하거나 거부하고 병합은 수행하지 않음을 의미합니다. 내 경험에 따르면 코드를 작성한 개발자가 다른 사람보다 병합을 수행하는 것이 거의 항상 좋습니다.

수 은서에서 제안한대로 후크 를 사용하여이 절차를 자동화 할 수 있습니다.

누군가가 변경 세트를 모든 사람이 가져 오는 서버로 푸시하면 서버는 변경 세트를 영구적으로 승인하기 전에 변경 세트를 테스트하고 테스트 스위트를 통과하지 못하면 거부합니다. 사람들이이 필터링 서버에서 변경 사항 만 가져 오면 사람들이 가져 오는 모든 변경 사항이 자동으로 검사되도록하는 역할을합니다.

다른 문제

테스트 데이터를 수은 하위 리포지토리 에 넣음으로써 대규모 테스트 데이터 세트의 문제를 해결할 수도 있습니다 . 이렇게하면 테스트 데이터가 개정 관리되는 동안 코드 리포지토리가 테스트 데이터로 부풀어 오르는 것을 방지 할 수 있습니다.


또 다른 우수하고 유익한 답변. 감사합니다.
윌리엄 페인

RE : 지점 조직. 첫 번째 조직도는 행복하게 무시할 수 있다는 데 동의합니다. 어쨌든 워크 플로우를 잘 전달하지 못했기 때문에 규칙을 강화하는 것 이상으로 실제 유틸리티를 제공하지 않았습니다. 그러나 (단순한) 워크 플로를 강력하게 전달하고 빈번한 커밋을 장려하는 것으로 대체하고 싶습니다. 아마도 주요 "트렁크 / 개발"브랜치를 "매일"이라고 부를 수 있을까요?
윌리엄 페인

RE : 디렉토리 조직. 소스 디렉토리 구성을 잠재적 인 의사 소통 수단으로 사용하고있었습니다. 코드의 구성에 (그리고 전체적으로 비즈니스에 대한) 암시 적 구조를 부과합니다. Mercurial은 매우 유연한 방식으로 사용되는 경향이 있음을 이해하기 시작했습니다. 그러나 나는 문서가 워크 스테이션과 네트워크 스토리지 영역에서 구성되는 방식에 구조를 부여함으로써 사람들이 비즈니스에 대해 생각하는 방식으로 구조를 강요 할 수있는 유연성을 제한하고 싶습니다. (기술보다 많은 회사 통신)
William Payne

RE : 워크 플로우. 가장 간단한 워크 플로는 "일일"리포지토리에서 가져와 로컬에서 작업 한 다음 (자주) "일일"리포지토리로 다시 돌아가서 정적 분석, 연기 테스트 및 CI 시스템을 통한 회귀 테스트를 시작하는 것입니다. 내가 알고있는 한 메인 리포지토리가 "파손"되어서 빨리 다시 고쳐지는 것이 기쁘다. 사실, 나는 "매일"저장소에 커밋하고 컴파일하고 빌드 할 수 있는 유일한 방법으로 커밋을 자주하고 테스트 범위를 넓히는 것을 고려하고있다. (IMHO는 격리 작업 능력보다 훨씬 중요합니다).
윌리엄 페인

@WilliamPayne-감사합니다. Mercurial은 융통성이 있지만 적절한 리포지토리, 브랜치 및 후크를 사용하면 조직 또는 리포지토리 수준에서 원하는 제한을 적용 할 수 있습니다. 개인적으로, 나는 단순히 조직적 통제와 몇 가지 CI 후크로 시작하여 필요에 따라 미래에 그러한 통제를 확장 할 것입니다. 또한, 하위의 repos의 현명한 사용은, 예를 들어, 그대로 사람들함으로써 예를 들어, 서버에서 동일한 구조에 로컬로 물건을 확인 장려 수 productLines또는 bigImportantCustomer슈퍼의 repos한다.
Mark Booth

9

좋아, 간단하게 대답하려고합니다.

당신이 알아야 할 것

알아야 할 첫 번째 사항 : Mercurial은 분산 버전 제어이며 아래에 나열된 몇 가지 속성을 알고 있습니다.

  • 소스는 하나의 저장소에서 제공되며 해당 저장소를 복제 할 수 있습니다. 복제 된 모든 리포지토리는 동기화를 통해 코드를 공유 할 수 있습니다 (풀 및 푸시 명령 사용, 액세스 제한 가능).
  • 코드 사본이있는 모든 사용자에게는 저장소 복제본이 있습니다. 분기하려는 경우 로컬 복제본에서이를 수행 할 수 있습니다. 즉, 모든 사용자가 어떻게 분기해야하는지 정리할 필요가 없습니다. 그들은 스스로 할 수 있습니다.
  • 태그는 커밋 (git의 하드 태그와 동일)에 의해 수은으로 생성됩니다. 즉, 저장소 구조 내에 태그를위한 디렉토리가 필요하지 않습니다.
  • 사람들이 DVCS (github 및 bitbucket에서 사용)에서 작업하는 일반적인 모델은 반 중앙화를 수행하는 것입니다.

    각 사용자에게는 공용 저장소 (일부 공유 또는 보안 서버)와 개인 저장소 (자체 워크 스테이션)가 있습니다. 둘 다 통합 자의 "축복 된"저장소의 복제본입니다. 코드를 게시 할 준비가되었다고 느낄 때마다 변경 사항을 공용 리포지토리로 푸시 할 수 있습니다. 그러면 통합자는 코드를 "축복 된"리포지토리로 가져올 사용자를 선택할 수 있습니다.

    통합자가 일부 사용자 코드를 쉽게 병합 할 수없는 경우 변경 사항이 거부되고 해당 사용자는 저장소를 업데이트하고 병합을 수정해야합니다. 병합해야하는 코드가 적기 때문에 자주 병합하는 것이 어렵지 않으며 일반적으로 사용자는 병합에 어떤 문제가 있는지 알아야합니다.

프로젝트 당 리포지토리 설정

따라서 일반적인 설정은 각 프로젝트마다 다음이 있습니다.

  • 통합자가 담당하는 공용 읽기 전용 저장소입니다. "축복"입니다.

    즉, 모든 사용자는 콘텐츠를 가져 오거나 가져올 수 있지만 콘텐츠를 푸시 할 수는 없습니다.

  • 각 사용자는 자신의 공용 저장소 복제본을 가질 수 있습니다.

    공유 드라이브에 넣을 때 가장 쉬운 설정 (비트 버킷과 같은 호스팅을 고려할 수도 있음). 통합자는 사용자로부터 풀 요청을 수신하고 이러한 리포지토리에서 새 코드를 가져옵니다. 장애없이 병합을 수행하면 읽기 전용 리포지토리에 저장됩니다. 그렇지 않은 경우 사용자는 로컬로 병합 및 병합하여 발생하는 병합 충돌을 수정하라는 요청을받습니다.

  • 각 사용자는 자신의 개인 저장소 복제본을 가질 수 있습니다.

    모범 사례는 퍼블릭 클론에서 가져 오는 것이지만 퍼블릭 또는 통합 업체에서 가져 오는 것은 중요하지 않습니다. 모든 커밋은 고유하게 식별 가능하므로 커밋을 병합하면 공개적으로 가져 오는 것을 잊어 버린 것을 고치기가 비교적 쉽습니다 (개인에서 공개로 변경 사항을 푸시하면 통합 자의 변경 사항도 자동으로 가져옵니다).

소스 코드 조직

프로젝트 소스 자체를 배열하는 방법과 마찬가지로 생각해야합니다. 아티팩트를 소스 제어해야하는 경우 소스 제어에 두십시오. 개인적으로 바이너리 또는 로그 파일과 같은 빌드 또는 런타임에 의해 생성 된 아티팩트 (이러한 아티팩트의 병합 충돌 위험이 높기 때문에)를 확인하는 아이디어는 마음에 들지 않습니다.

개발자가 쉽게 작업을 수행 할 수 있고 릴리스 또는 라이브 / 프로덕션 환경 (예 : 앱 / 웹 서버 설정)을 구성하지 않는 한 구성을 체크인 할 수도 있습니다. 이로 인해 개발자가 코드를 체크 아웃 한 후 5 분 이내에 시작하는 데 방해가되는 경우 리팩터링해야한다는 개념으로 이어집니다. 또 다른 요구 사항은 개발자가 릴리스 또는 라이브 / 프로덕션 환경을 망쳐 놓는 것이 어렵다는 것입니다.

코드의 일부 버전에 연결해야하는 테스트 데이터가 있다고 언급했습니다. Mercurial 및 Git과 같은 DVCS 시스템은 거대한 데이터를 체크인 할 때 속도가 느려지는 경향이 있기 때문에 이것은 조금 까다 롭습니다. 내 경험상 5GB의 바이너리 파일 후에는 참을 수 없습니다 (마일리지가 다를 수 있으므로 어떻게 작동하는지 테스트해야합니다). 그러나 생성 된 데이터를 자체 저장소에 넣고 테스트 시스템에서 체크인 할 때 적절하게 태그를 지정하거나 동일한 메타 데이터 목적으로 텍스트 파일을 작성하는 것이 좋습니다.

이 모든 것이 이해되기를 바랍니다. 자세한 내용을 놓쳤거나 추가 설명이 필요한 경우 아래에 의견을 남겨주세요.


몇 가지 매우 유용한 포인트로 매우 좋은 응답을 얻으려면 +1하십시오. 귀하의 답변의 첫 번째 섹션에 대한 답변으로, 각 사용자가 자신의 공용 저장소를 갖는 중요성을 파악하지 못했습니다. 피어 투 피어 워크 플로를 구성하는 방법에 대해 더 많이 생각해야 할 수도 있습니다.
윌리엄 페인

대답의 두 번째 섹션에 대한 응답으로 전체 조직을위한 단일 저장소를 갖는 요점은 작업 구조 방식에 대한 공유 된 정신 이미지를 작성하고 가능한 구성 요소를 쉽게 찾을 수 있도록하는 것입니다. 재사용 (바자회보다는 성당이 매우 많지만 그것이 내가 일하는 환경입니다). DCVS로 동일한 구조적 조직 구성 (파일링 시스템)을 달성하는 방법을 알고 싶습니다.
William Payne

귀하의 답변의 세 번째 섹션에 대한 답변으로 : 나는 소스 제어 시스템이 소스 문서를위한 것이며 파생 된 아티팩트가 거기에 속하지 않는다는 것에 전적으로 동의합니다. 또한 VCS에 설명의 큰 이진을 저장하는 것은 비현실적이라는 데 동의합니다. 그러나 동의 한 네트워크 위치에 정의 된 이름으로 큰 바이너리를 저장하고 VCS 내에서 참조 할 수 있다고 생각합니다. 예를 들어, 빌드 환경을 명명 된 VM 디스크 이미지로 저장하고 다양한 빌드 스크립트에서 참조 할 수 있습니다. (예 : build_env_A에서 빌드) 테스트 데이터에 대해서도 마찬가지입니다.
William Payne

과거에는 네트워크 드라이브에서 디렉토리의 계층 구조를 사용했습니다. 여기서 디렉토리 이름은 하위 버전 개정 번호 + 분기 위치의 해시에서 파생되어 중간 파일을 묶고 결과를 특정 개정에 연결합니다. 즉, 파생 된 파일을 버전 관리에 저장할 필요없이 추적 성이 있습니다.
William Payne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.