从提交ID创建git分支后,缺少一些git提交

时间:2018-11-15 11:49:17

标签: git github git-branch

我正在根据提交ID创建一个git分支,我期望它在创建新分支时应在指定的提交ID之后显示提交ID。但是在新创建的git分支中缺少一些git提交。

我有一个具有多个提交ID的主分支:

Main Branch commit ids

我已经使用git checkout -b testBranch 3331a4b命令从主分支创建了新分支

但是在该分支上执行fire git log --oneline命令时,我看到一些提交ID丢失了。请点击下面的链接查看提交ID

testBranch提交ID: testBranch commit ids

缺少主分支的提交ID: Missing commit ids of main branch

1 个答案:

答案 0 :(得分:1)

旁注:屏幕快照图像通常不是一个好主意,因为它们会使搜索和引用都变得困难。

这里的问题是,尽管git log --oneline显示提交的线性列表,但提交实际上不是线性的。考虑到一些看似线性的提交顺序,您期望得到这样的结果:

010 final
009 earlier
008 earlier-still
007 ...
...
001 first

从010开始并向后计数将给您10次提交,而从009开始并向后计数将给您9次提交。

如果提交是线性的,那将是正确的,但事实并非如此。

当然,实际数字不是连续的,也不是十进制的-它们是哈希ID,例如3331a4b(对于已经很长的东西来说,它已经很短了,始于 3331a4b)。因此,您已经知道您不能只使用数字作为简单索引。让我们用单个大写字母3331a4b A ... B(实际上是)替换序列号(001至010)或哈希ID(H等)绘制在小型存储库中进行的提交,其中包含十次提交,而 last 提交是 merge 提交:

A  <-B  <-C  <-D  <-----H
           \           /
            E  <-F  <-G

这些箭头-来自E指向C和来自{{11}}指向H的箭头没有箭头尖(因为很难绘制) (在文本中),但这些连接器也是箭头-允许Git从最后一次提交到第一次提交向后工作。

实际上,每个Git提交都包含一组父提交哈希ID。我们说提交指向其父级(带有上面绘制的箭头)。大多数提交只有一个父对象,这些提交形成一条简单的,向后的线性链,就像从G回到C一样。在这里,一切都很正常:当您从A开始时,只有一条返回C的路径。

至少一个提交(有史以来第一个提交)没有 no 父哈希,因为这是有史以来的第一个提交,并且没有更早的提交指向。这是动作停止的地方。请注意,该操作从 end 开始并向后进行。

有些提交,例如上例中的提交A,有两个父级。在这里,事情变得棘手,因为Git可以从H向后退到 H或到G。 (您可能已经看到了它的前进方向。)D命令使用一种特定的方法来线性化其向后移动,我们稍后将进行介绍。

git logmaster这样的分支名称实际上指向一个提交-一个特定的提交-例如提交develop ,因此我们可以像这样简单地绘制这些内容,然后在 right 的最后添加分支名称:

H

知道提交之间的内部链接是向后箭头。 (为了不要求进行任何更改提交,箭头本身嵌入在 children 中,指向其父级提交-提交中的任何内容都不能移动或更改;提交的所有内容都是永恒的。孩子知道孩子出生时父母是谁,但是直到孩子出生之前,父母都不知道孩子是谁,所以父母无法指出孩子的父母。孩子们。)

这里最棘手的部分是名称,例如A--B--C--D------H <-- master \ / E--F--G <-- develop master do 移动:名称develop得到了这里通过master命令的方式,可能是通过git merge运行的,或者可能是直接由某人运行的,或者是通过GitHub的“合并拉取请求”按钮或类似的命令运行的。在较早的某个时候,绘图看起来像这样:

git pull

提交A--B--C--D <-- master \ E--F--G <-- develop 尚不存在,并且从H开始并向后工作,master会先列举提交git log,然后依次是D和{{ 1}},然后C;从B开始并向后工作,A会枚举提交develop,然后依次是git log,然后G,然后依次是F和{{1 }},然后是E

这时,有人跑了C,或做了等效的事情。此创建的新提交B,指向Agit checkout master; git merge develop,并提供了我们最新的图纸。

现在,假设您附加一个 new 分支名称以提交HG。如果您一直在查看基于D的{​​{1}}输出,并假设提交F在提交E之前,那么您可能希望看到从{{1 }}或git log,向后遍历并包括master。但是,一旦我们绘制了提交的 graph 并将标签附加到DE上,您就会发现我们应该 not 期望提交F出现:

E

D可以从F到达(目前为E)这一事实并不意味着D可以从A--B--C--D------H <-- master \ / E--F--G <-- develop . .....<-- testBranch 到达。 / p>

在更复杂的图形中,从某个分支尖端开始并向后工作的可落实提交集可能很难看得多:图形变得纠结且难以查看或可视化。尽管如此,使用D(带有或不带有H)在这里仍然可以提供帮助。

master如何线性化非线性图

由于D一次必须显示一次提交-每行包含testBranch,或者一次使用多行而不显示输出-因此需要排队待处理的提交。此队列通常以您命名的一个提交开始:

git log --graph

或:

--oneline

,或者不带任何参数的当前(git log)提交。 Git将把提交移出队列,显示出来,然后将其父级放入队列。如果刚刚显示的提交是具有两个(或更多)父级的合并提交,则队列现在变得更深。

然后,

Git接受队列 front 中的任何提交,并显示该提交。那个提交有一些父母。如果尚未显示父项并且尚未将其放在队列中,则Git会将其放入队列。

因此,提交的显示顺序取决于它们在队列中的位置。当队列为空时(通常如此),并且只有一个单亲,该单亲就成为队列中的单个条目,并立即显示出来,将其从队列中删除,以便队列再次为空。这就是简单的线性链显示为简单的线性链的方式:我们可以将提交git log放入队列中,然后将其取出并显示出来,然后将--oneline放入队列中,然后将其放入队列中退出并显示它,并将$ git log <hash> 放入队列,依此类推。

如果您以{em>个以上的提交开始$ git log <branchname>

HEAD

(假设名称GF指向两个不同的提交-可能有两个分支名称指向同一提交),队列将开始其中有一个以上的提交,因此再次,队列中中的提交顺序将很重要。无论是E命名的队列还是git log命名的队列,Git都会首先显示队列的提交。显示了提交之后,Git会在适当的情况下将其父对象插入队列中,然后才有机会根据其他提交现在在队列中的位置显示 other 提交。您在命令行上命名的。

队列插入顺序的默认设置为 commit时间戳,其中较新的(较晚的时间戳)提交位于队列的最前面。您可以使用$ git log master develop masterdevelopmaster在某种程度上控制此顺序。使用develop会强制--date-order。有关详细信息,请参见the git log documentation