11장 Subversion 관련 도구

이재홍 http://www.pyrasis.com 2007.10.27 ~ 2008.04.20

목차

이번 장에서는 통합 개발 환경 구축과는 별개로, Subversion 사용과 관련된 유용한 도구들을 소개하겠습니다. 유료 소프트웨어도 있으며, 무료 소프트웨어도 있습니다. 각자 상황에 맞게 선택하여 사용하면 됩니다.

VisualSVN (Visual Studio 플러그 인)

VisualSVN은 Visual Studio 2003, 2005, 2008의 플러그인으로 Visual Studio의 파일 보기창 안에서 커밋, 업데이트, 비교 등 Subversion 명령을 실행할 수 있고, 수정된 파일은 아이콘의 색이 변하기 때문에 어떤 파일이 수정되었는지 쉽게 알 수 있도록 해줍니다. VisualSVN은 유료 소프트웨어이며 TortoiseSVN을 설치해야 사용할 수 있습니다. 실제 Subversion 명령 실행은 TortoiseSVN을 이용하기 때문입니다.

설치 파일은 http://www.visualsvn.com에서 받을 수 있으며, 30일 동안 사용할 수 있습니다. 30일이 지난 이후에는 라이센스를 구입해야 합니다.


그림 11-1 VisualSVN을 설치한 화면

Visual Studio의 Solution Explorer에서 솔루션에 포함된 파일들을 볼 수 있습니다. 수정되지 않은 파일은 파일명 앞의 아이콘이 초록색이며, 수정된 파일은 주황색으로 표시됩니다.


그림 11-2 VisualSVN 메뉴

각 파일을 선택하고 오른쪽 마우스 버튼을 누르면 팝업 메뉴가 나오는데, Subversion 명령이 추가된 것을 볼 수 있습니다. 이 메뉴에서 수정된 파일 비교, 업데이트, 커밋 등의 Subversion 명령을 실행할 수 있습니다.


그림 11-3 VisualSVN 이름 바꾸기

VisualSVN에서는 TortoiseSVN과는 별개로 자체적인 이름 바꾸기 기능을 제공해 주고 있습니다. 이름 바꾸기 뿐만 아니라 파일 이동도 가능합니다. 탐색기에서 TortoiseSVN으로 파일 이름을 바꾸어 버리면 Visual Studio 솔루션에서는 바뀐 파일을 인식하지 못하기 때문에 빌드가 되지 않을 수 있습니다. VisualSVN의 이름 바꾸기 기능은 Subversion 상의 이름도 바꾸어주고 Visual Studio 솔루션에도 적용해 줍니다. 따라서 Visual Studio를 주로 사용하는 프로젝트에서는 VisualSVN의 이름 바꾸기 기능을 사용하는 것이 편리합니다.

SVNSERVE Manager로 svnserve.exe를 쉽게 사용하기

SVNSERVE Manager는 필자가 제작하여 무료로 배포하고 있는 프로그램입니다. Subversion의 svnserve.exe을 편리하게 사용할 수 있도록 도와줍니다. 소규모 프로젝트 또는 간단한 개인 프로젝트에 적합합니다. svnserve.exe를 일반 모드와 서비스 모드로 실행 할 수 있도록 해주며 포트 지정, 윈도우 시작시 자동실행 기능도 있습니다.


그림 11-4 SVNSERVE Manager

SVNSERVE Manager의 사용법은 다음과 같습니다. 1. Subversion Repository Root에 Subversion 저장소의 경로를 입력합니다. … 버튼으로 경로를 찾을 수 있습니다.

  1. Port에 사용할 포트를 지정합니다. 아무것도 입력하지 않으면 기본 포트 번호(3690)로 실행됩니다. 예를 들면 서버 IP 주소가 192.168.1.100이고 포트를 6000으로 지정했다면 svn://192.168.1.100:6000으로 접속하면 됩니다.

  2. Run Mode에서 Normal과 Service 중에서 하나를 선택합니다. Normal은 svnserve.exe를 직접 실행하는 방식이며, Service는 svnserve를 서비스로 등록하여 실행하는 방식입니다.

  3. Automatically run program when you log on(Automatically run service when Windows starts up)에서 시스템 시작 시 자동실행을 할 것인지 설정합니다.
    Normal 모드에서는 윈도우에 로그인 하였을 때 SVNSERVE Manager와 svnserve.exe를 실행합니다. 단 로그인 하지 않으면 SVNSERVE Manager와 svnserve.exe는 실행되지 않습니다. Service 모드에서는 윈도우가 부팅 되었을 때 svnserve 서비스를 실행합니다. 이때는 로그인을 아지 않아도 서비스는 실행됩니다.

  4. Start 버튼으로 svnserve.exe 또는 svnserve 서비를 실행하며, Stop 버튼으로 종료합니다. Exit 버튼은 SVNSERVE Manager과 svnserve.exe를 함께 종료합니다. 단 Service 모드일 때에는 SVNSERVE Manager만 종료합니다. Hide 버튼은 SVNSERVE Manager 창을 숨깁니다.

필자가 SVNSERVE Manager를 제작하여 배포하면서, 의외로 사용자들이 저장소 경로와 다중 프로젝트 운영에 대해 어려워한다는 것을 알게 되었습니다. SVNSERVE로 여러 프로젝트를 운영하는 방법을 설명하겠습니다.

C:\Repos라는 디렉터리가 있고 이 디렉터리 아래에 각 프로젝트의 저장소가 위치하게 됩니다. 그냥 단순하게 SVNSERVE Manager의 저장소 경로를 지정하는(Subversion Repository Root) 부분에 C:\Repos만 지정하면 여러 프로젝트를 사용할 수 있습니다. 자주 하게되는 실수가 이 저장소 경로를 지정하는 부분에 C:\Repos\example과 같이 프로젝트의 저장소 경로까지 지정해 버리는 것입니다. 이렇게 지정하면 C:\Repos\example 프로젝트의 저장소만 접근할 수 있고, 다른 프로젝트는 절대 접근할 수 없게 됩니다.

따라서 저장소 경로를 지정하는 부분에 C:\Repos를 지정하고, svn://192.168.1.100/example, svn://192.168.1.100/hello, svn://192.168.1.100/world 처럼 저장소에 접근하는 URL의 마지막 부분을 원하는 프로젝트 이름으로 바꾸어 주면 되는 것입니다. 물론 example, hello, world 프로젝트의 저장소는 C:\Repos 디렉터리 아래에 있어야 합니다.

SVN Notifier으로 업데이트 상태를 실시간으로 확인하기

SVN Notifier는 현재 작업하고 있는 프로젝트를 다른 사람이 수정하여 커밋하였을 때, 업데이트가 필요하다는 메시지를 보여주는 프로그램입니다. 이 프로그램은 여러 사람이 하나의 프로젝트를 가지고 작업을 할 때 유용합니다. 다른쪽에서 프로젝트의 파일을 커밋 하였는데도, 업데이트를 제때 하지 않아 충돌이 자주 발생하고는 합니다. SVN Notifier를 이용하면 프로젝트가 수정된 즉시 업데이트가 필요하다는 것을 알려주기 때문에 충돌을 줄일 수 있습니다.

http://svnnotifier.tigris.org에서 받을 수 있습니다. 하지만, 공식 웹사이트에서 배포하는 설치파일(svnnotifier_1.4.0.msi)은 .NET Framework 2.0 체크를 정상적으로 하지 못하기 때문에 .NET Framwork 2.0이 설치된 윈도우에는 SVN Notifier가 설치되지 않습니다. 따라서 이 문제를 해결한 설치 파일을 부록 CD에 포함하였습니다. SVN Notifier는 Subversion과 TortoiseSVN을 설치해야 사용할 수 있습니다.

svnnotifier_1.4.0.msi를 설치합니다. 설치에는 특별한 것이 없으므로 기본 설정대로 설치합니다. C:\Program Files\SVN Notifier\SVN_Notifier.exe를 실행하면 아래와 같은 화면이 나옵니다.


그림 11-5 SVN Notifier

바탕 화면 sample이라는 프로젝트를 체크아웃 하고 + 버튼을 이용하여 등록 한 화면입니다. 작업 디렉터리는 여러 개를 등록할 수 있고, 로그 보기, 업데이트, 커밋 명령을 사용할 수 있습니다.


그림 11-6 sample 작업 디렉터리 추가

체크아웃한 sample 프로젝트에서 파일을 수정한 다음의 모습입니다. 프로젝트 목록의 맨 앞 S 아이콘에 붉은색 느낌표가 생긴 것을 볼 수 있습니다. 각 프로젝트를 선택하면 Commit 버튼이 활성화 되고 Commit 버튼을 누르면 TortoiseSVN의 커밋 창이 뜹니다.


그림 11-7 업데이트 필요 메시지

다른 사람이 프로젝트의 파일을 수정하여 커밋하면, SVN Notifier의 트레이 아이콘 색깔이 노란 색으로 변합니다. 그리고 업데이트가 필요하다는 메시지를 표시해줍니다.


그림 11-8 sample 작업 디렉터리의 상태 변화

프로젝트 목록 앞의 S 아이콘도 노란색으로 변합니다. 프로젝트를 선택하면 Update 버튼이 활성화 됩니다. Update 버튼을 누르면 TortoiseSVN을 통해 업데이트를 합니다.


그림 11-9 SVN Notifier의 설정 화면

SVN Notifier의 설정 화면입니다. svn.exe와 TortoiseSVN의 TortoiseProc.exe 경로를 지정할 수 있습니다. 프로젝트 저장소의 파일들이 변경되었는지 체크하는 주기도 설정할 수 있습니다. 기본적으로 체크 주기는 SVN Notifier 창을 열어놓았을 때에는 5초, 창을 종료하고 트레이 아이콘으로만 있을 때에는 1분입니다.

프로젝트를 클릭했을 때 작업 디렉터리 열기, 로그 보기, 업데이트, 커밋이 실행되게 설정할 수 있고, 업데이트 필요 메시지가 표시되는 시간, 시스템이 시작했을 때 트레이 아이콘 상태로 시작되도록 하기, 새 버전 체크 설정도 할 수 있습니다.

ViewVC로 Subversion 저장소를 웹에서 보기

ViewVC는 Subversion 저장소를 웹에서 볼 수 있도록 해주는 도구입니다. CVS만 지원할 당시에는 ViewCVS로 불리었으나, Subversion을 지원하게 되면서 ViewVC로 이름을 바꾸게 되었습니다. Trac을 사용하면 웹에서 저장소를 살펴볼 수 있지만, Trac을 사용하지 않고 웹에서 저장소를 살펴보려면 ViewVC를 사용하면 됩니다. ViewVC는 mod python을 사용합니다.

ViewVC를 사용하려면 필요한 프로그램은 다음과 같습니다. 주요 프로그램들은 Trac을 설치할 때와 똑같으므로 따로 설치 방법은 설명하지 않겠습니다.

  • Subversion Windows : svn-win32-1.4.5.exe
    http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100&expandFolder=8100&folderID=91
    부록 CD 경로 : Applications/Subversion/Apache-2.2/

  • Apache : apache_2.2.6-win32-x86-openssl-0.9.8e.msi, http://httpd.apache.org
    부록 CD 경로 : Applications/Apache/

  • Python : python-2.5.1.msi, http://python.org/download/
    부록 CD 경로 : Applications/Python/

  • Python extensions for Windows : pywin32-210.win32-py2.5.exe, http://sourceforge.net/projects/pywin32
    부록 CD 경로 : Applications/Python/

  • Subversion Python Bindings : svn-python-1.4.5.win32-py2.5.exe
    http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100&expandFolder=8100&folderID=0
    부록 CD 경로 : Applications/Subversion/Apache-2.2/

  • mod_python : mod_python-3.3.1.win32-py2.5-Apache2.2.exe, http://www.modpython.org
    부록 CD 경로 : Applications/Trac/

  • ViewVC : viewvc-1.0.4.zip, http://www.viewvc.org
    부록 CD 경로 : Applications/Subversion/ViewVC

  • diffutils : diffutils-2.8.7-1.exe, http://sourceforge.net/projects/gnuwin32
    부록 CD 경로 : Applications/GNU Win32/

  • enscript : enscript-1.6.3-9-bin.exe, http://sourceforge.net/projects/gnuwin32
    부록 CD 경로 : Applications/GNU Win32/

  • sed : sed-4.1.4.exe, http://sourceforge.net/projects/gnuwin32
    부록 CD 경로 : Applications/GNU Win32/

받은 viewvc-1.0.4.zip를 C:\temp에 압축을 해제합니다.

C:\temp\viewvc-1.0.4\viewvc-1.0.4>C:\Python25\python.exe viewvc-install

저장소의 기본 경로는 C:\Repos로 하겠습니다. Apache의 httpd.conf 설정은 다음과 같습니다.

httpd.conf

LoadModule python_module modules/mod_python.so

ScriptAlias /viewvc "C:/Program Files/viewvc-1.0.4/bin/mod_python/viewvc.py"
<Location /viewvc>
    AddHandler mod_python .py
    PythonPath "[r'C:\\Program Files\\viewvc-1.0.4\\bin\\mod_python']+sys.path"
    PythonHandler handler
    PythonDebug On
    AddDefaultCharset UTF-8
    Options +Includes
</Location>

C:\Program Files\viewvc-1.0.4\viewvc.conf를 열고 다음과 같이 수정합니다.

viewvc.conf

[general]
# 저장소의 최상위 디렉터리를 설정합니다.
root_parents = C:\Repos : svn

# default_root는 주석 처리합니다.
#default_root = cvs

# Subversion이 설치된 경로
svn_path = C:\Program Files\Subversion\bin

[options]
# URL로 저장소를 구분합니다. 
# 이것을 0으로 하면 위의 default_root에서 기본 저장소를 지정해줘야 합니다.
root_as_url_component = 1

# UTC를 사용하지 않고 대한민국 표준시를 사용합니다.
use_localtime = 1

ViewVC의 handler.py 파일에서 apache.import_module 부분을 다음과 같이 수정합니다. 이것을 수정하지 않으면 mod_python에서 모듈을 찾지 못하여 ViewVC를 실행할 수 없습니다.

C:\Program Files\viewvc-1.0.4\bin\mod_python\handler.py

def handler(req):
  path, module_name = os.path.split(req.filename)
  module_name, module_ext = os.path.splitext(module_name)
  try:
    #module = apache.import_module(module_name, path=[path])
    module = apache.import_module(module_name, path)
  except ImportError:
    raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND

  req.add_common_vars()
  module.index(req)

  return apache.OK

diff는 각 리비전간의 차이점을 볼 때 꼭 필요한 프로그램입니다. enscript는 소스 코드 컬러링(Syntax highlighting)에 필요한 프로그램이며, sed는 enscript로 변환된 html 파일에서 특정 태그를 제거할 때 필요합니다.

diffutils, ensript, sed는 설치파일 형태이기 때문에 별다른 설정없이 바로 설치하면 됩니다. 설치경로는 기본값 그대로 합니다. diff와 sed를 사용하기 위해 시스템 환경변수의 Path에 C:\Program Files\GnuWin32\bin를 추가합니다.

enscript 경로를 설정합니다.

C:\Program Files\viewvc-1.0.4\viewvc.conf

# 0을 1로 수정합니다.
use_enscript = 1

# enscript.exe가 있는 디렉터리를 설정해줍니다.
enscript_path = C:\Program Files\GnuWin32\bin

ViewVC는 기본적으로 로그는 UTF-8로 표시해주지만 소스 코드는 변환없이 그대로 출력합니다. 그래서 윈도우에서 저장한 소스파일은 cp949(euc-kr)이기 때문에 브라우저에서는 깨져서 출력됩니다. 브라우저의 인코딩을 euc-kr로 바꾸면 잘 보이지만 UTF-8로 인코딩된 로그가 깨져서 볼 수 없게 됩니다.

그래서 소스 코드도 UTF-8로 변환하도록 ViewVC를 수정해 주어야 합니다. use_localtime을 1로 설정했을 경우 나오는 “대한민국 표준시”도 깨지지 않도록 UTF-8로 변환합니다. 아래는 패치입니다(버전 1.0.4 기준).

부록 CD에는 아래 패치를 적용한 viewvc-1.0.4.zip 파일이 포함되어 있습니다. 또는 http://www.pyrasis.com/repos/viewvc/에서 최신 수정 내용을 확인 할 수 있습니다.

  • 1. blame.py를 열고 다음과 같이 수정합니다. import vclib.ccvs.blame 아래에 import viewvc를 추가합니다.
import cgi
import vclib
import vclib.ccvs.blame
import viewvc

thisline = link_includes(cgi.escape(item.text), self.repos, 부분을 찾아 아래와 같이 수정합니다.

수정 전

thisline = link_includes(cgi.escape(item.text), self.repos,

수정 후

thisline = link_includes(cgi.escape(viewvc.to_utf8(item.text)), self.repos,
  • 2. viewvc.py를 열고 다음과 같이 수정합니다. def htmlify(html):과 html = cgi.escape(html) 사이에 html = to_utf8(html)를 추가합니다.
def htmlify(html):
  html = to_utf8(html)
  html = cgi.escape(html)
  • 3. def copy_stream(src, dst=None, htmlize=0): 부분을 찾아서 그 위에 아래 def to_utf8(txt): 함수를 추가합니다.
def to_utf8(txt):
  for enc in ['utf-8', 'euc-kr', 'cp949']:
    try:
      u = unicode(txt, enc)
      return u.encode('utf-8')
    except UnicodeError:
      pass
  return txt

def copy_stream(src, dst=None, htmlize=0):
  • 4. if htmlize: 부분을 찾아서 아래와 같이 else: chunk = to_utf8(chunk)를 추가합니다.
    if htmlize:
      chunk = htmlify(chunk)
    else:
      chunk = to_utf8(chunk)
  • 5. return time.asctime(localtime) + ‘ ‘ + time.tzname[localtime[8]] 부분을 찾아서 아래와 같이 수정합니다.

수정 전

return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]

수정 후

return time.asctime(localtime) + ' ' + to_utf8(time.tzname[localtime[8]])

이제 아파치를 재시작하면 ViewVC를 사용할 수 있습니다. 아파치는 재부팅을 하지 않으면 시스템 환경 변수의 Path를 인식하지 못합니다. 그래서 diff, enscript, sed가 제대로 실행되지 않기 때문에 꼭 재부팅을 해줘야 합니다. ViewVC 소스를 수정하였을 경우 아파치를 재시작해야 적용되며, 그래도 적용이 안될 경우 ViewVC 아래에 있는 확장자가 .pyc 파일을 모두 삭제하면 됩니다.

TIP
viewvc 소스를 수정하고, *.pyc 파일을 삭제했더라도 적용이 되지 않을 때가 있습니다. 이럴 때에는 인터넷 옵션에서 임시 인터넷 파일을 삭제하고 새로 고침 하면 적용이 될 것입니다.

WebSVN으로 Subversion 저장소를 웹에서 보기

WebSVN은 ViewVC와 똑같은 역할을 하는 Subversion 저장소의 웹 인터페이스입니다. PHP로 작성되어 있으며 Python을 사용할 수 없지만, PHP를 사용할 수 있는 환경에서 유용합니다. WebSVN은 Subversion의 svn.exe, svnlook.exe를 이용하므로 Subversion이 필요하며, 소스코드 문법강조(highlighting)에는 Trac과 마찬가지로 enscript를 사용합니다. 파일 비교 내용을 출력하기 위해 diff와 sed도 필요합니다.

다음 URL에서 php-5.2.5-win32-installer.msi 파일을 받습니다. 이 파일은 부록 CD에도 포함되어 있습니다.

PHP 설치

  1. 설치 파일을 실행하면 설치 마법사가 표시됩니다. Next를 눌러 넘어갑니다.


    그림 11-10 PHP 설치 마법사

  2. I accept the terms in the License Agreement를 체크하고 Next를 누릅니다.


    그림 11-11 라이센스 동의

  3. PHP 설치 디렉터리를 지정하는 화면입니다. 기본 설정대로 설치합니다.


    그림 11-12 PHP 설치 디렉터리 지정

  4. 우리는 Apache 2.2를 설치했기 때문에 Apache 2.2.x Module을 선택합니다. 다른 버전의 Apache를 사용하고 있다면 그에 맞는 Module을 선택하면 됩니다.


    그림 11-13 웹 서버 버전 선택

  5. Browse…을 눌러 Apache의 설정 파일이 있는 디렉터리를 지정해줍니다. 여기서는 C:\Program Files\Apache Software Foundation\Apache2.2\conf\가 설정 파일 디렉터리입니다.


    그림 11-14 아파치 설정 디렉터리 지정

  6. 구성 요소를 선택하는 화면입니다. 기본 설정대로 설치합니다.


    그림 11-15 PHP 설치 구성 요소 선택

설정

httpd.conf 파일을 열고 DirectoryIndex 부분에 index.php를 추가합니다.

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

PHP 모듈 설정 부분은 인스톨러로 설치하면 httpd.conf에 자동적으로 설정이 추가되므로 따로 설정할 필요는 없습니다.

WebSVN은 현재 2.0이 최신 버전이며, http://websvn.tigris.org에서 받을 수 있습니다. websvn-2.0.zip을 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs에 압축을 해제합니다. 그리고 디렉터리 이름을 websvn-2.0에서 websvn으로 바꿉니다. include 디렉터리의 distconfig.php를 config.php로 이름을 바꿉니다. 그리고 config.php를 열고 각자 환경에 맞게 수정합니다. 아래는 config.php 예제입니다.

config.php

// 윈도우에 설치하므로 이 부분은 꼭 활성화 해주어야 합니다.
$config->setServerIsWindows();

// Subversion과 Diff가 설치된 디렉터리를 지정합니다.
$config->setSVNCommandPath('C:\\Program Files\\Subversion\\bin');
$config->setDiffPath('C:\\Program Files\\GnuWin32\\bin');

// enscript와 sed가 설치된 디렉터리를 지정합니다.
$config->setEnscriptPath('C:\\Program Files\\GnuWin32\\bin');
$config->setSedPath('C:\\Program Files\\GnuWin32\\bin');

// 저장소 부모 디렉터리를 지정합니다. 우리는 지금까지 C:\Repos를 사용해 왔기 때문에 C:\Repos로 지정합니다.
$config->parentPath('C:\\Repos');

// C:\가 아닌 다른 드라이브에 있는 저장소도 지정할 수 있습니다.
// $config->addRepository('Hello', 'file:///D:/Repos/Hello)');
// 그룹으로 저장소를 구분할 수 있습니다. 
// $config->addRepository('Hello', ' file:///D:/Repos/Hello ', 'worldgroup');
// 원격에 있는 저장소도 표시해 줄 수 있습니다. http://192.168.1.200과 같이 http(https) 프로토콜뿐만 아니라 svn://192.168.1.100과 같이 svn 프로토콜도 사용할 수 있습니다.
// $config->addRepository('Hello', 'http://192.168.1.200/svn/hello)', NULL, 'username', 'password');
// $config->addRepository('Hello', 'http://192.168.1.200', 'group', 'username', 'password');

// 템플릿(테마)를 설정하는 부분입니다. clam과 BlueGray를 선택할 수 있습니다.
$config->setTemplatePath("$locwebsvnreal/templates/calm/");

// MultiViews는 http://192.168.1.100/websvn/wsvn/example/trunk/example.cpp와 같이 저장소와 그 아래 파일들의 경로를 URL로 표시할 수 있도록 해줍니다.
// MultiViews 사용하기 부분 참고
// $config->useMultiViews();

// authz 파일의 경로를 지정합니다. 여기서 권한을 지정한 대로 WebSVN에서 표시됩니다. rw나 r로 지정하였다면 해당 경로가 표시 되고, * = 와 같이 읽기 쓰기 모두 주지 않으면 해당 경로는 표시되지 않습니다.
$config->useAuthenticationFile('C:\\Repos\\authz');

// 저장소 각자의 authz 파일을 설정하여 사용한다면 아래와 같이 설정합니다.
// $config->useAuthenticationFile('C:\\Repos\example\conf\authz', 'example');

// enscript를 사용하려면 이 부분을 활성화 해줍니다.
$config->useEnscript();

// 탭 문자를 스페이스 몇 글자로 표시해 줄지 설정합니다. 기본적으로 스페이스 8칸으로 설정되어 있습니다.
$config->expandTabsBy(8);

// 특정 저장소만 탭 문자 설정을 따로 해 줄 수도 있습니다. 아래는 example 저장소만 탭 문자를 스페이스 3칸으로 표시한다는 설정입니다.
// $config->expandTabsBy(3, 'example');

MultiViews 사용하기

wsvn.php를 열고 다음과 같이 수정합니다. WebSVN을 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs 아래에 websvn이라는 디렉터리에 설치하였으므로 /websvn이 됩니다.

wsvn.php

// Location of websvn directory via HTTP
//
// e.g.  For http://servername/websvn use /websvn
//
// Note that wsvn.php need not be in the /websvn directory (and normally isn't).
// If you want to use the root server directory, just use a blank string ('').
$locwebsvnhttp = '/websvn';

httpd.conf의 Options 부분에서 Indexes를 삭제하고 MultiViews를 추가합니다.

$config->useMultiViews();를 활성화 한 뒤 이 부분을 설정하게 되면 http://192.168.1.100/websvn/wsvn으로만 접속해야 합니다. http://192.168.1.100/websvn/index.php로 접속하면 WebSVN이 정상적으로 동작하지 않을 것입니다. 즉 wsvn.php($config->useMultiViews(); 활성화)과 index.php($config->useMultiViews(); 비활성화)는 동시에 사용할 수 없습니다.

<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.2/mod/core.html#options
    # for more information.
    #
    Options FollowSymLinks MultiViews

생략...

WebSVN도 ViewVC와 마찬가지로 한글을 출력하려면 소스코드를 수정해주어야 합니다. 아래 패치대로 소스코드를 수정하면, 윈도우에서 ANSI(cp949, euc-kr)로 저장한 소스코드와 UTF-8로 저장한 소스 코드 모두 정상적으로 출력할 수 있습니다.

아래 패치를 적용한 websvn-2.0.zip 파일은 http://www.pyrasis.com/repos/websvn/에서 최신 수정 내용을 확인 할 수 있으며 부록 CD에도 포함되어 있습니다.

  • 1. include 디렉터리의 svnlook.php을 열고 다음과 같이 수정합니다. 아래 수정 전 부분을 찾아 수정 후 내용으로 코드를 수정합니다.

수정 전

$curLog->curEntry->date = "$y-$mo-$d $h:$m:$s GMT";

수정 후

setLocale(LC_TIME, "ko_KR");
$curLog->curEntry->date = date("Y-m-d H:i:s \G\M\TO", gmmktime($h, $m, $s, $mo, $d, $y));

수정 전

$committime = strtotime($curLog->curEntry->date);

수정 후

$committime = mktime($h, $m, $s, $mo, $d, $y);  // GMT+0
  • 2. include 디렉터리의 command.php를 열고 다음과 같이 수정합니다. if (empty($inputEncoding)) $inputEncoding = $config->inputEnc; 부분을 찾아 그 아래에 if (isUTF8($str)) return $str;를 추가합니다.
if (empty($inputEncoding))
   $inputEncoding = $config->inputEnc;

if (isUTF8($str))
   return $str;
  • 3. include 디렉터리의 utils.php를 열고 다음과 같이 수정합니다. getFullURL 함수를 찾고 그 아래에 다음 isUTF8 함수를 추가합니다.
function getFullURL($loc)
{
    생략
}

function isUTF8 ($Str) {
   for ($i = 0 ; $i < strlen ($Str); $i ++)
   {
      if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
      elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n = 1 ; # 110bbbbb
      elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n = 2 ; # 1110bbbb
      elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n = 3 ; # 11110bbb
      elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n = 4 ; # 111110bb
      elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n = 5 ; # 1111110b
      else
         return false; # Does not match any model

      for ($j = 0 ; $j < $n ; $j ++) # n bytes matching 10bbbbbb follow ?
      {
         if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
            return false;
      }
   }
   return true;
}

hardspace 함수를 찾고 함수 안에 global $rep; $s = toOutputEncoding($s, $rep->getContentEncoding());를 추가합니다.

function hardspace($s)
{
   global $rep;

   $s = toOutputEncoding($s, $rep->getContentEncoding());

    return '<code>' . expandTabs($s) . '</code>';
}
  • 4. include 디렉터리의 feedcreator.class.php를 열고 다음과 같이 수정합니다. 아래 수정 전 부분을 찾아 수정 후 내용으로 코드를 수정합니다.

수정 전

return gmdate("r",$this->unix);

수정 후

return date("r",$this->unix);
  • 5. languages 디렉터리의 korean.php를 열고 다음과 같이 수정합니다. $lang[“NOPATH”]를 찾고 그 아래에 $lang[“NOACCESS”]와 $lang[“RESTRICTED”]를 추가합니다.
$lang["NOREP"] = "저장소가 지정되어 있지 않습니다.";
$lang["NOPATH"] = "경로를 찾을 수 없습니다.";
$lang["NOACCESS"] = "디렉터리를 읽을 수 있는 권한이 없습니다.";
$lang["RESTRICTED"] = "제한된 접근";

$lang[“DIFFPREV”]를 찾고 그 위에 $lang[“FILEDETAIL”]를 추가합니다.

$lang["FILEDETAIL"] = "파일 세부 내용";
$lang["DIFFPREV"] = "이전 리비전과 비교";
$lang["BLAME"] = "수정한 사람 보기";

$lang[“BADCMD”]를 찾고 그 아래에 $lang[“UNKNOWNREVISION”]를 추가합니다.

$lang["BADCMD"] = "명령 실행 에러";
$lang["UNKNOWNREVISION"] = "리비전을 찾을 수 없습니다.";

$lang[“SEARCHLOG”]을 찾고 그 위에 $lang[“FILTER”], +$lang[“STARTLOG”], $lang[“ENDLOG”], $lang[“MAXLOG”]를 추가합니다. $lang[“NOMORERESULTS”]를 찾고 그 아래에 $lang[‘NOPREVREV’]를 추가합니다.

$lang["FILTER"] = "필터링 옵션";
$lang["STARTLOG"] = "에서";
$lang["ENDLOG"] = "까지";
$lang["MAXLOG"] = "최대 리비전";
$lang["SEARCHLOG"] = "로그 검색";
$lang["CLEARLOG"] = "검색 조건 삭제";
$lang["MORERESULTS"] = "나머지 검색 결과...";
$lang["NORESULTS"] = "검색 조건에 맞는 결과가 없습니다.";
$lang["NOMORERESULTS"] = "더 이상 검색 조건에 맞는 결과가 없습니다.";
$lang['NOPREVREV'] = '이전 리비전이 없습니다.';

아래 수정 전 부분을 찾아 수정 후 내용으로 코드를 수정합니다.

수정 전

$lang["YEARS"] = "년";
$lang["MONTHS"] = "개월";
$lang["WEEKS"] = "주일";
$lang["DAYS"] = "일";
$lang["HOURS"] = "시간";
$lang["MINUTES"] = "분";

수정 후

$lang["DAYLETTER"] = "일";
$lang["HOURLETTER"] = "시간";
$lang["MINUTELETTER"] = "분";
$lang["SECONDLETTER"] = "초";

$lang[“WITHPATH”]를 찾고 그 아래에 $lang[“FILEDELETED”], $lang[“FILEADDED”]를 추가합니다.

$lang["WITHPATH"] = "경로:";
$lang["FILEDELETED"] = "파일 삭제됨";
$lang["FILEADDED"] = "새 파일";

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.