버전 관리 시스템

CVS(Concurrent Versions System)

예전부터 Unix 계열에서는 RCS(Revision Control System) 라는 command 방식의 버전 관리 소프트웨어가 많이 사용되었다.

RCS는 로컬 시스템의 파일로 동작하는 소프트웨어로 중앙 집중적 버전 관리 시스템이 아니었으므로 협업을 지원하지 않았고 팀이 일하기는 적합하지 않았다.

이에 RCS 기반의 CVS(Concurrent Versions System) 라는 client-server 방식의 중앙집중식 소프트웨어가 개발되었고 오픈 소스 프로젝트에서는 유일한 대안이었으므로 한동안 널리 사용되었다.

CVS 는 파일의 변경과 이력을 중앙 서버에 보관하며 client 는 특정 시점의 프로젝트를 개인 개발 환경으로 가져(check-out)오므로 변경을 중앙 서버에 보내면 중앙 서버는 이를 병합하거나 충돌이 발생하면 거절하는 방식으로 동작하여  팀원간의 협업이 가능했고 CVS 는 오픈소스 프로젝트에 오랫동안 널리 사용되었다.

 

CVS로 진행되는 프로젝트가 많아질수록 CVS 의 단점도 많이 발견이 되었고 이로 인해 CVS 를 대체할 오픈 소스 버전 관리 시스템의 필요성이 대두되기 시작하였다.

 

CVS 단점

파일이나 디렉터리의 이동, 이름 변경에 대해 버전 관리가 되지 않음

프로젝트를 진행하다보면 refactoring이나 기타 여러 가지 이유로 파일이나 디렉터리를 옮기거나 이름을 변경할 수 있다. CVS 는 파일이나 디렉터리에 대해 버전 관리를 하지 않으므로 이럴 경우 변경 내역을 추적하지 못한다.

 

commit 이 원자적이 아님

사용자가 변경 내역을 커밋할 경우 특정 파일이 충돌하거나 네트워크가 끊어지거나 등의 이유로 커밋이 실패할 수 있다. CVS 는 커밋을 DBMS 의 트랜잭션처럼 전체 성공 혹은 전체 실패처럼 처리하지 못한다. 그러므로 10개의 파일에 대해 커밋요청을 했어도 어떤 파일은 커밋이 되고 어떤 파일은 커밋이 되지 않을수가 있다. 이는 매우 심각한 문제로 커밋이 실패시 실패한 파일만 따로 찾아서 커밋을 재시도해야 한다. 

 

tagging(꼬리표), branch 작업이 매우 오래걸리고 용량을 많이 차지함

개발을 하다보면 분기를 하거나 특정 리비전에 대해 꼬리표를 붙여야 하는 경우가 자주 발생한다. CVS 는 꼬리표나 분기 작업이 발생할 경우 해당 프로젝트의 전체 파일을 별도의 영역에 복사를 하여 큰 프로젝트일 경우 꼬리표를 붙이는 시간도 오래 걸리고 용량도 많이 차지했다.

 

revision 이 change-set 이 아니고 개별 파일임

하나의 커밋이라도 변경된 파일은 여러 개인 경우가 일반적이다. 예로 사용자 등록 기능에 추가로 전화번호와 이메일을 받기로 했다. 이럴 경우 Data Access Object(UserDao.java), DB Mapper(UserMapper.java)와 Controller (UserService.java)등 3개의 파일이 변경될 수 있다.  변경 내역을 커밋할 경우 버전관리 사용자들은 "사용자 등록시 추가 정보 입력" 이라는 변경 묶음(changeset)으로 해당 커밋을 관리하고 싶어하나 CVS 는 UserDao.java, UserMapper.java, UserService.java 각각의 파일마다 별도의 revision 을 부여하여 관리한다. 부여되는 revision 은 해당 파일의 직전 revision 이후(1.1 이었을 경우 1.2)이며 특정 파일은 많이, 특정 파일은 적게 커밋되었을 경우 revision 이 다 다르므로 프로젝트의 특정 시점의 변경 내역을 묶어서 확인하기가 어려웠다. 또 현재 소스 파일의 revision 이 무엇인지 확인하려면 별도의 CVS 명령어를 통해야 했다. 그래서 CVS 사용자들은 소스 파일에 특별한 keyword 를 붙여서 관리하는 경향이 있었다. 예로 소스 파일의 주석 부분에 다음과 같이 $Author$ 과 $Id$ 키워드를 붙이면 commit 시 해당 내용이 다음과 같이 변경된다.

/*
 * $Author$
 * $Id$
*/

 

$Id$ 에는 파일의 revision 과 변경일, 변경자가 포함된다.

/*
 * $Author: lesstif $
 * $Id: a.c,v 1.1 2014/03/16 15:01:13 lesstif Exp $
 */

 

이런 문제를 해결하기 위해 CVS 사용자들은 특정 시점에 revision 을 의미있게 만들기 위해 tagging 기능을 이용하여 다음과 같이 revision 에 꼬리표를 달아줘야 했다. 

cvs tag -b Tagname

   

 

revision 에 꼬리표를 자주 달아줘야 하므로써 추가로 발생하는 문제는 위에 언급했듯이 CVS 에서 꼬리표 붙이기와 가지치기 작업은 매우 비싼 작업이라 시간이 오래 걸리고 디스크의 용량도 많이 차지한다는 점이다.

 

서브버전(Subversion - svn) 

서브버전은 중앙 집중형 버전 관리 시스템으로 CVS 와 아키텍처, 명령어, 옵션등을 유사하게 하여 사용자들의 편의를 도모하는 한편 위에서 열거한 단점들을 해결하는 것을 주요 목표로 하여 2000년 부터 개발되었다.

콜랩이라는 소프트웨어 개발에 필요한 협업과 관리 솔루션을 개발하는 회사가 주축이 되어 개발을 진행하였으며 2001년부터는 어느 정도 기능이 개발되어 서브버전 프로젝트의 버전관리 시스템으로 사용되었다. 2004년에는 버전 1.0 이 발표되었고 CVS 의 대체품으로 자리 잡기 시작하였다.

서브버전의 특징

서브버전의 목적이 CVS 의 단점 개선이므로 CVS 항목에서 언급한 단점들이 모두 다 개선이 되었다.

 

파일이나 디렉터리의 이동, 이름 변경에 대해 버전 관리 가능

서버버전은 디렉터리나 파일을 옮기거나 이름을 변경한 내역을 추적할 수 있으며 심볼릭 링크된 파일도 이력 관리를 한다.

 

원자적인 commit 

서브버전은 커밋을 트랜잭션으로 처리하므로 특정 소스가 충돌이 나서 커밋이 실패하거나 네트워크가 끊어지거나 할 경우 모든 파일의 커밋이 실패하며 성공시에는 전체 성공으로 처리된다.

 

tagging(꼬리표), branch 작업이 빠르게 처리

서브버전은 내부적으로 tag와 branch 을 복사가 아닌 symbolic link 로  처리하여 CVS 에 비해 매우 빠르게 수행할 수 있다.

 

change-set 기반의 리비전

서브버전은 다음 그림처럼 해당 리비전은 모든 변경된 파일/디렉토리의 묶음이므로 리비전 기반으로 변경 이력을 관리하기 용이하다.