6

我的文件名包含一个空格,所以当我执行以下操作时:

git add first%20file.txt

上面的命令在我的控制台中向我返回了无效路径

4

3 回答 3

21

如何逃离空间:

git add first\ file.txt
于 2013-11-02T13:14:50.357 回答
9

正如 sschuberth 在评论中提到的那样 - 您仅用于%20转义 URL 中的空格,而不是命令行上的文件名中的空格。

您有两个选项来添加这些文件

1) 文件名中的转义空格

git add first\ file.txt
git add first\ file\ name.txt

2)在引号内添加文件名

git add "first file.txt"
git add "first file name.txt"

FWIW,如果您只有一个名称以字符串开头的文件,您也可以使用制表符完成first

于 2013-11-02T19:44:24.370 回答
1

Git 2.18 应该改进文件名中带有空格的文件的完成。
(并且 Git 2.21,Q1 2019,也应该看到这个答案的第二部分)

请参阅SZEDER Gábor ( ) 的提交 f12785a(2018 年 4 月 16 日szeder

完成:改进在命令行上处理引用路径

当必须在命令行上完成一个已经包含引号和/或反斜杠转义字符的单词时,我们的 git 感知路径完成不起作用。
问题的根本原因是完成函数逐字查看命令行上的所有单词,即包括所有反斜杠、单引号和双引号字符,shell 在执行完成的命令时最终会删除这些字符。
这些引用/转义字符会导致不同的问题,具体取决于要完成的单词的哪个路径组件包含它们:

  • 引用/转义位于前缀路径组件中。
    假设我们有一个名为 ' New Dir' 的目录,其中包含两个未跟踪的文件 ' file.c' 和 ' file.o',并且我们有一个忽略目标文件的 gitignore 规则。
    在这种情况下,所有这些:

    git add New\ Dir/<TAB>
    git add "New Dir/<TAB>
    git add 'New Dir/<TAB>
    

应该立即唯一地完成 ' file.c',但 Bash 同时提供了 ' file.c' 和 ' file.o'。
这种行为的原因是我们的完成脚本使用前缀目录名称,如' git -C "New\ Dir/" ls-files ...",即双引号内的反斜杠。
然后Git尝试输入一个名为' New\ Dir'的目录,这(很可能)失败,因为这样的目录没有' t 存在。
因此,我们的完成脚本没有列出任何文件,将COMPREPLY数组留空,这反过来又导致 Bash 回退到其简单的文件名完成并列出该目录中的所有文件,即“ file.c”和“ file.o”。

  • 引用/转义在要完成的路径组件中。
    假设我们有两个未跟踪的文件 ' New File.c' 和 ' New File.o',并且我们有一个忽略目标文件的 gitignore 规则。
    在这种情况下,所有这些:

    git add New\ Fi<TAB>
    git add "New Fi<TAB>
    git add 'New Fi<TAB>
    

应该立即唯一地完成 ' New File.c',但 Bash 同时提供了 ' New File.c' 和 ' New File.o'。
这种行为的原因是我们的完成脚本使用这个 ' New\ Fi' 或 ' "New Fi' 等词来过滤匹配的路径,当然,由于包含反斜杠或双引号,任何潜在的文件名都不会匹配。
最终结果与上面相同:
完成脚本没有列出任何文件,Bash 回退到其文件名完成,然后也列出匹配的目标文件。

添加新的辅助函数__git_dequote(),它从作为参数的单词中删除引用和转义。
为了最小化调用这个函数的开销,将它的结果存储在变量$dequoted_word中,应该在调用者中声明为本地的;简单地打印结果将需要命令替换,这会增加 fork() 子shell 的开销。
使用此功能__git_complete_index_file()取消引用当前单词,即要完成的路径,以避免上述与引用相关的问题,从而修复两个失败的引用路径完成测试。


Git 2.21 (Q1 2019) 将改进 zsh " ",当完成的路径中包含 SP 等特殊字符时git cmd path<TAB>,它已完成为 " git cmd path name" ,而不会尝试保留 " " 单个文件名。 path name

这已被修复以将其完成为“ git cmd path\ name”,就像 Bash 完成一样。

请参阅Chayoung You ( ) 的提交 6d54f52提交 7a478b3(2019 年 1 月 1 日(由Junio C Hamano 合并 -- --提交 b84e297中,2019 年 1 月 18 日)yous
gitster

completion: 将结果git ls-tree视为文件路径

假设存储库中有名为“ foo bar.txt”和“ abc def/test.txt”的文件。
当以下命令触发完成时:

git show HEAD:fo<Tab>
git show HEAD:ab<Tab>

完成结果为 bash/zsh:

git show HEAD:foo bar.txt
git show HEAD:abc def/

他们两个在路径中都有一个未转义的空间,所以它们会被 Git 误读。文件名或目录的
所有条目,因此是正确的而不是.git ls-tree__gitcomp_file()__gitcomp_nl()

请注意提交 f12785a, Git v2.18.0-rc0,它正确处理引用的路径。
像这种情况,我们应该取消引用 $cur_?*:*

例如,假设有未跟踪的目录' abc deg',则触发完成:

git show HEAD:abc\ de<Tab>
git show HEAD:'abc de<Tab>
git show HEAD:"abc de<Tab>

应该唯一地完成 ' abc def',但 bash 会完成 ' abc def' 和 ' abc deg'。

在 zsh 中,触发完成:

git show HEAD:abc\ def/<Tab>

应该完成' test.txt',但什么也没有。
这两个问题都将通过取消引用路径来解决。

__git_complete_revlist_file()将参数传递给__gitcomp_nl()第一个是列表的地方,例如:

abc def/Z
foo bar.txt Z

Z的标记在哪里EOL

  • 中 blob 的尾随空格__git ls-tree | sed
    它使完成结果变为:

    git show HEAD:foo\ bar.txt\ <CURSOR>
    

所以 Git 会尝试寻找一个名为 ' foo bar.txt' 的文件。

  • 中树的尾部斜线__git ls-tree | sed
    它使 zsh 上的完成结果变为:

    git show HEAD:abc\ def/ <CURSOR>
    

因此,应该在 zsh 上删除命令 like 上的最后一个空格,以完成 ' abc def/' 下的文件名。

于 2018-06-03T22:16:47.187 回答