【问题标题】:Using SVN post-commit hook to update only files that have been committed使用 SVN 提交后挂钩仅更新已提​​交的文件
【发布时间】:2009-01-15 12:15:26
【问题描述】:

我正在使用 SVN 存储库进行 Web 开发工作。我设置了一个开发站点,其中包含存储库的签出。

我已经设置了一个 SVN 提交后挂钩,以便每当对存储库进行提交时,开发站点都会更新:

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 大小,包含约 7.5GB。 600,000 项,这主要是由于有多个分支/标签

【问题讨论】:

    标签: svn hook post-commit


    【解决方案1】:

    您可以使用 svnlook dirs-changedsvn up -N 仅更新每个更改的文件夹的内容:

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

    或者,如果每个文件可能更适合您(使用 sed 去除动作字符):

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

    【讨论】:

    • 我喜欢 sed 解决方案。但是我们如何确定文件名路径前有 4 个字符呢?
    • @FelipeAlvarez 不能保证它不会改变。但是,截至目前(1.8.0),它是3 charactersa space,然后是路径。
    【解决方案2】:
    #!/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
    

    【讨论】:

      【解决方案3】:

      对于 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
      

      只需将上述内容复制到您的提交后挂钩批处理文件(或 VisualSVN 的窗口)中即可完成 - 您将更新后的目录导出到 c:\

      您可以尝试使用 %1 而不是上面的 c:/path/to/repo,但我发现它不起作用,因为 VisualSVN 为 %1 路径提供了反斜杠路径分隔符,而 svnlook 为它们提供了 forward -斜线。这似乎无法正常工作,因此我对 repo 路径进行了硬编码(出现“文件名、目录名或卷标语法不正确”错误)

      【讨论】:

        【解决方案4】:
        猜你喜欢
        • 2012-10-18
        • 2010-11-09
        • 1970-01-01
        • 1970-01-01
        • 2014-08-10
        • 2016-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多