我的文件名包含一个空格,所以当我执行以下操作时:
git add first%20file.txt
上面的命令在我的控制台中向我返回了无效路径
如何逃离空间:
git add first\ file.txt
正如 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
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/
' 下的文件名。