1.1. Installing CVS ¶
CVS서버 설치는 알아서 잘해라. -_-; 리눅스에서는 패키지로 설치하면 되고, 윈도우에서는 알아서 받아서 설치하면 된다. 이미 서버가 있으면 더 좋다. 내 경우에는 데비안 리눅스를 사용하는 관계로 apt-get install cvs로 간단히 설치를 끝냈다.
1.2. Creating a Repository ¶
현재 우리는 테스트용으로 CVS를 쓰기 때문에 CVS의 저장소를 임시로 만들 필요가 있다.
CVS저장소를 만드는 명령은 다음과 같다.
CVS저장소를 만드는 명령은 다음과 같다.
~cpp Unix: cvs -d ~/sandbox init // 나의 경우에는 /home/CVSHOME 로 지정하였다. Wind: cvs -d d:sandbox init
1.3. CVS Commands ¶
CVS클라이언트는 현재 우리가 쓰는 커맨드 형태의 클라이언트도 있지만, GUI형태의 TortoiseCVS, WinCVS등도 있다. (sourceforge.net에서 확인) 또한 IDE 자체가 CVS 클라이언트의 기능을 하는 것들도 있다. (ex. eclipse, dev-cpp)
1.4. Creating a Simple Project ¶
간단한 프로젝트를 CVS상에 만들자. 예제는 소스로 보이지는 않지만 크게 상관은 없다.
color.text
number.text
이 파일이 저장된 폴더에서 다음의 명령어를 실행시킨다.
-m " " 프로젝트를 임포트할때 기록할 메시지임. (서드파티 코드를 사용하는 경우에 유리하다.)
sesame 저장소안에서 프로젝트의 이름
마지막 2개의 파라메터(sesame initial) tag이다.
이런과정을 마치면 CVS 루트 디렉토리에 프로젝트가 정상적으로 생성되었는지 ls 명령으로 확인해보자.
~cpp black brown red orange yellow green
~cpp zero one two three four
~cpp tmpdir#cvs -d /home/CVSHOME/ import -m " " sesame sesame initialimport는 프로젝트를 저장소에 넣을 것이라는 파라메터이다.
-m " " 프로젝트를 임포트할때 기록할 메시지임. (서드파티 코드를 사용하는 경우에 유리하다.)
sesame 저장소안에서 프로젝트의 이름
마지막 2개의 파라메터(sesame initial) tag이다.
1.5. Starting to Work With a Project ¶
이제 저장소에 저장된 파일을 로컬 작업공간에 체크아웃해보자. 이를위해서 일단 ~/work 라는 디렉토리를 구성하자.
~cpp #mkdir ~/work #cd ~/work #cvs -d /home/CVSHOME co sesame cvs checkout: Updating sesame U sesame/color.txt U sesame/number.txt~/work를 조사해서 ~/work/sesame 디렉토리에 정상적으로 저장소의 파일이 체크아웃되었다면 원본 파일을 삭제한다.
1.6. Making Changes ¶
color.txt 의 변경
~cpp black brown red orange yellow blue purple gray whitecolor.txt를 위와 같이 변경한뒤에 프로프트에서 다음의 명령어를 사용해보자.
~cpp root@eunviho:~/tmpdir/sesame# cvs status color.txt =================================================================== File: color.txt Status: Locally Modified Working revision: 1.1.1.1 Tue Aug 2 05:50:14 2005 Repository revision: 1.1.1.1 /home/CVSHOME/sesame/color.txt,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)상기의 status 옵션으로 확인이 가능하듯이 cvs는 자동으로 현재의 파일이 로컬 작업공간에서 수정되었다는 사실을 판단할 수 있다.
~cpp root@eunviho:~/tmpdir/sesame# cvs diff color.txt Index: color.txt =================================================================== RCS file: /home/CVSHOME/sesame/color.txt,v retrieving revision 1.1.1.1 diff -r1.1.1.1 color.txt 6a7,10 > blue > purple > gray > white또한 diff 옵션을 이용해서 변경된 파일이 어떤 변경이 있었는지를 조사하여 보여주는 옵션도 존재한다.
~cpp root@eunviho:~/tmpdir/sesame# cvs diff --side-by-side color.txt Index: color.txt =================================================================== RCS file: /home/CVSHOME/sesame/color.txt,v retrieving revision 1.1.1.1 diff --side-by-side -r1.1.1.1 color.txt black black brown brown red red orange orange yellow yellow green green > blue > purple > gray > white--side-by-side 옵션을 이용하면 지역 버전과 저장소버전을 한화면에 출력하여서 비교를 할 수 있다.
1.7. Updating the Repository ¶
파일을 수정, UnitTest를 거치면 수정한 내용을 저장소에 저장해야할 것이다.
(직접해보면 안다. -_-;)
~cpp root@eunviho:~/tmpdir/sesame# cvs commit -m "고객이 4가지 색을 더 원함" cvs commit: Examining . /home/CVSHOME/sesame/color.txt,v <-- color.txt new revision: 1.2; previous revision: 1.1변경된 프로젝트는 commit 옵션으로 체크인시키는 것이 가능하다. 이때 -m 옵션으로 변경된 사항에 대한 주석을 다는 것이 가능하며, 만약 주석을 달지 않을 경우에는 vi 에디터가 실행되면서 주석을 저장할 수 있는 파일이 열린다.
(직접해보면 안다. -_-;)
~cpp root@eunviho:~/tmpdir/sesame# cvs status color.txt =================================================================== File: color.txt Status: Up-to-date Working revision: 1.2 Tue Aug 2 13:08:47 2005 Repository revision: 1.2 /home/CVSHOME/sesame/color.txt,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)commit 을 통해서 저장소를 체크인하고난뒤 status로 변경된 파일의 정보를 출력하면 그 결과가 반영된 것을 알 수 있다.
~cpp root@eunviho:~/tmpdir/sesame# cvs log color.txt RCS file: /home/CVSHOME/sesame/color.txt,v Working file: color.txt head: 1.2 branch: locks: strict access list: symbolic names: initial: 1.1.1.1 sesame: 1.1.1 keyword substitution: kv total revisions: 3; selected revisions: 3 description: ---------------------------- revision 1.2 date: 2005-08-02 13:16:58 +0000; author: sapius; state: Exp; lines: +4 -0 고객이 4가지 색을 더 원함 ---------------------------- revision 1.1 date: 2005-08-02 05:50:14 +0000; author: sapius; state: Exp; branches: 1.1.1; Initial revision ---------------------------- revision 1.1.1.1 date: 2005-08-02 05:50:14 +0000; author: sapius; state: Exp; lines: +0 -0 =============================================================================log옵션을 통해서 특정파일이 어떤 식으로 변경이 되었는지를 알 수 있다.
1.8. When Worlds Collide ¶
이제 한개의 파일을 두사람이 동시에 변경할때 생기는 상황에대해서 살펴보자.
이러한 경우를 살피기 위해서 기존의 sesame 이라는 디렉토리이외의 공간에 저장소에 저장된 sesame을 받아야한다.
이렇게하면 디렉토리에
sesame/number.txt
최신 버전이 아닌 로컬 작업공간의 내용과 저장소의 내용을 비교한다
저장소의 최신버전의 내용을 로컬에 반영하기
이러한 경우를 살피기 위해서 기존의 sesame 이라는 디렉토리이외의 공간에 저장소에 저장된 sesame을 받아야한다.
~cpp root@eunviho:~/tmpdir# cvs -d /home/CVSHOME/ co -d aladdin sesame cvs checkout: Updating aladdin U aladdin/color.txt U aladdin/number.txt
~cpp root@eunviho:~/tmpdir# ll total 8 drwxr-xr-x 3 root root 4096 2005-08-02 22:23 aladdin drwxr-xr-x 3 root root 4096 2005-08-02 22:08 sesame과 같이 동일한 저장소의 프로젝트가 서로다른 디렉토리의 로컬 작업공간을 할당받았다는 것을 알 수 있다.
~cpp root@eunviho:~/tmpdir# vi sesame/number.txt zero one two three four five six상기와 같이 변경한 파일을 체크인 시킨다.
~cpp root@eunviho:~/tmpdir/sesame# cvs commit -m "숫자가 더 필요했다." cvs commit: Examining . /home/CVSHOME/sesame/number.txt,v <-- number.txt new revision: 1.2; previous revision: 1.1sesame 폴더에 받아진 파일을 변경하여 체크인 시켰기 때문에 이제 aladdin 폴더에 존재하는 파일들은 더이상 최신 버전이 아니다.
~cpp root@eunviho:~/tmpdir/aladdin# cvs status number.txt =================================================================== File: number.txt Status: Needs Patch Working revision: 1.1.1.1 Tue Aug 2 05:50:14 2005 Repository revision: 1.2 /home/CVSHOME/sesame/number.txt,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)상기와 같이 확인을 해보면 aladdin/number.txt 는 체크아웃을 통해서 저장소의 소스와 동기화를 해주어야한다는 상태를 나타내고 있다.
~cpp root@eunviho:~/tmpdir/aladdin# cvs diff -rHEAD number.txt Index: number.txt =================================================================== RCS file: /home/CVSHOME/sesame/number.txt,v retrieving revision 1.2 retrieving revision 1.1.1.1 diff -r1.2 -r1.1.1.1 6,7d5 < five < six-rHEAD는 현재의 branches에 존재하는 가장 최신버전의 것과 비교하는 옵션이다. 만약 이 옵션이 없다면 cvs는 현재 받아진 지역 버전과 동일한 저장소상에 기록된 소스와 비교를 한다.
~cpp root@eunviho:~/tmpdir/aladdin# cvs diff number.txt저장소상의 aladdin 과 동일한 버전의 number.txt는 전혀 변화가 없었기 때문에 출력되는 내용이 없다.
~cpp root@eunviho:~/tmpdir/aladdin# cvs update cvs update: Updating . U number.txt반영되는 파일은 오로지 최신버전의 파일이 저장소에 존재할 경우만이다. 그렇지 않으면 파일은 다시 받을 필요가 없기 때문에 받지 않는다.
1.9. Conflict Resolution ¶
다음과 같이 변경을 해서 동시에 두사람이 파일의 수정작업을 하는 경우를 가정해보자.
sesame/number.txt
sesame/number.txt
우선 aladdin 의 파일들을 체크인한다.
그렇게 만든뒤에 sesame의 파일을 수정한 사람이 체크인을 한다고 생각해보자.
이 경우는 동시에 수정이 일어나서 저장소의 최신버전이 반영되지 못했기 때문에 발생한 것이다.
우선은 다음처럼 해보자.
sesame/number.txt의 내용을 확인해보자
로컬에 반영이 되었으므로
~cpp root@eunviho:~/tmpdir# vi sesame/number.txt ZERO one two three four five six
~cpp root@eunviho:~/tmpdir# vi aladdin/number.txt zero one two three four five SIX
~cpp root@eunviho:~/tmpdir/aladdin# cvs commit -m "make number six to be important" cvs commit: Examining . /home/CVSHOME/sesame/number.txt,v <-- number.txt new revision: 1.3; previous revision: 1.2
~cpp root@eunviho:~/tmpdir/sesame# cvs commit -m"make number zero to be emphasized" cvs commit: Examining . cvs commit: Up-to-date check failed for `number.txt' cvs [commit aborted]: correct above errors first!상기에서 보듯이 에러를 내면서 체크인하지 못한다.
우선은 다음처럼 해보자.
~cpp root@eunviho:~/tmpdir/sesame# cvs update cvs update: Updating . RCS file: /home/CVSHOME/sesame/number.txt,v retrieving revision 1.2 retrieving revision 1.3 Merging differences between 1.2 and 1.3 into number.txt M number.txt
~cpp root@eunviho:~/tmpdir/sesame# vi number.txt ZERO one two three four five SIX상기에서 보듯이 cvs는 너무도 잘 변경된 부분을 판단해서 현재의 로컬 소스에 반영시켜준다.
~cpp root@eunviho:~/tmpdir/sesame# cvs commit -m"make number zero to be emphasized" cvs commit: Examining . /home/CVSHOME/sesame/number.txt,v <-- number.txt new revision: 1.4; previous revision: 1.3상기와 같이 정상적인 체크인이 가능하다. 물론 aladdin 폴더의 내용도 다음번 수정시에는 이와 같은 일이 발생할 것이다.
1.9.1. 박치기 - 변경 내용이 충돌하는 경우 ¶
상기의 경우에는 2가지 프로그램의 바뀐 부분이 동일한 줄에 해당하지 않기 때문에 큰 문제없이 cvs가 알아서 반영을 해주었다. 그렇나 만약 변경부분이 동일한 부분이라면 어떨까?
sesame/number.txt
aladdin/number.txt
이런경우에 rcsmerge 는 그 변경을 다음과 같이 표현한다.
sesame/number.txt
이런일이 발생한 경우에는 어떤 일이 발생했는지 기록을 우선적으로 찾아보아야한다.
이런 정보를 종합해서 이전 소스의 수정한 사람과 토의를 통해서 올바른 결과를 얻어낼 수 있다.
이 경우에는 ichi를 쓰기로 했다고 가정하자. ichi이외의 다른 부분의 나용을 모두 삭제한다. 그리고 토의 결과
two를 due로 쓰기로 했다고 하자
위와 같은 방식(느슨한 잠금)에 의해서 버전 커트롤이 가능하기 대문에 동기화로 인한 문제는 거의 발생하지 않는다.
----
PragmaticVersionControlWithCVS
~cpp root@eunviho:~/tmpdir# vi sesame/number.txt ZERO ichi two three four five SIX
~cpp root@eunviho:~/tmpdir# vi aladdin/number.txt ZERO uno two three four five SIX
~cpp root@eunviho:~/tmpdir/aladdin# cvs commit -m "users like italian word of one" cvs commit: Examining . /home/CVSHOME/sesame/number.txt,v <-- number.txt new revision: 1.5; previous revision: 1.4 . . root@eunviho:~/tmpdir/sesame# cvs commit -m "must be japanese of word one" cvs commit: Examining . cvs commit: Up-to-date check failed for `number.txt' cvs [commit aborted]: correct above errors first! . . root@eunviho:~/tmpdir/sesame# cvs update cvs update: Updating . RCS file: /home/CVSHOME/sesame/number.txt,v retrieving revision 1.4 retrieving revision 1.5 Merging differences between 1.4 and 1.5 into number.txt rcsmerge: warning: conflicts during merge cvs update: conflicts found in number.txt C number.txt3번재에서 알 수 있듯, 동일한 줄을 수정한 경우에는 충돌이 일어난다는 것을 알 수 있다.
이런경우에 rcsmerge 는 그 변경을 다음과 같이 표현한다.
~cpp ZERO <<<<<<< number.txt ichi ======= uno >>>>>>> 1.5 two three four five SIX이 경우 변경된 내용은 <<<<<<< >>>>>>> 의 가운데에 존재하는 내용이 충돌을 일으킨 부분이다.
~cpp root@eunviho:~/tmpdir/sesame# cvs log -r1.5 number.txt RCS file: /home/CVSHOME/sesame/number.txt,v Working file: number.txt head: 1.5 branch: locks: strict access list: symbolic names: initial: 1.1.1.1 sesame: 1.1.1 keyword substitution: kv total revisions: 6; selected revisions: 1 description: ---------------------------- revision 1.5 date: 2005-08-02 13:46:44 +0000; author: sapius; state: Exp; lines: +1 -1 users like italian word of one =============================================================================마지막 세개의 줄에는 이전에 먼저체크인 된 소스를 수정한 사람과 그와 관련된 주석, 변경된 라인의 정보가 출력된다.
이런 정보를 종합해서 이전 소스의 수정한 사람과 토의를 통해서 올바른 결과를 얻어낼 수 있다.
이 경우에는 ichi를 쓰기로 했다고 가정하자. ichi이외의 다른 부분의 나용을 모두 삭제한다. 그리고 토의 결과
two를 due로 쓰기로 했다고 하자
~cpp root@eunviho:~/tmpdir/sesame# vi number.txt ZERO ichi due three four five SIX . . root@eunviho:~/tmpdir/sesame# cvs commit -m "one is japanese, two is italian" cvs commit: Examining . /home/CVSHOME/sesame/number.txt,v <-- number.txt new revision: 1.6; previous revision: 1.5
PragmaticVersionControlWithCVS