메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

CVS 소개

한빛미디어

|

2002-01-30

|

by HANBIT

14,780

저자: Jennifer Vesperman, 역 한동훈

이것은 CVS에 대한 두 편의 글 중에 첫번째에 해당합니다. 이 글은 이미 시스템에 CVS를 사용하고 있는 사람들을 위한 것입니다. 이 글에서 저자는 체크 아웃, 업데이트, 추가, 병합과 다른 함수들을 설명합니다. 두 번째 글은 이 달 말에 나올 것이고, 처음으로 CVS를 구축하는 사람들을 위해서 어떻게 CVS 레포지토리를 생성하고 관리하는 가를 보여줄 것입니다. -- 편집자

CVS(Concurrent Versioning System, 버전관리 시스템)는 개발 과정 중에 사용하는 파일들을 관리하기 위한 시스템이다. 이러한 버전 관리 시스템은 큰 프로그래밍 프로젝트에서 일상적으로 사용되고 있으며, 시스템 관리자, 테크니컬 라이터, 그리고 파일 관리가 필요한 사람에게도 유용하다.

CVS는 중앙 레포지토리에 파일을 저장하고, 모든 사용자가 파일에 엑세스할 수 있도록 설정한다(표준 UNIX 권한을 사용한다). “체크 아웃”은 개발을 위해서 파일을 복사하는 것이며, “commit”은 변경된 사항을 레포지토리에 다시 저장하는 것이다. 사용자가 파일을 레포지토리에서 가져오고, 레포지토리에 다시 넣을 때도 검색하며, 한 사람의 작업을 다른 사람이 덮어쓰지 못하도록 한다.

역주 참고 : 레포지토리(repository) : 번역하면 ‘저장소’에 해당하는 뜻을 갖고 있으며, 사용자가 신경쓰지 않고 어떤 종류의 파일이든지 넣고, 뺄 수 있는 가상의 ‘창고’와 같은 개념으로 많이 쓰인다.

이 시스템은 파일의 히스토리(history)를 보존하기 때문에, 여러분이 몇 달 전에 폐기처분했던 기능을 사장이 원할 때 매우 유용하다. 또한 레포지토리를 백업하는 것만으로 프로젝트에 대한 백업으로 충분하다(레포지토리에 필요한 모든 파일을 집어넣는 경우).

CVS는 일반적으로 프로젝트 관리를 도와줄 뿐만 아니라 개인 파일 관리를 위해서도 사용된다.

전형적인 사용자

CVS Pocket Reference
CVS는 혼자 개발하든지 팀에 속해 있든지 간에 개발자를 위해서 고안되었다. 개인사용자라면 집, 사무실, 고객 사이트, 어디에 있든지 간에 디스크를 들고 돌아다니지 않아도 되는 레포지토리를 제공한다. CVS는 또한 데이터 손상에 대한 롤백을 할 수 있으며, 버전 관리를 제공한다. 누가 파일의 몇 번째 라인을 변경했는지 기록을 유지할 수 있으며, 다른 사용자의 작업을 덮어쓰는 것을 방지할 수 있다.

시스템 관리는 CVS에 설정 파일을 관리할 수 있다. 시스템 설정 파일을 변경한 다음에 cvs commit으로 변경 사항을 적용하고, 변경된 설정을 테스트하도록 한다. 테스트가 실패한다면 변경 사항을 롤백(roll back)하면 된다. - 심지어 6개월 전에 잘못된 설정을 발견할 수도 있을 것이다.

관리자는 서버 팜(farm)의 설정 파일에 대한 CVS 트리를 유지할 수도 있다. 새로운 서버를 추가한다면 해당 서버 타입의 설정 트리에서 cvs checkout으로 설정 파일을 가져오기만 하면 된다. 모든 변경 사항을 커밋(commit)하면 누가 무엇을, 언제 했는지 추적하는 데 도움이 된다.

CVS는 저자에게도 유용하다. 필자는 CVS 트리에 원고들을 보관한다 - 로컬 복사본을 읽어버려도 자동 백업본을 갖고 있는 것이 된다. CVS는 공동 작업을 하고 있거나, 제거했던 섹션을 가져올 필요가 있을 때도 유용하다.

예제에 대해서

이 글에서 사용하는 예제는 프로젝트에 대해서 이미 생성된 CVS 레포지토리가 있다고 가정하고 있다.

이 시리즈의 다음 글은 “CVS 관리”부분으로, CVS 레포지토리를 생성하고, 프로젝트를 분류하고, 레포지토리를 관리하는 방법에 대해서 설명한다. 지금이라도, cvs 매뉴얼 페이지에서 cvs initcvs import를 확인하도록 한다.

필요한 환경 변수

여러분이 하나의 레포지토리를 사용하고 있다면, $CVSROOT 환경 변수에 레포지토리 전체
경로를 :protocol:user@host:path 와 같은 형식으로 설정하도록 한다.
이것은 :ext:jenn@cvs.example.com.au:/home/cvs와 비슷하다.

보안을 위해서, ssh에 대한 환경 변수 $CVS_RSH를 설정한다. 기본적으로 CVS는 원격 머신에서의 레포지토리 액세스는 rsh을 사용한다.

트리(Tree) 가져오기 : cvs checkout

CVS는 중앙 레포지토리에 파일을 저장하지만, 사용자들은 레포지토리에서 떨어진 곳에서 파일의 복사본으로 작업한다.
  • 여러분이 작업하는 디렉터리를 만든다. 필자는 ~/cvs를 주로 사용한다.
  • 해당 디렉터리로 이동한다(cd ~/cvs).
  • cvs checkout module을 사용하여 해당 모듈을 가져온다.
    예. cvs checkout example (모듈은 파일 컬렉션에 대한 CVS 이름이다.)
$CVSROOT 환경 변수를 설정하지 않았거나 다른 장소에 레포지토리를 두고 싶다면, 모듈을 체크아웃하기 위해 cvs -d repository-path를 사용한다.

체크아웃은 cvs 디렉터리에서 모듈에 있는 파일과 서브디렉터리의 복사본을 가져온다.

cvs$ ls
example
cvs$ cd example; ls
CVS src
cvs/example$ cd CVS; ls
Entries  Repository  Root
CVS 디렉터리는 CVS에서 자체적으로 사용하는 특별한 디렉터리다. CVS/Entries는 CVS가 알고 있는 파일과 서브 디렉터리에 대한 목록을 나타낸다. CVS/Repository는 레포지토리에서 해당하는 디렉터리에 대한 경로를 갖고 있다. CVS/Root는 레포지토리에 대한 경로를 포함하고 있으므로, 이러한 파일에 대해서 -d repository-path 옵션을 사용할 필요는 없다.

CVS/Root$CVSROOT 환경 변수를 오버라이드한다는 점에 주의한다. 따라서 여러분이 레포지토리를 변경한다면, 모듈을 다시 체크아웃 해야한다.

cvs/src$ ls
CVS  Makefile  sample.h  sample.c
src 디렉터리는 예제 프로젝트에 대한 소스 파일을 갖고 있다. sample.c, sample.h, Makefile은 작업 복사본(Working Copt)에서는 보통의 일상적인 파일이지만, 레포지토리에서는 변경 사항을 추적할 수 있는 특별한 형태로 저장된다.

변경 사항 가져오기 : cvs update

매일매일 일을 시작하기 전에, 다른 누군가가 어떤 것을 수정하고, 변경사항을 커밋(commit) 할 수도 있기 때문에, 작업 디렉터리로 이동해서 cvs update를 실행하도록 해야한다. 이 명령은 레포지토리에 있는 파일과 여러분의 작업 본사본을 확인하고, 작업 복사본에 어떤 변경 사항이 있다면, 그 변경 사항을 적용해준다. cvs update -d를 사용하여 새로운 디렉터리를 사용할 수도 있다.

체크가 되면 각각의 파일 상태에 대한 리포트를 업데이트한다.
U file 
       성공적으로 업데이트 완료
A file 
       추가하지만, 변경 사항을 적용하지 않음(cvs commit을 실행해야한다.)
R file
       제거하지만, 변경 사항을 적용하지 않음(cvs commit을 실행해야한다.)
M file
       작업 디렉터리에 있는 것을 수정 : 레포지토리에 있는 파일이 변경되었고, 
       여러분의 디렉터리에 있는 파일이 CVS에 마지막으로 체크된 시간보다 오래되었거나 
       레포지토리가 변경되었다면 시스템에서 안전하게 병합하도록 한다.
C file 
       레포지토리에 있는 파일과 여러분의 파일이 일치하지 않는 경우에 사용자 간섭이
       필요한 경우.
? file
       작업 디렉터리에는 파일이 있고, 레포지토리에는 파일이 없는 경우에 CVS는
       그 파일에 대해서 무엇을 해야할지 모르는 경우.
변경사항 충돌할 때 : 파일 병합하기

CVS가 레포지토리에 있는 파일을 수정된 파일을 성공적으로 병합할 수 없다면, cvs update의 결과로 충돌이라는 것을 알려준다. 원본 파일은 해당 파일의 작업 디렉터리에 .#file.version로 저장되며, 병합 결과는 원본 파일 이름으로 저장된다.

cvs/example$ cvs update
jenn@cvs.example.com.au"s password: 
cvs server: Updating .
RCS file: /home/cvs/example/sample.c,v
retrieving revision 1.3
retrieving revision 1.4
Merging differences between 1.3 and 1.4 into sample.c 
rcsmerge: warning: conflicts during merge
cvs server: conflicts found in sample.c 
C sample.c 
CVS는 병합할 때 충돌이 있는 라인에 대해서 CVS 태그를 작성한다. CVS는 두 버전의 파일에서 같은 라인이 변경된 경우에 충돌사항을 자동으로 병합할 수 없다.

<<<<<<< sample.c 
Deliberately creating a conflict.
=======
Let"s make a conflict.
>>>>>>> 1.4
변경 사항 적용하기 : cvs commit

여러분의 파일을 체크 아웃했으면 다른 보통 파일처럼 편집하고 컴파일하면 된다. 레포지토리에 변경 사항을 적용하려면 cvs commit을 사용하도록 한다. 이 명령은 여러분이 변경한 모든 파일들 보다 높은 계층에서 실행될 필요가 있다. - 또한, 기본 작업 디렉터리에서 이 명령을 실행할 수도 있다.

cvs commit filename을 사용하여 하나의 파일을 커밋할 수도 있으며, 디렉터리와 하위 디렉터리를 모두 커밋할 수도 있다.

프로젝트 팀들마다 cvs commit을 얼마나 자주 해야하는 가에 대한 저마다의 의견을 갖고 있다. 경험에 따르면 가장 좋은 것은 “클린 컴파일을 할 때마다”와 “매일매일의 점심시간", 그리고 "자리를 비우기 전"이다.

역주 : 클린 컴파일(Clean Compile) : 에러없이 코드가 컴파일될 때를 클린 컴파일이라한다.

cvs/example$ cvs commit
cvs commit: Examining .
cvs commit: Examining src 
jenn@cvs.sample.com.au"s password:
CVS는 현재 작업 디렉터리에 밑에 있는 각각의 디렉터리와 서브디렉터리를 검사한다. CVS가 알고 있는 파일들이 변경되었는지 확인한다. cvs 레포지토리가 로컬 머신에 있는 것이 아니라면, cvs는 원격 머신에 대해서 비밀번호를 물어본다.

비밀번호를 물어본 다음에 CVS는 사용자 환경에서 기본으로 사용하는 에디터를 연다. - $CVSEDITOR$EDITOR 환경변수에 정의되어 있는 에디터를 연다. 파일에 대한 변경 사항 노트를 추가한다.

CVS:------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with "CVS:" are removed automatically
CVS: 
CVS: Committing in .
CVS: 
CVS: Modified Files:
CVS:  example/src/sample.h example/src/sample.c 
CVS:------------------------------------------------------------------
필자는 의미있는 변경 사항을 적는 것을 권한다 - 여러분이 롤백을 시도하고, “몇 가지 버그 수정함”이라고 적어둔다면, cvs diff를 사용하지 않고 롤백한 것이 어떤 버전인지 알 수 없을 것이다.

충돌이 일어날 가능성이 있다면, cvs commit은 제대로 실행되지 않는다. 이런 경우에는 레포지토리에 대해서 cvs update를 실행하여 문제를 수정할 수 있다 - CVS는 파일을 병합하려고 시도하며, 데이터를 잃어버리지 않고 병합할 수 없다면 사용자에게 병합할 것인지 물어볼 것이다.

cvs server: Up-to-date check failed for "cvs_intro.html"
cvs [server aborted]: correct above errors first!
cvs commit: saving log message in /tmp/cvst7onmJ
새로운 파일 만들기 : cvs add

CVS가 모르는 파일들은 cvs update 과정이나 커밋 과정 후에 "?"로 보고된다. 이러한 파일들을 레포지토리에 추가해야 CVS에서 이 파일들을 인식할 수 있다.

cvs add filename을 사용하여 새로운 파일을 포함시킬 것이라는 것을 알려줘야한다. CVS는 cvs commit을 사용할 때까지 레포지토리에 파일을 집어넣지 않는다.

디렉터리도 같은 명령으로 추가할 수 있다. 디렉터리에 있는 파일은 디렉터리가 추가 될 때까지 추가 될 수 없다.

파일 제거하기 : cvs remove

파일을 작업본에서 제거할 것이라는 것을 표시하기 위해 cvs remove filename을 사용한다. CVS를 레포지토리에서 제거하려면, 파일 시스템에서 파일을 실제로 삭제해야한다. CVS는 실제로 파일 전체를 제거하지는 않으며, 레포지토리에 Attic이라는 특별한 서브 폴더에 파일을 보관한다.

디렉터리는 제거하지 않는다

디렉터리를 제거하는 것은 변경 사항 추적을 망가뜨릴 수 있기 때문에 디렉터리를 제거하지 않는다. - 이것에 대해서는 “CVS 관리”에서 설명할 것이다.

마지막으로

CVS는 동시(concurrent) 개발, 파일 히스토리 관리에 대해서 유용할 뿐만 아니라, 어떤 종류의 파일에 대해서도 중앙 데이터베이스로 사용할 수 있다. CVS는 자세히 들여다보고 사용할만한 가치가 있다.

참고 자료
  • man cvs
  • man 5 cvs
  • info cvs에는 “what CVS is”와 “what CVS is not”와 같은 좋은 글이 있다.
    “Repository” 섹션에서는 프로토콜에 대해서 설명한다.
  • Big Scary Daemons 컬럼의 BSD Tricks: CVS
  • Sourceforge에도 몇 가지 CVS 관련 글이 있으며, Sourceforge Site Docs 페이지에서 섹션 6과 7을 참고한다.
Jennifer Vesperman 는 척추 마디에 실리콘 워터를 갖고 태어났다고 생각하길 좋아하지만 그녀의 부모님은 이것을 인정하지 않는다. 그는 사용자로서, 지지자로서 오픈 소스에 기여했으며, 현재 Linuxchix.org의 코디네이터다.
TAG :
댓글 입력
자료실

최근 본 상품0