如何在Subversion管理的文件名中转义@字符?

194

对于许多Subversion操作,将“@”符号附加到文件或URL参数的末尾可以使您针对该文件的特定修订版本。例如,“svn info test.txt @ 1234”将提供有关test.txt在修订版本1234中存在时的信息。

但是,当文件名包含@字符时,它会被Subversion错误地解释为修订版本说明符:

svn info 'test@.txt' svn:解析修订版本“.txt”时出现语法错误

我已经尝试了双引号和单引号,以及用“/”,“\”和“@”进行转义。如何告诉Subversion将@符号视为文件名的一部分?


3
你为什么会在文件名中加入@符号呢?如果你问我,这样做很容易出问题... :-) - JesperE
57
自iOS 4+起,苹果为其所有iOS开发者创建了这个规定。如果某些资源是为高分辨率显示设计的,则它们的名称应该以@2x结尾。 - Dimitris
2
传统的 Matlab 面向对象编程规范 - Chinasaur
在Linux的systemd服务中,@字符经常被使用。 - Damgot
@JesperE 有时候你别无选择,开发人员会在文件名中使用 @ 符号来表示分辨率相关的变体。 - Peter Flynn
显示剩余2条评论
11个回答

288

来自SVN书(加重强调):

敏锐的读者可能会想知道,在工作副本路径或URL中实际包含@符号时,这个钉住修订号语法是否会引起问题。毕竟,svn怎么知道news@11是树中一个目录的名称还是“news的第11个修订版本”的语法?幸运的是,尽管svn总是假设后者,但有一个微不足道的解决办法。您只需要在路径末尾添加一个@符号,例如news@11@svn仅关注参数中最后一个@符号,并且省略该@符号之后的文字形式的钉住修订号标识符也不被认为是非法的。即使对于以@符号结尾的路径,此解决方法也适用——您可以使用filename@@来表示名为filename@的文件。


4
请注意,在使用“svn diff”命令时,需要添加版本参数。虽然“svn up @file@”可以正常工作,但“svn diff @file@”无法正常工作。您需要使用“svn diff -r HEAD @file@”。 - analytik
SVN书的注意事项:文件可以没有扩展名存在,即使在Windows上也是如此,因此news@11也可能是一个文件。 - trysis
1
请注意,对于某些命令(例如重命名),参数可以是版本化的项目或本地文件名。在重命名的情况下,目标还会被扫描以查找固定的修订版,但之后可能会被视为普通名称。例如,如果您想将“@foo”重命名为“@bar”,则“svn rename @foo@ @bar”会抱怨“@bar”;但如果您将其设置为“svn rename @foo@ @bar@”,新名称将成为字面上的“@bar@”。为了避免这种情况,请添加“./”(或Windows上的“.\”)以明确它是本地路径:“svn rename @foo@ ./@bar”。 - Zastai

83

原回答是正确的,但可能不够明确。特定的Unix命令行选项如下:

svn info 'image@2x.png@'


svn info "image@2x.png@"


svn info image\@2x.png\@

我刚刚测试了所有三个。


5
我也测试了 svn info icon@2x.png@ ,它也可以正常工作。是的,没有引号或斜杠! - Nate
引用的必要性取决于您使用的shell - 我使用KSH,确保您需要引号(因为“@”是一个符号,表示您想在后台运行进程)。根据不同的shell,情况可能有所不同。 - David H
是的,我的里程碑在“bash”高速公路上 :) - Nate
1
@Nate 现在我无法让它失败 - 在ksh中没有引号也可以正常工作。我不知道为什么我认为我需要它们 - 也许是其他问题 - 我发帖已经两年了... - David H

14

添加不同子文件夹中的多个文件的解决方案:

for file in $(find ./ -type f -name "*@*.png"); do svn add $file@; done

只需将“@.png”中的“png”替换为您想要添加的文件类型即可。


请确保引用或转义文件名(并进行不区分大小写的匹配)。此外,没有必要将名称中带有“@”符号的文件视为特殊情况,您可以安全地将“@”符号附加到所有文件名上:for file in $(find ./ -type f -iname "*.png"); do svn add "$file@"; done。另外,这种方法是否会使您的svn仓库与本地工作副本的文件/目录结构不一致? - ardnew
使用 execfind 可能更容易:find . -type f -name "*@*.png" -exec svn add {}@ \; - Walty Yeung

12

只需在需要使用的文件末尾添加

@

无论使用什么SVN命令,都要添加它,例如:

file@2x.jpg

file@2x.jpg@

12

为添加以下文件:image@2x.png,请执行以下操作: svn add image\@2x.png@


8
在我的情况下,我需要从一个包含@符号的SVN存储库中删除文件:
这样做不起作用:
svn remove 'src/assets/images/hi_res/locales-usa@2x.png'

但是这个做到了:
svn remove 'src/assets/images/hi_res/locales-usa@2x.png@'

6
为添加多个文件,有另一种解决方案:
svn status | grep \.png | awk '{print $2"@"}'| xargs svn add

请解释你的答案。 - Hemang
3
你可以使用awk代替grep: svn status | awk '/\.png/ {print $2"@"}'| xargs svn add - h3dkandi

1

对于像“move”这样带有2个参数的svn命令,您必须将“@”仅添加到左侧(第一个)参数。例如:

$ svn add README@txt@
A         README@txt

$ svn move README@txt@ README2@txt
A         README2@txt
D         README@txt


$ svn status
A       README2@txt

$ svn commit -m "blah"
Adding         README2@txt
Transmitting file data .
Committed revision 168.

$ svn delete README2@txt@
D         README2@txt

$ svn commit -m "blahblah"
*Deleting       README2@txt

Committed revision 169.

这一行很重要:$ svn move README@txt@ README2@txt

正如您所看到的,我们不需要在“README2 @ txt”后附加“@”


0

@David H

我刚刚尝试了一个类似的命令,没有转义@符号,它仍然可以正常工作。

svn ci splash.png splash@2x.png@

这是在GNU bash版本3.2.48(1)-release (x86_64-apple-darwin10.0)和svn 1.6.16上。


0
我遇到的唯一有效的解决方案是与@NPike建议的相同。
svn revert 'path/to/filename@ext@'

你确定这个回复应该是对原始问题的回答吗?最好只是点个赞或者留下评论。 - Nico Haase
抱歉,我的错。我还不能添加评论。 - Jonyx4

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