[CVS] CVS 사용법

Linux 2010. 5. 11. 11:10

CVS는 Concurrent Versions System의 약자로
프로젝트 개발시 여러 사용자가 함께 작업을 할 때 상호간 버전 관리를 해주는 프로그램이다.

보통 여러 사용자가 함께 작업을 진행할 때 버전을 관리해주는 것이 주 목적이지만
혼자 작업할 때 사용자가 작업 할 때 잘못해서 되돌리고 싶을 때나 버전을 관리하는데도 사용할 수 있다.

시작하기 전에 먼저 용어 정리를 하면
Repository(저장소): CVS가 버전 관리를 하기위해 소스 코드를 저장해 놓는 공간이다. 사용자가 작업하는 공간이 아님.
Work directory(작업공간): 사용자가 작업하는 공간이다.

<CVS 사용하기 전>
1. CVS를 사용하기 위해서는 먼저 repository를 설정해 주어야 한다.
그럼 먼저 사용자가 원하는 곳에 저장소 디렉토리(A)를 만들어준다.
예) ~/CVS/
그 다음 그 하위 디렉토리로 반드시 CVSROOT라는 디렉토리를 만들어 주어야 한다.
예) ~/CVS/CVSROOT/

2. 그리고 나서 이를 환경 변수 CVSROOT로 설정해 주면 되는데

csh이나 tcsh같은 경우에는
setenv CVSROOT repository_dir

sh이나 bash같은 경우에는
CVSROOT = repository_dir

이를 환경변수로 설정해 주면 된다. (repository_dir = 저장소 디렉토리(A))

이렇게 하면 앞으로 진행하는 프로젝트는 저장소 디렉토리(A)에 저장되게 된다.
(c.f. 만약 이미 다른 사용자가 지정해 놓은 저장소 디렉토리가 있다면, 저장소를 만들어줄 필요없이  2. 환경 변수 설정만 해 주면 된다.)

3. 이후 CVS를 사용하기 위해서는 로그인을 해야하는데, 한번 로그인을 하면 그 내용이 계속 저장되므로 딱 한번만 해 주면 된다.
로그인 하는 방법은 다음과 같다.
cvs -d :pserver:user_id@cvs.hostname.com:repository_dir login
여기서
user_id: 사용자 계정
cvs.hostname.com: 서버 IP
repository_dir: 저장소 디렉토리(A)

이렇게 하면 CVS를 사용할 준비가 다 끝난 것이다.


<CVS에 프로젝트 등록>
CVS를 사용하는 방법은 예제로 알아보도록 한다.
먼저 예제를 위해 작업공간(B)을 만들어 보도록 하자.
~/test
라는 디렉토리를 만들고
~/test/a.txt
라는 파일을 만들어 적당한 내용을 넣어준다.

1. CVS에 프로젝트 등록
cvs import -m "Log message" project_name(C) vendor_tag release_tag
와 같이 해 주면 새로운 프로젝트가 저장소 디렉토리(A)에 등록되게 된다.
예제를 통해 직접 해 보면,
중요한 것은 프로젝트로 올릴 디렉토리의 내에서 이 작업을 해야한다는 것이다.
즉 ~/test/에서
cvs import -m "Imported source" test vt start
같이 해 주면 저장소 디렉토리(A)에 test라는 디렉토리가 생기면서 저장공간이 생긴 것을 확인할 수 있다.

2. 저장소(A)와 작업공간(B)의 동기화
여기까지 진행했다면 CVS에 프로젝트를 등록한 상태이지만
아직 저장소(A)와 작업공간(B)가 동기화되어 있는 상태는 아니다.
이는 작업공간(B) (예: ~/test/) 밑에 CVS라는 디렉토리가 생성되지 않은 것을 통해 확인할 수 있다. 동기화되어 있는 작업공간의 경우 그 밑에 CVS라는 디렉토리가 있다.
동기화 작업은 다음과 같다.
일단 처음에 프로젝트로 등록해 주었던 작업공간을 지워야 한다.
~ (home)에서
rm -rf test
해 주어서 기존의 작업공간을 지우고
~ 에서
cvs checkout project_name(C)
이라고 해주면
~/project_name
이라는 디렉토리가 생기면서
동기화된 작업공간이 생긴 것을 확인할 수 있다.
여기에서는 1에서 project_name을 기존의 작업공간과 같은 test라고 사용했으므로,
~/test에 들어가서 그 내용을 확인해보면 기존의 test에 있던 a.txt가 존재하는 것을 확인할 수 있고 추가로 ~/test/CVS 디렉토리가 생긴것을 확인할 수 있을 것이다.

여기까지 진행했다면 이제 CVS에 프로젝트를 등록하는 작업을 마친것이다.


<CVS 사용방법>
이제 등록된 프로젝트 내 작업공간(B)에서 작업을 하는 과정에서 해주어야 하는 것에 대해서 알아보도록 하자.

1. 작업공간(B)의 수정된 소스를 저장소(A)에 등록
cvs commit [-m "log message"] [filename]
또는
cvs ci [-m "log message"] [filename]

-m을 사용하였을 경우 log message의 내용을 같이 저장한다.
이는 생략해도 되지만 해당 버전의 내용을 기억하기 위해서 log message를 꼭 남기는 습관을 들이자.

filename을 명시해줄 경우 해당 파일을 저장소에 저장하고,
명시하지 않을 경우 해당 디렉토리와 그 하위 디렉토리의 수정된 파일의 내용을 저장소에 모두 저장하게 된다.


2. 저장소(A)에 있는 최신버전을 작업공간(B)으로 가져오기
cvs update

저장소에 있는 해당 디렉토리와 그 하위 디렉토리에 있는 최신 내용을 모두 가져온다.
여기에 옵션을 붙여

cvs update -dP
를 실행시키면 저장소(A)를 체크하여 비어있는 디렉토리는 작업공간(B)에서 지우고,
저장소(A)에 비어있지 않은 디렉토리는 작업공간(B)에 모두 복사해온다.


3.  파일의 로그 보기
cvs log filename

filename의 버전 로그를 본다. 


4. 새로운 파일이나 디렉토리 추가하기
CVS는 오로지 저장소(A)에 있는 파일과 디렉토리의 버전만을 관리해 준다.
그러므로 프로젝트 중 새로 생성된 파일은
저장소에 버전관리할 새로운 파일과 디렉토리가 생겼다는 사실을 알려주어야 한다.
이는

cvs add new_filename
cvs add new_dirname

을 통해서 할 수 있다.

이렇게 해주면 저장소(A)에 버전관리할 새로운 파일이나 디렉토리가 있다는 사실만을 알려준 것이지 그 내용을 저장한 것은 아니다.
그래서 이후

cvs ci new_filaname
cvs ci new_dirname

을 통해 그 내용을 반드시 저장소에 저장해 주어야 한다.

한 디렉토리 내에서 여러 파일이 추가되어야 한다 하는 경우에는

cvs add *
cvs ci

이렇게 해주면 그 디렉토리에 있는 새로 생성된 파일은 저장소(A)에 저장되게 된다.

여기에서 약간 불편한 점이 생기는데, 
만약 추가되어야 할 디렉토리가 hierarchy를 이루고 있다면, 즉 해당 디렉토리와 그 하위 디렉토리도 새롭게 추가되어야 한다면 다른 명령어와 혼합해서 이를 등록해주어야만한다. (-r (recursive) 옵션이 있을 듯 하지만 없다.)

현재 디렉토리와 그 하위 디렉토리에 있는 새로 생성된 디렉토리와 파일을 모두 CVS 저장소에 포함시키기 위해서는

find . -type d -print | grep -v CVS | xargs cvs add
find . -type f -print | grep -v CVS | xargs cvs add
cvs ci

와 같이 linux command와 혼합해서 사용하여야 한다.


5. 파일 제거하기
이미 저장소(A)에 포함된 파일을 제거하기 위해서는
해당파일을 먼저 작업공간(B)에서 제거한 다음

cvs remove [filename]

명령어를 사용한다.
그러면 CVS는 저장소에 해당파일을 버전관리 대상에서 제외할 것이라는 것을 통보하게 되고
실제로 이 파일을 지우는 것은 cvs add에서와 같이

cvs ci

를 통해 이루어지게 된다.

filename이 명시되어 있다면 해당 파일을 제거하고,
명시되어 있지 않다면 CVS는 작업공간(B)의 현재 디렉토리와 그 하위 디렉토리에는 없지만 저장소(A)에는 있는 파일을 모두 찾아 저장소(A)에서 제거하게 된다.
cvs add명령와는 달리 cvs remove는 recursive하게 현재 디렉토리와 그 하위 디렉토리를 모두 찾아 이를 처리해주게 된다.

해당 파일을 저장소에서 제거하였다 하더라도
이후 특정 버전으로 파일을 복구 시키는 것이 가능하다. 이 명령어는 아래에서 설명하도록 한다.

가끔 cvs remove를 하는 도중
cvs server: cannot remove file `filename' which has a numeric sticky tag of `1.3'.
이와 같은 에러 메세지가 뜨곤 하는데 이는 해당 파일에 sticky tag가 붙어 있어서 그렇다.
이러한 경우 해당 파일을

cvs update -A filename

해주어서 sticky tag를 제거하고 cvs remove를 하면 문제가 해결된다.


6. 디렉토리 제거하기
디렉토리를 제거하기 위해서는 일단 내부에 아무것도 없는 빈 디렉토리이어야 한다.
내부 파일 제거는 위의 5. 파일 제거하기의 방법을 사용하면 된다.
이후 제거할 디렉토리의 상위 디렉토리에서

cvs update -P

를 해주면 비어 있는 디렉토리를 CVS가 자동적으로 제거해 준다.


7. 특정 버전으로 파일 되돌리기
cvs up -r version -p old_filename > new_filename

version: 여기에서 명시해야할 버전은 cvs log 명령어를 통해 확인할 수 있다.
old_filename: 복구할 파일 이름
new_filename: 복구해서 저장할 파일 이름


8. 파일의 특정 부분을 어느 사용자가 수정했는지 확인
cvs annotate filename
cvs ann filename


9. 작업공간(B)의 파일과 저장소(A)의 최신버전의 차이 확인
cvs diff filename


10. 버전별로 파일의 차이 확인
cvs diff -r version1 -r version2 filename

version1, 2: 여기에서 명시해야할 버전은 cvs log 명령어를 통해 확인할 수 있다.


11. 특정 시점으로 파일 되돌리기
cvs up -D YYYY-MM-DD HH-MM [filename]

YYYY-MM-DD: 날짜 (예: 2005-02-22)
HH-MM: 시간 (예: 05:00)
filename을 명시해 주었을 경우 해당 파일을 되돌리고
명시하지 않았을 경우 해당 디렉토리와 그 하위 디렉토리의 내용을 모두 명시한 시점으로 되돌린다.


12. 태그 생성
cvs tag tag_name

해당 디렉토리와 그 하위 디렉토리의 내용에 tag_name의 tag를 붙인다.


13. 태그를 건 시점으로 되돌리기
태그를 생성하였다면 그 태그가 생성된 시점으로 내용을 복구할 수 있다.

cvs up -R tag_name

과 같이 하면
해당 디렉토리와 그 하위 디렉토리의 내용을 tag_name이 지정된 시점으로 복구한다.

14. Revision Number 바꾸기
큰 변화에 따른 revision number를 바꾸기가 가능하다

cvs ci -m "updating major revision number" -r new_version


<TIP>
1. 소스 코드에 log message 남기기
작업을 하다보면 일일히 cvs log를 해가며 로그를 보는 것이 불편할 때가 있다.
이럴 때 소스 코드에 log message를 남기는 기능이 CVS에 있다.
이 방법을 쓰면
cvs ci -m "log message"
와 같은 명령어를 사용하였을 때 log message와 작성자 사용자 계정, 시점 등을 소스코드에 저장할 수 있다.

C코드를 예를 들어 이를 설명하도록 하겠다.
원래의 소스 helloworld.c는 다음과 같다.
helloworld.c
------------------------------------------------------
#include <stdio.c>

int main() {

printf ("Hello, World!\n");
return 1;
}
------------------------------------------------------

소스 코드에 로그를 남기는 방법은 다음과 같다.

먼저 작업공간(B)의 소스코드(helloworld.c)의 상단에
helloworld.c
------------------------------------------------------
/*
 * $Log$
 */

#include <stdio.c>

int main() {
printf ("Hello, World!\n");
return 1;
}
------------------------------------------------------
와 같이 Bold로 표현된 부분을 써 주고
cvs ci -m "Add the superfrobnicate option"를 해 주면
작업공간(B)의 소스 코드가 다음과 같이 변경된 것을 확인할 수 있다.
helloworld.c
------------------------------------------------------
/*
 * $Log: helloworld.c,v $
 * Revision 1.1  1997/01/03 14:23:51  joe
 * Add the superfrobnicate option
 */

#include <stdio.c>

int main() {
printf ("Hello, World!\n");
return 1;
}
------------------------------------------------------

이렇게 작업공간의 소스 코드에 CVS가 추가할 수 있는 log message의 유형은 다음과 같이 있다.
$Author$
$CVSHeader$
$Date$
$Header$
$Id$
$Name$
$Locker$
$Log$
등을 적어넣어주면
CVS가 이들을 자동으로 갱신하여 파일에 버전에 대한 내용을 각각 넣어준다.

2. Sticky Tag Error 해결
Commit을 하다 보면 가끔 다음과 같은 sticky tag error가 발생하는 경우가 있다.
cvs commit: sticky tag `2.0' for file `filename' is not a branch
이런 경우 해당 파일을
cvs update -A filename
과 같이 update를 한 후에 commit하면 문제가 해결된다.
(-A option은 해당 파일의 sticky tag 정보를 제거해준다)

자세한 내용은 아래 파일/링크를 참조.

http://suntans.stanford.edu/documentation/cvs_howto/cvs_html/index.html

'Linux' 카테고리의 다른 글

[awk] awk 사용법#3 - Statements  (0) 2010.05.14
[awk] awk 사용법#2 - awk program basic  (0) 2010.05.13
[awk] awk 사용법#1 - awk program의 구조  (0) 2010.05.13
[Linux] Linux Command Summary  (0) 2010.04.16
[Linux] Regular Expression  (0) 2010.04.16
Posted by sunshowers
,