更新

  • 2021/07/14 补充说明正确做法
  • 2019/01/27 初次发布

正确做法

下面介绍的用脚本形式添加忽略文件并不合适,正确的做法是将忽略内容以 SVN 属性修改的方式直接提交到 SVN 仓库中。

脚本中做的正确的是修改了用户的全局配置,删除了 TortoiseSVN 默认的用户级别的全局忽略规则,这一步手动处理也可以。

svn:global-ignores 是用在目录上可以递归忽略所有子目录中内容的属性。svn:ignore 是用在目录上只忽略当前目录中内容的属性。因此正确的用法是直接将 svn:global-ignores 当作 Git 的 .gitignore 文件使用。

问题

项目内使用的 xLua 库 libxlua.so libxlua.a 文件被莫名其妙地忽略。

  1. 经过仔细检查发现项目内没有使用任何 svn:ignoresvn:global-ignores 属性去忽略文件。
  2. ~/.subversion/configglobal-ignores 字段也没有设置,但是仓库内的文件依然被忽略。
  3. 最后尝试在 ~/.subversion/config 中单独加一行 global-ignores= 后文件不被忽略了。相当于覆盖系统级别的规则。
  4. 查找 Subversion 安装目录中没有找到系统级别的配置,推测忽略规则应该是硬编码到了程序中。

最后确定的处理方案就是修改用户配置文件增加一行空白规则以覆盖系统级别的规则,忽略规则全部在项目内自定义。

官方有人提到仓库内的 svn:global-ignores 属性应该覆盖系统级别的忽略规则,但是还没处理。

介绍

项目内会存在一些应该存在但不需要提交的文件,可以使用忽略规则将其忽略。

Subversion 命令是 svn,因此以下使用 SVN 代替全名。

方式

官方推荐书籍中对忽略规则相关的介绍:

配置

运行时配置可以控制全局的忽略规则:

  • Windows %APPDATA%\Subversion\config
  • macOS ~/.subversion/config

注意:配置文件中默认并未启用忽略规则(忽略规则已被 # 注释掉了),但是此忽略规则已被嵌入到 SVN 程序代码中作为系统级忽略规则。

svn - How do I ignore files in Subversion? - Stack Overflow

属性

SVN 使用目录上设置的两种属性来管理忽略规则:

  • svn:ignore 只能控制忽略当前目录中的文件与目录,并不能递归处理子目录
  • svn:global-ignores 可以忽略所有子目录中的文件与目录,可以递归处理子目录(注意:这是 SVN 1.8 中新增加的属性 Apache Subversion 1.8 Release Notes

限制

SVN 使用的文件模式匹配相当简陋:

  • 只能匹配文件名与目录名
  • 不能匹配在目录中的文件路径
  • 不能匹配多级目录
  • 不能使用 / 开头的目录限制目录为当前目录的子目录

Shell 下的文件匹配模式,但是 SVN 支持不全:Shell Command Language - The Open Group

整合

全局忽略规则

将全局需要忽略的目录与文件以 svn:global-ignores 属性存放在根目录中。

注意:由于受到上述的匹配规则只能是文件名与目录名的限制,这里的配置只能是精确的名字匹配与通配符的名字匹配。

显式局部忽略规则

由于 SVN 内置的文件匹配模式无法匹配路径,因此需要忽略路径唯一的子目录或文件时,需要设置父目录的 svn:ignore 属性。

注意:如果一个目录已经被版本控制了,那么即使添加到忽略规则也不会忽略目录中的文件,需要先 svn delete --keep-local path/to/dir 从版本库中删除目录但保留本地目录,然后切换到 path/to 目录下再使用 svn propset svn:ignore "dir" . 设置父目录的忽略属性。在 TortoiseSVN 右键菜单中操作时会自动做这两步操作,非常方便。Ignoring Files And Directories - TortoiseSVN

应用

忽略规则

参考 Git 规则

从下面的网站生成 Git 的忽略规则,然后转换成 SVN 的规则:

  • 删除目录结尾的斜线 /
  • 删除用不到的规则,如 AssetStoreTools、unitypackage 之类的
  • 删除路径形式的规则,也可以删除目录路径部分,只保留文件名

参考链接

创建忽略文件

.svnignore

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Created by https://www.gitignore.io/api/unity
# Edit at https://www.gitignore.io/?templates=unity

# Converted ignore rules from Git to Subversion
# Remove trailing slash / in dir rule

### Unity ###
[Ll]ibrary
[Tt]emp
[Oo]bj
[Bb]uild
[Bb]uilds
[Ll]ogs

# Visual Studio cache directory
.vs

# Gradle cache directory
.gradle

# Autogenerated VS/MD/Consulo solution and project files
ExportedObj
.consulo
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.opendb
*.VC.db

# Unity3D generated meta files
*.pidb.meta
*.pdb.meta

# Unity3D generated file on crash reports
sysinfo.txt

# Builds
*.apk

# Crashlytics generated file
crashlytics-build.properties

# End of https://www.gitignore.io/api/unity

# macOS
.DS_Store

# Rider
.idea

设置

创建设置脚本放在项目根目录执行,脚本分为 macOS 与 Windows 版本。

macOS

  • macOS Mojave 10.14.2
  • Subversion 1.11.1
脚本

setup.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash

# Set global ignores

echo ------ Unset user global ignores
CONFIG=$HOME/.subversion/config
echo [miscellany] >> $CONFIG
echo global-ignores= >> $CONFIG
echo $CONFIG

echo
echo ------ Import ignore rules
svn propset svn:global-ignores --file .svnignore .

echo
echo ------ Ignore rules
svn propget svn:global-ignores .

echo
echo ------ Ignore files and directories
svn status --no-ignore | grep ^I

Windows

  • Windows 7
  • TortoiseSVN 1.9.4
SVN command line

由于 TortoiseSVN 默认安装选项中并不勾选 command line client tools 选项,因此无法在命令行下使用 svn 命令,需要手动添加命令行支持。

安装 TortoiseSVN 并勾选 command line client tools 选项。已安装的机器上也可以通过运行安装包,执行 Modify 来添加命令行支持。

svn - Using TortoiseSVN via the command line - Stack Overflow

可以配置脚本来自动化安装修改:

TortoiseSVN_1.9.4.27285_x64.bat

1
msiexec /i TortoiseSVN_1.9.4.27285_x64.msi ADDLOCAL=ALL /qb

建议:将 SVN 安装程序与安装脚本放在单独的以 SVN 命名的目录中,这样其他人下载整个目录后双击安装脚本即可全部按照默认值一键安装完成,而不会要求有任何交互。

脚本

setup.bat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@echo off

REM Set global ignores

echo ------ Unset user global ignores
set CONFIG=%APPDATA%\Subversion\config
echo [miscellany] >> %CONFIG%
echo global-ignores= >> %CONFIG%
echo %CONFIG%

echo=
echo ------ Import ignore rules
svn propset svn:global-ignores --file .svnignore .

echo=
echo ------ Ignore rules
svn propget svn:global-ignores .

echo=
echo ------ Ignore files and directories
svn status --no-ignore | findstr "^I"

pause

windows cmd 定义和使用变量 - VictaminC的博客 - CSDN博客

提交

提交根目录属性时并不希望将所有修改的文件提交,那么要在提交时显式地指定 --depth empty 参数:

svn commit --message "SVN:增加仓库全局忽略规则" --depth empty . .svnignore setup.sh setup.bat

TortoiseSVN 可以在提交时直接将目录的属性变化提交,但是 macOS 下的 Cornerstone 中看不到根目录的属性变化,需要使用命令行处理。

svn - Commit only property changes on root of repo, not files - Stack Overflow

GUI 客户端

使用 GUI 客户端时应注意:如果其选项中存在全局忽略列表且未遵守使用用户设置 ~/.subversion/config 中的全局忽略列表,需要手动禁用,如 macOS 下的 Cornerstone。