2009-01-15 102 views
21

我正在使用SVN存儲庫進行我的Web開發工作。我有一個開發站點設置了存儲庫的簽出。使用SVN提交後掛鉤只更新已提交的文件

我已成立這樣,每當有內容提交到存儲庫網站的發展更新由一個SVN post-commit鉤子:

cd /home/www/dev_ssl 
/usr/bin/svn up 

這工作不錯,但由於資源庫中更新的大小需要很長時間(大約3分鐘),這在定期提交時非常令人沮喪。我想要的是更改後提交掛鉤只更新已提交的文件/目錄,但我不知道如何去做這件事。更新「最低公用目錄」可能是最好的解決方案,例如

如果犯如下文件:

  • /branches/feature_x/images/logo.jpg
  • /branches/feature_x/css/screen.css

這將更新目錄:/ branches/feature_x/

任何人都可以幫助我創建一個解決方案,實現這一目標嗎?

更新

  • 信息庫和開發站點位於同一服務器上,以便網絡問題不應參與。
  • CPU使用率非常低,並且I/O應該可以(它在高性能專用服務器上運行)
  • 開發站點大約爲。 7.5GB的大小,包含約。 600000項,這主要是由於有多個分支/標籤

回答

18

您可以使用svnlook dirs-changedsvn up -N只更新每個文件夾中的內容發生變化:

cd /home/www/dev_ssl 
svnlook dirs-changed [REPOS] -r [REV] | xargs /usr/bin/svn up -N 

或者,如果每-file可能對你更好(使用sed去除動作字符):

svnlook changed [REPOS] -r [REV] | sed "s/^....//" | xargs /usr/bin/svn up 
+0

我喜歡sed解決方案。但是,如何才能在路徑到文件名之前確保4個字符? – 2013-07-11 06:29:38

+1

@FelipeAlvarez不能保證它不會改變。但是,截至目前(1.8.0),它是[3個字符](https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L568)和[空間] (https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L601),然後路徑。 – 2013-07-11 07:56:47

1

對於Windows:

for /F "eol=¬ delims=¬" %%A in ('svnlook dirs-changed %1 -r %2') do svn export "file:///c:/path/to/repo/%%A" "c:/svn_exports/%%A" --force 

只是上面的複製到您的post-commit鉤子批處理文件(或窗口的VisualSVN),你就大功告成了 - 你會得到更新的目錄導出到c:\

您可以嘗試使用%1代替上面的c:/ path/to/repo,但是我發現它不起作用,因爲VisualSVN給%1路徑提供了反斜槓路徑分隔符,而svnlook給它們提供了正斜槓。這似乎並不正確,所以我硬編碼回購路徑(我得到「文件名,目錄名稱或卷標語法不正確」的錯誤)

10
#!/bin/bash 

REPOS="$1" 
REV="$2" 

# A - Item added to repository 
# D - Item deleted from repository 
# U - File contents changed 
# _U - Properties of item changed; note the leading underscore 
# UU - File contents and properties changed 

# Files and directories can be distinguished, as directory paths are displayed with a trailing "/" character. 

LOOK=/usr/local/svn/bin/svnlook 
SVN=/usr/local/svn/bin/svn 
DEV=/var/www/test 

cd /var/tmp/svn 
    for changes in `$LOOK changed $REPOS | awk '{print $1 "=" $2;}'`; 
    do 
     len=${#changes} 
     idx=`expr index "$changes" =`; 
     directory=${changes:$idx}; 
     action=${changes:0:$idx-1}; 
     if [ ${changes:len-1} = '/' ] 
     then 
      case "$action" in 
       "A") \ 
        mkdir --mode=775 -p $DEV/$directory; 
        chown nobody:nobody $DEV/$directory; 
        chmod 775 $DEV/$directory; 
        ;; 
       "D") \ 
        rmdir $DEV/$directory; 
        ;; 
      esac 
     else 
      case "$action" in 
       "A"|"U"|"UU") \ 
        $SVN export --force --non-interactive -r HEAD -q file://$REPOS/$directory; 
        BASE=`basename $directory`; 
        DIR=`dirname $directory`; 
        chown nobody:nobody $BASE; 
        chmod 775 $BASE; 
        mkdir --mode=775 -p $DEV/$DIR; 
        cp -f --preserve=ownership $BASE $DEV/$DIR; 
        unlink $BASE; 
        ;; 
       "D") \ 
        rm -f $DEV/$directory; 
        ;; 
      esac 
     fi 
    done 

exit 0