Git结帐双破折号的含义


274

此git命令中文件名前面的双破折号是什么意思?

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

他们是强制性的吗?等于

git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt

24
这是一个shell表达式。参见unix.stackexchange.com/questions/11376/…– iltempo
2012年

15
@iltempo:对于Git来说有点不同。对于Git,在树和路径看起来相同的情况下,它将树与路径分开。
Dietrich Epp

@Dietrich_Epp。我懂了。感谢您的澄清。
iltempo 2012年


3
它是重复项,但是此重复项至少可以通过查询“ git double dash”进行谷歌搜索。
索恩

Answers:


376

假设我path/to/file.txt在Git存储库中有一个名为的文件,我想还原对其的更改。

git checkout path/to/file.txt

现在假设该文件名为master...

git checkout master

哎呀!那改变了分支。将--要检出的树与要检出的文件分开。

git checkout -- master

如果某些怪胎添加了一个名为-f我们存储库的文件,这也对我们有帮助:

git checkout -f      # wrong
git checkout -- -f   # right

这在git-checkout中记录:Argument Disambiguation


12
这对许多bash命令都是正确的,而不仅仅是git命令,是吗?
NHDaly 2013年

40
@NHDaly:是的,的确如此。但是,有一个术语注释:“ Bash”只有几个命令(大约20个左右),大多数命令是与Bash分开的程序。它实际上是POSIX标准的一部分,--可用于将选项与其他参数区分开,因此您将在诸如cpmv(这不是Bash的一部分)之类的命令上看到它。
Dietrich Epp 2013年

6
知道为什么在checkout命令文档中没有正确描述此语法的原因吗?
TanguyP

4
@DietrichEpp在一些地方,它像checkout命令的可能参数一样被列出,但是文档在任何地方都没有解释它的作用或使用原因……这最终将我带到这里。
克里斯,2016年

7
@DietrichEpp正确,但是在进入Stack Overflow之前已经阅读了语法(和示例),我仍然不明白为什么会或不想使用--。作为不是来自linux背景的人,这样做是不明显的。对我来说,它似乎是特定于git的语法,没有描述其功能目的。我认为最好像其他选项一样简短描述,或者至少链接到linux手册页
克里斯,2016年

109

双破折号“-”表示“命令行标志结束”,即它告诉前面的命令不要尝试解析命令行选项后面的内容。


2
为了清楚起见,git它的含义还不止于此,因为它还意味着the后面的参数--不能是分支名称,并且暗示之前的参数--不能是文件路径。
宝石泰勒,

0

请注意,由于Git 2.5(2015年第二季度)自--变量包含通配符(*) ,因此您将不需要' '

一种帮助“ git <cmd> <revs> <pathspec>”命令行约定捕获错误键入路径的启发式方法是确保命令行后面的所有非rev参数都是工作树中文件的名称,但这意味着“git grep $str -- \*.c ”必须始终为消除了“ --”的歧义,因为没有人理智地创建一个名称从字面上看是星号-点-see的文件。

Git 2.5松散了启发式声明,即声明用户使用通配符字符串可能意味着要给我们一个pathspec

git checkout 'a*'
# same as
git checkout -- 'a*'

参见Duy Nguyen()的commit 28fcc0b(2015年5月2日(由Junio C Hamano合并--949d167号提交中,2015年5月19日)nguyenlocduy
gitster

pathspec--使用通配符时避免使用“ ”

--命令行中缺少“ ”并且命令可以同时使用修订版和路径时,其想法是,如果可以将参数视为扩展的SHA-1和路径,则--需要“ ”或git拒绝继续。
当前实现为:

  • (1)如果参数是rev,则它一定不能存在于工作树中
  • (2)否则,它必须存在于工作树中
  • (3)否则,必须为“ --”。

这些规则适用于文字路径,但是当涉及非文字路径规范时,几乎总是要求用户添加“ --”,因为它失败了(2)且很少遇到*.c(1)(例如,“(1)”)如果有一个名为“ *.c” 的引用,则会被满足。

该补丁通过考虑*“存在于工作树中”的任何有效()通配符pathspec 稍微修改了规则。
规则变为:

  • (1)如果arg是一个rev,则它必须存在于工作树中或不是有效的通配符pathspec。
  • (2)否则,它要么存在于工作树中,要么是通配符pathspec
  • (3)否则,必须为“ --”。

使用新规则,--在涉及通配符pathspec的大多数情况下,不需要“ ”。


在Git 2.26(2020年第1季度)中,对区分歧义的逻辑进行了调整,以区分修订版本和pathspec,以使反斜杠转义的glob特殊字符不计入“通配符为pathspec”规则。

参见Jeff King()的commit 39e21c6(2020年1月25日(通过合并JUNIOÇ滨野- -提交341f8a6,2020年2月12日)peff
gitster

verify_filename():在“通配符是pathspecs”规则中处理反斜杠

汇报人:DavidBurström
签名人:Jeff King

提交28fcc0b71apathspec--使用通配符时避免使用“ ”,2015-05-02):

git rev-parse '*.c'

没有双破折号。

但是它用来检查通配符的规则实际上会查找任何特殊的glob。
这过于宽松,因为这意味着实际上不执行任何通配符匹配的模式(例如“ a\b”)将被视为pathspec。

如果确实在磁盘上有这样的文件,那大概就是您想要的。
但是,如果您不这样做,结果就会令人困惑:与其说“ there's no such path a\b”,不如说它是一个很可能不匹配任何东西(或者至少不匹配您想要的东西)的pathspec。
同样,寻找路径“a\*b ”根本不会扩大搜索范围。它只会找到一个条目“ a*b”。

此提交将规则切换为仅在全局元字符扩展搜索时才触发,这意味着这两种情况现在都将报告错误(--当然,您仍然可以使用“ ” 消除歧义;我们只是在加强DWIM启发式方法)。

DWIM:按我的意思做

请注意,我们根本没有测试28fcc0b71a中的原始功能。
因此,此修补程序不仅可以测试这些极端情况,还可以针对现有行为添加回归测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.