Git中的符号^代表什么意思?

162

我看到了一个关于如何在git中恢复已删除文件的解答

解决方案如下:

git checkout <deleting_commit>^ -- <deleted_file_path>

插入符号 (^) 是什么作用?我在 git 中看到它做了很多有用的事情,它很神奇。请告诉我它是什么并且它是如何工作的。


13
关于 Windows:在 DOS shell 中,^ 无法按预期工作。请使用 Git Bash shell,它可以正常工作。 - Cincinnati Joe
9
当我尝试使用它时(猜测其含义时),我甚至没有想到过这一点。插入符号(^)是cmd.exe中的转义字符。每次我尝试使用它来查看它是否有帮助时,实际上都没有传递任何内容,这就解释了为什么结果从未不同。> _>愚蠢的cmd.exe。您可以通过将其加倍或引用来进行转义:git log master^^git log "master^" - bambams
9个回答

181

HEAD^ 表示当前分支末尾的第一个父提交。

请记住,git提交可以有多个父提交。HEAD^ 等同于 HEAD^1,您还可以根据需要使用 HEAD^2 等地址其他父提交。

您可以获取任何提交的父提交,不仅限于 HEAD。您也可以向后移动多个代数:例如,master~2 表示主分支末尾的祖父提交,在歧义情况下偏向于第一个父提交。这些指定符可以任意链接,比如 topic~3^2。请参见Git 中 HEAD^HEAD~ 的区别是什么?相关的答案。

了解更多详情,请查看 git rev-parse --help 中的“指定修订版本”部分。


2
但是,按照线性历史,为什么HEAD^^^返回第三个更旧的提交,即它等同于HEAD~~~ - Vorac
2
@Vorac 对于线性历史,是的。 - Greg Bacon

27

它的意思是“父级的”。因此,HEAD^的意思是“当前HEAD的父级”。你甚至可以将它们链接在一起: HEAD^^的意思是“当前HEAD的父级的父级”(即当前HEAD的祖父级),HEAD^^^的意思是“当前HEAD的父级的父级的父级”,以此类推。


此答案不适用于合并提交。如果HEAD后面跟着一个合并提交,则HEAD^表示HEAD第一个父级,而HEAD^^(或HEAD^2)表示HEAD第二个父级。在合并提交中,HEAD的第二个父级并不等同于HEAD的父级的父级。请参阅Git手册中的祖先引用 - bhagerty
@bhagerty:那是错误的。虽然HEAD^2确实表示HEAD的第二个父级,但HEAD^2HEAD^^并不是同义词。多个插入符号确实与第一个父提交有关,因此就像HEAD^^通常指HEAD的祖父一样,当HEAD是合并提交时,HEAD^^HEAD第一个提交的父代的祖父;同样,HEAD^2^是第二个父级的父级。 - mipadi
谢谢,@mipadi。我认为你是正确的,尽管文档并没有明确说明这一点。据我所知,HEAD~~HEAD~2是同义词,因此类比地,我期望数字运算符与插入符号的工作方式类似。从你的话来看,它并不是这样的。这很不幸。 - bhagerty

27

^(脱字符)也可以在指定范围时使用

为了排除从一个提交可达的提交,使用前缀^符号。例如,^r1 r2 表示从 r2 可达的提交,但不包括从 r1 可达的提交。

<rev>

包含可由(即祖先)<rev> 到达的提交。

^<rev>

排除可由(即祖先)<rev> 到达的提交。


是的,这正是我正在寻找的。 - Lajos

15

这里有一个视觉解释。假设您的历史记录如下:

                      master  
  ... <- B <- C <- D
             /
... <- E <- F
              feature
当功能并入主分支时,将创建带有两个祖先的C。 Git为这些祖先分配编号。主线祖先B被分配1,功能祖先F被分配2。
因此,C^1指的是B,C^2指的是F。C^是C^1的别名。
只有在合并3个分支时才会使用^3。

这真的合法吗?一个合并提交可以包含三个父节点吗? - matthias_buehlmann
合并提交可以有N个父级。常规提交和合并之间唯一的区别是父级数量。 - cdosborn
阅读完这条评论后,阅读 https://dev59.com/UnE95IYBdhLWcg3wn_j2#2222920 可以更清晰地理解。 - Albert

8

符号^指向一个特定提交的父级。例如,HEAD^指向当前HEAD提交的父级。(同样,HEAD^^指向祖父级)。


5

克拉表示提交偏移量(父级)。例如,HEAD^ 表示“距离 HEAD 一次提交”,HEAD^^^ 表示“距离 HEAD 三次提交”。


4

(^)获取命令的父源,例如HEAD^将获取HEAD的父源。


4

OP: Git中的字符caret (^)是什么意思?

^(Caret)和~(Tilde)选择器

HEAD^(Caret)和HEAD~(Tilde)之间的区别在于它们如何从指定的起始点,即HEAD向后遍历历史记录。

Tilde ~

<rev>~[<n>] = 选择第<n>代祖先,只跟踪第一个*父节点

Caret ^

<rev>^[<n>] = 选择第一代祖先的<n>个父节点

*第一个父节点始终是合并的左侧,例如合并到分支上的提交。

将 ~ 和 ^ 结合使用

如下图所示,两个选择器~^可以组合使用。还要注意的是,除了使用HEAD作为起始点外,任何常规引用都可以使用,例如分支标签甚至是提交哈希

此外,根据所需选择的祖先,^~可以互换使用,如下表所示。

Illustration of relative references in Git

来源:有关此主题的详细信息,请参见博客文章。


1
这是一个几乎完美的解释和图表。我唯一的小评论与图表中的字母有关。我认为如果字母按照字母表顺序倒过来,理解起来会更容易。现在你的字母流动与时间流动相反,这是违反直觉的。从你的时间箭头可以清楚地看出,在时间上C先于B先于A。但这不是我们期望字母表工作的方式。 - bhagerty
感谢您的反馈@bhagerty!非常好的建议,我一定会考虑进行更改。确实,这有点违反直觉。 - Alexis Määttä Vinkler

2

3
这个链接可能更接近预期的位置。http://git-scm.com/book/zh/v2/Git-工具-修订版本选择#祖先引用。 - bholben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接