【问题标题】:sparse svn update of deep directory structure深度目录结构的稀疏svn更新
【发布时间】:2013-12-05 00:01:28
【问题描述】:

有没有办法对具有深层嵌套目录结构的 SVN 存储库进行稀疏签出。

我正在使用 repo 中所有文件的列表并仅过滤 *.xml:

svn list --recursive "http://myRepo.com/trunk" > allFiles.txt

我正在尝试执行以下操作:

svn checkout "http://myRepo.com/trunk" --depth empty "myRepo"
svn update --set-depth empty project1/dirs/moreDirs/evenMore/file.xml

我尝试了这个,但得到一个错误,说它正在跳过更新该文件。

如果我手动执行以下操作,我可以在结帐时获取该文件(我想要一个 --set-depth empty 来获取嵌套 SVN 路径的父目录)。

svn update --set-depth empty project1
svn update --set-depth empty project1/dirs/moreDirs
svn update --set-depth empty project1/dirs/moreDirs/evenMore
svn update --set-depth empty project1/dirs/moreDirs/evenMore/file.xml

svn status -v project1/dirs/moreDirs/evenMore/file.xml
# prints svn file information

编辑

我现在有 2 个解决方法都不理想

1.零碎 svn update --set-depth empty

我编写了一个 bash 函数,它采用我正在寻找的文件路径执行 svn update --set-depth empty 。例如对于project1/dirs/moreDirs/evenMore/file.xml,它会调用:

svn update --set-depth empty updateproject1 updateproject1/dirs updateproject1/dirs/moreDirs updateproject1/dirs/moreDirs/evenMore updateproject1/dirs/moreDirs/evenMore/file.xml

它可以工作,但似乎很慢(也许我可以将多个文件的调用批处理到一个 svn update 调用中)。我不能同时对单独的文件进行多个 svn update 调用,因为 svn 锁定了 repo。

这是完整的脚本:

function getContentFile() 
{

    CONTENT_FILE="$1"
    SVN_FILE="${SVN_REMOTE}${CONTENT_FILE}"
    LOCAL_CONTENT_FILE="${SVN_CHECKOUT}/${CONTENT_FILE}"
    LOCAL_CONTENT_FILE_DIR=$(dirname ${LOCAL_CONTENT_FILE})

    SVN_UPDATE_ARG="${CONTENT_FILE}"
    PARENT_DIR="$(dirname ${CONTENT_FILE})"
    if [ ! -e "${LOCAL_CONTENT_FILE}" ]; then
        pushd "${SVN_CHECKOUT}"
        while [ "$PARENT_DIR" != "." ]; do
            # Escape any spaces in the argument list being passed to svn update
            PARENT_ARG=$(echo $PARENT_DIR | sed 's/ /\\ /g')
            if [ -e "${SVN_CHECKOUT}/${PARENT_DIR}" ]; then
                # Stop if we detect a directory already controlled by SVN
                break
            fi
            SVN_UPDATE_ARG="$PARENT_ARG $SVN_UPDATE_ARG"
            PARENT_DIR="$(dirname ${PARENT_DIR})" || true
        done
        svn update --set-depth empty ${SVN_UPDATE_ARG}
    fi
}
# export function to use in xargs
export -f getContentFile

cat "$SVN_FILE_LISTING_CACHE" | egrep '\.xml$' | xargs -P 1 -n 1 -I{} bash -e -c 'getContentFile "$@"' _ {}

2。 svn cat 获取文件

我也可以只创建文件夹结构的路径和 svn cat 文件,我可以同时对多个文件执行此操作,但这会受到未连接到 svn 的影响(例如,我无法将其提交回来轻松地或从 svn 更新文件而无需步行和匹配路径),这不是真正的 svn 结帐。

function getAllContentFiles() 
{
    FILE_REGEX="$1"
    #NUM_PROCESSORS=`sysctl hw.ncpu | awk '{print $2}'`
    # Do this in parallel (doesn't have to match number of actual processors)
    NUM_PROCESSORS=50
    #TODO: need to do it 1 at a time because of SVN lock for svn updates
    cat "$SVN_FILE_LISTING_CACHE" | egrep $FILE_REGEX | xargs -P ${NUM_PROCESSORS} -n 1 -I{} bash -ex -c 'getContentFile "$@"' _ {}
}

function getContentFile() 
{

    CONTENT_FILE="$1"
    SVN_FILE="${SVN_REMOTE}${CONTENT_FILE}"
    LOCAL_CONTENT_FILE="${SVN_CHECKOUT}/${CONTENT_FILE}"
    LOCAL_CONTENT_FILE_DIR=$(dirname ${LOCAL_CONTENT_FILE})

    SVN_UPDATE_ARG="${CONTENT_FILE}"
    PARENT_DIR="$(dirname ${CONTENT_FILE})"
    mkdir -p "${PARENT_DIR}"

    if [ ! -e "${LOCAL_CONTENT_FILE}" ]; then
        pushd "${SVN_CHECKOUT}"
        svn cat "${SVN_FILE}" > "${LOCAL_CONTENT_FILE}"
    fi
}

【问题讨论】:

  • 如果您使用svn cat 获取单个文件?例如svn cat "http://myRepo.com/trunk/path/to/file.xml" > "path/to/file.xml"
  • 我可以获取单个文件并使用 mkdir -p $(dirname ${FILE_PATH}) 但如果我使用 svn update --set-depth 我可以在 SVN 中编辑和跟踪它(例如,我可以提交回这些文件或更新到最新版本)。

标签: svn version-control sparse-checkout


【解决方案1】:

由于 Subversion 1.7.0 update 接受了 --parents 选项,可以满足您的需求。

因此您可以执行以下操作:

$ svn co --depth empty https://svn.apache.org/repos/asf/subversion svn-sparse
 U   svn-sparse
Checked out revision 1544721.

$ svn up --parents trunk/subversion/libsvn_ra_svn/protocol
A    trunk
A    trunk/subversion
A    trunk/subversion/libsvn_ra_svn
Updating 'trunk/subversion/libsvn_ra_svn/protocol':
A    trunk/subversion/libsvn_ra_svn/protocol
Updated to revision 1544721.

【讨论】:

  • 那行得通,结帐仍然超级慢(猜测 svn update 中的每个路径都在进行远程调用)。使用 xargs -P 50 运行svn cat 版本,它能够打开很多并行网络连接。
  • 是的,它是在树上行走,所以它与您手动操作并没有什么不同。可悲的是,它不仅发出多个请求,而且在单独的会话中这样做。这意味着它必须打开一个新的 TCP 连接、协商 SSL(如果使用)、处理身份验证(如果需要)、执行 OPTIONS 请求,然后最后执行 REPORT。我们应该在整个路径上填写一个条目。如果您在创建这样的情况后运行更新,我们也会这样做。
  • @Dougnukem I did some work tonight toward improving this。如果您想试一试(通过 Subversion 主干上的源代码构建,我会对它有多大帮助非常感兴趣)。我可能可以对其进行更多改进,但这是一个更具侵入性的更改,这使svn update --parents 为我花费的时间比 DAV 减少了一半。
  • 看来这应该是公认的答案@Dougnukem
猜你喜欢
  • 1970-01-01
  • 2019-11-19
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 2016-09-07
相关资源
最近更新 更多