我正在根据提交ID创建一个git分支,我期望它在创建新分支时应在指定的提交ID之后显示提交ID。但是在新创建的git分支中缺少一些git提交。
我有一个具有多个提交ID的主分支:
我已经使用git checkout -b testBranch 3331a4b
命令从主分支创建了新分支
但是在该分支上执行fire git log --oneline
命令时,我看到一些提交ID丢失了。请点击下面的链接查看提交ID
testBranch提交ID:
缺少主分支的提交ID:
答案 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 log
或master
这样的分支名称实际上指向一个提交-一个特定的提交-例如提交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
,指向A
和git checkout master; git merge develop
,并提供了我们最新的图纸。
现在,假设您附加一个 new 分支名称以提交H
或G
。如果您一直在查看基于D
的{{1}}输出,并假设提交F
在提交E
之前,那么您可能希望看到从{{1 }}或git log
,向后遍历并包括master
。但是,一旦我们绘制了提交的 graph 并将标签附加到D
或E
上,您就会发现我们应该 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
(假设名称G
和F
指向两个不同的提交-可能有两个分支名称指向同一提交),队列将开始其中有一个以上的提交,因此再次,队列中在中的提交顺序将很重要。无论是E
命名的队列还是git log
命名的队列,Git都会首先显示队列的提交。显示了提交之后,Git会在适当的情况下将其父对象插入队列中,然后才有机会根据其他提交现在在队列中的位置显示 other 提交。您在命令行上命名的。
队列插入顺序的默认设置为 commit时间戳,其中较新的(较晚的时间戳)提交位于队列的最前面。您可以使用$ git log master develop
,master
,develop
和master
在某种程度上控制此顺序。使用develop
会强制--date-order
。有关详细信息,请参见the git log
documentation。