소개 en ko

버전 관리 시스템의 저장소 관리

2012-10-26

요즘 버전 관리 시스템을 사용하지 않는 곳을 찾아 보기 어려울 정도로 버전 관리 시스템은 이제 개발에 필수 요수가 되었다. 이 시스템을 사용하기 전엔 도대체 어떻게 개발을 했나 싶을 정도다.

이제는 사용 요령이나 유용한 팁들이 많아 시스템 사용에 큰 어려움이 없이 잘 쓰지만 정리 차원에서 저장소 관리 가이드라인을 적어본다. 어디까지나 개인적인 프로젝트 경험에 의한 내용이니 적용에는 응용이 필요하다. 저장소와 관련된 가장 기본적인 가이드라인은 다음과 같다.

  • 소스 저장소에 개발 / 빌드에 필요한 모든 것을 넣어둔다.
  • 소스 저장소와 리소스 저장소를 분리한다.
  • 사용 / 관리 정책을 세워야 하고 관심을 기울여 줘야 한다.

좀 더 자세히 살펴보자.

소스 저장소에 개발 / 빌드에 필요한 모든 것을 넣어둔다.

소스 저장소에는 팀에서 개발하는 소스에 더해 빌드에 필요한 라이브러리와 툴이 포함되어 있어야 한다. 만약 개발중인 프로그램이 expat, boost, directx sdk 를 필요로 한다면 이 라이브러리들을 모두 넣어둔다. 이렇게 하면 프로그래머가 일일이 라이브러리를 구해야 하는 수고도 줄고 버전이 불일치 하는 일도 없고 언젠가 있을 라이브러리 업데이트도 자연스럽게 되어 좋다. 

다만 배포되는 라이브러리에 포함되어 있는 모든 파일을 넣지 않도록 조심해야 한다. 라이브러리에 포함되어 있는 튜토리얼, 샘플, 문서, 다른 플랫폼용 파일, 안쓰는 빌드 구성용 lib, pdb 파일 등은 불필요하게 저장소 용량만 차지한다. (예를 들어 boost 1.51 의 경우 빌드 없는 구성으로 총 용량이 334MB 인데 그 중 빌드에 필요한 boost 폴더는 86MB 로 25% 에 불과하다.) 필요한 파일만 등록하고 나중에 해당 라이브러리를 업데이트 할 수 있으니 어디서 구할 수 있는지, 중요 파일을 어떻게 추렸는지 기록해두거나 스크립트로 만들어 저장소에 넣어두면 도움이 된다. 상용 라이브러리라 보관이 꼭 필요하다 싶으면 패키지를 압축해서 올리는 것도 요령이다. 버전 관리 시스템은 많은 파일, 큰 용량 처리에 특화되어 있지 않다.

외부 라이브러리를 svn 의 external link 등으로 연결하는 방법은 효과적인 방법이다. 하지만 내부 프로젝트에서는 추천하지 않는다. 외부 네트워크에서 격리된 곳에서 빌드를 해야할 수도 있고 네트워크 장애로 설치에 어려움을 겪을 수도 있기 때문이다.

외부 라이브러리에 더해 빌드에 관여하는 툴도 저장소에 넣어둔다. 예를 들면 빌드 솔루션, 코드 생성기, 어셈블리 컴파일러 등을 저장소에 같이 넣어둔다. 단 비주얼 스튜디오 등 배보다 배꼽이 커지는 경우도 있으니 득실을 따져보고 넣는다.

소스 저장소와 리소스 저장소를 분리한다.

기본적으로 1개의 프로젝트에 1개의 저장소가 원칙이다. 하지만 리소스가 소스 보다 열 배 이상 용량이 크다면 분리하는 편이 관리와 사용에 유리하다.

소스는 아무리 커져봐야 스냅샷 기준으로 1GB 이상을 넘기가 어렵다. (팀에 코딩 머신이 있어) 매일 10% 분량이 새롭게 수정된다고 해도 저장소 용량이 1TB 까지 가는데 대충 30년이 걸린다. 게다가 텍스트 데이터는 보통 delta 압축이 되어서 실제 용량보다 훨씬 적게 늘어난다.

리소스의 경우 요즘 온라인 게임은 10GB 정도는 기본이고 그 이상도 많다. (역시 팀에 리소스 머신이 있어) 매일 10% 분량이 새롭게 수정된다고 하면 저장소 용량이 1TB 까지 가는데 대충 3년이 걸린다. 3년이 어떤 조직에는 충분히 길 수도 있겠지만 보통 개발 기간 + 라이브 기간 이렇게 합치고 보면 3년은 프로젝트 일생의 유년기 쯤에 해당한다.

문제는 저장소 용량이 커지면 일단 하드도 부족하고 버전 관리 시스템도 느려지고 백업도 어려워지고 이래저래 골치가 아파진다. 이럴 때 보통 최신 스냅샷 + 최근 이력 정보만 남기고 데이터를 지워버리는 저장소 세탁을 하게 된다. 그런데 소스랑 리소스가 같은 저장소에 있으면 소스 이력도 세탁이 되어버린다. 그러면 과거 로그, blame 을 할 수 없게 된다. 특히 몇 년쯤 된 코드의 버그를 추적하다가 로그가 없는 것을 발견하는 것만큼 당황스러운 것도 없다.

백업도 비슷한 이슈가 있다. 백업 공간이 충분하다면 그냥 저장소 내용 전부를 덤프해버리면 되겠지만 백업 용량이 부족하면 스냅샷만 남겨야 한다. 소스의 경우 과거 이력을 잘 보존하는 것이 중요하기 때문에 스냅샷만 남기는 것만으로는 부족하다. 만약 소스와 리소스의 저장소가 분리되어 있다면 ‘소스는 저장소 전부. 리소스는 스냅샷만.’ 과 같이 스토리지 용량에 맞춰 융통성 있게 정책을 세울 수 있다.

사소하지만 권한 설정도 소스, 리소스 저장소가 분리되어 있다면 원천적으로 분리되니 도움이 된다.

소스랑 리소스가 분리되어서 서로 버전 매칭하기가 atomic 하지 않을 수 있는데 일단 대강 시간으로 맞출 수 있고, 좀 더 타이트 하게 하고 싶다면 tag, branch 등의 기능을 활용해 해결할 수 있다.

사용 / 관리 정책을 세워야 하고 관심을 기울여 줘야 한다.

저장소는 쉽게 오염된다. thumbs.db, project.ncb, 누구누구받아.zip 등 용량만 크고 올라갈 필요가 있는 것들이 올라간다. 이런 문제는 커밋 단계에 적당한 후킹 핸들러를 붙여 애초에 이런 파일이 커밋되지 않도록 시스템화 하는 것이 좋다. 비슷하게 커밋 로그를 강제하는 용도로도 사용할 수 있다.

저장 솔루션을 배포 시스템으로 사용하는 것은 추천하지 않는다. 예를 들어 프로그램 실행파일을 팀에서 공유하기 위해 배포 시스템에 올리는 것은 빠르게 저장소 공간을 소모하는 가장 쉬운 방법이다. 예를 들어 빌드로 생성되는 파일 용량이 50MB 라고 하고 매일 10번 정도 빌드가 이루어지면 365 일 열심히 일하고 나면 저장소 공간을 180GB 차지하게 된다. 가끔 있는 작은 크기의 파일이라면 모를까 일반적인 배포는 ftp, 공유 폴더, torrent 등 파일 공유를 위한 솔루션을 쓰는 것이 좋다.

로그를 남기는 방식, 커밋 주기, 단위 등은 팀에서 사용 방식을 결정하고 잘 지켜지도록 보조 시스템을 붙이고 모니터링 해야 한다. 장기적으로 잘 관리된 저장소와 친절한 로그는 개발 단계와 라이브 시기 모두에게 큰 힘이 된다. 저장소 용량 증감, 버전 관리 시스템 건강 상태를 주기 적으로 살펴야 한다. 그리고 불필요한 파일이 올라가는지, 저장소 사용 정책에 위배되는 것이 있는지 살피는 것도 중요하다. 버전 관리 시스템은 개발 시스템중 가장 중요한 시스템임을 잊어서는 안된다.

정리

버전 관리 시스템의 가장 기본인 저장소 관리에 대해한 가이드라인을 정리했다. 이걸 잘 하고 나면 이제 그 위에 폴더 구성, 브랜치 전략을 고민할 수 있다.