【问题标题】:SVN Update specific files from repository onlySVN 仅从存储库更新特定文件
【发布时间】:2013-11-29 00:23:39
【问题描述】:

这个存储库有很多 GB,其中 99% 是我不需要的。我想要做的是只获取/更新 *.js *.css *.html .doc 和 *.pdf 文件。其余的都是巨大的,我想留在上面,而不是浪费时间和磁盘空间,因为我不需要查看它们,也永远不会更改它们。

我意识到 svn:ignore 功能不是我需要的,它只与签入的内容和被忽略的内容有关。我也知道 SVN 中没有我可以利用的参数或设置来做我想做的事。

但我发现,如果我右键单击我的 SVN 文件夹并选择“检查修改”,然后在下一个对话框中选择“检查存储库”,那么我会得到我没有的文件的完整列表有。然后,将“扩展名”添加到列标题并按扩展名排序是一项简单的任务。然后我可以向下滚动并找到所有组合在一起的 .js 文件。

这就是我的#fail 发生的地方。如果我右键单击 JS 文件中的 ONE 并选择 UPDATE,那么它将关闭文件并创建支持该文件所需的子目录层次结构。这正是我想要发生的。在这一点上,我跳到空中,以为我找到了我需要的东西。这不是一个麻烦的过程,我可以忍受。然后我选择了所有的JS文件并右键单击。我注意到的第一件事是出现的上下文菜单选项较少,这很麻烦。但是 UPDATE 选项在那里,所以我不太担心。我选择 UPDATE 然后单击 OK,就像我之前尝试的一个 JS 文件一样。不过接下来发生的事情很奇怪。而不是重复一个文件发生的过程,但这次对所有选定的文件,它对每个文件显示“已跳过”并报告它已完成。每次都会发生这种情况。我可以手动完成每个文件(这需要几个小时),但我不能一次完成所有文件。

帮助。我在虚拟机中执行此操作,我不希望将大小增加四倍以获取我不需要的文件。

【问题讨论】:

  • 既然您说“...右键单击我的 SVN 文件夹...”,您似乎正在使用一些 SVN shell 集成。它是哪一个,在哪个操作系统上?当我们在这里时,哪个版本的 SVN?
  • 非常好。我正在使用将 Tortoise SVN 集成到资源管理器中的 Windows XP 虚拟机。 Tortoise SVN 版本是 1.5.0 Build 13316。期待更新到最新的建议,我刚刚做了,1.8.3 Build 24901,现在情况更糟了。现在,当我选择更新时,我不再看到“已跳过”,而是不再选择更新。当我更新 SVN 时总是会发生这样的事情:(

标签: file svn ignore


【解决方案1】:

很抱歉延迟回答,发生了很多事情,我也不得不花一些时间来完成这项工作。正如您已经指出的那样,没有直接的方法来执行“仅扩展结帐”。但是有一种方法可以使用Subversion command-line tools 和我编写的批处理脚本。它通过使用 Subversion 的sparse directories 功能工作,它允许您指定结帐应该具有的“深度”。通过指定empty 的深度,会创建一个空的工作副本,并且实际上不会签出任何文件或文件夹。然后,您可以update 立即将您选择的文件和文件夹从存储库中放入该工作副本。这允许创建您所追求的“仅扩展结帐”。

我编写的脚本允许您在EXTENSIONS 变量中指定多个扩展名,以空格分隔。然后扫描SVN_ROOT 变量中指定的存储库以查找具有给定扩展名的文件。然后它继续构建一个工作副本,该副本仅包含支持具有您指定的扩展名的文件所需的目录结构(使用上述方法)。我对它进行了相当多的测试,希望它能满足您的需求。

注意:根据存储库的大小和与指定扩展名匹配的文件数量,创建工作副本的过程将需要一些时间。

@ECHO OFF
SetLocal EnableDelayedExpansion

SET SVN_ROOT=svn://your-repository.com/svn/your-project
SET EXTENSIONS=.js .css .html .doc .pdf
SET ROOT_DIR=%CD%

ECHO Listing repository...
svn -R ls %SVN_ROOT% > _files-all.txt

REM filter list for specified extensions
FOR %%H IN (%EXTENSIONS%) DO (
    TYPE _files-all.txt | FINDSTR /I /R "%%H$" >> _files-selected.txt
)

REM initial checkout in empty mode
svn co %SVN_ROOT% --depth empty .

FOR /F "tokens=*" %%I IN (_files-selected.txt) DO (
    REM "escape" path elements by wrapping them into double quotes
    SET TMP_PATH=%%I
    SET TMP_PATH="!TMP_PATH:/=" "!"
    ECHO Fetching %%I
    REM iterate over path elements
    FOR %%J IN (!TMP_PATH!) DO (
        REM "unescape" each path element again
        SET PATH_ELEM=%%J
        SET PATH_ELEM=!PATH_ELEM:~1,-1!
        REM if we don't have this element, fetch it from repository
        IF NOT EXIST "!PATH_ELEM!" (
            svn up %%J --depth empty 2>&1 > nul
        )
        REM if the element is a directory, enter it
        IF EXIST %%~sJ\NUL CD %%J
    )
    CD !ROOT_DIR!
)

REM clean up temporary files
DEL _files-all.txt _files-selected.txt

【讨论】:

  • 非常感谢 zb,这太棒了。但我有个问题。我看到您正在测试元素是否存在以确定它是否应该“更新”。寻找我还没有的新项目是有道理的,但我认为 svn up %%J 命令可能应该始终执行,以测试我已经拥有的任何文件是否需要更新。我看到了脚本的一个缺点——它不会删除我已经拥有的文件,因为有人从存储库中删除了 SVN。在主更新循环之前,可能需要先迭代我拥有的文件并查看是否需要删除。
  • 脚本创建一个工作副本 (WC),其中仅包含具有所需扩展名的文件。它无法“转换”现有的 WC 并清除不需要的文件。但是,如果您使用此脚本创建 WC,更新就像 svn update 一样简单 - 它不会引入任何不需要的文件,而只会更新已经存在的文件(由于使用稀疏目录功能的特制 WC )。此外,如果在 repo 中删除了想要的文件,svn update 也会在 WC 中删除它。
  • 但在另一种情况下,如果将具有所需扩展名的新文件添加到存储库中,确实是一个问题 - 这不会被注意到。预计当天会有更新...
【解决方案2】:

我最终不得不放弃我的梦想,即拥有一个 svn 更新,它只会让我获得某些文件扩展名,而将所有其他文件扩展名留在服务器上。我不得不接受我需要获得全部内容,除非我希望每次更新都涉及导航大型树结构并仅选择我想要的子文件夹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多