[출처 : http://xinet.kr/tc/63]


서버를 운용하다 보면 X-윈도우가 필요하는 경우가 있는데 이럴때 O/S를 재 설치하지 않고
yum 서비스를 이용하여 X-윈도우를 설치 할수 있습니다.

X-윈도우 설치에 앞서 서버에 메모리 사양이 어느정도 인지 확인을 합니다.
시스템 기본 메모리가 최소 1G 이상일 경우 추천을 권합니다 (512M 에서 설치시 부팅 후 메모리 부분 많이 차지함)

또한 / 파티션의 용량이 넉넉한지 확인합니다 ( 최소 200M 이상)

환경 : CENTOS 4.X 5.X

1.  yum을 이용해 grouplist 를 확인합니다 

[root@localhost ~]# yum grouplist
Setting up Group Process
base                      100% |=========================| 2.1 kB    00:00     
updates                   100% |=========================| 1.9 kB    00:00     
addons                    100% |=========================|  951 B    00:00     
extras                    100% |=========================| 2.1 kB    00:00     
comps.xml                 100% |=========================| 920 kB    00:00     
yumgroups.xml             100% |=========================| 9.7 kB    00:00     
Installed Groups:
   MySQL Database
   Development Libraries
   Editors
   System Tools
   Text-based Internet
   Legacy Network Server
   DNS Name Server
   Dialup Networking Support
   Network Servers
   Web Server
   Mail Server
   Available Groups:
   Tomboy
   Cluster Storage
   Office/Productivity
   Virtualization
   Engineering and Scientific
   Beagle
   GNOME Software Development
   X Software Development
   GNOME Desktop Environment
   Authoring and Publishing
   Base
   FTP Server
   Mono
   Games and Entertainment
   XFCE-4.4
   Legacy Software Development
   Clustering
   Java
   Java Development
   OpenFabrics Enterprise Distribution
   Emacs
   Legacy Software Support
   X Window System
   Graphics
   Ruby
   Windows File Server
   Printing Support
   KDE Software Development
   KDE (K Desktop Environment)
   Server Configuration Tools
   Horde
   Sound and Video
   PostgreSQL Database
   Administration Tools
   News Server
   Development Tools
   KVM
   Yum Utilities
   FreeNX and NX
   Graphical Internet
Done

2.  groupinstall 이용하여 x-windows를 설치 합니다.

[root@localhost ~]# yum groupinstall "X Window System"
[root@localhost ~]# yum groupinstall "X Software Development"

  메세지가 나타나면 y를 입력합니다 

 3. GNOME을 사용할지 KDE 를 사용할지 선택에 따라서 install합니다    저는 여기서 GNOME를 사용하겠습니다. 
 
[root@localhost ~]# yum groupinstall "GNOME Desktop Environment"

 메세지가 나타나면 y를 입력합니다.

4. 랜카드 정보 확인 및 수정 
 재부팅하기에 앞서 네트워크 정보가 일치하는지 한번 확인해봅니다
보통의 경우 eth0의 랜카드 정보가 백업이 되어 재 부팅시 연결이 안되는 경우가 있습니다.
이럴 경우를 대비해 eth0의 랜카드 정보를 확인합니다. eth0.bak 파일이 존재하면 이것을 다시 eth0파일로 변경합니다

[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# ls -l ifcfg-eth0*
-rw-r--r-- 2 root root 198  5월 20 18:33 ifcfg-eth0
-rw-r--r-- 2 root root 198  5월 20 18:33 ifcfg-eth0.bak
2개의 eth0 랜카드 정보를 가지고 있으면 원래 있던 파일 내용을 확인해서 변경해 줍니다 
[root@localhost network-scripts]# mv ifcfg-eth0.bak ifcfg-eth0

5.  부팅 순서 변경 및 재 부팅 
 부팅시 x-windows 로 부팅하기 위해서 inittab 부분을 수정해 줍니다. 

[root@localhost ~]# vi /etc/inittab 

id:3:initdefault ---> id:5:initdefault 수정 

  재부팅 
[root@localhost ~]# init 6



 이제 x-윈도우 환경접속을 위해서 freenx라는 프로그램을 설치합니다  (vnc보다 속도 향상)

  freenx : 리눅스 원격 터미널 접속 프로그램 (기존 vnc 접속보다 안정성과 보완성이 뛰어납니다)

6. freenx 설치 
    yum 서비스를 이용하여 freenx를 설치 할수 있습니다 

[root@localhost ~]# yum -y install freenx

7. 환경 설정 파일 복사 및 내용 수정 

[root@localhost ~]# cp /etc/nxserver/node.conf.sample /etc/nxserver/node.conf
 [root@localhost ~]# vi /etc/nxserver/node.conf

  SERVER_NAME="$(hostname)"  --> 주석해제
  SSHD_PORT=22  ---> 주석해제
  ENABLE_SSH_AUTHENTICATION="1"  ---> 주석해제

8. 방화벽에서 포트 허용 

[root@localhost ~]# iptables -A INPUT -p tcp --dport 5000:6000 -j ACCEPT
또는 oops-firewall을 사용한다면 /etc/oops-firewall/filter.conf 에 추가해 준다
[root@localhost ~]# vi /etc/oops-firewall/filter.conf
TCP_ALLOWPORT = 22 53 21 110 25 5000-6000
방화벽 재 시작
[root@localhost ~]# /etc/rc.d/init.d/oops-firewall restart
OOPS Firewall 종료:                                        [  OK  ]
OOPS Firewall 시작:                                        [  OK  ]


9. freenx-server 재 시작 
   freenx가 사용하는 권한이있는데 권한 문제로 윈도우에서 에러가 나는 경우가 발생합니다 
  2개의 퍼미션을 변경하면 이상없이 접속이 가능합니다 

[root@localhost ~]# chmod 755 /usr/bin/find  
[root@localhost ~]# chmod 755 /usr/bin/which
[root@localhost ~]# /etc/rc.d/init.d/freenx-server restart


10.  윈도우 접속 프로그램에서 개인키값을 가지고 인증하기 때문에 키파일의 값을 메모장에 붙혀넣기 합니다 

[root@localhost ~]# cat /etc/nxserver/client.id_dsa.key 

----이 아래부분부터 복사----------

-----BEGIN DSA PRIVATE KEY-----
MIIBugIBAAKBgQD1qqbtnPKnbWSVQpYP9IZgfxQN3VC8x/Hlg2i3Plg10cU2Cw02
0vnwqpMUFl6846BCk6g/gmdu8u/RC0z19veeQdCn7G/cgvdAPeZzfb3aQ6DLvQB1
YrFnc2IBOohWjoMxm/OJZASygWk45lvjtOCNkoY9Zmu0EIN3wuAcgk5CpQIVAP4z
S4Kni531KTN5EI+ADmic5wmpAoGAbIBQxYKBfyNOz16+kjobOuvh8B9KQHhXpx5H
pEdtHnBj/VViPrSkzf4OcQ/sDg5koHGqm3MKnqporGTc0LVKSGLEnKHZpQhf5cmY
ptN2YzDFBZ4yhdtf6QLKRiL1IJ31wKTrPCp7M9tUG1Q9+TGMDBkKd4aE8oTqCCJL
P4UtCRsCgYB7S+AuJoUFLQfUXZE/0XjoPlvUa5bkAGOVdlp/4smCvAa8ibAsatU1
fmcJBS4FVLnn6bvccfpVDF4+/lSxSu/mjIpwkfTERIeUZHp2xSkY7jOr0fxcwvJW
pRFuEK8rYwkXK8f8qX3ZBM/3ItOw64ZDy4LnC2yYSwIeDQFjeT//aQIULfs3ch8j
OCC7yw3OHA3Zsdbm/V8=
-----END DSA PRIVATE KEY-----




NX Client for windows  (실제 이 프로그램을 이용하여 윈도우에서 리눅스-xwindows를 접속합니다)

11. FreeNX 윈도우 접속 클라이언트 설치  
    이제 윈도우 환경에서 접속해서 사용할 클라이언트 프로그램을 설치합니다.
   즉 윈도우에서 기본적으로 사용되는 원격터미널접속과 비슷하다고 보시면 됩니다 

    다운로드 주소 :    http://64.34.161.181/download/3.4.0/Windows/nxclient-3.4.0-7.exe

   다운로드 프로그램을 설치 합니다 

12. freenx 접속환경 설정 및 접속 
     시작 -프로그램 - NX Client for Windows ---> NX Connection Wizard 실행 
    
   

사용자 삽입 이미지
                                      Next 버튼을 클릭 합니다 

사용자 삽입 이미지
                       host 부분에 해당 서버의 아이피를 입력합니다  LAN 드래그 


사용자 삽입 이미지
        X-WINDOWS 설치시 환경을 GNOME으로 설치하였기 때문에 GNOME을 선택후 NEXT 버튼 클릭을 합니다 


사용자 삽입 이미지
                     설정이 완료되었으므로 Finish 버튼을 클릭 합니다 


사용자 삽입 이미지
                      login 부분에 일반계정 user 와 패스워드 입력후 아래 configuer 버튼 클릭( key값 변경)


사용자 삽입 이미지
                                                  key 버튼을 클릭 합니다 


사용자 삽입 이미지
       여기서  기존 key파일의 내용을 지우고 위에서  메모장에 붙혀넣었던 키값을 붙혀넣기 합니다
      또는 위에서 붙혀넣기 한 key파일의 내용을 파일로 저장해서 import 버튼을 눌러 key 파일을 불러올수 있습니다  
      완료가 되었으면 save 버튼을 클릭 합니다


사용자 삽입 이미지

            최종 설정값이 완료되었으므로 Login 버튼을 클릭 합니다 


 
사용자 삽입 이미지
                               인증 메세지가 나타나면 Yes 버튼을 클릭 합니다 


사용자 삽입 이미지

  freenx-server 를 이용하여 리눅스의 x-windows 접속하였습니다 작업시에는 root로 변경 후 작업하시면 됩니다.

아래는 제가 사용하는 visual studio 편집기 색상입니다. (with Visual Assist)
아래 설정은 Visual Assist가 있어야 동일하게 나옵니다.


나름 여러가지로 바꾸다가 최종 선택된 모드입니다.

이렇게 바꾸시려면 다음 파일을 다운 받으시고.
Visual studio에서 [도구] -> [설정가져오기 및 내보내기] 선택하시고
[선택한 환경 설정 가져오기] -> [아니오, 새 설정을 가져와 현재 설정을 덥어씁니다] -> [찾아보기] 로 다운 받을 파일 선택하시고 진행 하시면 됩니다.

아직 색상이 저라 같지 않을텐데 그건 Visual Assist의 도움을 받으셔야 합니다.

Assist에서 위 그림처럼 색 설정하시면 끝입니다.

그럼 편히 코딩하시기 바랍니다.


[출처 : http://dev1.tistory.com/20]

 ----------------------------------------------------
Ctrl-K, Ctrl-H : 바로가기 설정. ( 작업목록 창에서 확인가능 )
Ctrl-K,K : 북마크 설정 / 해제
Ctrl-K,L : 북마크 모두 해제
Ctrl-K,N : 북마크 다음으로 이동
Ctrl-K,P : 북마크 이전으로 이동
Ctrl-K,C : 선택한 블럭을 전부 코멘트
Ctrl-K,U : 선택한 블럭을 전부 언코멘트(코멘트 해제)
Ctrl-F3 : 현재 단어 찾기
  -> F3 : 다음 찾기

Ctrl-F7 : 현 파일만 컴파일
            : 현 프로젝트만 빌드
Ctrl-Shift-B : 전체 프로젝트 빌드
Ctrl-F5 : 프로그램 시작

Ctrl-i : 일치하는 글자 연속적으로 찾기
Ctrl+i 를 누르면 하단에 자세히보면, "증분검색" 이라는 텍스트가 나온다.
그러면 그때 찾기 원하는 단어를 입력할때마다 일치하는 위치로 바로바로
이동한다. (좋은기능)
타이핑은 "증분검색" 이라는 텍스트옆에 커서는 없지만 입력이된다.
입력하는 문자를 수정하려면, backspace로, 그만 찾으려면 엔터.

줄넘버 보여주기 : 도구 > 옵션 > 텍스트편집기 > 모든언어 > 자동줄번호 선택하면 됨.

Ctrl+ - (대시문자), Ctrl+Shift+ -  :
현재 커서를 기억하는 Ctrl+F3(VS6에서), Ctrl+K,K(VS7에서) 와는 달리
사용자가 별도로 입력을 해주는건 없고, 단지 이전에 커서가 있었던곳으로
위 키를 누를 때마다 이동된다. (shift를 이용하면 역순)

Ctrl-F12 : 커서위치 내용의 선언으로 이동( 즉, 대략 헤더파일 프로토타입으로 이동)

F12 : 커서위치 내용의 정의로 이동( 즉, 대략 CPP파일 구현부로 이동)

Shift+Alt+F12 : 빠른기호찾기 ( 이거 찾기보다 좋더군요. 함수나 define등 아무거나에서 사용)

F12: 기호찾기. (s+a+f12 비교해볼것)

Ctrl-M, Ctrl-L : 소스파일의 함수헤더만 보이기 (구현부는 감추고) (토글 키)
Ctrl-M, Ctrl-M : 현재 커서가 위치한 함수를 접는다/편다. (토글 키)

#include "파일명" 에서 "파일명" 파일로 바로 직접이동
하고 싶을경우 -> Ctrl-Shift-G


<편집>---------------------------------------------------------------------------
Ctrl-F : 찾기 대화상자
Ctrl-H : 바꾸기 대화상자
Ctrl-Shift-F : 파일들에서 찾기 대화상자
Ctrl-Shift-H : 파일들에서 바꾸기 대화상자
Ctrl-G : 해당 줄로 가기 (별로 필요없음)
Ctrl-K,Ctrl-F : 선택된 영역 자동 인덴트 (VS6의 Alt-F8기능)
Ctrl-] :괄호({,}) 쌍 찾기 : 괄호 앞이나 뒤에서 눌러서 닫거나,
여는 괄호이동
Ctrl-Shift-Spacebar : 함수이름편집중 툴팁으로나오는 함수와매개변수설명이 안나올경우, 강제로 나오게

alt-LButton ->Drag : 원하는 영역의 블럭을 세로로 잡기

Ctrl+Shift+R (키보드 레코딩) : 
  가끔 연속된 연속기만으로는 부족한경우가 있다.
  이럴때, 몇번의 키동작으로 레코딩하여, 이것을 반복하고 싶은경우가있다.
  이때 Ctrl+Shift+R 을 누르고, 원하는 동작들을 수행후, 다시 Ctrl+Shift+R을
  눌러 종료한다.  이 중간동작을 원하는 위치에서 반복하고 싶다면 
  Ctrl+Shift+P 를 누른다.
 
Ctrl+Shift+V (히스토리 붙이기) :
  Ctrl + V와는 달리 클립보드에 있는 복사된내용을 돌아가면서 붙여준다.
  따로 복사를 해주거나 할 필요는 없다. 그냥 Ctrl+C로 계속 원하는것을
  복사하면 된다.

Ctrl-Z : 이전으로 되돌리기

Ctrl-Shift-Z : 되돌렸다, 다시 복구하기



<디버그/빌드>-------------------------------------------------------------------------
F5 : 디버그 시작
F9 :디버그 브렉포인트 설정
Ctrl-F9 : 현위치 설정된 브렉포인트 해제
Ctrl-Shift-F9 : 모든 브렉포인트 해
Shift-F5 : 디버그 빠져나오기
Ctrl-F10 : 커서가 있는곳까지 실행
Shift-F11 : 현 함수를 빠져나감.

Shift+Ctrl+B :  전체 빌드(프로젝트가 여러개있을경우 모두 빌드)
Alt+B, C : 해당 프로젝트만 정리.
Alt+B, U : 해당 프로젝트만 빌드.


 

<창관련>-------------------------------------------------------------------------

Shift+Alt+Enter : 전체 창 (토글 됨)
F4 : 속성창 보여준다.
Ctrl+Alt+X : 리소스에디터 툴박스창
Ctrl+Alt+K : 작업목록 창.


[출처 : http://ydux.tistory.com/39]


# 에러 내용 #

1) 외부에서 원격서버 접속시 발생
Could not establish connection! Details:
SQL Error: Access denied for user 
'userid'@'192.168.1.111' (using password: YES)


2) mysql 백업시 발생
 예) mysqldump -u 사용자 아이디 -p 데이타베이스명 > 파일명.sql
# mysqldump -u userid -p database_name > user.sql
# Enter password: 패스워드입력

mysqldump: Got error: 1045: Access denied for user 'root'@'localhost' (using password: NO) when trying to connect


# 원격서버에 접속을 하고자하는 호스트 접속권한 주기 
mysql>GRANT ALL PRIVILEGES ON userid.* TO 'userid'@'192.168.1.111' IDENTIFIED BY 'password' WITH GRANT OPTION;


# 접속권한을 줄때 중요한 부분은 'userid'@'192.168.1.111' 입니다.
'사용자명'@'호스트' 와 같은 형식인데, 에러가 발생하는 내용의 호스트를 연결설정에서 적용해줍니다.
예) 위에서의 2) mysql 백업시 발생 오류 처리
mysql>GRANT ALL PRIVILEGES ON userid.* TO 'userid'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;





[출처 : http://develop.sunshiny.co.kr/407]


CVS의 단점들을 개선한 버전 관리 시스템인 Subversion을 이용하여 프로그램의 소스 코드를 관리하는 방법과 유닉스, 리눅스 및 Windows에서 Subversion을 설치해보고 사용하는 방법을 설명합니다.

목차

1 소프트웨어 버전 관리의 이해
1.1 버전 관리 시스템의 필요성
1.2 버전 관리 시스템의 종류
1.3 버전 관리 시스템의 용어들
1.4 저장소의 디렉토리 배치
2 Subversion
2.1 CVS와 비교한 Subversion의 장점들
2.2 설치 준비 작업
2.3 사용 할 각각의 파일들 구하기
3 설치하기
3.1 OpenSSL 컴파일과 설치
3.2 Berkeley DB 컴파일과 설치
3.3 Apache 컴파일과 설치
3.4 Subversion 컴파일과 설치
4 세부 설정
4.1 저장소 만들기
4.1.1 공동 작업을 위한 저장소 그룹 설정
4.2 Apache 설정
4.2.1 Apache에서 ID로 사용자 인증
4.3 svnserve를 사용한 서버
4.3.1 svnserve에서 ID로 사용자 인증
4.4 SSH + svnserve 서버
5 실제로 사용하기
5.1 에디터 설정
5.2 기본 디렉토리 만들기
5.3 Import
5.4 Checkout
5.5 Update
5.6 Commit
5.7 Log
5.8 Diff
5.9 Blame
5.10 lock
5.11 Add
5.12 Rename
5.13 Export
5.14 Branch와 Tag
5.14.1 Branch
5.14.1.1 Merge
5.14.2 Tag
5.15 Revert
5.16 백업 및 복구
5.16.1 Dump
5.16.2 Load
5.17 svnsync
6 Microsoft Windows에서 사용하기
6.1 설치 파일 구하기
6.2 설치
6.3 사용하기
7 운영체제별 전용 패키지
8 GUI 클라이언트 프로그램
8.1 TortoiseSVN
8.2 Ankhsvn
8.3 RapidSVN
9 웹 인터페이스
9.1 ViewVC
9.2 WebSVN


1 소프트웨어 버전 관리의 이해 #

Subversion은 소프트웨어 버전 관리 시스템입니다. 이전에 CVS같은 역사가 깊은 소프트웨어 버전 관리 시스템을 사용해 본 경험이 있다면 쉽게 진행 할 수 있을 것입니다. 이 장에서는 소프트웨어 버전 관리 시스템을 처음 접하는 분들을 위해 자주 나오는 용어들과 개념을 정리 하였습니다.

1.1 버전 관리 시스템의 필요성 #

과연 소프트웨어를 만드는데 버전관리가 왜 필요할까요? 버전 관리가 필요하게 된 이유는 공동 작업 때문입니다. 한사람이 큰 프로젝트를 진행 하는 것이 아니기 때문에 버전 관리 시스템이 필요 하게 되었습니다.

버전 관리 프로그램을 사용하게 되면 다음과 같은 장점이 있습니다.
  • 개발 버전과 릴리즈 버전이 섞이지 않고 쉽게 관리 할 수 있습니다.
  • 소스를 잘못 수정 했더라도 기록이 남고 되돌리기가 쉽습니다.(많은 파일의 경우 유용)
  • 수정, 추가, 삭제 등의 기록이 모두 남고 변경 사항을 추적하기 쉽습니다.
  • 개발자들이 따로 따로 백업을 하지 않아도 됩니다.

가장 유용한 장점은 아무래도 잘못 수정한 소스를 쉽게 되돌릴 수 있다는 것입니다. 프로젝트가 커지다보면 소스가 꼬이게 되고 골치 아픈 상황이 한두 번 발생하는 것이 아니죠. 그리고 변경 사항이 모두 기록되고 무엇을 변경 했는지 쉽게 볼 수 있습니다. 옆 사람이 수정한 것을 쉽게 볼 수 있습니다. 그리고 가장 큰 문제를 일으키는 백업을 하지 않아 소스를 분실하는 최악의 상황도 쉽게 해결 됩니다.

장점을 나열하자면 더 많습니다만 단점을 이야기 하자면 아무래도 프로그램 개발자들이 소프트웨어 버전 관리 시스템의 개념을 제대로 이해하고 기능들을 잘 사용하여 효율적인 버전 관리가 되려면 또다시 새로운 것을 배워야 한다는 것 때문에 쉽게 접근하지 않으려는 경향이 있습니다. 특히나 우리나라 프로그램 개발자들의 경우 윈도우 공유 폴더를 이용해서 개발을 하는 경우가 많습니다. 이렇게 되면 누가 무엇을 수정했는지 알 수도 없고 남이 해 놓은 소스 위에 잘못된 소스를 덮어쓰는 경우도 많이 발생하고 있습니다.

한사람이 개인적으로 진행 하는 프로젝트가 있더라도 버전 관리 프로그램을 사용하는 것이 매우 편리합니다. 앞서 말한 장점들은 여러 명이 개발 하는 것과 한사람이 개발 하는 것에 모두 해당되는 것들입니다.

소프트웨어 버전 관리 시스템을 이용하는 프로젝트들은 아주 많습니다. 대부분 Open Source로 된 프로젝트들은 CVS를 이용하여 버전 관리를 합니다. 대표적으로 *BSD, OpenOffice, Mozilla, XFree86, Apache와 SourceForge.net의 모든 프로젝트들 입니다. 비단 Open Source 뿐만이 아닌 상업 프로그램을 만드는 회사들에서도 소프트웨어 버전 관리 시스템은 필수적입니다. 

1.2 버전 관리 시스템의 종류 #

현재 나와 있는 소프트웨어 버전 관리 시스템은 여러 종류가 있습니다. 각각 장단점이 있습니다.
  • CVS (Concurrent Version System) : 가장 널리 사용되며 역사가 깊은 버전 관리 시스템입니다.http://www.cvshome.org[]
  • Subversion : CVS의 단점을 개선하고 CVS를 대체할 목적으로 개발 되었습니다. 이 문서에서 설명할 버전 관리 시스템입니다. http://subversion.tigris.org[]
  • Visual Sourcesafe : Microsoft에서 만든 버전 관리 시스템입니다. CVS와는 버전 관리 관점에서 조금의 차이점이 있습니다. 윈도우 기반 소프트웨어의 버전 관리를 할 때 자주 사용됩니다.http://msdn.microsoft.com/ssafe/[]
  • Clear Case : Rational이라는 회사에서 만든 버전 관리 시스템입니다. 지금은 IBM에 합병되었습니다. 상용 소프트웨어입니다. http://www-306.ibm.com/software/rational[]
  • BitKeeper : 리눅스 커널이 BitKeeper를 이용해서 개발 하고 있습니다. 상용 소프트웨어입니다.http://www.bitkeeper.com[]

1.3 버전 관리 시스템의 용어들 #

소프트웨어 버전 관리 시스템에서 사용되는 용어들을 알아보도록 하겠습니다.

저장소 : 리포지토리(Repository)라고도 하며 모든 프로젝트의 프로그램 소스들은 이 저장소 안에 저장이 됩니다. 그리고 소스뿐만이 아니라 소스의 변경 사항도 모두 저장됩니다. 네트워크를 통해서 여러 사람이 접근 할 수 있습니다. 버전 관리 시스템 마다 각각의 저장소 포맷을 가지고 있으며 Subversion은 Berkeley DB를 사용합니다. 한 프로젝트 마다 하나의 저장소가 필요합니다.

체크아웃 : 저장소에서 소스를 받아오는 것입니다. 체크아웃을 한 소스를 보면 프로그램 소스가 아닌 다른 디렉토리와 파일들이 섞여 있는 것을 볼 수 있습니다. 이 디렉토리와 파일들은 버전 관리를 위한 파일들입니다. 임의로 지우거나 변경하면 저장소와 연결이 되지 않습니다. 이 체크아웃에는 권한을 줄 수 있습니다. 오픈 소스 프로젝트들에서는 대부분 익명 체크아웃을 허용하고 있습니다.

커밋(Commit) : 체크아웃 한 소스를 수정, 파일 추가, 삭제 등을 한 뒤 저장소에 저장하여 갱신 하는 것입니다. 커밋을 하면 CVS의 경우 수정한 파일의 리비전이 증가하고 Subversion의 경우 전체 리비전이 1 증가하게 됩니다.

업데이트(Update) : 체크아웃을 해서 소스를 가져 왔더라도 다른 사람이 커밋을 하였다면 소스가 달라졌을 것입니다. 이럴 경우 업데이트를 하여 저장소에 있는 최신 버전의 소스를 가져옵니다. 물론 바뀐 부분만 가져옵니다.

리비전(Revision) : 소스 파일등을 수정하여 커밋하게 되면 일정한 규칙에 의해 숫자가 증가 합니다. 저장소에 저장된 각각의 파일 버전이라 할 수 있습니다. Subversion의 경우 파일별로 리비전이 매겨지지 않고 한번 커밋 한 것으로 전체 리비전이 매겨 집니다. 리비전을 보고 프로젝트 진행 상황을 알 수 있습니다.

임포트(Import) : 아무것도 들어있지 않은 저장소에 맨 처음 소스를 넣는 작업입니다.

익스포트(Export) : 체크아웃과는 달리 버전 관리 파일들을 뺀 순수한 소스 파일을 받아올 수 있습니다. 오픈소스 프로젝트의 경우 소스를 압축하여 릴리즈 할 때 사용합니다. 

1.4 저장소의 디렉토리 배치 #

저장소에 바로 소스를 넣어 프로젝트를 진행 할 수 있습니다. 그렇지만 버전 관리 시스템에서 권장하는 디렉토리 배치 방법이 있습니다.
-- http://svn.samplerepository.org/svn/sample
 +--+---+- branches
    |   +--+- dav-mirror
    |   |  |--- src
    |   |  |--- doc
    |   |  +--- Makefile
    |   |
    |   +--- svn-push
    |   +--- svnserve-thread-pools
    |
    +---+- tags
    |   +--- 0.10
    |   +--+- 0.10.1
    |   |  |--- src
    |   |  |--- doc
    |   |  +--- Makefile
    |   |
    |   +--- 0.20
    |   +--- 0.30
    |   +--- 0.50
    |   +--- 1.01
    |
    +---+- trunk
        |--- src
        |--- doc
        +--- Makefile

위에 보이는 구조는 보통 자주 사용되는 디렉토리 구조입니다. 저장소 디렉토리 아래 branches, tags, trunk 라는 3개의 디렉토리가 있습니다. 이 디렉토리들은 각각의 용도가 있습니다. CVS는 branch와 tag를 위한 명령이 따로 존재 하지만. Subversion의 경우 명령이 있긴 하지만 단순한 디렉토리 복사와 같은 효과를 냅니다.

trunk : 단어 자체의 뜻은 본체 부분, 나무줄기, 몸통 등 입니다. 프로젝트에서 가장 중심이 되는 디렉토리입니다. 모든 프로그램 개발 작업은 trunk 디렉토리에서 이루어집니다. 그래서 위의 구조에서 trunk 디렉토리 아래에는 바로 소스들의 파일과 디렉토리가 들어가게 됩니다.

branches : 나무줄기(trunk)에서 뻗어져 나온 나무 가지를 뜻합니다. trunk 디렉토리에서 프로그램을 개발하다 보면 큰 프로젝트에서 또 다른 작은 분류로 빼서 따로 개발해야 할 경우가 생깁니다. 프로젝트안의 작은 프로젝트라고 생각하면 됩니다. branches 디렉토리 안에 또 다른 디렉토리를 두어 그 안에서 개발하게 됩니다.

tags : tag는 꼬리표라는 뜻을 가지고 있습니다. 이 디렉토리는 프로그램을 개발하면서 정기적으로 릴리즈를 할 때 0.1, 0.2, 1.0 하는 식으로 버전을 붙여 발표하게 되는데 그때그때 발표한 소스를 따로 저장하는 공간입니다. 위에서 보면 tags 디렉토리 아래에는 버전명으로 디렉토리가 만들어져 있습니다. 

2 Subversion #

Subversion은 CVS를 대체하기 위해 개발되고 있습니다. Subversion은 소스 코드는 물론 바이너리 파일 등의 여러가지 형식의 파일을 관리 할 수 있습니다.

2.1 CVS와 비교한 Subversion의 장점들 #

  • 커밋 단위가 파일이 아니라 체인지셋이라는 점입니다. CVS에서라면 여러 개의 파일을 한꺼번에 커밋하더라도 각각의 파일마다. 리비전이 따로 붙습니다. 반면 Subversion에서는 파일별 리비전이 없고 한번 커밋할 때마다 변경 사항별로 리비전이 하나씩 증가합니다.
  • CVS에 비해 엄청나게 빠른 업데이트/브랜칭/태깅 시간.
  • CVS와 거의 동일한 사용법. CVS 사용자라면 누구나 어려움 없이 금방 배울 수 있습니다.
  • 파일 이름변경, 이동, 디렉토리 버전 관리도 지원.
  • 원자적(atomic) 커밋. CVS에서는 여러 파일을 커밋하다가 어느 한 파일에서 커밋이 실패했을 경우 앞의 파일만 커밋이 적용되고 뒤의 파일들은 그대로 남아있게 됩니다. Subversion은 여러개의 파일을 커밋하더라도 커밋이 실패하면 모두 이전 상태로 되돌아 갑니다.
  • 양방향 데이터 전송으로 네트워크 소통량(트래픽) 최소화.
  • 트리별, 파일별 접근 제어 리스트. 저장소 쓰기 접근을 가진 개발자라도 아무 소스나 수정하지 못하게 조절할 수 있습니다.
  • 저장소/프로젝트별 환경 설정 가능
  • 확장성을 염두에 둔 구조, 깔끔한 소스

2.2 설치 준비 작업 #

이 장에서는 리눅스, 유닉스 등의 POSIX 호환 운영체제에서 소스를 컴파일하고 설치하는 방법을 다루고 있습니다.

Microsoft Windows에서의 사용은 Microsoft Windows에서 사용하기 장을 참조하십시오.

각각 리눅스 배포판 및 FreeBSD, NetBSD 등의 전용 패키지에 대해서는 운영체제별 전용 패키지 장을 참조하십시오.

설치를 위해 준비해야 할 일. 

2.3 사용 할 각각의 파일들 구하기 #

위의 파일들을 /root에 받습니다. 

3 설치하기 #

Subversion과 연관된 프로그램들을 컴파일 하고 설치하겠습니다.

3.1 OpenSSL 컴파일과 설치 #

# tar vxzf openssl-0.9.7c.tar.gz
# cd openssl-0.97c
openssl-0.97c# ./config
openssl-0.97c# make
openssl-0.97c# make install

3.2 Berkeley DB 컴파일과 설치 #

Berkeley DB는 bdb 형식의 저장소를 사용할 때 필요합니다. fsfs 형식의 저장소만 사용할 경우 Berkeley DB는 설치하지 않아도 됩니다.
# tar vxzf db-4.3.29.tar.gz
# cd db-4.3.29
db-4.3.29# cd build_unix
db-4.3.29/build_unix# ../dist/configure
db-4.3.29/build_unix# make
db-4.3.29/build_unix# make install
db-4.3.29/build_unix# echo "/usr/local/BerkeleyDB.4.3/lib" >> /etc/ld.so.conf
db-4.3.29/build_unix# ldconfig

3.3 Apache 컴파일과 설치 #

Apache는 설치해도 되고 안 해도 됩니다. 웹으로 저장소를 공개한다거나. http:// 프로토콜을 이용해서 subversion을 이용하고 싶다면 설치하도록 합니다.
# tar vxzf httpd-2.0.59.tar.gz
httpd-2.0.59# ./configure --prefix=/usr/local/apache2 --enable-suexec \
                          --enable-so --with-suexec-caller=bin \
                          --enable-ssl --with-ssl=/usr/local/ssl --enable-cache \
                          --enable-ext-filter --with-z=/usr/include --enable-dav \
                          --with-dbm=db4 --with-berkeley-db=/usr/local/BerkeleyDB.4.2
httpd-2.0.59# make
httpd-2.0.59# make install

Berkeley DB를 설치하지 않은 경우
# tar vxzf httpd-2.0.59.tar.gz
httpd-2.0.59# ./configure --prefix=/usr/local/apache2 --enable-suexec \
                          --enable-so --with-suexec-caller=bin \
                          --enable-ssl --with-ssl=/usr/local/ssl --enable-cache \
                          --enable-ext-filter --with-z=/usr/include --enable-dav
httpd-2.0.59# make
httpd-2.0.59# make install

3.4 Subversion 컴파일과 설치 #

데비안의 경우 zlib1g-dev, libxml2-dev, libexpat1-dev의 패키지가 필요합니다. 다른 배포판의 경우도 거의 같은 이름으로된 패키지가 있을 것입니다. 이 패키지들은 라이브러리와 헤더 파일을 포함하고 있는 것들입니다. 

앞에서 Apache를 설치했을 경우
# tar vxzf subversion-1.4.2.tar.gz
# tar vxzf subversion-deps-1.4.2.tar.gz
# cd subversion-1.4.2
subversion-1.4.2# ./configure --with-zlib \
                           --with-apxs=/usr/local/apache2/bin/apxs \
                           --with-berkeley-db=/usr/local/BerkeleyDB.4.3
subversion-1.4.2# make
subversion-1.4.2# make install

앞에서 Apache를 설치했을 경우(Berkeley DB를 사용하지 않고자 하는 경우)
# tar vxzf subversion-1.4.2.tar.gz
# tar vxzf subversion-deps-1.4.2.tar.gz
# cd subversion-1.4.2
subversion-1.4.2# ./configure --with-zlib \
                           --with-apxs=/usr/local/apache2/bin/apxs \
                           --without-berkeley-db
subversion-1.4.2# make
subversion-1.4.2# make install

Apache를 설치하지 않았을 경우
# tar vxzf subversion-1.4.2.tar.gz
# tar vxzf subversion-deps-1.4.2.tar.gz
# cd subversion-1.4.2
subversion-1.4.2# ./configure --with-zlib \
                              --with-berkeley-db=/usr/local/BerkeleyDB.4.3
subversion-1.4.2# make
subversion-1.4.2# make install

Apache를 설치하지 않았을 경우(Berkeley DB를 사용하지 않고자 하는 경우)
# tar vxzf subversion-1.4.2.tar.gz
# tar vxzf subversion-deps-1.4.2.tar.gz
# cd subversion-1.4.2
subversion-1.4.2# ./configure --with-zlib \
                              --without-berkeley-db
subversion-1.4.2# make
subversion-1.4.2# make install

4 세부 설정 #

4.1 저장소 만들기 #

소스를 저장할 공간을 만들어야 합니다. 저장소(Repository)는 프로젝트 마다 하나씩 있어야 합니다. 저장소 안에 프로젝트의 소스가 다 들어가게 되며 다른 프로젝트를 진행한다면 그 프로젝트를 위한 저장소를 하나 더 만들어 주어야 합니다. /home/svn안에 저장소를 만들도록 하겠습니다. 앞으로 저장소를 추가 할 때에는 /home/svn 아래에 추가하면 됩니다. 꼭 /home/svn에 하지 않아도 되며 다른 곳에 해도 됩니다.

버클리DB를 이용한 저장소 만들기
# mkdir /home/svn
# cd /home/svn/
/home/svn# svnadmin create --fs-type bdb sample

파일시스템을 이용한 저장소 만들기
# mkdir /home/svn
# cd /home/svn/
/home/svn# svnadmin create --fs-type fsfs sample

svnadmin으로 sample이라는 저장소를 만들면 /home/svn 아래 sample이라는 디렉토리가 생깁니다. 이 디렉토리 안에는 Subversion이 제어하는 파일들이 들어있습니다. 이 디렉토리 안의 파일들은 Berkeley DB 형식으로 되어 있습니다. DB 파일들은 수정하는 일이 없도록 합니다. sample 저장소의 전체 경로는 /home/svn/sample이 됩니다.

이제부터 sample 저장소를 계속 사용하여 설명을 하겠습니다. 

4.1.1 공동 작업을 위한 저장소 그룹 설정 #

svn+ssh://로 작업을 하려면 시스템 계정을 만들어야 합니다. 대부분 계정을 만들고 그룹을 하나로 묶는데. 이럴 경우 그룹에 소속된 사용자들에게도 저장소 쓰기 권한을 주어야 합니다. 그래서 저장소의 그룹 권한을 조정해주어야 합니다. 그룹 쓰기 권한을 주지 않으면 저장소를 만든 계정만 저장소에 접근이 가능하고. 그룹에 속해 있더라도 다른 사용자는 저장소에 접근 할 수 없게 됩니다. 
# chmod -R g+w sample

4.2 Apache 설정 #

Apache를 설치했다면 Apache 설정을 해주어야 합니다.

Apache가 저장소에 접근할 수 있도록 소유자와 권한을 바꿉니다. Apache는 기본적으로 설치하면 nobody와 nogroup로 실행됩니다.
# cd /home/svn
/home/svn# chown -R nobody.nogroup sample

Apache를 /usr/local/apache2에 설치했으므로 설정파일은 /usr/local/apach2/conf/httpd.conf 입니다. dav, dav_svn 모듈이 설정되어 있는지 확인 합니다. 주석처리 되어 있으면 주석을 없애고 없다면 아래 두줄을 추가합니다.
LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so

httpd.conf 파일 맨 뒷부분에 아래와 같이 추가 합니다. 설정을 저장한 뒤에 Apache를 재시작 합니다.
<Location /svn/sample>
  DAV svn
  SVNPath /home/svn/sample
</Location>
이렇게 설정을 하고 웹 브라우저에서 http://(Subversion과 Apache를 설치한 IP주소 또는 도메인)/svn/sample 로 접속을 합니다.

웹 브라우저에 아래와 같은 화면이 보이면 Subversion 저장소와 아파치가 잘 동작하고 있는 것입니다. 아래와 같이 나오지 않는다면 아파치 설정과 저장소의 소유자와 그룹을 다시 한 번 살펴보시기 바랍니다.
Revision 0: /

--------------------------------------------------------------------------------
Powered by Subversion version 1.0.0.
위와 같이 설정하면 누구든지(Anonymous) 웹 브라우저로 저장소를 볼 수 있고 Subversion 클라이언트를 이용해서 소스를 체크아웃, 익스포트, 커밋을 할 수 있습니다.

이렇게 실행 시켰으면 "# svn checkout http://(Subversion서버 IP또는 도메인)/svn/sample sample"을 입력합니다. "Checked out revision 0."이 나오면 제대로 설정이 된 것입니다. 아무나(Anonymous) 저장소에 접근해서 체크아웃, 커밋 등을 할 수 있습니다. 

4.2.1 Apache에서 ID로 사용자 인증 #

이제 ID를 통해 인증된 사용자만 소스를 체크아웃하고 커밋 할 수 있도록 설정 하겠습니다.
아파치에 사용할 패스워드 파일을 만듭니다. "# htpasswd -c 패스워드파일명 사용자ID"
# cd /usr/local/apache/conf
/usr/local/apache/conf# ../bin/htpasswd -c passwd sampleuser
New password:
Re-type new password:
"# htpasswd -c"는 패스워드 파일을 처음 만들 때의 옵션이고 사용자를 추가하고 싶을 때에는 "# htpasswd 패스워드파일명 사용자ID" 로 해주면 됩니다.

방금 수정했던 /usr/local/apache2/conf/httpd.conf 파일의 맨 마지막 부분에 추가한 부분을 다시 설정 합니다.
<Location /svn/sample>
  DAV svn
  SVNPath /home/svn/sample
  AuthType Basic
  AuthName "pyrasis's Repository"
  AuthUserFile /usr/local/apache2/conf/passwd
  Require valid-user
</Location>
4줄이 추가 되었습니다. AuthType Basic은 Apache 기본 패스워드 인증입니다. AuthName은 패스워드가 걸린 웹페이지에 뜨는 로그인창에 나올 문장입니다. AuthUserFile은 방금 전 만들었던 아파치 패스워드 파일입니다. 절대경로로 적어주어야 합니다. Require valid-user는 인증된 사용자만 볼 수 있게 한다는 것입니다.

이제 웹 브라우저로 다시 sample저장소로 접속해 보면 ID와 패스워드를 묻는 창이 나올 것입니다. 만든 ID와 패스워드를 입력하면 저장소를 볼 수 있습니다. 이렇게 되면 체크아웃, 커밋등을 할 때 ID와 암호를 물어보게 됩니다.

웹 브라우저로 저장소를 보는 것과 체크아웃은 아무에게나(Anonymous) 할 수 있게 하고 커밋은 지정된 사용자만 할 수 있도록 하려면 httpd.conf에서 설정한 부분을 아래와 같이 바꾸어 주면 됩니다.
<Location /svn/sample>
  DAV svn
  SVNPath /home/svn/sample
  AuthType Basic
  AuthName "pyrasis's Repository"
  AuthUserFile /usr/local/apache2/conf/passwd
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>
이렇게 하면 저장소를 보거나 체크아웃을 할 때는 ID와 패스워드를 묻지 않고 커밋이나 디렉토리. 파일복사 등의 저장소를 변경하는 작업을 할 때에는 ID와 패스워드를 물어보게 됩니다.

"# svn checkout http://(Subversion서버 IP또는 도메인)/svn/sample sample" 을 입력하면 ID와 패스워드를 물어옵니다. ID와 패스워드를 입력하고 나서 "Checked out revision 0." 이 출력되면 제대로 설정 된 것입니다. 

4.3 svnserve를 사용한 서버 #

Subversion의 고유 프로토콜인 svn://을 이용할 수 있는 svnserve를 사용해서 서버 설정을 해보겠습니다. 이것을 사용하면 Apache를 사용한 것보다 체크아웃, 커밋 속도가 더 빠릅니다.

svnserve로 서버를 실행 시키면 3690번의 포트가 열립니다. sample 저장소가 /home/svn 아래에 있을 경우
# svnserve -d -r /home/svn/

이렇게 실행 시켰으면 "# svn checkout svn://(Subversion서버 IP또는 도메인)/sample sample"을 입력합니다. "Checked out revision 0."이 나오면 제대로 설정이 된 것입니다. 이것 또한 아무나(Anonymous) 저장소에 접근해서 체크아웃, 커밋 등을 할 수 있습니다. 

4.3.1 svnserve에서 ID로 사용자 인증 #

Subversion 0.33.0버전 이후부터 svnserve로 ID로 사용자 인증이 가능하게 되었습니다. 그 이전 버전에서 svnadmin으로 저장소를 만들면 저장소 디렉토리 아래에 conf 디렉토리가 생기지 않지만 0.33.0 버전이후에 svnadmin으로 저장소를 만들었다면 저장소 디렉토리 아래에 conf 디렉토리가 자동으로 생성됩니다. 이전 버전에서 먼저 저장소를 만들어 두었다면 저장소 디렉토리 /home/svn/sample 아래 conf 디렉토리를 만들어 줍니다. (/home/svn/sample/conf)

이제 각 저장소 디렉토리 아래 conf 디렉토리가 있습니다. /home/svn/sample/conf/svnserve.conf 파일이 svnserve의 설정 파일입니다. 0.33.0 버전 이전 만든 저장소에는 conf 디렉토리 및 svnserve.conf 파일이 없습니다. 그럴 경우에는 conf 디렉토리와 svnserve.conf 파일을 만들어 주면 됩니다. 

svnserve.conf 파일을 아래와 같이 설정 합니다.
### This file controls the configuration of the svnserve daemon, if you
### use it to allow access to this repository.  (If you only allow
### access through http: and/or file: URLs, then this file is
### irrelevant.)

### Visit http://subversion.tigris.org/ for more information.

[general]
### These options control access to the repository for unauthenticated
### and authenticated users.  Valid values are "write", "read",
### and "none".  The sample settings below are the defaults.
anon-access = none
auth-access = write
### The password-db option controls the location of the password
### database file.  Unless you specify a path starting with a /,
### the file's location is relative to the conf directory.
### The format of the password database is similar to this file.
### It contains one section labelled [users]. The name and
### password for each user follow, one account per line. The
### format is
###    USERNAME = PASSWORD
### Please note that both the user name and password are case
### sensitive. There is no default for the password file.
password-db = passwd
### This option specifies the authentication realm of the repository.
### If two repositories have the same authentication realm, they should
### have the same password database, and vice versa.  The default realm
### is repository's uuid.
realm = pyrasis's Repository

anon-access = none으로 아무에게나(Anonymous) 저장소에 접근하는 것을 막았습니다. read로 하면 읽기만 가능하며 write로 해주면 읽고 쓰기가 가능해집니다.

auth-access = write는 ID로 인증된 사용자에게 쓰기 권한을 주는 것입니다.

password-db = passwd 이 설정은 svnserve의 패스워드 파일입니다 이전의 Apache 패스워드 파일과는 별개입니다. 아래 내용으로 /home/svn/sample/conf 아래 passwd 라는 이름으로 만듭니다. ID = 패스워드 형식 입니다. 아직 암호화된 패스워드는 지원하지 않는 것 같습니다. 버전 업을 통해 개선 될 것 같습니다.

passwd
[users]
sampleuser = 02030104

이제 "# svn checkout svn://(Subversion 서버의 IP또는 도메인)/sample sample" 을 해보면 ID와 패스워드를 입력하라고 나옵니다. 위에서 설정했던 ID와 패스워드를 입력하면 체크아웃이 되며 "Checked out revision 0." 이 나오면 설정이 제대로 된 것입니다. 

4.4 SSH + svnserve 서버 #

SSH2 데몬으로 svnserve을 터널링 하여 작동시킵니다. 이렇게 되면 svn+ssh:// 프로토콜을 사용하게 되며 사용자 인증은 시스템 계정으로 인증을 합니다. 구동시키는 방법은 따로 있지 않으며 SSH데몬만 떠 있으면 됩니다.

클라이언트에서 svn+ssh:// 를 사용하기

클라이언트에서 서버로 접속할 ID설정, 각 사용자 계정의 디렉토리에 .subversion이라는 디렉토리가 있습니다. 여기에 보면 config 라는 파일의 맨 마지막에 아래와 같이 추가합니다. ssh -l 서버에 접속할 ID

~/.subversion/config
[tunnels]
ssh = ssh -l sampleuser

주의할 점은 IP주소나 도메인 뒤에 저장소의 절대 경로를 적어주어야 합니다. svnserve를 띄워서 /home/svn/과 같이 지정해 주지 않았기 때문에 각 저장소의 절대경로인 /home/svn/sample로 합니다.
# svn checkout svn+ssh://(Subversion 서버의 IP주소 또는 도메인)/home/svn/sample sample

5 실제로 사용하기 #

간단한 예제 프로그램을 통해서 Subversion의 사용법을 알아보도록 하겠습니다. 커맨드 라인 클라이언트을 통해 알아보겠습니다. X 윈도우, MS 윈도우용 GUI 클라이언트 프로그램에 대해서는 뒤에 설명하도록 하겠습니다. 

5.1 에디터 설정 #

Subversion에서 사용할 기본적인 에디터를 지정해야 합니다. 이것을 지정하지 않으면 커밋 등을 할 수 없게 됩니다.

각 사용자 계정의 디렉토리에는 .profile이나 .bash_profile 등의 환경 변수 등을 지정하는 파일이 있습니다. 여기에 아래와 같이 추가 합니다. 여기에서는 에디터를 vim으로 설정 하겠습니다. vim의 경로는 사용자마다 다를 수 있으므로 사용하고자 하는 시스템에 맞게 적어주십시오.
SVN_EDITOR=/usr/bin/vim
export SVN_EDITOR

5.2 기본 디렉토리 만들기 #

앞서 설명 했던 trunk, branches, tags 디렉토리를 만들어 보겠습니다.

trunk 디렉토리의 생성, 앞에서 Apache를 통해 설정 했다면 http://를 svnserve로 설정했다면 svn://로 SSH를 사용한다면 svn+ssh://로 하여 서버 설정에 맞게 주소를 적어 주십시오.
apache를 연동한 경우
# svn mkdir http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk
svnserve만 실행한 경우
# svn mkdir svn://(Subversion서버 IP또는 도메인)/sample/trunk
위처럼 입력을 하면 vim이 실행되면서 아래와 같이 나올 것입니다. :q!로 빠져 나갑니다.
--This line, and those below, will be ignored--

A    http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk

vim을 빠져 나왔다면 아래와 같이 나오는데(커밋 로그를 입력하지 않으면 아래와 이 나오게됩니다.) c를 누르고 엔터를 치면 디렉토리가 만들어 지게 됩니다.
Log message unchanged or not specified
a)bort, c)ontinue, e)dit

c를 입력한뒤 아래와 같이 나오면 디렉토리 생성은 성공한 것입니다. 이 방법대로 branches, tags 디렉토리도 만듭니다.
Committed revision 1.

만약 read-only에러가 나올 경우 conf/svnserve.conf에서 계정을 만들지 않아서 그렇습니다. anonymous로 사용할 경우 #general, #anon-access = read 가 주석 처리 되어 있는데 주석을 없애고 anon-access = write로 바꾸시면 됩니다.

제대로 만들어 졌는지 확인을 하려면 다음과 같이 입력 합니다. list는 저장소 안의 디렉토리와 파일들을 표시해 줍니다.
# svn list http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample
branches/
tags/
trunk/

앞으로 디렉토리 생성, 삭제, 이름변경, 파일, 추가, 삭제, 복사, 이동과 커밋, 등을 할 때 vim이 실행되면서 어떤 것들이 바뀌는지 표시가 됩니다. 커밋 로그를 입력한뒤 vim을 종료하면 커밋이 완료 됩니다. 커밋 로그를 입력하지 않았을 경우a)bort, c)ontinue, e)dit가 나오게 되는데 c)ontinue)로 계속 하면 됩니다.
<!> 하지만! 커밋 로그 입력은 필수입니다. 소프트웨어 버전 관리에서 가장 중요한 것은 커밋 로그입니다. 어떤 코드를 어떻게 수정했고 디렉토리, 파일을 만들고 삭제 했는지를 꼼꼼히 기록해야합니다. 나중에 소스코드가 바뀌는 흐름을 따라가고자 할때나 문제점(버그)을 추적할때 커밋 로그가 아주 유용하게 이용될 것입니다.

5.3 Import #

맨 처음 프로젝트를 시작할 때 저장소에 소스들을 넣어야 합니다. 이럴 때 하는 것이 import 작업입니다. sampledir 이라는 디렉토리를 만든 뒤에 그 아래 다음과 같은 간단한 소스를 작성해 보십시오.
# mkdir sampledir
# cd sampledir
sampledir# vim sample.c
#include <stdio.h>

int main()
{
  printf("Sample Program Version 0.1\n");

  return 0;
}

이 소스를 저장소의 trunk 디렉토리에 import 하겠습니다. 아래 sampledir은 디렉토리입니다. 파일을 적으면 import되지 않습니다. 꼭 디렉토리를 만들고 그 디렉토리를 적어 주십시오. 저장소의 trunk 디렉토리에는 sampledir 디렉토리안의 sample.c 파일만 올라가게 되고 sampledir은 올라가지 않습니다. sampledir 아래 디렉토리를 만들었다면 그 디렉토리는 저장소의 trunk 디렉토리 아래에 올라가게 됩니다.
sampledir# cd ..
# svn import sampledir http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk
import도 위에서 디렉토리를 만들었을 때 처럼 vim이 실행되게 됩니다. import되는 파일들이 표시됩니다. :q!로 닫고 c를 입력하면 import 되게 됩니다.

import가 제대로 되었는지 확인해 봅시다. list 명령을 이용해 trunk 디렉토리에 무엇이 있나 보겠습니다.
# svn list http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk
sample.c


5.4 Checkout #

이제 부터 Subversion을 이용해서 프로그램 소스를 관리 할 수 있습니다. checkout을 해서 어디서든 소스를 받아 볼 수 있습니다. 방금 import를 하기위해 만들었던 sampledir은 지워도 됩니다.

svn checkout은 svn co로 줄일 수 있습니다. "svn checkout 저장소주소 로컬디렉토리" 의 형식 입니다.
# svn checkout http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk sample
A  sample/sample.c
Checked out revision 4.

checkout을 한 디렉토리 안에는 .svn 이라는 디렉토리가 있습니다. 이 디렉토리는 Subversion 저장소 정보가 들어 있기 때문에 지우면 안 됩니다.

5.5 Update #

체크아웃 해서 받은 소스를 저장소의 최근 내용으로 업데이트 하는 명령입니다. 체크아웃 해서 받은 소스의 revision보다 저장소의 revision이 높으면 업데이트 하게 됩니다. 업데이트를 하게 되면 전부 다 받아오는 것이 아니라 변경 된 것들만 받아옵니다. 소스를 수정하기 전에 언제나 update 명령으로 소스를 가장 최신 revision으로 맞추고 작업을 해야 합니다.

svn update는 svn up로 줄여 사용할 수 있습니다.
sample# svn update

5.6 Commit #

checkout 해서 받은 소스를 수정하고 저장소에 수정된 소스를 적용해 보겠습니다. 이 작업을 커밋(Commit)이라고 합니다.

체크아웃 받은 sample.c 소스를 아래처럼 수정합니다.
#include <stdio.h>

int main()
{
  printf("Sample Program Version 0.2\n");
  printf("Hello Subversion\n");

  return 0;
}

이제 커밋을 해 봅시다 커밋 명령은 체크아웃 해서 소스를 받은 디렉토리에서 해야 됩니다. svn commit은 svn ci로 줄여 쓸 수 있습니다. 커밋 명령을 내리면 커밋 로그를 작성하는 에디터가 실행 됩니다. 커밋 로그를 입력한후 저장을 하면 커밋이 됩니다.
sample# svn commit
Sending        sample.c
Transmitting file data .
Committed revision 5.

5.7 Log #

이제 저장소에 어떠한 것들이 변경 되었는지 확인 할 수 있는 log 명령에 대해 알아보겠습니다.

log 명령은 체크아웃 받은 디렉토리 안에서 해야 합니다. revision과 날짜, 누가 커밋을 했는지 알 수 있습니다. 여기서는 (no author)로 나옵니다. 이것은 서버 설정에서 아무나 커밋 할 수 있게 하여서 이렇게 나오는 것이고 ID를 통해 인증을 하도록 설정을 했으면 ID가 표시 됩니다.
sample# svn log
------------------------------------------------------------------------
r4 | (no author) | 2003-11-23 14:40:05 +0900 (Sun, 23 Nov 2003) | 1 line


------------------------------------------------------------------------
r1 | (no author) | 2003-11-23 14:39:00 +0900 (Sun, 23 Nov 2003) | 1 line


-----------------------------------------------------------------------
--revision과 -r은 같습니다.
sample# svn log --revision 5:19    # revision 5부터 9까지의 로그를 출력합니다.
sample# svn log -r 19:5            # revision 19부터 5까지 역으로 출력합니다.
sample# svn log -r 8               # revision 8의 로그를 출력합니다.
하나의 파일이나 디렉토리 로그를 볼 수도 있습니다.
sample# svn log sample.c
sample# svn log http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk/sample.c
-v 옵션은 더 자세한 정보를 얻을 수 있습니다. 아래 M은 Modify(수정)의 표시 입니다. 소스 파일을 수정하고 커밋 했기 때문입니다.
sample# svn log -r 5 -v
------------------------------------------------------------------------
r5 | (no author) | 2003-11-23 14:42:34 +0900 (Sun, 23 Nov 2003) | 1 line
Changed paths:
   M /trunk/sample.c


------------------------------------------------------------------------
A 는 Add(추가) 표시 입니다. trunk라는 디렉토리를 만들었고 sample.c 파일을 import 했기 때문에 A(추가) 표시가 나오게 되는 것입니다.
sample# svn log -v
------------------------------------------------------------------------
r4 | (no author) | 2003-11-23 14:40:05 +0900 (Sun, 23 Nov 2003) | 1 line
Changed paths:
   A /trunk/sample.c


------------------------------------------------------------------------
r1 | (no author) | 2003-11-23 14:39:00 +0900 (Sun, 23 Nov 2003) | 1 line
Changed paths:
   A /trunk


------------------------------------------------------------------------

5.8 Diff #

diff 명령을 사용하면 예전 소스 파일과 지금의 소스 파일을 비교해 볼 수 있습니다. 위에서 나온 로그와 같이 우리는 revision 4(r4)에서 sample.c를 import 했습니다. 그리고 revision 5에서 소스를 수정하고 커밋 했습니다.

최초에 import 했던 소스 sample.c의 revision 4와 수정해서 커밋한 revision 5의 차이점을 diff 명령으로 출력해 보겠습니다. --revision 4만 적으면 현재 revision 5와 비교하게 됩니다.
sample# svn diff --revision 4 sample.c
Index: sample.c
===================================================================
--- sample.c    (revision 4)
+++ sample.c    (working copy)
@@ -2,7 +2,8 @@

 int main()
 {
-  printf("Sample Program Version 0.1\n");
+  printf("Sample Program Version 0.2\n");
+  printf("Hello Subversion\n");

   return 0;
 }
revision 4와 5를 비교 하고 싶으면 --revision 4:5 (-r 4:5)로 하면 됩니다. --revision 8:10 도 가능합니다.
sample# svn diff --revision 4:5 sample.c
Index: sample.c
===================================================================
--- sample.c    (revision 4)
+++ sample.c    (revision 5)
@@ -2,7 +2,8 @@

 int main()
 {
-  printf("Sample Program Version 0.1\n");
+  printf("Sample Program Version 0.2\n");
+  printf("Hello Subversion\n");

   return 0;
 }

여기서 주의할 점은 CVS는 revision을 파일 하나하나에 다 매기지만 Subversion은 파일에 revision을 매기지 않고 소스 수정, 파일 복사, 이동, 삭제 등을 하고 그때 한 커밋으로 revision을 매깁니다. 그래서 다른 파일들이라도 같은 revision 번호를 가지게 됩니다. 

5.9 Blame #

Blame은 한 소스파일을 대상으로 각 리비전 대해서 어떤 행을 누가 수정했는지 알아보기 위한 명령입니다.
리비전, 커밋한 사용자의 ID, 소스 순서입니다.
sample# svn blame sample.c
     4 sampleuser #include <stdio.h>
     4 sampleuser
     4 sampleuser int main()
     4 sampleuser {
     5 sampleuser   printf("Sample Program Version 0.2\n");
     5 sampleuser   printf("Hello Subversion\n");
     4 sampleuser
     4 sampleuser   return 0;
     4 sampleuser }
     4 sampleuser
여기서는 커밋한 사용자가 한명 밖에 없으므로 전부 똑같이 나옵니다. 

한 예로 여러사람이 커밋했을 경우 아래처럼 나옵니다.
     4 sampleuser #include <stdio.h>
     4 sampleuser
     4 sampleuser int main()
     4 sampleuser {
     7 epifanes     printf("Sample Program Version 0.3\n");
     6 pyrasis      printf("Hello Subversion\n");
     4 sampleuser
     4 sampleuser   return 0;
     4 sampleuser }
     4 sampleuser

특정 리비전만 지정해서 볼 수도 있습니다. 리비전을 지정하지 않으면 현재 리비전을 대상으로 합니다.
sample# svn blame -r 4 sample.c

5.10 lock #

svn lock 명령으로 파일을 잠글 수 있습니다.
sample# svn lock hello.c
svn lock 명령으로 파일을 잠그었을 경우 왜 잠그었는지 로그를 기록할 수 있습니다.
파일을 잠그었을 경우 파일을 잠근 사용자만 수정을 해서 커밋을 할 수 있고 다른 사용자는 수정을 할 수 없습니다. 파일의 잠금을 해제할 경우에는 svn unlock 명령을 사용하면 됩니다.
파일 잠금기능은 여러명이 개발을 하고 있을 경우 한 파일에서 작업이 너무 많아 모두 끝내지 못하고 중간 중간에 커밋만 해놓았을 경우 다른 사람이 그 파일을 수정해버리면 하던 작업이 엉망이 되어 버립니다. 그래서 파일을 잠그어 작업이 끝날때 까지 한 사람만 커밋을 할 수 있도록 하는 것입니다. 작업이 끝나면 파일 잠금을 해제 하면 됩니다.

5.11 Add #

svn add 명령으로 새 파일을 추가할 수 있습니다.
sample# svn add hello.c
A         hello.c
svn add로 파일을 추가한 뒤에는 svn commit으로 커밋을 해주어야 완전히 파일이 저장소에 추가됩니다.
sample# svn commit
물론 커밋 로그도 입력해야 됩니다.

5.12 Rename #

svn rename 명령으로 파일 및 디렉토리의 이름을 바꿀 수 있습니다.
sample# svn rename hello.c world.c
sample# svn commit
svn rename 현재 파일명 바꿀 파일명 형식으로 사용합니다. svn rename 명령으로는 이름이 바로 바뀌지는 않고 svn commit 명령으로 커밋을 해줘야 완전히 바뀌게 됩니다.

5.13 Export #

체크아웃은 Subversion이 버전관리를 할 수 있도록 각종 파일이 소스 폴더 안에 함께 생깁니다. 이것과는 달리 Export는 순수하게 프로그램의 소스만 가져올 수 있습니다. 만들어진 소스를 압축하여 릴리즈 할 때 사용합니다.
sample# svn export http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample2/trunk sample
--revision (-r)으로 revision을 지정하면 지정한 revision의 소스를 받아옵니다. 지정하지 않으면 가장 최근의 revision의 것을 가져옵니다.

5.14 Branch와 Tag #

CVS에서의 Branch와 Tag는 Branch와 Tag를 위한 명령이 있습니다. CVS에서 Branch와 Tag를 하게 되면 저장소의 파일에는 Branch 또는 Tag 되었다는 표시가 함께 붙게 됩니다. 체크아웃 할 때에도 Branch와 Tag의 소스를 받아오려면 Branch, Tag를 지정하는 옵션을 주어야 했습니다.

CVS와는 달리 Subversion은 Branch와 Tag가 특별한 명령이 있는 것도 아니고 이런 것들을 한다고 해도 저장소에 특별히 Branch, Tag라고 기록이 남는 것도 아닙니다. Subversion에서 Branch와 Tag는 단순한 디렉토리 복사 명령으로 할 수 있고 Branch, Tag를 했더라도 디렉토리 복사와 같습니다.

5.14.1 Branch #

Branch를 해야 할 경우는 앞서 설명 했듯이 프로젝트중 작은 분류로 나누어 개발 하거나 소스를 따로 분리하여 실험적인 코드 를 작성할 경우 등 입니다.

Subversion에서는 Branch를 copy 명령으로 수행 합니다. trunk의 내용을 Branches안에 새로운 이름으로 복사 하는 것입니다. 체크아웃 받은 소스에서 바로 copy를 할 수도 있고 원격에서 URL로 복사를 할 수도 있습니다. 아래 체크아웃 받은 것은 trunk만 받은 것이 아니고 sample 디렉토리 아래를 전부 받는 것입니다.
svn checkout http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample sample
sample# svn copy trunk branches/sample-branch
sample# svn commit
원격에서 URL로 copy를 하면 commit도 같이 이루어집니다. 체크아웃 받은 소스에서는 update를 해주어야 합니다.
# svn copy http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk \
http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/branches/sample-branch
Branch된 소스를 받기 위해서는 branches/sample-branch를 체크아웃 하면 됩니다. trunk와 branche는 따로 revision을 가지지 않습니다. Subversion의 revision은 저장소 전체의 revision입니다.
# svn checkout \
  http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/branches/sample-branch \
  sample-branch

5.14.1.1 Merge #
위와 같이 우리는 trunk를 sample-branch로 Branch 했습니다. sample-branch를 수정하다가 trunk에도 반영하고 싶다면. merge 명령을 사용하면 됩니다. 하나하나 소스 코드를 옮겨서 입력하지 않아도 됩니다. 다만 merge 한 뒤에는 꼭 사람이 확인을 해 봐야겠죠.

sample-branch를 체크아웃 합니다.
# svn checkout \
  http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/branches/sample-branch \
  sample-branch

sample-branch의 sample.c를 다음과 같이 수정 합니다. printf("Hello World\n");를 추가 했습니다. 그리고 commit을 합니다. 지금 수정된 것은 revision 7입니다.
#include <stdio.h>

int main()
{
  printf("Sample Program Version 0.2\n");
  printf("Hello Subversion\n");

  printf("Hello World\n");

  return 0;
}
이제 sample의 trunk를 체크아웃 합니다.
# svn checkout http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk sample
trunk의 sample.c는 아래와 같습니다.
#include <stdio.h>

int main()
{
  printf("Sample Program Version 0.2\n");
  printf("Hello Subversion\n");

  return 0;
}
이제 sample-branch의 수정된 것을 trunk에 merge 해 보겠습니다. "svn merge -r N:N 저장소주소 체크아웃된디렉토리" 형식 입니다. 아래는 저장소 주소 하나만 입력되어 있습니다. 이렇게 되면 지금 체크아웃한 소스와 merge를 하게 됩니다. merge할 revision 번호를 주의해 주십시오. 6:7은 r 6과 r 7의 차이점을 뜻합니다. sample-branch의 r 6과 r 7의 차이점을 지금의 체크아웃된 trunk에 적용하라는 것 입니다.
sample# svn merge -r 6:7 \
        http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/branches/sample-branch
U  sample.c
sample# svn commit
sample# svn update
이제 sample.c를 열어보면 아래와 같이 sample-branch에서 수정한 것이 merge가 되어 있습니다.
#include <stdio.h>

int main()
{
  printf("Sample Program Version 0.2\n");
  printf("Hello Subversion\n");

  printf("Hello World\n");

  return 0;
}

파일 하나만 merge를 할 수도 있습니다.
# svn merge -r 6:7 sample.c

저장소 주소끼리 merge를 할 수도 있습니다.
# svn merge http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample2/trunk \
  http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample2/branches/sample-branch

5.14.2 Tag #

Tag는 만든 프로그램을 웹 사이트 등에 공개할 때 사용합니다. Tag도 Subversion에서는 Branch와 마찬가지로 디렉토리 복사(copy)와 같습니다. tags 디렉토리 안에는 일반적으로 릴리즈(발표)하는 버전별 디렉토리를 만들어 사용합니다.

0.1 버전을 발표할 때 0.1 버전의 순간을 tags 디렉토리에 복사하는 것입니다. 0.2가 되었을 때 tags아래 0.2 디렉토리로 복사합니다. 이렇게 되면 각각의 버전별로 소스를 관리 할 수 있습니다. 저장소에서는 실제로 복사가 되는 것은 아니고 변경된 점만 복사하기 때문에 저장소의 용량이 소스코드의 크기만큼 배로 늘어나지는 않습니다.

trunk의 소스를 0.1 버전으로 Tag, Branch와 마찬가지로 체크아웃 받은 소스에서도 할 수 있고 원격에서 URL로도 할 수 있습니다. 아래 체크아웃 받은 것은 trunk만 받은 것이 아니고 sample 디렉토리 아래를 전부 받는 것입니다.
# svn checkout http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample sample
sample# svn copy trunk tags/0.1
sample# svn commit

원격에서 URL로 복사합니다. 이 경우 commit도 같이 이루어집니다. 체크아웃 받은 소스는 update를 해주어야 합니다.
# svn copy http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/trunk \
  http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/tags/0.1

이제 0.1로 Tag한 소스를 Export로 받아서 압축한 뒤에 릴리즈(공개)를 하면 됩니다.
# svn export http://(Subversion 서버의 IP주소 또는 도메인)/svn/sample/tags/0.1 sample-0.1

5.15 Revert #

소스를 수정하면서 merge를 하다 보면 분명히 잘못 했을 경우가 생깁니다. 이럴 때 하는 것이 revert입니다. revert는 단어 뜻 그대로 되돌리는 명령입니다. 커밋을 하기 전에만 되돌릴 수 있습니다. 커밋 하기전의 체크아웃 받은 소스를 되돌리는 명령입니다. 원격 저장소의 것은 되돌릴 수 없습니다.
sample# svn revert sample.c

5.16 백업 및 복구 #

저장소는 가장 중요한 공간이기 때문에 백업은 필수입니다. 저장소 디렉토리를 그대로 보관할 수도 있지만 백업과 복구 명령을 사용하는것이 편리합니다.
Windows, 리눅스, BSD 등 운영체제에 관계없이 백업 및 복구가 가능합니다. Windows에서 백업한것을 리눅스에서 사용할 수도 있고 BSD에서 백업한 것을 Windows에서 사용할 수도 있습니다.
저장소의 서버를 옮길때에는 저장소 디렉토리를 옮기는 것이 아니라 저장소 백업을 한뒤 그 백업파일을 이용하여 새 서버에서 복구를 하는 방식으로 옮겨야합니다.

5.16.1 Dump #

sample 저장소를 백업합니다. 표준 입출력을 통해서 저장소의 내용을 파일로 생성합니다. svnadmin dump 명령을 사용하며 이 명령은 저장소 디렉토리 바깥에서 사용해야 합니다.
repos# ls
sample
repos# svnadmin dump sample > sample.dump

5.16.2 Load #

저장소 백업 파일을 이용해서 저장소를 복구합니다. svnadmin load 명령을 사용합니다.
빈 저장소를 생성한 뒤 백업 파일을 이용해서 복구를 합니다.
repos# svnadmin create sample
repos# ls
sample   sample.dump
repos# svnadmin load sample < sample.dump

5.17 svnsync #

svnsync는 1.4.0에서 새로 생긴 명령입니다. svnsync 명령을 이용해서 저장소를 그대로 복사해 올 수 있습니다. 단 복사해오고자 하는 원본 저장소가 Subversion 1.4 이상을 사용하고 있어야 하며 1.4 이하를 사용하고 있을 경우 svnsync 명령이 동작하지 않습니다.

먼저 빈 저장소를 만듭니다.
# cd /home/svn/
/home/svn# svnadmin create syncsample

새로 만든 빈 저장소의 hooks 디렉토리에 pre-revprop-change 파일을 만들고 아래의 내용을 입력한 뒤 저장합니다. /home/svn/syncsample/hooks/pre-revprop-change
#!/bin/sh

pre-revprop-change 파일을 실행할 수 있도록 권한을 조정합니다.
/home/svn/syncsample/hooks# chmod 777 pre-revprop-change

svnsync를 사용할 수 있도록 저장소를 초기화 합니다. file:///home/svn/syncsample은 방금 만든 빈 저장소 경로이고 http://svn.collab.net/repos/svn은 복사해 올 원본 저장소의 주소입니다. http://, svn://등 접속 가능한 저장소 주소이면 되고 trunk나 branches같은 디렉토리가 아닌 최 상위 디렉토리의 주소로 설정해줘야 합니다.
/home/svn# svnsync init file:///home/svn/syncsample http://svn.collab.net/repos/svn
Copied properties for revision 0.

이제 저장소를 복사를 시작합니다.
/home/svn# svnsync sync file:///home/svn/syncsample
Committed revision 1.
Copied properties for revision 1.
Committed revision 2.
Copied properties for revision 2.
Committed revision 3.
Copied properties for revision 3.
Committed revision 4.
Copied properties for revision 4.
Committed revision 5.
Copied properties for revision 5.
Committed revision 6.
Copied properties for revision 6.
....
최신 리비전 까지 복사해오면 svnsync 명령이 끝난 것입니다.
이제 이 저장소에서 소스를 체크아웃 하여 살펴볼 수 있습니다.

Windows의 경우는 아래와 같이 사용합니다.

저장소 생성
C:\repos>svnadmin create syncsample

새로 만든 저장소의 hooks 디렉토리에 pre-revprop-change.bat라는 빈 파일을 만듭니다.

초기화
C:\repos>svnsync init file:///c:/repos/syncsample http://svn.collab.net/repos/svn

저장소 복사
C:\repos>svnsync sync file:///c:/repos/syncsample

6 Microsoft Windows에서 사용하기 #

Microsoft Windows에서도 Subversion을 사용할 수 있습니다. 소스를 컴파일하지 않고 설치 파일을 통해 간단하게 설치해서 사용할 수 있습니다. Windows에서도 리눅스, 유닉스와 똑같은 기능을 사용할 수 있습니다. Subversion 서버를 구성하는 방법은 윈도우에서 Subversion 서버 운영하기를 참고하시기 바랍니다.

6.1 설치 파일 구하기 #

Subversion Windows 설치파일


Windows 용 설치 파일을 받습니다. ZIP으로 압축된 바이너리를 사용해도 상관없습니다.

svn-1.0.0-setup.exe

6.2 설치 #

설치 파일을 받았다면 일반적인 Windows 프로그램을 설치하듯이 설치하면 됩니다. ZIP으로 압축된 것은 적당한 디렉토리에 압축을 해제한뒤 사용하면 됩니다.

6.3 사용하기 #

지금 설치한것들은 Subversion 커맨드 라인 클라이언트와 저장소를 네트워크에서도 사용할 수 있도록 하는 서버 프로그램 들입니다. 커맨드라인 사용법은 리눅스, 유닉스와 똑같습니다. 다만 Windows에서는 명령 프롬프트(cmd.exe)에서 사용합니다.

ZIP으로 된 바이너리를 사용하려 한다면 명령 프롬프트에서 Subversion의 명령을 실행하기 위해 환경 변수의 시스템 변수 PATH에 Subversion 압축을 해제한 디렉토리를 추가합니다. 설치 파일로 설치했다면 자동으로 환경 변수에 추가됩니다.

커밋 로그를 입력할 수 있도록 환경 변수의 Administrator에 대한 사용자 변수에 변수이름 SVN_EDITOR, 값 notepad를 설정합니다. notepad가 아닌 다른 편집기를 이용하려면 편집기의 실행파일의 경로를 지정해 주면 됩니다.

저장소 만들기. C:\에 repos라는 폴더를 만들었습니다. 명령 프롬프트를 실행합니다.
C:\Documents and Settings\Administrator>cd c:\repos
버클리 DB를 이용한 저장소
C:\repos>svnadmin create --fs-type bdb sample
파일시스템을 이용한 저장소
C:\repos>svnadmin create --fs-type fsfs sample

체크아웃. svn://, http://를 이용한 체크아웃 방식은 위에서 설명한 방법과 똑같습니다.

윈도우 파티션에 있는 저장소에 직접 접근하는 방법.
C:\temp>svn checkout file:///C:/repos/sample

svnserve를 사용한 서버
C:\>svnserve -d -r C:\repos

명령행에서 일일이 실행하는 불편함을 덜어주는 SVNSERVE Manager같은 프로그램을 이용할 수도 있습니다. svnserve의 동작/정지 상태를 트레이 아이콘으로 표시해 주며 시스템 시작시 svnserve를 자동으로 실행 하게 할 수 있습니다.

Windows용 Subversion 명령도 리눅스, 유닉스에서의 명령과 똑같습니다. 하지만 Windows에서는 그래픽 클라이언트가 있기 때문에 명령 프롬프트를 사용하는 일은 많지 않습니다. TortoiseSVN을 사용하면 팝업 메뉴를 이용해서 저장소 만들기, 체크아웃, 커밋 등 매우 편리하게 사용할 수 있습니다.


[출처 : 이재홍 http://www.pyrasis.com 2003.11.14 ~ 2007.11.28 버전 1.4.3]
CygWIN 에 sshd 를 설치하고, PuTTY 를 통해 ssh 로 localhost 에 접속하려니 도메인 계정을 사용해서 그런지 접속 과정이 매우 느렸다.  전에 PuTTY 를 local CygWIN terminal 로 사용한다는 글을 본 기억이 있어서, 이것 저것 검색해 보다가 PuTTYcyg 를 컴파일하는 방법을 찾았다.

내가 한 작업은 다음과 같다.
1. PuTTY 0.58 소스 파일 다운로드
2. PuTTY 0.58 cygterm (PuTTYcyg patch & make script) 다운로드
3. PuTTY 0.58.h2 (PuTTY 0.58 한글화 버전) 의 diff 파일 다운로드
4. PuTTY 0.58 소스에 PuTTY 0.58 cygterm 의 patch 적용
5. PuTTY 0.58 소스에 한글화 diff 파일 patch 적용(수작업 T-T)

한글화 diff 파일 적용은 수작업으로 했기에, 귀찮아서 메뉴 한글화는 제외하고 한글 입출력 부분만 했다.


☞ 위 작업을 통해 생성한 (가칭) PuTTYcyg 0.58 h2 바이너리



압축을 풀면 PuTTYcyg 실행파일과 cthelper.exe 라는 파일이 있는데, 이 cthelper 파일은 PuTTYcyg 실행파일과 같은 디렉토리에 두어야 한다.

이 PuTTYcyg 파일은 아래와 같이 실행하면 된다.
    예) black.reg 설정을 읽어 CygWIIN 터미널 열기
    PuTTY.exe -load black -cygterm /bin/bash --login -i


[출처 : http://vany.tistory.com/163]

cygwin으로 Windows를 Linux처럼 쓴다.

cygwin이라는 프로그램을 windows에 설치하면 Linux 명령과 bash sell을 사용 할 수 있습니다.
보통 개인적 취향이나 학습의 목적으로 cygwin을 자신의 컴퓨터에 설치하여 사용하고는 하는데,
나아가서 원격머신 흔히 서버로 사용할 머신이 windows 계열일때의 불편을 해소하고자 할 때 
이 보다 좋은 방법은 없는듯 합니다.

목차 :
  1. cygwin을 깔면 무얼 할 수 있나?
  2. cygwin 설치 방법
  3. 한글 설정
  4. sshd 띄워 원격에서 접속하기
 
1. cygwin을 깔면 무얼 할 수 있나?
 cygwin이라는 프로그램은 windows에 설치하여 Linux와 같은 환경을 제공합니다.

사용자 삽입 이미지

cygwin을 실행한 모습


위의 그림처럼 cygwin을 실행시키면 Dos창과 비슷한 콘솔이 열리는데, 이것을 이용해서 Unix 명령과 각종 Shell을 실행 시킬 수 있습니다. 
물론 이미 설치되어 있는 모든 프로그램의 실행도 가능합니다.  GUI를 갖는 윈도우 프로그램도 포함해서 말이죠.(물론 그렇게 할 필요는 없어 보이지만..)

IT, 특히 개발자로서는 grep, find, tail 명령만으로도 이 프로그램을 사용하는 충분한 이유가 될 수 있을듯 합니다.
Unix 환경에 익숙하지 않은 사람은 이것을 이용해서 학습을 할 수 있을 것이구요.

제가 이와 같이 개인적 성향이나 학습의 가능성을 알리기 위해 이렇게 글 까지 쓰지는 않았을 겁니다. 자기 혼자 사용하는 개인용 PC인 경우라면 grep이나 find가 없어도 알아서 잘들 쓰고 있고, 이런게 있는데 좋으네 마네 설명하고 자시고 할 필요는 없어 보입니다.

그런데, 서버 환경이 Windows인 경우에는 문제가 다릅니다.
원격 서버에서 실행되어야 하는 각종 서버 데몬의 실행과 중단 명령, 원격 서버에 쌓이고 있는 로그파일의 tail, 원격 서버의 CPU, Memory 사용률과 Process List를 확인 하려 할때, 윈도우 원격 데스트탑 연결(mstsc.exe)이나 VNC를 이용해야 하는것은 무척 불편하고 퇴근시간을 늦추는 요인이 됩니다.

사용자 삽입 이미지

CecureCRT로 cygwin을 이용한 ssh 접속모습


cygwin의 sshd를 이용하면 원격에서 telnet과 같이 ssh를 이용하여 모든 콘솔 명령을 이용할 수 있으니 소스적용이나 시스템 모니터링에서 windows와 Unix의 차이를 모르고 작업 할 수 있게 해줍니다.
자 어때요. 이정도면 cygwin 쓸만 한가요? 그렇다면 설치와 환경 설정 방법을 설명해 드릴께요.

2. cygwin 설치 방법
  cygwin을 설치 하기 위해서는 ftp가 열려 있어야 합니다.
금융사 내부에서 인터넷을 할때는 대부분 ftp가 닫혀 있기 때문에 설치 프로그램이 필요한 패키지를 다운로드 하지 못하는 경우가 있읍니다. 이 경우에는 첨부한 설치 프로그램과 패키지를 이용해서 설치해야 합니다.

 가. FPT가 가능하다면 http://www.cygwin.com에 방문하여 설치 프로그램을 다운로드 받습니다.
FTP가 불가능하다면 첨부 파일인 setup.exe를 다운받습니다.
사용자 삽입 이미지

http://www.cygwin.com


 나. 설치 프로그램을 실행하여 평소처럼 "다음"을 눌줍니다.
 
사용자 삽입 이미지

cygwin installer


 다. 만약 FTP가 가능하다면 "Install from Internet"을 선택하고 "다음"을 클릭합니다.
사용자 삽입 이미지
   만약 FTP가 불가능 하다면 "Install from Local Directory"를 선택합니다.
사용자 삽입 이미지

  라. 설치할 경로와 설치 환경을 설정합니다. 왠만하면 그대로 두시면 됩니다.
사용자 삽입 이미지

  마. 패키지 경로를 지정합니다.
   FTP가 가능한 경우는 패키지를 다운받을 경로를 지정하시면 되고, 
   FTP가 불가능한 경우는 첨부파일 release.zip을 다운받아 압축해제한 경로를 지정하시면 됩니다.
사용자 삽입 이미지

 바. FTP 접속 방법 선택
  FTP가 불가능한 경우에는 해당 사항 없는 화면입니다.
  FTP로 다운받아 설치하는 경우에 FTP를 어떻게 접속할지를 선택하는 방법입니다.
사용자 삽입 이미지
   어떤걸 선택할 지는 알아서 판단 해야 겠죠.

  사. 다운로드 사이트 선택
   release.zip을 다운받으신 경우에은 마찬가지로 해당 사항 없는 화면입니다.
   어느 미러 사이트에서 받을지 묻는 것인데, ftp://ftp.kaist.ac.kr 가 제일 빠르다고 합니다.
사용자 삽입 이미지

   아. 설치 패키지 선택
   어떤 패키지를 설치 할지 선택하는 것인데요, 이부분은 모두 해당 되는 부분입니다.
    패키지를 설명하고 자시고 할 자신은 없으니 모두 설치를 하십시요.
   이때!! "All Default"라고 되어있는 "Default"를 클릭하여 "Install"로 바꾸시는 것은 매우 중요합니다.
 
사용자 삽입 이미지
사용자 삽입 이미지

  자. 설치 진행 및 종료
    나머지는 굳이 설명 안드리겠습니다. 그냥 놔두면 설치하고 "마침" 클릭하시면 되겠습니다.

 자 이제 생성된 아이콘을 클릭하여 cygwin을 실행하고 Unix 처럼 사용하시면 됩니다.
  
  • C: D: 드라이브 변경은 Dos에서 처럼  "cd c:" , "cd d:" 하시면 되고 /(root) 디렉토리는 cygwin이 설치된 경로, 다시말해 디폴트로 설치했다면 "c:\cygwin" 이 되게 됩니다.
    ~(home) 디렉토는  "c:\document and settings\계정이름" 입니다.

  
3. 한글 설정
cygwin을 설치하고 바로 쓰면 한글 파일명이나 디렉토리명이 물음표(?)로 표시되고, 한글 입력도 잘 되지 않습니다. 그래서 설치 후 한글 설정 작업이 필요합니다.

 가. c:\cygwin\Cygwin.bat 파일을 노트패드로 열어 굵은 글씨로 된 문장을 추가 합니다.
... 생략
set CYGWIN=tty

bash --login -i

 나. cygwin콘솔에서 vi로  ~/.bashrc 열어 아래 내용을 맨 아래에 넣습니다.
alias ls='ls -ahF --color=tty --show-control-char'
 그 밖에 alias를 추가 하거나 수정하셔도 됩니다.

다. cygwin 콘솔에서 vi로 ~/.inputrc 를 열어 아래 내용을 맨 아래에 추가합니다.
set meta-flag on
set convert-meta off
set output-meta on

자. 이제 한글 입/출력도 잘 될것입니다. 
로칼에서만 사용하실 꺼라면 이대로 잘 사용하시면 됩니다.


4. sshd 설정하여 원격에서 접속하기
  가. 환경변수 설정
 내컴퓨터 아이콘의 속성을 선택해서 "시스템 등록정보" 창을 열어 봅니다.
"고급" 탭의  "환경변수"를 클릭하여 환경변수를 추가합니다.
사용자 삽입 이미지

저장할 변수내용은 다음과 같습니다.
CYGWIN=ntsec tty

    나. cygwin 콘솔에서 다음 명령을 실행합니다.
 
ssh-host-config
CYGWIN=ntsec tty 

  다. cygwin 콘솔에서 sshd 데몬을 실행합니다.
cygrunsrv --start sshd
 
이와 같이 하고 나면 윈도우 서비스에 sshd 가 추가 되어 실행되고 있는 것을 확인 할수 있습니다.
사용자 삽입 이미지

라. ssh 접속
 SecureCRT와 같은 ssh를 지원하는 콘솔 프로그램을 이용해서 원격에서 접속해 봅니다.
 계정은 windows 로그인 계정과 같습니다. 대부분 Administrator 이겠죠.
사용자 삽입 이미지


자 이제 윈도우 시스템을 원격에서도 Unix와 같이 사용해서 퇴근 시간이 빨라지길 바랍니다.

X를 띄워 쓰는 분도 있으니 더 쓸모 있는 방법이 있지 않알까 생각도 됩니다.

[출처 : http://rainer.tistory.com/22]

CVS사용법

last updated 2002-03-14 by 박주형
$Revision: 1.3 $


1. 관련 사이트




2. 관련 문서

한글 문서

영문 문서




3. CVS서버 설치하기

3-1. 리눅스에 설치하기 - cvspserver 를 통해 서비스하기

3-2. NT에 설치하기




4. 저장소 ( Repositery)

CVS의 저장소는 버전관리하는 모든 파일과 디렉토리들의 완벽한 복사본을 저장한다.

보통 저장소안에 있는 파일을 직접 조작하지 않는다. 그대신 CVS명령어를 이용해 작업디렉터리에 카피본을 만들고, 그 카피본으로 작업을 하게된다. 수정이 되면 그것을 저장소로 반영시켜 넣는다. 그러면 저장소는 수정된 내용을 포함할 뿐 아니라, 무엇을 수정했는지에 관한 정확한 기록도 포함한다. 저장소가 작업디렉터리의 서브디렉터리가 아니라는 것에 주의해라. 저장소와 작업디렉터리는 다른 위치에 존재해야 한다.

CVS는 저장소를 다양한 방법으로 접근할 수 있다. 저장소는 로컬컴퓨터일수도 있고, 아니면 방건너에 있거나 다른 나라에 있을수도 있다. 저장소를 접근하는 다양한 방법을 구분하기위하여, 저장소이름은 접근방으로 시작한다. 예를들면 :local:란 것은 저장소 디렉터리를 의미하는 접근방법이다. 따라서 :local:/usr/local/cvsroot는 저장소가 같은 컴퓨터의 `/usr/local/cvs'에 있다는 것을 의미한다. 다른 접근방법에 관해서는 아래에서 설명한다.

저장소는 두분으로 나뉘어진다. `$CVSROOT/CVSROOT' 는 CVS의 관리파일을 담고있다. 다른 디렉터리는 사용자가 정의한 모듈들을 담고 있다. (*주: 모듈은 프로젝트라고 해석하면 된다. 즉 파일의 집합체이다.)

4-1. CVS에 저장소가 어디있는지 알리기

CVS에게 저장소가 어디있는지 알리는 몇가지 방법이 있다. 쉘명령어에서 -d (directory란 의미) 옵션으로 지정할수 있다.


cvs -d /usr/local/cvsroot checkout yoyodyne/tc
그렇지 않으면 환경변수 $CVSROOT에 저장소의 절대위치를 지정할 수 있다. csh이나 tcsh인경우:

setenv CVSROOT /usr/local/cvsroot
sh이나 bash인 경우

CVSROOT=/usr/local/cvsroot
export CVSROOT
옵션 -d가 환경변수 $CVSROOT 보다 우선시된다.




5. 로그인 하기

5-1. 로그인 하기

CVS서버가 설치된후 서버를 이용하려면 일단 로그인이 되어야 한다. 즉 다음장부터 나오는 작업을 하려면 먼저 로그인이 선행되어야 한다. 최초로 로그인이 성공하면 아이디와 패스워드가 저장되므로 두번다시는 암호와 패스워드를 입력하지 않다도 된다.


$ cvs -d :pserver:userid@cvs.hostname.com:/opt/cvsroot login 
          ^^^^^^^ ^^^^^  ^^^^^^^^^^^^^^^  ^^^^^^^^^^^^ ^^^^^
         프로토콜   |    서버주소 혹은IP     |          로그인명령
                    |                        |
                 사용아이디              저장소 디렉터리

중간의 -d옵션은 환경변수로 설정하면 생략가능하다.


$ CVSROOT=:pserver:userid@cvs.hostname.com:/opt/cvsroot
$ export CVSROOT

$ cvs login

로그인이 성공하면 `$HOME/.cvspass' 에 저장되어 다음부터 로그인 절차를 무시해도 된다

5-2. 유닉스 계정유저 - CVS만을 위한 유저

CVS에 사용되는 아이디는 두가지가 있다. 

첫번째 방법은 유닉스의 어카운트를 그대로 cvs에사 사용하는 방법이다. 유닉스에 TELNET으로 들어갈 수있는 아이디가 있다면 CVS에서도 그대로 사용할 수 가 있다. 이 경우 사용자는 CVSROOT디렉토리에 사용권한을 가지고 있어야 한다. 

두번째 방법은 CVS전용의 사용자를 만드는 방법이다. 이 방법은 시스템의 다른 부분의 보안에 영향을 주지 않기때문에 보다 안전하다. 그러나 유저의 생성과 삭제를 해주는 툴이 아직 만들어지지 않아서 번거롭다.




6. 저장소에 프로젝트 등록하기

저장소를 등록하려면 작업디렉토리가 있어야 하고, 저장소의 어느위치에 넣을지를 정해야 한다.


$ cd wdir
$ cvs import -m "Imported source" yoyodyne/rdir yoyo start
      ^^^^^^ ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^ ^^^^^
      명령어   로그 옵션           프로젝트의
                                    저장소 위치
wdir CVS에 등록하려고 하는 파일들이 들어있는 폴더
-m "Imported source" -m 옵션을 주지 않으면 CVS가 프롬프트로 물어보게 된다.
yoyoydne/rdir 저장소에서 위치가 $CVSROOT/yoyoydne/rdir 로 설정된다.
yoyo vendor 태그 - 판매구분
start 릴리즈 태그

이렇게 하면 wdir의 내용이 $CVSROOT/yoyodyne/rdir 의 위치에서 관리된다. 

이 작업이 완료되면 저장소의 내용과 원본과 같은지 확인을 하고, 원본 디렉토리를 지워야 한다.

$ cd ..
$ cvs checkout yoyoydne/rdir
$ diff -r wdir yoyoydne/rdir
$ rm -r wdir
처음 import한 직후는 checkout한 상태가 아니다. VSS와는 달리 별도로 checkout을 해야 작업디렉토리안의 파일과 저장소의 파일이 연관성을 갖는다. 원본(wdir)안의 내용은 백업한 후 지우는 것이 좋다. 같은 내용이 두곳에 존재하면 작업에 혼돈을 줄 수 있다. 이후부터 yoyodyne/rdir 에서 작업하고 저장소로 업데이트 하게된다.

checkout하는 과정은 작업파일과 저장소파일이 연관성을 만들어준다. 연관관계가 생긴 파일은 같은 디렉터리에 CVS란 디렉터리가 생성된다. 이 디랙터리안에 저장소와 연관되는 정보가 들어있다. 연관성을 없애려면 release 명령어를 이용한다.


$ cvs release -d yoyoydne/rdir
release명령은 디렉터리와 저장소간의 연관관계를 없애준다. -d 옵션은 추가로 작업디렉토리도 지우라는 의미이다.




7. CVS를 이용해 버전 관리

7-1. 저장소에서 파일 받아오기

이미 저장소에 프로젝트가 등록되었다면 CVS를 통해서 파일들을 받아올 수 있다. 방법은 6장에서 나와있는 방법과 동일하다.


$ cvs checkout yoyodyne/rdir
이렇게 하면 현재의 디렉터리에 yoyodyne/rdir 이란 디렉터리가 생성되고 저장소로부터 파일들이 다운로드 된다.

checkout은 위와같이 디렉터리단위로 할 수도 있지만, 파일단위로도 가능하다.


$ cvs checkout yoyodyne/rdir/somefile.txt

7-2. 수정된 파일을 저장소로 보내기

commit 명령어를 사용하면 된다. 디렉터리를 통체로 업데이트하려면


$ cvs commit yoyodyne/rdir
이렇게 하면, 지정한 디렉터리안의 수정된 파일들만 버전업되고 나머지파일은 업데이트 되지 않고 버전 번호를 그대로 유진한다.

$ cvs commit yoyodyne/rdir/somefile.txt
이렇게 하면 파일 하나만 업데이트 할 수 있다.

7-3. 구 리비젼으로 되돌리기

7-4. 저장소에서 파일 지우기




8. 리비젼 ( Revision )

많은 CVS사용에관해서 리비젼 번호를 너무 걱정할 필요가 없다; CVS가 1.1, 1.2 등등 으로 번호를 부여하고, 그것이 알아야할 모든 것이다. 어쨋거나, 어떤 사람들은 CVS가 리비젼번호를 어떻게 부과하는지에 관한 지식과 제어를 좀더 알고싶어한다.

하나이상의 파일을 포함한 리비젼들을 추적하고 싶다면, 태그(tag)를 사용하라. 태그는 각 파일의 숫자 리비젼을 부과하는 심볼 리비젼이다.<※주: 복잡한 말인데 뒤를 읽어보면 더 자세히 설명이 나온다>

8-1. 리비젼 번호

각각의 버전의 파일은 1.1, 1.2, 1.3.2.2, 혹은 1.3.2.2.4.5와 같이 고유한 리비전번호(revision number)를 갖는다. 리비전번호는 항상 마침표로 구분된 짝수의 숫자로 이루어져 있다. 1.1이 기본 값으로 파일의 첫번째 리비젼 값이 된다. 각각의 연속된 리비젼은 가장 오른쪽 숫자를 하나 증가해서 새로운 값으로 부여된다. 다음의 그림은 오른쪽이 최신 리비젼인 그림이다.

       +-----+    +-----+    +-----+    +-----+    +-----+
       ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
       +-----+    +-----+    +-----+    +-----+    +-----+
1.3.2.2 와 같이 하나이상의 마침표를 포함하는 숫자일 수 있다. 이러한 리비젼은 가지(branch)의 리비젼을 표현한다.

8-2. 버젼(Versions), 리비젼(Revisions), 배포(Releases)

위에서 설명한대로 파일은 여러개의 버전을 가질 수 있다. 게다가 소프트웨어 제품도 종종 4.1.1과 같은 버전번호가 부과된다.

첫번째 예에서 버전은 이 문서에서 리비젼이라고 불리우고, 또 다른 예에서는 배포(release)라고 불리운다. 혼동을 피하기위해서 이 문서에서 버젼이란 말은 사용하지 않는다.

8-2. 리비젼 부과

지정하지 않으면 CVS는 첫번째 숫자는 바꾸지 않고, 두번째 숫자를 증가하는 숫자 리비젼을 부여할 것이다. 예를 들면 1.1, 1.2, 1.3 등등

새로운 파일을 추가할 때, 두번째 숫자는 언제나 1이고 첫번째 숫자는 그 디렉토리에 있는 파일중 가장 높은 첫번째 숫자와 같을 것이다. 예를 들면, 현재의 디렉터리중에 있는 파일중 가장높은 리비젼이 1.7, 3.1, 4.12 라면 추가되는 파일은 4.1 란 리비젼을 가질 것이다.

보통은 리비젼번호에 관심을 가질 이유가 없다. 리비젼들을 CVS가 관리하는 내부적인 것으로 여기는 것이 편하고, 태그(tag)가 배포판1로부터 배포판2와 같은 것들을 구분하는데 더 좋은 방법을 제공한다. 어쨋든, 리비젼번호를 설정하고 싶으면 cvs commit할 때 `-r'옵션을 부과하면 된다. -r 옵션은 -f옵션을 포함하는 것으로 여겨진다. 즉 파일이 수정되지 않았더라도 강제적으로 커밋시켜버린다.

예를 들면, 모든 파일들을 리비젼3.0으로 올리기 위해서는 다음을 호출하면 된다.


$cvs commit -r 3.0
주의할 것은 -r옵션으로 자정하는 숫자가 반드시 존재하는 리비젼보다 커야한다는 점이다. 만약 3.0리비젼이 존재한다면 `cvs commit -r 1.3아로 할 수 없다. 만약 여러개의 배포판을 동시에 관리하길 원한다면 가지치기(branch)를 사용하라.

8-3. 태그 (tag)

리비젼 번호는 독립적으로 진핸된다. 리비젼 번호는 소프트웨어 제품의 배포번호와는 아무런 연관성을 가질 필요가 없다. CVS를 어떻게 사용할지에 따라서 리비젼번호는 두 배포판간에 여러번 바뀔 수 있다. 예를 들면, RCS 5.6으로 작성된 몇몇 소스파일들이 다음과 같은 리비젼 번호를 갖는다고 하자.


ci.c            5.21
co.c            5.9
ident.c         5.3
rcs.c           5.12
rcsbase.h       5.11
rcsdiff.c       5.10
rcsedit.c       5.11
rcsfcmp.c       5.9
rcsgen.c        5.10
rcslex.c        5.11
rcsmap.c        5.2
rcsutil.c       5.10
tag명령어를 이용해서 심볼 이름을 어떤 파일의 리비젼번호에 줄 수 있다. status명령어에 -v옵션을 줘서 파일이 가지고 있는 모든 태그들을 볼 수 있다. 태그명은 반드시 알파벳 대소문자로 시작해야 해야하고, 알파벳 대소문자, 숫자, '-', '_'로 이루어져있다. 두 태그명 BASE와 HEAD는 CVS가 특별한 용도로 정의되어있어서 사용할 수 없다. CVS에서 특별한 용도로 사용될 이름들은 실제의 태그명들과 충돌을 피하기위해서 이름붙여질 것이다.

프로그램의 이름과 배포판의 버젼번호같은 정보를 기본으로 한 규칙에 의해서 태그의 이름을 붙이지를 원할것이다. 예를 들면 프로그램의 이름을 사용하고 뒤에 버전번호를 `.'를 `-'로 바꿔서 붙이면 CVS 1.9는 cvs1-9 라고 태그를 붙일 수 있다. 모순없는 규칙을 정한다면 태그가 cvs-1-9인지 cvs1-9인지 빈번히 추측하지 않을 것이다. 또한 태그정보파일(taginfo file)안의 고딩규칙을 강제화하는 것을 고려할수도 있다.

다음 예는 파일에 태그를 어떻게 붙이는지 보여준다. 명령어는 반드시 작업디렉터리안에서 실행되어야 한다. 다시말하면 `backend.c' 파일이 있는 디렉터리에서 명령을 실행시켜야 한다는 것을 의미한다.


$ cvs tag rel-0-4 backend.c
T backend.c
$ cvs status -v backend.c
===================================================================
File: backend.c         Status: Up-to-date

    Version:            1.4     Tue Dec  1 14:39:01 1992
    RCS Version:        1.4     /u/cvsroot/yoyodyne/tc/backend.c,v
    Sticky Tag:         (none)
    Sticky Date:        (none)
    Sticky Options:     (none)

    Existing Tags:
        rel-0-4                     (revision: 1.4)
(디렉터리를 CVS에게 인수로 준다면, 해당하는 처리를 디렉터리안의 모든 파일과 그 서브디렉터리안의 파일에까지 재귀적으로 적용한다는 것을 의미한다.

checkout명령어는 `-r'명령을 가지고 있는데, 이 옵션은 모듈의 임의의 리비젼을 채크아웃하게 해준다. 이 옵션은 차후에 `tc'란 모듈의 1.0배포판이라고 붙여진 소스들을 얻어오는 것을 수월하게 해준다.


$ cvs checkout -t rel-1-0 tc
이것은 아주 유용하다. 예를 들면, 누군가 그 배포판에 버그가 있다고 요청하고 현재의 작업카피에서는 버그를 찾을수 없다.

주어진 날자의 상태대로 모듈을 채크아웃할 수 있다. `-r'옵션을 이런 명령어에 준다면, 접착성 태그에 관해서 고려할 필요를 느낄것이다. (?)

한개이상의 파일에 동일한 태그를 붙였다면 태그를 "파일명 리비젼번호로 구성된 행열에 그은 곡선"으로 생각될수 있다. 다음과 같은 리비젼을 가진 5개의 파일이 있다고 하자. (*주: 아래그림에서는 곡선으로 안보이지만 곡선으로 생각하자)


          file1   file2   file3   file4   file5

        1.1     1.1     1.1     1.1  /--1.1*      <-*-  TAG
        1.2*-   1.2     1.2    -1.2*-
        1.3  \- 1.3*-   1.3   / 1.3
        1.4          \  1.4  /  1.4
                      \-1.5*-   1.5
                        1.6
과거의 어떤 시점에 *버전에 태그가 붙여졌다. 태그를 태그붙여진 리비젼들을 잇는 곡선의 손잡이라고 여길 수 있다. 이 손잡이를 잡아당기면 모든 태그붙여진 리비젼들을 얻을 수 있다. 이것을 보는 다른 방법은 다음과 같이 태그가 붙여지 리비젼들을 평평하게 놓고 보는 것이다.

          file1   file2   file3   file4   file5

                        1.1
                        1.2
                1.1     1.3                       _
        1.1     1.2     1.4     1.1              /
        1.2*----1.3*----1.5*----1.2*----1.1     (--- <--- Look here
        1.3             1.6     1.3              \_
        1.4                     1.4
                                1.5

8-4. 접착성 태그 (Sticky Tags)

때때로 작업중인 카피본의 리비젼은 리비젼과 관련된 테이터를 가지고 있다. 예를 들면 리비젼은 가지(branch)이거나, `checkout -D'`update -D'에의해서 어떤 날자에 우선해 버젼으로 제한될 수 있다. (뭔말이여?) 왜냐하면, 이 날자는 접착된것(Sticky)으로 여겨진다.

대부분의 경우에, 접착성(stickiness)은 생각할 필요가 없는 CVS의 불투명한 면이다. 어쨋거나, 이 기능을 사용하지 않았으면 하더라도 접착성 태그(sticky tahg)에 관해서 좀 알필요가 있다. (예를 들면 어떻게 이것을 안쓰는지에 관해서)

어떤 접착성 태그들이나 날자가 설정되었는지 보기위해서 status 명령어를 쓸 수 있다.


$ cvs status driver.c
===================================================================
File: driver.c          Status: Up-to-date

    Version:            1.7.2.1 Sat Dec  5 19:35:03 1992
    RCS Version:        1.7.2.1 /u/cvsroot/yoyodyne/tc/driver.c,v
    Sticky Tag:         rel-1-0-patches (branch: 1.7.2)
    Sticky Date:        (none)
    Sticky Options:     (none)


이 접착성 태그들은 `cvs update -A'명령어로 지울때까지 당신의 작업파일들에만 남아있다. `-A'옵션은 본체의 해더로부터 파일의 버젼을 받아오고, 다른 접착성태그들과 날자들과 다른 옵션들은 무시한다.

가장 일반적인 접착성태그의 사용은 어떤 가지(branch)가 작업진행중인지를 구분하는 것이다. 어쨋건, 가지쳐지지 않은 접착성태그들도 또한 사용법을 가지고 있다. 예를 들면, 다른 사람들이 만드는 불안정한 수정내용들로부터 현재 작업중인 디렉터리가 업데이트되는 것을 막고싶다고 가정하자. 물론 `cvs update'를 실행하는 것을 자제할수 있다. 그러나 거대한 트리의 일부분만을 업데이트하는 것을 막고싶다면 접착성 테그가 그것을 도와줄 수 있다. 만약 어떤 리비젼으로 채크아웃한다면 (예를 들어 리비젼 1.4) 이 리비젼은 접착성 태그가 된다. 그 뒤에 이어서cvs update명령어는 당신이 cvs update -A명령어를 해서 리셋하기전까지는 최신 리비젼을 받아오지 않을것이다. 마찬가지로, updatecheckout명령에 `-D'옵션의 사용은 적착성 날자(sticky date) 를 설정한다. 이 방법은 나중에 파일을 받아올때 그 날자가 사용되게 해준다.

사람들은 보통 접착성태그의 사용없이 구버전의 파일을 받아오길 원한다. 이것은 checkout나 update 에 `-p'옵션을 줘서 할 수 있다. 예를 들어서


$ cvs update -p -r 1.1 file1 >file1
===================================================================
Checking out file1
RCS:  /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v
VERS: 1.1
***************
$

어쨌든, 이미 채크인한 것을 되돌릴때 이것이 가장 간단한 방법이다.




9. 가지나누기와 병합 ( Branching and merging )

CVS에서는 가지나누기(branch)라고 알려진 방법을 통해서 독립된 개발선상에서 작업할수 있다. 가지에 있는 파일을 바꿔도 본작업이나 다른 가지의 작업에는 영향을 주지 않는다.

후에 당신은 병합(merging)을 통해서 한쪽 가지에 한 수정을 다른쪽 가지로 옮길 수 있다. 병합은 수정내용을 작업디텍터리에 넣는 `cvs update -j' 를 포함한다. 그런후 그 리비젼을 거밋할 수 있고, 그렇게 해서 작업을 다른 가지에 수정내용을 효과적으로 옮길 수 있다.

9-1. 가지나누기의 잇점

tc란 모듈의 릴리즈 1.0이 만들어졌다고 가정하자. 당신은 tc를 계속 개발하면서 릴리즈 1.1을 두달동안 만들기로 계획을 세웠다. 그러는 중에 고객이 치명적인 버그에 대해서 불평을 하기 시작하였다. 당신은 릴리즈1.0을 채크아웃하고 버그를 찾는다. 어쨋거나 소스의 현재 리비젼은 고쳐지고 있는 상태이고 적어도 한달쯤 지나야 안정화될 것이다. 새로운 소스를 기반으로 버그를 고칠수 있는 방법이 없다.

이런 경우에 하는 것이 리비젼 트리에 가지를 생성하는 것이다. (이 가지에는 모든 파일이 tc의 릴리즈1.0이라고 적혀있다.) 당신은 본체에 방해를 주지않고 수정을 만들 수 있다. 수정이 끝났을 때 수정내용을 본체에 혼합하던가 가지에 그대로 남겨두던가 결정할 수 있다.

9-2. 가지 생성하기

현재 디렉터리가 작업폴더라고 가정하면 tag -b로 가지를 생성할 수 있다.


$ cvs tag -b rel-1-0-patches
이것은 `rel-1-0-patches'란 이름을 부여함으로서 작업본에 있는 현재 리비젼들을 기반으로 가지를 분리한다. 가지가 작업본에 생성되는 것이 아니라 저장소에 생성된다는 것을 이해하는 것이 중요하다. 예와 같이 현재의 리비젼을 기반으로 가지를 생성하는 것은 작업본을 새로운가지로 자동으로 전환하지 않는다.

또한 rtag를 통해 어떠한 작업본의 참조 없이도 가지를 만들 수 있다.


$ cvs rtag -b -r rel-1-0 rel-1-0-patches tc
`-r rel-1-0'는 이 가지가, 태그`rel-l-0'에 해당하는 리비젼의 루트가되어야한다는 것을 나타낸다. `rel-1-0'가 가장 최신의 리비젼일 필요는 없다. -- 종종 과거리비젼에서 가지치는 거이 유용하다. (예를들어, 과거 릴리즈에서 버그를 잡는 것이 안정하다고 알려져있다.)

`tag'를 사용하면서 `-b'옵션은 rtag가 (단지 심볼릭 리비젼 명을 만드는 것이 아니라) 가지를 만든다는 것을 나타낸다. `rel-1-0'와 일치하는 파일들의 숫자 리비젼은 파일마다 틀릴것이다.

그렇다면 이 명령어의 전체 결과는 모듈 `tc'안에 (`rel-1-0-patches'라고 이름 붙여진) 새로운 가지를 생성하는 것인데, 이 가지는 `rel-1-0'라고 지정된 리비젼트리의 루트이다. --

9-3. 가지 제어하기


$ cvs status -v driver.c backend.c
===================================================================
File: driver.c          Status: Up-to-date

    Version:            1.7     Sat Dec  5 18:25:54 1992
    RCS Version:        1.7     /u/cvsroot/yoyodyne/tc/driver.c,v
    Sticky Tag:         rel-1-0-patches (branch: 1.7.2)
    Sticky Date:        (none)
    Sticky Options:     (none)

    Existing Tags:
        rel-1-0-patches             (branch: 1.7.2)
        rel-1-0                     (revision: 1.7)

===================================================================
File: backend.c         Status: Up-to-date

    Version:            1.4     Tue Dec  1 14:39:01 1992
    RCS Version:        1.4     /u/cvsroot/yoyodyne/tc/backend.c,v
    Sticky Tag:         rel-1-0-patches (branch: 1.4.2)
    Sticky Date:        (none)
    Sticky Options:     (none)

    Existing Tags:
        rel-1-0-patches             (branch: 1.4.2)
        rel-1-0                     (revision: 1.4)
        rel-0-4                     (revision: 1.4)

9-4. 가지와 리비젼


       +-----+    +-----+    +-----+    +-----+    +-----+
       ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
       +-----+    +-----+    +-----+    +-----+    +-----+



                                                      +-------------+
                           Branch 1.2.2.3.2 ->        ! 1.2.2.3.2.1 !
                                                    / +-------------+
                                                   /
                                                  /
                 +---------+    +---------+    +---------+
Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
               / +---------+    +---------+    +---------+
              /
             /
+-----+    +-----+    +-----+    +-----+    +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !  <- The main trunk
+-----+    +-----+    +-----+    +-----+    +-----+
                !
                !
                !   +---------+    +---------+    +---------+
Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 !
                    +---------+    +---------+    +---------+
 

9-5. 마법 가지 번호 (Magic branch numbers)


$ cvs admin -NR4patches:1.4.2 numbers.c

9-6. 가지 전체를 병합하기


+-----+    +-----+    +-----+    +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !      <- The main trunk
+-----+    +-----+    +-----+    +-----+
                !
                !
                !   +---------+    +---------+
Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
                    +---------+    +---------+

$ cvs checkout mod               # Retrieve the latest revision, 1.4

$ cvs update -j R1fix m.c        # Merge all changes made on the branch,
                                 # i.e. the changes between revision 1.2
                                 # and 1.2.2.2, into your working copy
                                 # of the file.

$ cvs commit -m "Included R1fix" # Create revision 1.5.

$ cvs checkout -j R1fix mod
$ cvs commit -m "Included R1fix"

9-7. 하나의 가지에서 여러번 병합하기


9-8. 두 리비젼간의 다른점 병합하기 (Merging difference between any two revisions) --> ?


+-----+    +-----+    +-----+    +-----+    +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk
+-----+    +-----+    +-----+    +-----+    +-----+
                !                           *
                !                          *
                !   +---------+    +---------+
Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
                    +---------+    +---------+
 

+-----+    +-----+    +-----+    +-----+    +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk
+-----+    +-----+    +-----+    +-----+    +-----+
                !                           *
                !                          *
                !   +---------+    +---------+    +---------+
Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
                    +---------+    +---------+    +---------+


cvs update -j 1.2.2.2 -j R1fix m.c    # Merge changes from 1.2.2.2 to the
                                      # head of the R1fix branch

cvs update -j R1fix:yesterday -j R1fix m.c

cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c

9-9. 병합은 파일을 추가하거나 삭제할 수 있다.


$ cvs update -j 1.5 -j 1.3 backend.c

$ cvs update -j 1.2 -j 1.1 file1
U file1
$ cvs commit -m test
Checking in file1;
/tmp/cvs-sanity/cvsroot/first-dir/file1,v  <--  file1
new revision: 1.3; previous revision: 1.2
done
$

9-10. 병합과 키워드


touch a b c
cvs add a b c ; cvs ci -m "added" a b c
cvs tag -b branchtag
cvs update -r branchtag
touch d ; cvs add d
rm a ; cvs rm a
cvs ci -m "added d, removed a"
cvs update -A
cvs update -jbranchtag
 



10. 공동작업

여러명이 공동으로 작업하는 경우에 두명이상의 사람이 한파일을 동시에 checkout 할 수가 있다. 첫번째 해결책은 파일잠금(file locking)혹은 예약된 채크아웃(Reserved checkout)으로 알려진 방법이다. 이 방법은 한번에 한사람만 파일을 수정할수 있게 하는 방법이다. 이 방법은 RCS나 SCCS등에서 제공하는 유일한 방법이다. CVS에서 예약된 채크아웃을 하는 일반적인 방법은 cvs admin -l 명령이다. 이 방법은 CVS와 훌륭하게 통합되어있지 않다. 필요한 사람만 사용하도록 하자.

CVS에서 기본으로 사용하는 방식은 예약안한 채크아웃 (unreserved checkout) 이다. 이 방식에서 여러개발자가 동시에 한 파일을 자신들의 작업디렉터리에서 작업할 수 있다. 수정내용을 커밋하는 첫번째 개발자는 다른 사람이 그것을 수정하기 시작했다는 것을 자동적으로 알수있는 방법이 없다. 다른 사람들은 그 파일을 커밋하려고 할때 에러메시지를 받는다. 그들은 자신들의 작업용 카피가 업데이트되도록 CVS명령어를 사용해야만 한다. 이 공정은 거의 자동이다.

10-1. 파일 상태

채크아웃된 파일에 어떤 처리를 했느냐에 따라, 그리고 다른이들이 저장소에있는 파일들에 어떤 처리를 했느냐에 따라, 한 파일은 여러 상태로 분류될수 있다. 상태들은 status 명령으로 볼 수 있다.

Up-to-date 파일이 사용되고 있는 가지(branch)의 저장소의 최신 리비전과 동일하다.
Locally Modified 당신이 파일을 수정하였고, 아직 커밋하지 않아 저장소에는 반영되지 않았다..
Locally Added 당신이 add명령으로 파일을 추가하였지만, 아직 커밋하지 않아 저장소에는 반영되지 않았다.
Locally Removed 당신이 remove명령으로 파일을 삭제하였지만 커밋하지 않아 저장소에는 반영되지 않았다.
Needs Checkout 다른 사람이 이미 새로운 리비전으로 커밋해버렸다. 이 이름은 약간 혼란을 준다. 보통 commit가 아니라 update로 새로운 리비전을 받아온다
Needs Patch Need Checkout와 같지만, CVS서버가 전체파일을 보내주기보다 패치를 보내줄것이다. 전체 파일을 보내주거나 패치를 보내주거나 결과물은 같다.
Needs Merge 누군가가 저장소에 새로운 리비전을 커밋했고, 당신도 그 파일을 수정했다.
File had conflicts on merge 선행된 update명령이 충돌(conflict) 되었다는 것을 빼고는 Locally Modified와 같다. 뒤에 설명하는 충돌 해결을 참고하세요.
Unknown CVS가 이 파일에 관해서 아무것도 모른다. 예를 들면 새로운 파일을 만들고 add를 하지 않았다.

status 명령어와 update 명령어를 다소 보충적인 것으로 생각할 수 있다. 파일을 업데이트하기위해 update명령을 사용하고, update가 무었을 했었나를 보기위해 status를 사용할 수 있다. 사실 status 명령보다 간략한 포멧으로 상태를 보고싶다면, 다음을 쓸수도 있다.


$ cvs -n -q update

10-2. 파일 업데이트

파일을 업데이트하거나 병합(merge)하고 싶을때는 update 명령어를 사용하라. 이것은 갱신되지않은 파일인 경우는 commit명령과 대충 동등하다 : 최신 리비젼의 파일이 저장소로부터 추출되어 작업디렉토리에 놓여진다.

파일의 수정내용은 update를 사용할때 없어지지 않는다. 더 새로운 리비젼이 존해하지 않는다면 update는 아무것도 안한다. 파일을 수정했고 새로운 리비젼이 있다면, CVS는 모든 수정내용을 작업디렉터리에 병합한다.

10-3. 충돌의 예

리비젼 1.4인 파일 driver.c가 있다고 가정하자.

#include 

void main()
{
    parse();
    if (nerr == 0)
        gencode();
    else
        fprintf(stderr, "No code generated.\n");
    exit(nerr == 0 ? 0 : 1);
}
리비전 1.6인 driver.c가 다름과 같다고 가정하자.
#include 

int main(int argc,
         char **argv)
{
    parse();
    if (argc != 1)
    {
        fprintf(stderr, "tc: No args expected.\n");
        exit(1);
    }
    if (nerr == 0)
        gencode();
    else
        fprintf(stderr, "No code generated.\n");
    exit(!!nerr);
}
이때 cvs update 를 실행하면 다음과 같은 결과를 얻는다.

$ cvs update driver.c
RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
retrieving revision 1.4
retrieving revision 1.6
Merging differences between 1.4 and 1.6 into driver.c
rcsmerge warning: overlaps during merge
cvs update: conflicts found in driver.c
C driver.c
CVS가 충돌이 났다는 메시지를 보낸다. 당신이 작업하던 원본파일은 수정한된채로 `.#driver.c.1.4'란 이름으로 저장된다. 새로운 버전의 driver.c에는 다음의 내용이 저장된다.
#include 
#include 

int main(int argc,
         char **argv)
{
    init_scanner();
    parse();
    if (argc != 1)
    {
        fprintf(stderr, "tc: No args expected.\n");
        exit(1);
    }
    if (nerr == 0)
        gencode();
    else
        fprintf(stderr, "No code generated.\n");
<<<<<<< driver.c
    exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
=======
    exit(!!nerr);
>>>>>>> 1.6
}
덮어씌울 수 없는 수정된부분이 작업본에 합체되고, 겹쳐진 부분은 `<<<<<<<', `=======' and `>>>>>>>' 로 구분되는 것에 주목해라.

마커를 지우고 잘못된 라인을 수정하는 것으로 문제를 해결한다. 다음과 같이 수정했다고 가정하자

#include 
#include 

int main(int argc,
         char **argv)
{
    init_scanner();
    parse();
    if (argc != 1)
    {
        fprintf(stderr, "tc: No args expected.\n");
        exit(1);
    }
    if (nerr == 0)
        gencode();
    else
        fprintf(stderr, "No code generated.\n");
    exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
그러면 계속할 수 있고, 이 것을 리비젼1.7로 커밋할 수 있다.

$ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c
Checking in driver.c;
/usr/local/cvsroot/yoyodyne/tc/driver.c,v  <--  driver.c
new revision: 1.7; previous revision: 1.6
done





+ Recent posts