如何在Subversion中忽略文件?

713

如何在Subversion中忽略文件?

此外,如何找到未处于版本控制下的文件?

18个回答

801

(此解答已更新以匹配SVN 1.8和1.9的行为)

您有2个问题:

标记文件为被忽略:

通过“被忽略的文件”,我是指该文件在列表中甚至不会出现为“未版本化”状态:您的SVN客户端将假装文件在文件系统中根本不存在。

被忽略的文件由“文件模式”指定。文件模式的语法和格式在SVN的在线文档中有详细解释: http://svnbook.red-bean.com/nightly/en/svn.advanced.props.special.ignore.html 《Subversion中的文件模式》。

从版本1.8(2013年6月)开始,Subversion支持三种不同的指定文件模式的方法。以下是摘要及示例:

1 - 运行时配置区域 - global-ignores选项:

  • 这是一个仅限客户端设置,因此您的global-ignores列表不会被其他用户共享,并且适用于您在计算机上检出的所有repos。
  • 该设置在运行时配置区域文件中定义:
    • Windows(基于文件)- C:\Users\{you}\AppData\Roaming\Subversion\config
    • Windows(基于注册表)- HKLMHKCU中的Software\Tigris.org\Subversion\Config\Miscellany\global-ignores
    • Linux/Unix - ~/.subversion/config

2 - 设置在目录上的svn:ignore属性(而不是文件):

  • 这个存储在repo中,所以其他用户将拥有相同的忽略文件。类似于.gitignore的工作方式。

  • svn:ignore应用于目录并且不是递归或继承的。匹配文件模式的任何文件或直接子目录都会被排除。

  • 虽然SVN 1.8增加了“继承属性”的概念,但svn:ignore属性本身在非直系后代目录中被忽略:

  cd ~/myRepoRoot                             # Open an existing repo.
  echo "foo" > "ignoreThis.txt"                # Create a file called "ignoreThis.txt".

  svn status                                  # Check to see if the file is ignored or not.
  > ?    ./ignoreThis.txt
  > 1 unversioned file                        # ...it is NOT currently ignored.

  svn propset svn:ignore "ignoreThis.txt" .   # Apply the svn:ignore property to the "myRepoRoot" directory.
  svn status
  > 0 unversioned files                       # ...but now the file is ignored!

  cd subdirectory                             # now open a subdirectory.
  echo "foo" > "ignoreThis.txt"                # create another file named "ignoreThis.txt".

  svn status
  > ?    ./subdirectory/ignoreThis.txt        # ...and is is NOT ignored!
  > 1 unversioned file

(因此,即使在根目录应用了“ignoreThis.txt”,文件./subdirectory/ignoreThis也不会被忽略。

  • 因此,要递归地应用忽略列表,必须使用svn propset svn:ignore <filePattern> . --recursive

    • 这将在每个子目录上创建一个属性副本。
    • 如果子目录中的<filePattern>值与父目录中的不同,则子目录的值完全覆盖父目录的值,因此没有“加法”效果。
    • 因此,如果更改根目录.<filePattern>,则必须使用--recursive进行更改,以在子目录和后代目录上覆盖它。
  • 我注意到命令行语法是反直觉的。

    • 我最初认为您可以通过键入svn ignore pathToFileToIgnore.txt之类的内容来忽略SVN中的文件,但是这不是SVN的忽略功能的工作方式。
  • 3-svn:global-ignores 属性。需要 SVN 1.8(2013年6月):

    • 这类似于svn:ignore,但它利用了SVN 1.8的“继承属性”功能。

    • svn:ignore相比,文件模式自动应用于每个后代目录(而不仅仅是直接子目录)。

      • 这意味着不必使用--recursive标志设置svn:global-ignores,因为继承的忽略文件模式会在继承时自动应用。
    • 以与先前示例中相同的命令集运行,但改用svn:global-ignores

        cd ~/myRepoRoot                                    # Open an existing repo
        echo "foo" > "ignoreThis.txt"                       # Create a file called "ignoreThis.txt"
        svn status                                         # Check to see if the file is ignored or not
        > ?    ./ignoreThis.txt
        > 1 unversioned file                               # ...it is NOT currently ignored
      
        svn propset svn:global-ignores "ignoreThis.txt" .
        svn status
        > 0 unversioned files                              # ...but now the file is ignored!
      
        cd subdirectory                                    # now open a subdirectory
        echo "foo" > "ignoreThis.txt"                       # create another file named "ignoreThis.txt"
        svn status
        > 0 unversioned files                              # the file is ignored here too!
      

    对于TortoiseSVN用户:

    对我来说,整个设置都很令人困惑,因为TortoiseSVN的术语(如其Windows资源管理器菜单系统中所用)最初让我感到误导 - 我不确定Ignore菜单中“Add recursively”、“Add *”和“Add ”选项的重要性。我希望这篇文章解释了忽略功能是如何与SVN属性功能相关联的。话虽如此,我建议使用命令行设置被忽略的文件,这样您就可以了解它的工作原理,而不是使用GUI,并且只有在熟悉命令行之后才使用GUI来操作属性。

    列出被忽略的文件:

    命令svn status将隐藏被忽略的文件(即与RCA global-ignores模式匹配的文件,或与直接父目录的svn:ignore模式匹配的文件,或与任何祖先目录的svn:global-ignores模式匹配的文件)。

    使用--no-ignore选项查看列出这些文件。被忽略的文件状态为I,然后将输出传输到grep以仅显示以“I”开头的行。

    命令如下:

    svn status --no-ignore | grep "^I"
    
    例如:
    svn status
    > ? foo                             # An unversioned file
    > M modifiedFile.txt                # A versioned file that has been modified
    
    svn status --no-ignore
    > ? foo                             # An unversioned file
    > I ignoreThis.txt                  # A file matching an svn:ignore pattern
    > M modifiedFile.txt                # A versioned file that has been modified
    
    svn status --no-ignore | grep "^I"
    > I ignoreThis.txt                  # A file matching an svn:ignore pattern
    

    呈现完毕!


    7
    寻找被忽略的文件:使用命令"svn status -u -v --no-ignore |grep "^I"|awk "{print $2}"。 - Christian Madsen
    3
    如果你想忽略文件 "./FolderA/FolderB/FileToIgnore",请在你的 ". " 文件夹中执行以下命令:svn propset svn:ignore "FileToIgnore" FolderA/FolderB/。 - jnj
    10
    如果你正在通过SSH连接执行命令 svn propedit svn:ignore .,但没有配置文本编辑器,你会收到一个错误消息,提示“_svn: E205007: 没有设置环境变量SVN_EDITOR,VISUAL或EDITOR,并且找不到'editor-cmd'运行时配置选项_”,而不是打开编辑器。因此,只需像这样指定 _--editor-cmd nano_:svn propedit svn:ignore . --editor-cmd nano - Jonathan Morales Vélez
    12
    你可以使用"--recursive"参数忽略所有子文件夹中具有特定文件名的文件。例如:svn propset svn:ignore "*.jpg" . --recursive - Templar
    2
    一个比awk更简单的替代方案是grep:svn status | grep '^?' - Johnride
    显示剩余12条评论

    96

    使用以下命令创建一个未受版本控制的列表。

    svn status | grep "^\?" | awk "{print \$2}" > ignoring.txt
    

    然后编辑该文件,只留下您实际想要忽略的文件。 然后使用此文件来忽略文件列表中列出的文件:

    svn propset svn:ignore -F ignoring.txt .
    

    注意行末的点号。它告诉SVN属性正在设置当前目录上。

    删除该文件:

    rm ignoring.txt
    

    最后提交

    svn ci --message "ignoring some files"
    

    你可以通过以下方式检查被忽略的文件:

    svn proplist -v
    

    2
    不错。一个小改进是 svn status | awk "/^?/ {print \$2}" > ignoring.txt - Dirk Eddelbuettel
    5
    为什么要删除文件?如果需要重新创建、添加或删除,请将其保留在代码库中。 - tgkprog
    请注意,此解决方案不会忽略子目录中的文件(即使它们出现在ignoring.txt中)。 - shaneb
    @tgkprog 这只是一次性使用,将文件加载到属性中。因此,不能保证文件包含与属性中相同的内容。因此,删除它并让人们运行 svn proplist -v 来检查哪些文件实际上被忽略是有意义的。 - icc97
    似乎对于 node_modules 文件夹不起作用,我仍然需要在 SVN GUI 中手动设置忽略。 - Lying_cat
    显示剩余2条评论

    78

    .gitignore类似的方法

    您可以像使用.gitignore一样忽略文件或目录。只需创建一个文本文件,列出您想要忽略的目录/文件,并运行下面的代码:

    svn propset svn:ignore -F ignorelist.txt .
    

    如果您不想使用文本文件,您可以这样做:

    svn propset svn:ignore "first
     second
     third" .
    

    源自:Karsten的博客 - 从命令行设置多个文件的svn:ignore属性


    3
    请注意,如果您稍后修改了忽略文件,您需要重新运行svn:ignore命令(参见https://dev59.com/Nbbna4cB1Zd3GeqPiuXs#58380306)。 - Sensei James

    51
    如果您正在使用TortoiseSVN,请右键单击文件,然后选择TortoiseSVN/Add to ignore list。这将把文件/通配符添加到svn:ignore属性中。
    在检查文件时,将会检查svn:ignore,并且匹配的文件将被忽略。我有一个Visual Studio .NET项目的以下忽略列表:
    bin obj
    *.exe
    *.dll
    _ReSharper
    *.pdb
    *.suo
    

    您可以在TortoiseSVN / 属性上下文菜单中找到此列表。


    45

    似乎没有人提到过这一点...

    svn propedit svn:ignore .
    

    然后编辑文件内容以指定要忽略的模式,退出编辑器,一切都完成了。


    5
    这个回答很有用。在我的情况下,我需要将“.”更改为我想要忽略的文件的子目录,并只指定文件模式。另外,第一次运行时,我需要执行以下操作(我使用的是Mac):export SVN_EDITOR="nano" - Elijah Lofgren

    22

    我发现这篇文章:Java中的.svnignore示例

    示例:Ruby on Rails的.svnignore文件,

    /log
    
    /public/*.JPEG
    /public/*.jpeg
    /public/*.png
    /public/*.gif
    
    *.*~
    

    之后:

    svn propset svn:ignore -F .svnignore .
    

    用于 .gitignore 的示例。你可以将其用于你的 .svnignore

    https://github.com/github/gitignore


    1
    我按照您说的做了...但是当我运行svn status时,它仍然显示带有“?”的被忽略文件。 - Harshit Gupta
    我从未使用svn status进行检查,而是使用svn add *,然后再使用svn commit,这样忽略的文件就不会被提交。 - d.danailov
    如果文件"a.txt"已经在版本控制中,那么忽略操作可以通过命令"svn propset svn:ignore -F .svnignore a.txt"来完成吗?这样正确吗? - errakeshpd
    如果你在你的 .svnignore 文件中添加了 "a.txt",我不确定,但命令应该是正确的。 - d.danailov

    10

    使用propedit时,请确保没有任何尾随空格,否则文件将被排除在忽略列表之外。

    如果您最初使用Linux上的tab自动完成功能创建文件,则这些空格会自动插入:

    svn propset svn:ignore 'file1
    file2' .
    

    7
    这仅适用于某些shell,比如bash。请注意,重新发出propset命令会覆盖先前设置的模式。 - J. A. Faucett
    1
    所以 file1file2 必须分别放在不同的行上吗? - IgorGanapolsky

    8
    另一种解决方案是:
    svn st | awk '/^?/{print $2}' > svnignore.txt && svn propget svn:ignore >> svnignore.txt && svn propset svn:ignore -F svnignore.txt . && rm svnignore.txt
    

    或按行处理

    svn st | awk '/^?/{print $2}' > svnignore.txt 
    svn propget svn:ignore >> svnignore.txt 
    svn propset svn:ignore -F svnignore.txt . 
    rm svnignore.txt
    

    功能描述:

    1. 从svn获取状态文件
    2. 将所有带有?的文件保存到文件“svnignore.txt”中
    3. 获取已经被忽略的文件并将它们附加到文件“svnignore.txt”中
    4. 告诉svn忽略“svnignore.txt”中的文件
    5. 删除文件

    8
    此外,如果您使用Tortoise SVN,您可以这样做:
    1. 在上下文菜单中选择“TortoiseSVN”,然后选择“属性”
    2. 在弹出的窗口中点击“新建”,然后选择“高级”
    3. 在弹出的窗口中,在“属性名称”对面选择或输入“svn:ignore”,在“属性值”对面输入所需的文件名、文件夹名或文件掩码(在我的情况下是“*/target”),点击“递归应用属性”
    4. 好。好。
    5. 提交

    6

    以下是更易读的版本,参考自bkbilly的答案:

    svn st | awk '/^?/{print $2}' > svnignore.txt
    svn propget svn:ignore >> svnignore.txt
    svn propset svn:ignore -F svnignore.txt .
    rm svnignore.txt
    

    它的作用:

    1. 从svn获取状态文件。
    2. 将所有标有?的文件保存到文件“svnignore.txt”中。
    3. 获取已经被忽略的文件,并将它们附加到文件“svnignore.txt”中。
    4. 告诉svn忽略“svnignore.txt”文件中的文件。
    5. 删除该文件。

    我喜欢bkbilly的回答,但这个版本将每一行都分开以使其更易读,并删除了&&,在我的测试中没有任何作用,因为第一行总是创建临时文件,而这个相同的临时文件总是进入忽略列表。 - LivingDust
    在这种情况下,编辑建议更为合适。感谢您的努力! - Jim
    我还没有足够的声望来建议编辑,但我不想破坏一个好的协议。是否有一个简单的自述文件,介绍何时更好地建议编辑而不是发布新答案等指南? - LivingDust
    1
    如果你的答案与一年半前发布的完全相同,那就很简单明了了。你甚至复制了“它是做什么的”的解释。 - Jim

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接