【发布时间】:2025-12-15 07:20:15
【问题描述】:
我的文件名包含一个空格,所以当我执行以下操作时:
git add first%20file.txt
上面的命令在我的控制台中返回了无效路径
【问题讨论】:
-
那么问题是什么?为什么它不起作用?因为您只使用 "%20" 来转义 URL 中的空格,而不是命令行上的文件名中的空格。
标签: git
我的文件名包含一个空格,所以当我执行以下操作时:
git add first%20file.txt
上面的命令在我的控制台中返回了无效路径
【问题讨论】:
标签: git
逃出空间怎么样:
git add first\ file.txt
【讨论】:
正如 sschuberth 在 cmets 中提到的 - 您只能使用 %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,也应该看到这个答案的第二部分)
请参阅commit f12785a(2018 年 4 月 16 日)SZEDER Gábor (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”的目录,但(很可能)失败了,因为这样的目录不存在。
结果,我们的完成脚本没有列出任何文件,将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(2019 年第一季度)将改进 zsh "git cmd path<TAB>",它已完成为 "git cmd path name"当完成的路径中有特殊字符如 SP 时,无需任何尝试保留“path name”一个文件名。
这已修复为“git cmd path\ name”,就像
bash 完成。
参见Chayoung You (yous)@commit 6d54f52、commit 7a478b3(2019 年 1 月 1 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit b84e297,2019 年 1 月 18 日)
completion:将@987654360@ 的结果视为文件路径假设有文件名为“
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()。注意commit 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的标记。
__git ls-tree | sed中 blob 的尾随空格。
使得补全结果变成:git show HEAD:foo\ bar.txt\ <CURSOR>因此,Git 将尝试查找名为“
foo bar.txt”的文件。
__git ls-tree | sed中树的尾部斜线。
它使得 zsh 上的补全结果变成:git show HEAD:abc\ def/ <CURSOR>所以命令 like 上的最后一个空格应该在 zsh 上删除以完成 '
abc def/' 下的文件名。
【讨论】: