저장소에 id 기반 인증 설정




svn 및 저장소의 정상 설정 여부가 확인되었다. 이제 프로젝트 보안을 위해 ID와 암호로 인증을 통해야만 사용할 수 있도록 설정해 보자.

  1. 선호하는 에디터로 /etc/httpd/conf/httpd-vhost.conf 를 열어서 전 절에서 추가한 인증 관련 주석을 모두 제거한다.

    <VirtualHost *:80>
    	ServerAdmin svnadmin@example.com
    	ServerName svn.example.com
    	ErrorLog logs/svn.example.com-error_log
    	CustomLog logs/svn.example.com-access_log common
    	<Location /repos>
    		DAV svn
    		SVNPath /var/svn/myrepos/
    		AuthType Basic
    		AuthName "SVN Repo"
    		AuthUserFile /var/svn/myrepos/svn.passwd
    		Require valid-user
    	</Location>
    </VirtualHost>
    CODE
  2. AuthUserFile 파일은 사용자의 계정과 암호를 갖고 있는 파일이다. 이 파일은 htpasswd 명령어로 생성 및 관리할 수 있다. 아직 파일이 없으므로 touch 명령어로 빈 파일을 생성하고 서브 버전 사용자를 추가한다. 
    -b 옵션은 사용자의 암호를 프롬프트에서 입력하지 않고 파라미터로 바로 전달할 수 있다. 사용자의 ID 는 dev1 이고 암호는 dev1pwd 이다.

    touch /var/svn/myrepos/svn.passwd
    htpasswd -b /var/svn/myrepos/svn.passwd dev1 dev1pwd

    htpasswd 에는 계정 정보 파일을 생성하고 사용자의 정보를 추가할 수 있는 -c (create) 옵션이 있다.

    하지만 이 옵션을 사용하지 않은 이유는 기존 파일이 있을 경우 실수로 -c 옵션을 사용하면 기존 파일을 삭제하고 새로운 사용자를 추가하므로 기존의 모든 계정 정보가 사라져 버리게 된다.

    실수의 여지가 큰 옵션이므로 사용하지 않기를 권장한다.

  3. 저장한후 httpd 를 재구동한다.

    service httpd restart

인증 설정 확인




Web Browser 로 http://svn.example.com/repos 을 연결하여 다음과 같은 인증창이 뜨는지 확인한다.

인증 기능이 설정되었다는 것을 확인했으니 svn 명령행 클라이언트를 통해 로그인하여 확인해 보자.

  1. 시작메뉴->실행에 cmd.exe 를 입력하여 실행한다.
  2. svn info 명령어 위에서 생성한 아이디와 암호를 넣어서 실행한다. 적합한 옵션은 --username 과 --password 이다.


    svn info http://svn.example.com/repos --username dev1 --password devpwd


        
  3. 정상적으로 인증을 거치고 저장소 정보가 표시된다.
  4. 잘못된 암호를 넣어서 인증이 동작하는 것을 확인해 볼 수도 있다. 다음과 같이 잘못된 인증 정보를 입력하면 아이디와 암호 입력창이 다시 뜨며 인증을 요구한다.

    svn info http://svn.example.com/repos --username dev1 --password wrongpwd  

    Authentication realm: <http://svn.example.com:80> SVN Repo
    Username: 


SVNPath 와 SVNParentPath 의 차이점

SVNPath 지시자는 단일 저장소일때 사용하며 SVNParentPath 는 특정 경로 아래에 여러 개의 저장소가 있을 경우 사용한다.

만약 /var/www/svn 디렉터리 밑에 repos1, repos2, repos3 세 개의 저장소가 있다면 Location 을 세 번 사용하지 않고 SVNParentPath 지시자를 사용하여 설정을 단순화 할 수 있다.

<VirtualHost *:80>
	ServerAdmin svnadmin@example.com
	ServerName svn.example.com
	ErrorLog logs/svn.example.com-error_log
	CustomLog logs/svn.example.com-access_log common
	<Location /repos>
		DAV svn
		SVNParentPath /var/svn/
		AuthType Basic
		AuthName "SVN Repo"
		AuthUserFile /var/svn/myrepos/svn.passwd
		Require valid-user
	</Location>
</VirtualHost>
CODE


SVNPath 로 지정된 저장소는 단일 저장소이므로 저장소 명을 입력하지 않고 상위의 Location URL (http://svn.example.com/repos) 까지만 입력하면 연결이 가능하나 SVNParentPath 는 저장소가 여러개 있으므로 명시적으로 저장소 이름을 지정해 주어야 한다.

만약 SVNParentPath  폴더밑에 repos2 저장소에 연결하고자 한다면 URL 에 하위 저장소도 명시해야 연결이 가능하다. 

svn list http://svn.example.com/repos/repos2

    

저장소 레이아웃 구성



저장소가 정상적으로 생성되고 client 에서 사용할 수 있게 되었다. 이제 저장소에 프로젝트를 생성하기전 저장소의 프로젝트 구성을 어떻게 가져갈지에 대해 정리해 보자.

하나의 저장소에는 여러 개의 프로젝트를 등록하여 사용할 수 있다.  프로젝트마다 별도의 저장소를 만들수도 있긴 하지만 특별한 이유가 없다면 하나의 저장소에 여러개의 프로젝트를 만드는 것을 권장한다.

여러개의 저장소를 만들 경우 저장소마다 별도의 인증과 접근 통제를 걸어야 하며 다음 장에서 기술할 svnsync 로 저장소를 백업할 때 저장소가 추가될 때마다 설정을 변경해야 한다.  

특히 저장소를 분리했다가 여러가지 이유로 두 개의 저장소를 합쳐야 할 경우 svn 에서는 저장소 병합 기능이 없으므로 합칠 수 있는 방법이 없다. (svn 내부적으로는 저장소의 revision 은 모두 0 으로 시작하므로 양 저장소간 동일한 revision 이 많아서 합칠 수 있는 방법이 없다.)

하나의 저장소에 여러 개의 프로젝트가 등록되어 특정 프로젝트에만 접근해야 할 개발자가 모든 프로젝트에 접근하는게 부담된다면 아래에서 기술할 경로 기반 접근 통제를 적용하여 관리할 수 있다.

일반적으로 권장하는 svn 저장소의 프로젝트 구조는 다음과 같다.

hello-webapp
    trunk
    tags
    branches
calculator
    trunk
    tags
    branches
    vendor
spamassassin
    trunk
    tags
    branches    

위와 같이 저장소 밑에 프로젝트명(hello-webapp, calculator, apache-httpd)으로 디렉터리를 만들고 하위에 세 개의 디렉터리를 만든다. 전장 리비전에 따른 저장소 상태 에서 설명했듯이 각 디렉터리의 용도는 다음과 같다.

  • trunk - baseline 이 되는 메인 소스를 관리한다.
  • tags - 리비전대신 꼬리표를 붙여서 의미있는 이름으로 관리하는 용도. 회사마다 다를수 있지만 일반적으로는 제품명_버전명, 또는 버전명으로 명명한다. 버전명은 하위 버전까지 명시해야 관리가 용이하다. 예로 apache httpd 의 tags 폴더에 있는 꼬리표는  다음과 같다.

    2.2.27
    2.2.28
    2.4.0
    2.4.1

    tomcat 의 경우 꼬리표는 다음과 같다.

    TOMCAT_7_0_0_RC1
    TOMCAT_7_0_0_RC2
    TOMCAT_7_0_0
    TOMCAT_7_0_1
  • branches - 큰 변경이 있을 경우 별도로 소스를 가지쳐서 트렁크에 영향을 주지 않게 한다. subversion 개발팀은 버그 수정, 기능 구현등 소스 변경이 일어날 경우마다 별도의 가지를 쳐서 진행을 하고 완료되면 트렁크에 병합하는 전략을 취하고 있다.

    1.7.x-commit-performance
    1.7.x-fs-verify
    1.7.x-issue-4295
    1.7.x-issue4091
  • vendor - C/C++ 프로젝트의 경우  내부에서 사용되고 있는 외부 라이브러리를 svn 에 넣어야 할 지 또 외부 라이브러리가 업그레이드 되면 어떻게 관리해야 할 지 애매할 수 있다. svn 은 이를 위해 svn:external 이라는 property 를 지원하며 사용하는 외부 라이브러리를 vendor 폴더에 넣고 svn:external property를 설정하면 현재 프로젝트를 check-out 하면 필요한 외부라이브러리도 같이 내려받으므로 손쉽게 빌드 환경을 구성할 수 있다. 

저장소에 디렉터리 생성

이제 저장소의 프로젝트 폴더 구성도 결정했으니 실제 프로젝트를 등록해 보자. 우리가 수행할 프로젝트 명은 자바 기반의 web project 로 프로젝트명은 hello-webapp이다. 프로젝트의 기본 골격은 템플릿으로부터 프로젝트를 생성하는 메이븐의 archetype 플러그인을 사용하여 만들고 권장하는 구조에 따라 루트에 hello-webapp 디렉터리를 생성하고 현재 소스는 trunk 에 넣고 tags와 branches 디렉터리도 만들어 보자.

사전에 자바와 메이븐이 설치되어 있어야 하며 메이븐 명령어인 mvn 이 PATH 에 걸려 있어야 한다. 이제 저장소를 체크 아웃하고 프로젝트 폴더를 만들어 보자

  1. 시작 메뉴 -> 실행 에서 cmd.exe를 실행한 후에 홈 디렉터리로 이동한다.

    cd c:\Users\lesstif\

  2. 루트 저장소를 project-home 디렉터리로 체크 아웃하고 이동한다. co 는 checkout 명령어의 축약 명령어다

    svn co http://svn.example.com/repos project-home

    cd project-home

  3. hello-webapp 프로젝트의 디렉터리 구조를 만든다. 메이븐으로 간단한 프로젝트를 만들고 이것을 트렁크 디렉터리로 이름을 변경할 것이므로 트렁크를 mkdir 로 만들지는 않는다.

    mkdir hello-webapp
    mkdir hello-webapp\tags

    mkdir hello-webapp\branches

  4. 이제 디렉터리가 변경 되었다는 것을 서브버전에 알려 주어야 한다. 파일이나 디렉터리가 추가 됐을 경우 add 명령어로 컨텐츠를 추가해 줄 수 있다. 디렉터리를 추가할 경우 하위의 파일과 디렉터리도 자동으로 추가된다.

    svn add hello-webapp

  5. 파일이나 디렉터리가 추가된 경우 앞에 A 가 표시된다. 이제 커밋해서 저장소에 반영해 보자. ci 는 commit 명령의 축약어이며 -m 옵션은 커밋 할때 사용할 로그 메시지를 터미널에서 바로 입력하는 옵션이다.

    svn ci -m "hello-webapp 프로젝트 디렉터리 구성"

  6. 커밋이 완료되고 리비전이 1이 되었다.

프로젝트 import

이제 프로젝트 소스를 저장소의 트렁크 디렉터리에 등록해 보자. 우리가 등록할 프로젝트는 java 기반의 간단한 웹 프로젝트이다. 빌드는 메이븐을 사용할 예정이며 프로젝트 템플릿을 사용하여 초기 환경을 구성할 것이다.

메이븐의 관례에 따라 다음과 같은 프로젝트 구성을 갖게 된다.

|-- src
        | -- main
            | -- java
            | -- resources
            | -- webapp
        | – test
    -- pom.xml
CODE


프로젝트 임포트 부터는 커맨드 방식과 GUI 툴을 이용한 방식 두 가지 모두 설명할 것이다.

  1. cmd.exe 를 열고 사용자의 홈 디렉터리로 이동한 후에 버전은 1.0-SNAPSHOT 이고 artifactId 는 hello-webapp 인 메이븐 프로젝트를 생성한다. 생성되는 프로젝트 디렉터리가 hello-webapp 이므로 동일 이름의 디렉터리가 없는 위치에서 실행하자.

    cd hello-webapp
    mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.example -DartifactId=hello-webapp -Dversion=1.0-SNAPSHOT

  2. artifactId 와 동일한 이름인 hello-webapp 디렉터리가 생기고 이 안에 메이븐 프로젝트 구조에 맞게 디렉터리가 생성된다. 이 디렉터리를 기존에 이미 만들어 놓은 hello-webapp 디렉터리내에 trunk 디렉터리로 임포트 하자.

    cd hello-webapp
    svn import http://svn.example.com/repos/hello-webapp/trunk -m "hello-webapp 트렁크 디렉터리 추가"

  3. TortoiseSvn 사용자는 다음 절차를 따른다.

    1. 다음과 같이 pom.xml 과 src 가 보이도록 한 상태에서 마우스 우측 버턴을 클릭하여 팝업 메뉴를 띄운 후에 Import 를 선택한다.

    2. 첨부와 같이 hello-webapp/trunk 밑에 임포트 되도록 URL 을 설정한다.

    3. 커밋 로그 메시지를 넣고 Ok 를 클릭한다.
  4. 정상적으로 임포트가 끝났다면 리비전이 하나 증가하며 저장소를 브라우징 해 보면 다음과 같이 서브버전이 권장하는 디렉터리 구조를 갖고 있어야 한다.

  5. cmd 에서는 저장소내 파일과 디렉터리의 목록을 조회하는 list 명령어에 -R(재귀 옵션)을 주면 하위 디렉터리 구조까지  확인해 볼 수 있다.

    svn list -R http://svn.example.com/repos/hello-webapp

  6. 저장소에 제대로 추가되었음이 확인되었다. 이제 원래 폴더는 필요가 없다. 삭제하거나 적당한 곳에 옮겨 놓자.

  7. 저장소에 추가한 프로젝트를 PC 로 체크아웃 받아서 작업 환경을 구성해 보자. svn 의 checkout 하위 명령어를 사용하여 체크아웃할 수 있으며 URL 뒤에 저장할 디렉터리 이름을 지정할 수 있다.

    svn co http://svn.example.com/repos/hello-webapp/trunk hello-webapp

  8. TortoiseSvn 사용자는 우측 메뉴에서 "SVN Checkout" 을 선택하고 체크아웃 할 URL 과 디렉터리를 지정할 수 있다.

  9. 성공적으로 작업 환경이 만들어졌다. 이제 프로젝트에 참가한 모든 사용자의 계정을 등록하고 구성된 프로젝트를 체크 아웃을 받게 하여 작업 환경을 구성하자.


경로기반(Path Based) 접근 제어설정

저장소 생성 및 최초 프로젝트 등록이 완료되었다. 그런데 hello-webapp 에 필요한 library 를 개발하는 lib-hello 이라는 하위 프로젝트가 필요할 것 같다.

이 프로젝트는 모두가 commit 을 하면 안되고 특정 인원만 커밋하고 나머지 인원은 checkout과 update 만 해도 될 것 같다. 또 2달후에 world-lib 이라는 하위 프로젝트를 또 진행해야 하는데 이 프로젝트는 프로젝트내 특정 인원만 보기를 허용할 예정이다.

lib-hello와 lib-world 이라는 저장소를 각각 새로 만들고 계정을 분리해도 세밀한 접근 권한을 설정하기는 어렵다. 이때 서브버전의 경로 기반 접근 제어를 사용하면 저장소의 Path에 따라 사용자의 접근 여부를 세밀하게 설정할 수 있다.

(warning) 경로 기반 접근 제어 기능은 httpd 기반의 서브버전을 사용할 때만 가능하다.



경로 기반 접근 제어 사용 여부는 저장소 설정에 AuthzSVNAccessFile 지시자에 접근 제어 설정 파일의 절대 경로를 설정하여 활성화 할 수 있다.

<VirtualHost *:80>
    ServerAdmin svnadmin@example.com
    ServerName svn.example.com
    ErrorLog logs/svn.example.com-error_log
    CustomLog logs/svn.example.com-access_log common
    <Location /repos>
        DAV svn
        SVNPath /var/svn/
        AuthType Basic
        AuthName "SVN Repo"
        AuthUserFile /var/svn/myrepos/svn.passwd
        AuthzSVNAccessFile /var/svn/myrepos/svn.authz
        Require valid-user
    </Location>
</VirtualHost>   
CODE

이제 svn.authz 파일을 만들어 보자. 각 라인이 # 으로 시작하면 주석으로 처리 된다. 설정 파일은 윈도의 ini 파일과 비슷하다.

먼저 접근 권한을 설정할 경로를 [저장소명:경로] 형식으로 설정한다. 그 아래에 name = value 방식으로 id = 권한 을 설정하면 된다. 다음 예제를 보자 

[calc:/branches/calc/bug-142]
lesstif = rw
twister = r
CODE

calc 저장소 아래의 branches/calc/bug-142 프로젝트는 lesstif 는 읽고 쓰기(rw) 가 가능하고 twister 는 읽기(r) 만 가능하다는 의미이다. 단일 저장소거나 모든 저장소 공통 설정이라면 저장소 이름을 생략할 수 있다.

또 권한은 부모 경로에서 자식 경로로 상속되므로 하위 경로에는 지정할 필요가 없다.

이제 위에서 만든 저장소에 맞게 다음 설정을 적용해 보자.

  1. 먼저 htpasswd 로 계정을 세 개 만들자. 계정의 암호는 id에 숫자1을 더한 문자이다.

    htpasswd -b /var/svn/myrepos/svn.passwd lesstif lesstif1
    htpasswd -b /var/svn/myrepos/svn.passwd twister twister1
    htpasswd -b /var/svn/myrepos/svn.passwd readonly readonly1

  2. 에디터로  /var/www/svn/myrepos/svn.authz 파일을 연다.
  3. lesstif 는 모든 프로젝트에 대해 읽기/쓰기(rw) 가능하고 readonly 계정은 읽기만 가능하다. dev1 계정은 hello-webapp 프로젝트는 읽기/쓰기가 가능하며 lib-hello 프로젝트는 아무 권한이 없다. 반대로 twister 는 lib-hello 프로젝트는 읽기/쓰기가 가능하며 hello-webapp 프로젝트는 아무 권한이 없다. 권한 부분을 빈 칸으로 두면 아무 권한을 부여하지 않은 것이다.
    readonly 계정은 외부 시스템과 통합할 때 사용할 계정으로 지속적인 통합 서버나 이슈 관리 시스템등에서 버전 관리 시스템을 연동시에는 읽기 권한만 있으면 된다.

    [repos:/]
    lesstif = rw
    readonly = r
    dev1 = r
    twister = r


    [repos:/hello-webapp]
    lesstif = rw
    dev1 = rw
    twister =

    [repos:/lib-hello]
    lesstif = rw
    dev1 =
    twister = rw

  4. 테스트를 위해 lib-hello 프로젝트를 저장소에 생성한다. svn 의 mkdir 명령어를 사용하면 명령창에서 간단하게 디렉터리를 생성할 수 있다. --parents 옵션을 추가하면 상위 디렉터리가 없을 경우 자동으로 생성해 준다.

    svn mkdir --parents -m "add lib-hello" http://svn.example.com/repos/lib-hello/trunk

     

  5. service httpd restart 를 실행하여 설정을 반영한다.
  6. svn list 명령어로 권한 설정 여부를 확인해 보자

    svn list http://svn.example.com/repos/hello-webapp --username twister --password twister1

    svn: E175013: Unable to connect to a repository at URL 'http://svn.example.com/repos/hello-webapp'
    svn: E175013: Access to '/repos/hello-webapp' forbidden

    svn list http://svn.example.com/repos/lib-hello --username twister --password twister1


    trunk/

위과 같이 접근 제어 설정에 따라 결과가 다르게 나오는 것을 확인할 수 있다.


일일이 개발자마다 경로에 따른 권한을 부여하려면 번거로울 수 있다. svn 은 그룹 기능을 지원하므로 권한별 그룹을 만들어서 관리해 보자.

그룹은 [groups] 키워드를 이용하여 지정하면 된다. 그룹을 사용할때는 @그룹명 처럼 앞에 @ 문자를 붙여주면 되며 다른 그룹을 포함할 수 있다. 그룹내에 다른 그룹을 지정할 경우 id 대신 @그룹명을 적어준다.

 

[repos:/]
@admin-users = rw
@readonly-users = r
@hello-web-developers = r
@lib-hello-developers = r

[repos:/hello-webapp]
@hello-web-developers = rw
@readonly-users = r
* =

[repos:/lib-hello]
@lib-hello-developers = rw
@readonly-users = r
* =

[groups]
admin-users = lesstif, admin
hello-web-developers = @admin-users, dev1
lib-hello-developers = @admin-users, twister
readonly-users = readonly

위와 같이 설정하면 admin-users, hello-web-developers 그룹은 hello-webapp 프로젝트에 대해 읽기/쓰기가 가능하며 readonly-users 는 읽기만 가능하다. admin-users와 lib-hello-developers 그룹은 lib-hello 프로젝트에 대해 읽기/쓰기가 가능하다.

id 부분에 * 이 있는 것은 모든 계정을 의미한다. 그러므로 "*  = " 설정에 따라 나머지 모든 사용자는 해당 경로에 접근 할 수 없게 된다.


일반적으로 서브버전을 사용하는 오픈 소스 프로젝트들은 커미터(committer - 프로젝트 소스의 커밋이 가능한 개발자)는 rw 권한이 있고 anonymous 사용자는 읽기가 가능하므로 아마 다음과 같이 설정되어 있을 것이다.

[repos:/]
@committers = rw
* = r

[groups]
committers = 개발자1, 개발자2, 개발자3, ...


SSL 적용

인증과 권한 관리를 성공적으로 적용했지만 인증에 필요한 정보가 네트워크를 통해 그냥 전송되는 것이 걸릴 수도 있다.


서브버전에 HTTPS 를 적용하여 인증 정보 유출을 방지해 보자. SSL 설정 파일인 /etc/httpd/conf.d/ssl.conf 을 에디터로 열어서 다음 가상 호스트 정보를 추가한다.

<VirtualHost *:443>
    ServerName svn.example.com
    ErrorLog logs/svn.example.com-error_log
    CustomLog logs/svn.example.com-access_log common
    <Location /repos>
        DAV svn
        SVNPath /var/svn/myrepos/
        AuthType Basic
        AuthName "SVN Repo"
        AuthUserFile /var/svn/myrepos/svn.passwd
        AuthzSVNAccessFile /var/svn/myrepos/svn.authz
        Require valid-user
    </Location>
    LogLevel warn
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

    CustomLog logs/svn.example.com-ssl_request_log \
      "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
CODE

변경해야 할 부분은 SSL용 인증서(SSLCertificateFile )와 개인키(SSLCertificateKeyFile) 설정 부분이다. 별도의 파일이 있다면 해당 파일의 경로로 변경하자.

설정을 마쳤으면 아파치 웹 서버를 재구동하여 설정을 반영해 보자. HTTPS 가 정상적으로 동작하는지는 서브버전 클라이언트로 연결시 URL 에 http 대신 https 를 주어서 확인할 수 있다.

svn list -R https://svn.example.com/repos/ --username readonly --password readonly1

HTTPS 가 정상 동작한다면 mod_rewrite 모듈을 이용하여 http 로 들어오는 연결은 모두 https 로 전환 하도록 설정해 보자. 다음은 conf/httpd-vhost.conf 의 가상 호스트 설정이다.

<VirtualHost *:80>
   ServerName svn.example.com
   ErrorLog logs/svn.example.com-error_log
   CustomLog logs/svn.example.com-access_log common
   <Location /repos>
        DAV svn
        SVNPath /var/svn/myrepos/
        AuthType Basic
        AuthName "SVN Repo"
        AuthUserFile /var/svn/myrepos/svn.passwd
        AuthzSVNAccessFile /var/svn/myrepos/svn.authz
        Require valid-user
    </Location>

    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
</VirtualHost>
CODE

이제 http 로 연결해 보면 다음과 같이 에러가 발생할 것이다.

svn list -R http://svn.example.com/repos/ --username readonly --password readonly1


svn: E175011: Unable to connect to a repository at URL 'http://svn.example.com/repos'
svn: E175011: Repository moved temporarily to 'https://svn.example.com/repos'; please relocate

서브버전은 브라우저와는 달리 서버에서 "HTTP 302 Found"  응답과 함께 Location: 헤더에 새로운 URL 을 전송해도 자동으로 전환하지 않으므로 명시적으로 https:// 를 사용해서 소스를 체크 아웃해야 한다.

기존에 이미 체크 아웃한 저장소는 저장소의 URL 을 변경해 주어야 한다. URL 변경 작업을 relocate 라고 하며 서브버전 1.6 까지는 switch 명령어에 --relocate 옵션을 주어야 했지만 1.7 부터는 relocate 명령이 생겨서 간편해 졌다.

사용법은 relocate 명령어 뒤에 새로운 URL 을 입력하면 된다.

svn relocate https://svn.example.com/repos/lib-hello

TortoiseSvn 은 메뉴에서 "Relocate" 를 선택한 후에 다음 그림처럼 새로운 URL 을 지정해 주면 되며 이 예제에서는 http 를 https 로 변경하면 된다.