2015年1月6日 星期二

Arch啟用http存取svn和svn搬移log到另一個repos下

系統:
Arch Linux
svn, version 1.8.9+
Apache/2.4.10

目標:
1. 使用http存取svn
2. 搬移一個svn repos的log到另一個repos下

使用http存取svn
我們假設現有的svn倉庫放在這裡:
/home/svn/test
1. 編輯 /etc/httpd/conf/httpd.conf,要注意順序
LoadModule dav_module           modules/mod_dav.so # 取消註解
LoadModule dav_fs_module        modules/mod_dav_fs.so # 取消註解
LoadModule dav_svn_module       modules/mod_dav_svn.so # 新增這行
LoadModule authz_svn_module     modules/mod_authz_svn.so # 新增這行

使用SSL? => 不使用,所以後面設定檔設在vhost中

新建 /home/svn/.svn-policy-file:
[/]
* = r
[REPO_NAME:/]
USER_NAME = rw

新建 /home/svn/.svn-auth-file:
# htpasswd -cs /home/svn/.svn-auth-file USER_NAME #沒有檔案時,新建第一個user
# htpasswd -s /home/svn/.svn-auth-file OTHER_USER_NAME  #在檔案後面新建其他的user

設定權限:
# chown -R http:http /home/svn/test
編輯 /etc/httpd/conf/sites-available/svn.localhost.conf:
(注意:這邊我是設在vhost設定檔中、網路上有些設在httpd-ssl.conf、mod_dav_svn.conf中)
<VirtualHost *:80>
    DocumentRoot "/srv/http/" 必須設不同於svn repos的位置否則出現錯誤:{
Redirecting to URL 'http://svn.localhost/test':
Redirecting to URL 'http://svn.localhost/test':

svn: E195019: Redirect cycle detected for URL 'http://svn.localhost/test'
}
    ServerName svn.localhost
    ServerAdmin you@example.com
    ErrorLog "/var/log/httpd/svn.localhost-error_log"
    TransferLog "/var/log/httpd/svn.localhost-access_log"

    <Directory />
        Options +Indexes +FollowSymLinks +ExecCGI
        AllowOverride All
        Order deny,allow
        Allow from all
    Require all granted
    </Directory>
    <Location /test/>
       DAV svn
       #SVNParentPath /home/svn/test
       SVNPath /home/svn/test
       AuthzSVNAccessFile /home/svn/.svn-policy-file
       AuthName "SVN Repositories"
       AuthType Basic
       AuthUserFile /home/svn/.svn-auth-file
       Require valid-user
    </Location>
    # 如果有其他repos就複製上面粗體那段加在這後面
</VirtualHost>

設定完就加入網址
# a2ensite svn.localhost
重啟apache
# systemctl restart httpd
沒設dns的話記得要設hosts

接著打開瀏覽器 http://svn.localhost/test/ 就能看到svn了,便可使用svn checkout http://svn.localhost/test/trunk/ 來下載svn
注意:
必須使用svn checkout http://svn.localhost/test/trunk/ ,否則會出現錯誤:
$ svn checkout http://svn.localhost/test/
svn: E175002: Unexpected HTTP status 405 'Method Not Allowed' on '/test'

svn: E175002: Additional errors:
svn: E175002: PROPFIND request on '/test' failed: 405 Method Not Allowed

若想要checkout出 svn.localhost/test/ 下所有東西(含branches、tags、trunk),則必須打開SSL用https去存取
打開SSL:
# cd /etc/httpd/conf/
# openssl req -new -x509 -keyout server.key -out server.crt -days 365 -nodes
(會在這資料夾下產生server.key和server.crt)
編輯 /etc/httpd/conf/extra/httpd-ssl.conf:
#SSLSessionCache        "shmcb:/run/httpd/ssl_scache(512000)" #註解掉,我不確定為什麼在這邊要註解掉,因為用 journalctl -xn 查到這行有syntax error,所以註解掉
#SSLSessionCacheTimeout  300 #註解掉
在</VirtualHost> 前加入:
<Location /svn>
   DAV svn
   SVNParentPath /home/svn/
   AuthzSVNAccessFile /home/svn/.svn-policy-file
   AuthName "SVN Repositories"
   AuthType Basic
   AuthUserFile /home/svn/.svn-auth-file
   Require valid-user
</Location>
編輯 /etc/httpd/conf/httpd.conf :
LoadModule ssl_module modules/mod_ssl.so #取消註解
Include conf/extra/httpd-ssl.conf #取消註解

重啟apache後就能用 svn checkout https://svn.localhost/svn/test (因為沒吃到vhost,所以 https://localhost/svn/test 也可以)下載含有trunk、branches、tags的svn資料了,只是他第一次連會要你接受他的憑證

如果要移除svn 在console的某個網址(http)的登錄設定:
$ rm ~/.subversion/auth/svn.simple/xxx #用grep查網址再刪除他

搬移一個svn repos的log到另一個repos下
有兩個repos
svn checkout file:///home/svn/test:
test
├── branches
├── tags
└── trunk
    └── hello.txt
svn checkout file:///home/svn/test2:
test2
├── branches
├── tags
└── trunk
    └── media
        └── cloud
            └── web
                └── internet
欲把test的trunck下的code(hello.txt)搬到test2的trunk/media/cloud/web/internet 下面:
$ sudo svnadmin dump /home/svn/test > test.dump 
$ cat test.dump | svndumpfilter include "trunk" --drop-empty-revs --renumber-revs > test_trunk.dump #只留trunk的資料
用vim移除trunk的資料夾,若沒做這步,之後檔案會移到 trunk/media/cloud/web/internet/trunk 下面
$ vim test_trunk.dump
:1,$s/trunk\///g
或用bash+perl 取代,注意:find到的檔案(test_trunk.dump)和>>儲存的檔案(test_trunk_new.dump)不能為同一隻檔案,否則會造成無窮迴圈,必須另外儲存
$ find . -name test_trunk.dump | xargs perl -ne 'open NEW, ">>test_trunk_new.dump"; s/trunk\///g; print NEW'
將dump檔load進test2 repos
sudo svnadmin load /home/svn/test2 --parent-dir trunk/media/cloud/web/internet --ignore-uuid < test_trunk_new.dump
檢查:
$ svn checkout file:///home/svn/test2/ test2_new
$ tree test2_new
test2_new
├── branches
├── tags
└── trunk
    └── media
        └── cloud
            └── web
                └── internet
                    ├── hello.txt
                    └── trunk
查log有沒有搬移進去:
$ cd test2_new/ ; svn log
------------------------------------------------------------------------
r2 | bear | 2015-01-06 16:33:57 +0800 (二, 06  1月 2015) | 1 line

hello test
------------------------------------------------------------------------
r1 | bear | 2015-01-07 09:29:23 +0800 (三, 07  1月 2015) | 1 line

hello test2
------------------------------------------------------------------------
最後再手動移除 trunk/media/cloud/web/internet 下的trunk資料夾,即成功

參考資料:
https://wiki.archlinux.org/index.php/Subversion_Setup
https://blog.tinned-software.net/merge-two-svn-repositories/ # Merge two SVN repositories
http://stackoverflow.com/questions/1948318/how-to-configure-svn-web-access-for-different-write-permissions # 注意:用SVNPath時要用 <Location /svn/> 而非 <Location /svn>
http://stackoverflow.com/questions/11240581/subversion-405-method-not-allowed # 405 Method Not Allowed 可改用https解決
http://stackoverflow.com/questions/10524646/tortoise-svn-giving-me-redirect-cycle-detected-for-url-domain-svn # DocumentRoot 和 SVNPath 不能設一樣
http://stackoverflow.com/questions/9234852/how-to-replace-strings-in-a-file-and-save-it-as-another-file # bash+perl 取代檔案並另存新檔

沒有留言:

張貼留言