为什么通过插入符号提交的排除实际上并不排除命令提示符下的提交



来自 https://git-scm.com/docs/git-rev-parse#_specifying_ranges:

提交排除项

^ (插入符号) 表示法

要排除可从提交中访问的提交,请使用前缀 ^ 表示法。 例如 ^r1 r2 表示可从 r2 访问的提交,但排除那些 可从 R1(即 R1 及其祖先)访问。

我有一个测试存储库,我已经尝试了这种语法。出于此问题的目的,它由三个正常提交组成:

git log --pretty=oneline topic1
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1
b5803f6c59cbc9ae6b4bba81b0d5ad8cfbd8f23a start of topic 1
75400b34ebc0936dd28513c686c8adb526f063e6 (origin/master) Initial Commit

让我们尝试排除除最新提交之外的所有提交:

git log --pretty=oneline ^topic1~ topic1
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1
b5803f6c59cbc9ae6b4bba81b0d5ad8cfbd8f23a start of topic 1
75400b34ebc0936dd28513c686c8adb526f063e6 (origin/master) Initial Commit

它没有用。这似乎很奇怪,因为我们完美地遵循了插入符号。假设我们尝试改用提交哈希:

git log --pretty=oneline ^b5803 topic1
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1
b5803f6c59cbc9ae6b4bba81b0d5ad8cfbd8f23a start of topic 1
75400b34ebc0936dd28513c686c8adb526f063e6 (origin/master) Initial Commit

仍然不工作。相比之下,其他表示法按预期工作:

git log --pretty=oneline topic1 --not topic1~
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1
git log --pretty=oneline topic1~..topic1
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1

为什么插入符号排除表示法的行为方式不同?

你没有说你正在使用哪个平台。但让我猜猜:你在Windows上,你正在Windows命令行提示符CMD中键入这些命令。

CMD是一种奇怪的野兽。特别是,插入符号^是某种转义字符。若要将单个插入符号传递给调用的程序,必须在命令行上键入两个插入符号:

git log --pretty=oneline ^^topic1~ topic1

我通常远离^并使用--not

git log --pretty=oneline topic1 --not topic1~

但它有自己的警告,最重要的是,它的效果延伸到命令行上给出的所有后续引用,而不仅仅是下一个。这就是为什么与原始示例相比,必须交换两个 ref 规范的原因。

命令提示符将插入符号视为转义字符 - 也就是说,插入符号会导致命令提示符将其后面的字符解释为文本。这会导致插入符号在这种情况下不起作用。在命令提示符下,只要通常使用一个插入符号,就可以使用两个插入符号(^^):

git log --pretty=oneline ^^topic1~ topic1
77ffe1ada25be4b465be9fc9b46f63981ecc8b16 (origin/topic1, topic1) second commit of topic 1

最新更新