【问题标题】:SVN : file names with special characters (éèà...)SVN : 带有特殊字符的文件名 (éèà...)
【发布时间】:2019-03-13 13:43:52
【问题描述】:

我们正在开发 Mac/Windows/Linux。 Windows 用户在 Eclipse 下使用 SVN 提交了一些名称包含特殊字符的文件。在 MacOs 上,进行全新的检出(使用命令行),SVN 无法匹配那些目录/文件。

$ svn co [...]
$ svn st
 ?      ShapeLibraries/Cahiers spéciaux
 !      ShapeLibraries/Cahiers spéciaux

[...]

由于文件是 UTF-8 编码的,我已经使用 latin-1 查看了字符串,看看 char 转换会是什么:

第一个字符串格式错误,而第二个字符串正常(UTF8 é == Latin1 é)

知道是什么原因造成的吗?任何解决方案(除了重命名没有特殊字符的所有文件)?

谢谢

【问题讨论】:

    标签: svn utf-8 character-encoding


    【解决方案1】:

    正如其他人在这里和其他地方提到的那样,根本原因如下: 对于某些字符,UTF-8 允许以不同的方式对其进行编码(组合与分解)。 macOS 上的文件系统(HFS+ 或 APFS)以规范化分解形式 (NFD) 对文件名进行编码,而 Subversion 在添加文件时似乎使用不同的 UTF-8 编码。

    所以当从命令行添加一个名为 ä_¥_é_ç_Ø.txt 的文件时:

    > svn add ä_¥_é_ç_Ø.txt
    A       ä_¥_é_ç_Ø.txt
    

    Subversion 以不同的编码存储文件名,这会导致问题:

    > svn status
    ?       ä_¥_é_ç_Ø.txt
    !       ä_¥_é_ç_Ø.txt
    

    第一行是关于现有文件(其名称是 NFD 编码的)。此文件存在于文件系统中,但 Subversion 未知(“?”)。
    第二行是关于添加的文件(其名称编码不同)。这个文件是 Subversion 已知的,但在文件系统中不存在(“!”)

    要查看不同的编码,请使用 xxd:

    > svn status | head -1 | xxd; echo; svn status | tail -1 | xxd
    00000000: 3f20 2020 2020 2020 61cc 885f c2a5 5f65  ?       a.._.._e
    00000010: cc81 5f63 cca7 5fc3 982e 7478 740a       .._c.._...txt.
    
    00000000: 2120 2020 2020 2020 c3a4 5fc2 a55f c3a9  !       .._.._..
    00000010: 5fc3 a75f c398 2e74 7874 0a              _.._...txt.
    

    这是我如何处理这个问题以使 Subversion 在 macOS 文件系统上使用 UTF-8 编码的文件名:

    从 Subversion 添加或删除文件时,我不会在 Subversion 命令中键入或自动完成文件名。 相反,我ls 文件,复制文件名,并将其粘贴到 Subversion 命令中,它将显示编码的实际十六进制代码。
    这样做会导致 Subversion 使用实际的文件名编码而不是使用转换后的形式。

    例子:

    > svn status
    ?       ä_¥_é_ç_Ø.txt
    > ls
    ä_¥_é_ç_Ø.txt
    

    复制文件名并粘贴到以下命令中

    > svn add a<0308>_¥_e<0301>_c<0327>_Ø.txt
    A         ä_¥_é_ç_Ø.txt
    > svn commit -m "Test"
    Füge hinzu         ä_¥_é_ç_Ø.txt
    Übertrage Daten .erledigt
    Übertrage Transaktion...
    Revision 4 übertragen.
    > svn status
    > 
    

    【讨论】:

      【解决方案2】:

      这两个名称是不同的 Unicode 代码点序列。对问题中的文本使用 JavaScript:

      "é".codePointAt(0).toString(16)
      > 65
      
      "é".codePointAt(1).toString(16)
      > 301
      

      但是

      "é".codePointAt(0).toString(16)
      > e9
      

      U+0065 是拉丁文小写 e U+0301 是结合重音 U+00E9 是带有锐音的拉丁文小写字母 E

      它们在语义上是相同的。程序应该将它们进行比较。尝试在对它的所有引用中将一个重命名为另一个:存储库、本地文件系统、项目文件等。

      【讨论】:

        猜你喜欢
        • 2014-04-17
        • 1970-01-01
        • 2018-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多