Intellij Idea Git Log 中的行意味着什么?

fal*_*all 6 git branch intellij-idea git-log

在Idea中按alt+9可以看到git log窗口:

在此输入图像描述

我看到这些点代表提交。这些线代表分支吗?如果是这样,如何找出每条线代表哪个分支?

我看到如果我将鼠标悬停在一行的某些部分上,其中的一部分就会突出显示,突出显示的部分是什么意思?如果我点击它,它会变成一条虚线。刚刚发生了什么?

在此输入图像描述

有没有文章或视频详细解释 Idea git log 窗口或其使用的树状 git log 结构?我已经阅读了Idea 的 git log window 帮助页面,但关于这些行的字数很少。

tor*_*rek 6

你的问题的一部分是:

\n
\n

这些线代表分支吗?如果是这样,如何找出每条线代表哪个分支?

\n
\n

我在两条 评论中提到它们确实代表了……我们可以称之为分支的东西:

\n
    \n
  • “branch”这个词在 Git 中往往会失去所有意义,因此除了作为name的修饰符之外,根本不清楚何时使用该词。如果我们说master是一个分支名称develop是一个分支名称,等等,这些就很清楚了。从技术master上讲,它是 的简写refs/heads/master,它是ref引用:它是保存提交哈希 ID 的一种方式。1

    \n
  • \n
  • 但我们还需要一种方法来引用某些提交组。我们也倾向于将其称为分支。

    \n
  • \n
  • Git 提供远程跟踪名称,例如origin/master. 我们经常将用这样的名称找到的提交集称为远程分支,Git 本身将这些东西称为远程跟踪分支名称,即使它们不是分支名称。2

    \n
  • \n
\n

我发现“分支”这个词被过度使用,以至于常常变得毫无意义。但这些线代表从提交到其他早期提交的链接。

\n

我们通过逐个提交找到这些链接。当我们找到起始提交时,为了遵循这些提交到提交的链接,使用分支名称,我们将其称为分支但这与分支名称不同,当我们看看它们如何随着时间的推移而演变时,这里的问题就变得清晰起来。

\n

让我们从一个只有三个提交的存储库开始,全部都在master或上main,并使用大写字母而不是 Git 实际使用的丑陋的大哈希 ID 来绘制这三个提交:

\n
A <-B <-C   <--main\n
Run Code Online (Sandbox Code Playgroud)\n

名称 包含三个提交中最后main一个提交的哈希 ID commit 。Commit本身保存了较早提交的原始哈希 ID ,而 commit保存了更早提交的原始哈希 ID 。我们说指向,并且指向\xe2\x80\x94,当然它本身也指向 C。CCBBAC BB Amain

\n

提交A是第一次提交。没有更早的提交!所以提交A没有指向任何地方。这使其成为根提交,并且 Git 可以在此处停止向后操作。

\n

现在,我们将一个新的分支名称添加到我们的提交集合中。这个新名称也指向 commitC,如下所示:

\n
A--B--C   <-- main, develop\n
Run Code Online (Sandbox Code Playgroud)\n

我们选择一个名称来使用git checkout

\n
A--B--C   <-- main, develop (HEAD)\n
Run Code Online (Sandbox Code Playgroud)\n

我们现在C通过 name使用 commit develop。如果我们git checkout main仍然使用,只是通过不同的名称,但我们现在C会坚持使用。develop

\n

每次提交都保存每个文件的快照,并以特殊、只读、仅限 Git、压缩和重复数据删除的形式永久冻结。因此,事实上,其中的大多数文件C可能与 中的文件相同,B这意味着C不需要太多额外空间。如果B共享一个 100 MB 的文件且未更改,则该文件C只有一份副本。

\n

但这些文件不能被其他任何东西使用。因此git checkout必须将它们复制为可用的形式。这就是您的工作树中的内容:可用形式的副本。我们不会进一步讨论这个想法,但它值得记住并稍后重新审视。

\n

不管怎样,现在让我们D以通常的方式进行一次新的提交。CommitD将像往常一样保存每个文件的(去重)快照,并将向后指向现有的 commit C。当 Git 完成 make 后D,Git 会根据 \xe2\x80\x94 指向的附件更新当前分支名称,无论是HEAD\xe2\x80\x94 D,如下所示:

\n
A--B--C   <-- main\n       \\\n        D   <-- develop (HEAD)\n
Run Code Online (Sandbox Code Playgroud)\n

提交A-B-C现已开启main,对吗?并且D仅在develop. 好吧,最后一部分是正确的\xe2\x80\x94,但是提交A-B-C也在.develop

\n

D您的查看器绘制的、向后连接的线条等等C,不会告诉您某物位于哪个分支上,部分原因是分支并不重要。只有提交才重要。提交C事务,并且可以从两个名字中找到,所以它在两个分支上。C向后链接的那一条线现在B代表两个分支。

\n

我们可能会继续做出一些更多的承诺:

\n
A--B--C   <-- main\n       \\\n        D--E--F   <-- develop (HEAD)\n
Run Code Online (Sandbox Code Playgroud)\n

人们很容易将它们视为独立的,就好像develop只有. Git 中的情况并非如此:分支名称只对入门有用。我们永远不知道什么时候停止,除非我们点击了 root 提交,比如. D-E-FA

\n

为了让 Git 早点停止,我们使用诸如main..develop. 这是 的简写develop ^main。这使用了集合论:via develop,我们找到所有提交,然后viamain我们找到集合,然后从整体中A-B-C减去排除的集合\xe2\x80\x94部分\xe2\x80\x94。^main这给我们留下了D-E-F,这是我们可能希望将其视为“在分支上develop”的提交。但为了达到这个目的,我们不得不说:提交是 on develop,减去提交是 onmain,因为A-B-C都在两个分支上。

\n

现在我们可以继续将新提交合并 main. 当我们这样做时,我们可以让 Git 进行快进,这根本不是合并:

\n
git checkout main && git merge --ff-only develop\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
A--B--C--D--E--F   <-- develop, main (HEAD)\n
Run Code Online (Sandbox Code Playgroud)\n

现在所有六个提交都在两个分支上。现在只有一条线,而不是两条线:我们不必分解绘图即可指向main更多C内容。

\n

或者,我们可以使用显式合并,或者首先进行提交main

\n
git checkout main; (... make new commit ...); git merge develop\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
A--B--C------G--H   <-- main (HEAD)\n       \\       /\n        D--E--F   <-- develop\n
Run Code Online (Sandbox Code Playgroud)\n

其中 commitH合并提交。有两个向后指向的箭头H:一个连接到之前的提交G(如果我们成功了,或者C如果没有成功则直接连接),另一个指向 commit F。现在所有提交都已开启main。合并提交H处于开启状态(至少目前如此),但因为它向后指向两者......无论我们称之为一组提交,所有这些提交都可以commit访问,因此所有提交都是“在” 。有两条线,但到目前为止只有一根分支用来找到它们。mainHmain

\n

当然还有那个 name develop,它找到 commit F,它找到 commit E,依此类推,一直回到A. F因此,提交是在分支上develop,就像以前一样。只是现在它也在分支main

\n

但是:现在我们可以完全删除该名称develop,使用git branch -d develop. 当我们这样做时,我们剩下的是这样的:

\n
A--B--C------G--H   <-- main (HEAD)\n       \\       /\n        D--E--F\n
Run Code Online (Sandbox Code Playgroud)\n

所有提交仍然保留。还有两条线。但现在只涉及一个分支名称

\n

这就是为什么我想说分支名称并不重要\xe2\x80\x94 除了查找一次提交之外。我们需要某种方法来找到 commit H。只要我们有了这个,我们就能找到所有较早的提交,因为它们是链接的,一个\xe2\x80\x94,或者对于合并提交H,一次两个\xe2\x80\x94,向后链接。

\n

可视化工具中的线条代表这些联系。链接是分支,或者不是分支,或者是您喜欢的任何内容,具体取决于您想要如何查看它们。

\n
\n

1我们最终还得到了.git/config一个配置部分:

\n
[branch "master"]\n    remote = origin\n    merge = refs/heads/master\n
Run Code Online (Sandbox Code Playgroud)\n

例如,分支名称不仅仅是提交哈希 ID。但这两个条目大多是静态的:如果我们运行,例如,更改 的上游设置,则remote和设置会发生变化。mergegit branch --set-upstream-tomaster

\n

2运行git checkout origin/master然后git status,我们看到这会产生分离的 HEAD状态,而不是on branch origin/master状态。因此,origin/master完整拼写为 \xe2\x80\x94 的refs/remotes/origin/master\xe2\x80\x94 不是分支名称。由于“分支一词在 Git 中因过度使用而被严重淘汰,因此我认为将其称为远程跟踪分支名称是一个坏主意。短语“远程跟踪名称”也可以用来识别这是什么类型的名称。

\n


Ant*_*cca 1

是的,是提交,线是分支。

要知道它引用的是哪个分支,只需查看右侧窗格即可,如下图所示:

在此输入图像描述

虚线仅代表您通过单击自己的提交而选择的分支。

  • 尽管如此,这*是*正确的答案。点是提交,线是……无论我们的意思是什么。或者,也许这是错误的答案。我也会在这里尝试一下我自己的答案。 (2认同)