버전 관리 저장소를 어떻게 구성합니까?


108

첫째, 저는 이것에 대해 알고 있습니다. 사내 소프트웨어 프로젝트를 위해 Subversion 저장소를 어떻게 구성 하시겠습니까? 다음으로, 실제 질문 : 우리 팀은 리포지토리를 재구성하고 있으며 구성 방법에 대한 힌트를 찾고 있습니다. (이 경우 SVN). 여기에 우리가 생각 해낸 것이 있습니다. 하나의 저장소, 여러 프로젝트 및 여러 svn : externals 상호 참조가 있습니다.

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

어휘를 정리하려면 솔루션은 단일 제품을 의미하고 Project는 Visual Studio 프로젝트 (단일 .dll 또는 단일 .exe가 생성됨)를 의미합니다.

이것이 우리가 저장소를 레이아웃하는 방법입니다. 주요 문제는 여러 솔루션이 있지만 솔루션간에 프로젝트를 공유하고자한다는 것입니다. 우리는 공유 된 프로젝트를 자체 솔루션으로 옮기는 데 아무런 의미가 없다고 생각했고 대신 svn : externals를 사용하여 솔루션간에 프로젝트를 공유하기로 결정했습니다. 또한 공통 도구 및 타사 라이브러리 세트를 저장소의 한 위치에 유지하고 svn : externals를 사용하여 각 솔루션에서 참조합니다.

이 레이아웃에 대해 어떻게 생각하십니까? 특히 svn : externals 사용에 대해. 이상적인 솔루션은 아니지만 모든 장단점을 고려할 때 우리가 생각할 수있는 최선의 방법입니다. 어떻게 하시겠습니까?


"thrash"를 의미합니까? 아니면 "쓰레기"?
ssc

답변:


92

아래의 권장 사항을 따르면 (나는 몇 년 동안) 다음을 수행 할 수 있습니다.

-프로젝트 루트 디렉토리의 구조를 아래로 유지하는 한 각 프로젝트를 소스 제어의 어느 곳에 나 배치

-위험을 최소화하고 준비를 최소화하면서 모든 기계에서 각 프로젝트를 구축합니다.

-바이너리 종속성 (로컬 "라이브러리"및 "출력"디렉토리)에 액세스 할 수있는 한 각 프로젝트를 완전히 독립형으로 빌드합니다.

-독립적이기 때문에 모든 프로젝트 조합을 구축하고 작업

-독립적이기 때문에 단일 프로젝트의 여러 사본 / 버전을 빌드하고 작업합니다.

-생성 된 파일 또는 라이브러리로 소스 제어 저장소를 복잡하게 만들지 마십시오.

나는 추천한다 (여기에 쇠고기가있다) :

  1. .DLL, .EXE 또는 .JAR (Visual Studio의 기본값)과 같은 단일 기본 결과물을 생성하도록 각 프로젝트를 정의합니다.

  2. 각 프로젝트를 단일 루트가있는 디렉토리 트리로 구성합니다.

  3. IDE에 대한 종속성없이 처음부터 빌드 할 루트 디렉터리의 각 프로젝트에 대한 자동화 된 빌드 스크립트를 만듭니다 (하지만 가능한 경우 IDE에서 빌드되는 것을 막지 마십시오).

  4. Windows의 .NET 프로젝트 용 nAnt 또는 OS, 대상 플랫폼 등에 따라 유사한 것을 고려하십시오.

  5. 모든 프로젝트 빌드 스크립트가 단일 로컬 공유 "라이브러리"디렉토리에서 외부 (타사) 종속성을 참조하도록합니다. 이러한 모든 바이너리는 버전 : %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. 모든 프로젝트 빌드 스크립트가 기본 결과물을 단일 로컬 공유 "출력"디렉토리 ( %DirOutputRoot%\ProjectA-9.10.11.12.dll,)에 게시하도록합니다 %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. 모든 프로젝트 빌드 스크립트가 "라이브러리"및 "출력"디렉토리에있는 구성 가능하고 완전한 버전의 절대 경로 (위 참조)를 통해 종속성을 참조하고 다른 곳은 없습니다.

  8. 프로젝트가 다른 프로젝트 나 그 내용을 직접 참조하게해서는 안됩니다. "출력"디렉토리 (위 참조)의 기본 결과물에 대한 참조 만 허용하십시오.

  9. 모든 프로젝트 빌드 스크립트가 구성 가능하고 완전한 버전의 절대 경로 ( %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. 모든 프로젝트 빌드 스크립트 참조 소스 콘텐츠를 프로젝트 루트 디렉터리에 상대적인 절대 경로 로 만듭니다 : ${project.base.dir}/src, ${project.base.dir}/tst(구문은 빌드 도구에 따라 다름).

  11. 항상 구성 가능한 절대 경로 (구성 가능한 변수로 지정된 디렉터리에 루트가 지정됨)를 통해 모든 파일 또는 디렉터리를 참조하는 프로젝트 빌드 스크립트가 필요합니다. ${project.base.dir}/some/dirs또는 ${env.Variable}/other/dir.

  12. 결코 같은 상대 경로로 참조 무엇이든 프로젝트 빌드 스크립트를 허용하지 .\some\dirs\here..\some\more\dirs, 항상 절대 경로를 사용합니다.

  13. 프로젝트 빌드 스크립트가 C:\some\dirs\here또는 같은 구성 가능한 루트 디렉터리가없는 절대 경로를 사용하여 어떤 것도 참조하도록 허용하지 마십시오 \\server\share\more\stuff\there.

  14. 프로젝트 빌드 스크립트에서 참조하는 구성 가능한 각 루트 디렉터리에 대해 해당 참조에 사용할 환경 변수를 정의합니다.

  15. 각 컴퓨터를 구성하기 위해 만들어야하는 환경 변수의 수를 최소화하십시오.

  16. 각 시스템에서 필요한 환경 변수를 정의하는 쉘 스크립트를 작성하십시오. 이는 해당 시스템에 고유하며 해당하는 경우 해당 사용자에 고유 할 수 있습니다.

  17. 시스템 특정 구성 셸 스크립트를 소스 제어에 넣지 마십시오. 대신 각 프로젝트에 대해 프로젝트 루트 디렉터리의 스크립트 복사본을 템플릿으로 커밋합니다.

  18. 각 프로젝트 빌드 스크립트가 각 환경 변수를 확인하고 정의되지 않은 경우 의미있는 메시지와 함께 중단해야합니다.

  19. 각 프로젝트 빌드 스크립트가 종속 빌드 도구 실행 파일, 외부 라이브러리 파일 및 종속 프로젝트 제공 파일을 확인하고 해당 파일이없는 경우 의미있는 메시지와 함께 중단해야합니다.

  20. 프로젝트 결과물, 생성 된 소스, 생성 된 문서 등이없는 생성 된 파일을 소스 제어에 커밋하려는 유혹에 저항하십시오.

  21. IDE를 사용하는 경우 가능한 모든 프로젝트 제어 파일을 생성하고 소스 제어에 커밋하지 마십시오 (Visual Studio 프로젝트 파일 포함).

  22. 개발자 워크 스테이션 및 빌드 머신에 복사 / 설치할 모든 외부 라이브러리 및 도구의 공식 사본으로 서버를 구축합니다. 소스 제어 저장소와 함께 백업하십시오.

  23. 개발 도구가 전혀없는 지속적인 통합 서버 (빌드 머신)를 구축합니다.

  24. Ivy (Ant와 함께 사용)와 같은 외부 라이브러리 및 결과물을 관리하기위한 도구를 고려하십시오.

  25. Maven을 사용하지 마십시오. 처음에는 당신을 행복하게하고 결국에는 울게 만들 것입니다.

이 중 어느 것도 Subversion에만 국한되지 않으며 대부분은 모든 OS, 하드웨어, 플랫폼, 언어 등을 대상으로하는 프로젝트에 일반적입니다. 저는 약간의 OS 및 도구 별 구문을 사용했지만 설명 용으로 만 사용했습니다. -나는 당신이 당신의 OS 또는 선택한 도구로 번역 할 것이라고 믿습니다.

Visual Studio 솔루션에 대한 추가 참고 사항 : 소스 제어에 넣지 마십시오! 이 접근 방식을 사용하면 전혀 필요하지 않거나 생성 할 수 있습니다 (Visual Studio 프로젝트 파일처럼). 그러나 솔루션 파일은 개별 개발자가 적절하다고 생각하는대로 만들고 사용하도록 남겨 두는 것이 가장 좋습니다 (하지만 소스 제어에 체크인하지 않음). Rob.sln현재 프로젝트를 참조 하는 파일을 워크 스테이션에 보관합니다 . 내 프로젝트는 모두 독립형이므로 원하는대로 프로젝트를 추가 / 제거 할 수 있습니다 (즉, 프로젝트 기반 종속성 참조가 없음을 의미 함).

Subversion 외부 (또는 다른 도구에서 유사한)를 사용하지 마십시오. 안티 패턴이므로 불필요합니다.

지속적 통합을 구현하거나 릴리스 프로세스를 자동화하려는 경우에도이를위한 스크립트를 작성하십시오. 프로젝트 이름 (저장소에 나열된대로) 및 태그 이름의 매개 변수를 가져오고, 구성 가능한 루트 디렉토리 내에 임시 디렉토리를 만들고, 주어진 프로젝트 이름과 태그 이름에 대한 소스를 확인하는 단일 셸 스크립트를 만듭니다. Subversion의 경우 적절한 URL) 해당 임시 디렉토리에 대한 테스트를 실행하고 결과물을 패키징하는 클린 빌드를 수행합니다. 이 쉘 스크립트는 모든 프로젝트에서 작동해야하며 "빌드 도구"프로젝트의 일부로 소스 제어에 체크인해야합니다. 지속적 통합 서버는이 스크립트를 프로젝트 빌드의 기초로 사용하거나 제공 할 수도 있습니다 (하지만 여전히 자체적으로 원할 수 있음).

@VonC : 빌드 스크립트가 깨졌을 때 불에 탔을 때 "ant-abcdjar"이 아닌 "ant.jar"로 작업하고 싶지 않습니다. 무의식적으로 Ant의 호환되지 않는 버전으로 실행했기 때문입니다. 이것은 특히 Ant 1.6.5와 1.7.0 사이에서 일반적입니다. 일반화하면 항상 플랫폼 (Java ABCD) 및 빌드 도구 (Ant EFGH)를 포함하여 사용중인 모든 구성 요소의 특정 버전을 알고 싶습니다. 그렇지 않으면 결국 버그가 발생하고 첫 번째 BIG 문제는 다양한 구성 요소의 버전을 추적하는 것입니다. 그 문제를 미리 해결하는 것이 더 낫습니다.


6
비판 할 점이 너무 많아요 ... 이것이 보편적 인 조리법 이 아니라고 말하면 충분합니다 ! 특히 포인트 5와 6은 프로젝트가 크고 제 3 자 수가 중요 할 때 매우 잘못되었습니다. 'ant1.5.4.jar'또는 제품 myProduct가 아닌 'ant.jar'로 항상 작업하고 싶습니다. 1.3.exe가 아닌 .exe
VonC

5
그래도 유효하고 주제에 대한 방대한 경험을 높이 평가하는 다른 많은 포인트에 +1합니다.
VonC

3
나는 당신의 비판을 듣고 상호 작용하고 싶습니다. 각 지점과 모든 지점은 대규모 프로젝트에서 나쁜 경험을 해결하는 데 기반을두고 있습니다. 예를 들어, Xxx.jar 및 Yyy.exe로 표시되는 버전의 문제를 해결합니다. 특히 참조되는 복사본이 말 그대로 12 개일 때 그렇습니다.
Rob Williams

2
@Rob- '외부 안티 패턴'테마에 대해 자세히 설명해 주시겠습니까? : 여기 질문으로 제기 한 stackoverflow.com/questions/338824/...

3
@Makis : # 12가 # 13과 균형을 이루지 않으면 맞습니다. 각 프로젝트 내의 파일 또는 디렉토리에 대한 모든 참조는 구성 가능한 루트 디렉토리 변수 (예 : Ant의 $ {basedir} /sub/dir/file.txt)로 시작하는 절대 경로를 통해 이루어져야합니다.
Rob Williams


3

게시 한 내용과 거의 일치하도록 설정했습니다. 우리는 일반적인 형식을 사용합니다.

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

나는 당신의 예만큼 완전하지는 않지만 그것은 우리에게 잘 작동하고 우리가 일을 분리 할 수있게합니다. 각 사용자가 "쓰레시"폴더를 가지고 있다는 생각도 마음에 듭니다. 현재 이러한 유형의 프로젝트는 소스 제어로 끝나지 않으며 항상 그래야한다고 느꼈습니다.


3
버전간에 변경되지 않는 문서를위한 별도의 디렉토리가 있다는 사실에 놀랐습니다. 이러한 제품을 작업하는 즐거움을 경험 한 적이 없습니다! :)
ARKBAN

1

왜 모든 것이 하나의 저장소에 있습니까? 각 프로젝트에 대해 별도의 저장소를 두지 않는 이유는 무엇입니까 ( "솔루션"을 의미)?

글쎄, 적어도 나는 저장소 당 하나의 프로젝트 접근 방식을 사용했습니다. 귀하의 저장소 구조가 나에게 지나치게 복잡해 보입니다.

그리고이 하나의 큰 저장소에 얼마나 많은 프로젝트를 넣을 계획입니까? 2? 삼? 10? 100?

한 프로젝트의 개발을 취소하면 어떻게하나요? 저장소 트리에서 삭제하면 나중에 찾기가 어려워집니다. 아니면 영원히 놔두시겠습니까? 아니면 한 프로젝트를 다른 서버로 완전히 옮기고 싶습니까?

그리고 모든 버전 번호의 엉망은 어떻습니까? 한 프로젝트의 버전 번호는 2, 10, 11과 같고 다른 프로젝트는 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

내가 어리석은 것 같지만 저장소 당 하나의 프로젝트를 좋아합니다.


1. 하나의 저장소는 회사 정책이며 변경할 수 없습니다. 2. 약 12 ​​개의 솔루션이 있습니다. 3. 버전 번호로 개정을 의미합니까? 그것은 우리에게 문제가 아닙니다.
Krzysztof Kozmic

좋은 프로젝트 구조는 특히 하나 이상의 리포지토리와 관련하여 나머지 리포지토리 구조를 인식하지 못합니다. 자세한 답변을 참조하십시오.
Rob Williams

1
많은 (대부분?) 소스 제어 도구에 여러 저장소가 있으면 보안을 구현할 때와 같이 비용이 많이들 수 있습니다.
Rob Williams

0

제안 된 구조의 주된 단점은 공유 프로젝트가 추가 된 첫 번째 솔루션으로 만 버전이 지정된다는 것입니다 (svn : externals가 제가 상상하는 것보다 더 멋지지 않는 한). 예를 들어 Solution2의 첫 번째 릴리스에 대한 분기를 만들 때 Project1은 Solution1에 있으므로 분기되지 않습니다. 나중에 해당 분기에서 빌드해야하는 경우 (QFE 릴리스) 분기 당시의 Project1 버전이 아닌 최신 버전의 Project1을 사용합니다.

이러한 이유로, 하나 (당신의 구조에 따라서 최상위 디렉토리) 이상의 공유 솔루션 공유 프로젝트를 넣어 다음의 각 릴리스를 분기하는 것이 유리할 수있다 있는 솔루션입니다.


당신은 어느 정도 옳습니다. 하지만 원하는 경우 참조를 업데이트 할 수 있습니다. 공유 프로젝트를 자체 솔루션에 넣는 것도 의미가 없습니다. 나는 svn : externals보다 더 나은 해결책을 찾고 싶지만 모든 곳에서.
Krzysztof Kozmic

"원하는 경우 참조 업데이트"란 무엇을 의미합니까? Solution1을 분기하지 않고 Project1 (Solution2를 분기 할 때마다 바람직한 것 같음)을 분기 할 수있는 방법을 알 수 없습니다.
C. Dragon 76

특히 Visual Studio 솔루션을 소스 제어에 넣지 않으려면 자세한 답변을 참조하십시오.
Rob Williams

0

상대 경로 문제를 추가하려면 :

문제인지 잘 모르겠습니다.
"Solution1"이라는 디렉토리 아래에서 Solution1 / trunk를 확인하고 Solution2도 마찬가지입니다. 실제로 분기를 나타내는 '디렉토리'의 목표 는 작업 공간으로 가져온 후에는 보이지 않는 것 입니다. 따라서 'Solution1'(실제로는 'Solution1 / trunk')과 'Solution2'(Solution2 / trunk)간에 상대 경로가 가능합니다.


이것은 매우 쉽게 깨질 것입니다. 자세한 답변을 참조하십시오.
Rob Williams

0

RE : 상대 경로 및 공유 파일 문제-

이것은 svn 특정인 것 같지만 문제가되지 않습니다. 다른 한 사람이 이미 별도의 리포지토리를 언급했으며 다른 임의의 프로젝트를 참조하는 다른 프로젝트가있는 경우 생각할 수있는 최상의 솔루션 일 것입니다. 공유 파일이없는 경우 OP 솔루션 (다른 많은 솔루션과 마찬가지로)이 제대로 작동합니다.

우리는 여전히이 문제를 해결하고 있으며 존재하지 않거나 열악한 버전 제어를 설정 한 이후로 지금 해결해야 할 3 가지 노력 (다른 클라이언트)이 있습니다.


프로젝트가 다른 프로젝트를 참조하게하면 종속성이 기하 급수적으로 증가하고 참조가 매우 취약하기 때문에 유지 관리에 악몽이 생깁니다. 자세한 답변을 참조하십시오.
Rob Williams

0

비슷한 레이아웃이지만 트렁크, 가지, 태그가 맨 위에 있습니다. 따라서 : / trunk / main, / trunk / utils, / branches / release / 등.

많은 번역 도구가 기본 교과서 SVN 레이아웃에서 가장 잘 작동했기 때문에 다른 버전 제어 시스템을 사용해보고 싶을 때 정말 편리했습니다.

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