为什么在Pro Git书中显示提交队列的所有图像导致相反的方向?
箭头反映了DAG所遵循的方向,定向非循环图表在此表示Git中提交的历史(从最近到最旧).
正如Eric Sink在他的文章中详述的那样,这种表现并不是一个"完美"的表现:
关于基于DAG的版本控制工具最酷的事情之一是DAG是合并历史的表达.我们将DAG中的箭头解释为"我已经得到了这个".
因此,当需要从5b合并到(a)分支时,我们可以使用DAG中的信息来知道3b和2b已经完成
同一篇文章详述了该表示的限制:
采摘樱桃
但是DAG只是合并历史的一种实现,它绝对不是完美的.
版本控制DAG中的箭头从子级转到父级.它告诉我们子进程包含父进程中的所有更改.和它的祖父母.还有曾祖父母.等等.
但如果这不是真的怎么办?
请看下面的图片:
我想创建变更集4.
我想从变更集1开始,然后我想应用变更集3中的更改,但不是变更集2中的内容.
此操作有时称为"cherrypicking".我不想将所有更改从一个分支合并到另一个分支.我只想采取一个变更集(或变更集的一部分)并将其作为补丁应用到其他地方.我如何在DAG中表示这一点?
我不能.
我可以画一个4到3的箭头(上面用红色显示).这将正确地说4包含3中的更改,但它会不正确地声称4包含2中的更改.
或者,我没有画箭头.实际上,我的合并历史记录根本不会记录4实际上是3转换为补丁并应用于1的事实.
在任何一种情况下,下次我从一个分支合并到另一个分支时会发生一些不好的事情:
如果我绘制那个躺着的箭头,我将不会有机会应用变更集2,因为合并历史记录认为我已经这样做了.
如果我没有绘制任何箭头,该工具将指望我处理变更集3,因为没有合并历史记录我已经做过的事实.
这些问题都不是灾难性的,不足以制作晚间新闻,但仍然如此.
这就是为什么在一次樱桃挑选操作之后,为了找回一个更经典的DAG,一个rebase永远不会发生.
这是为了显示父母的关系.在Git中,一个特定的提交知道它的父母,但不一定知道它的孩子.(显然,可以根据父链接派生信息,但我不认为它直接存储在提交对象中.)