2009-01-15 103 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