git有“相对”的树木吗?

时间:2012-02-21 19:40:02

标签: git

我正在尝试验证序列中的每个提交,从第一个提交到当前提示。它不是真正的git bisect,我不期待任何问题,并且提示有效。但我想确保每个提交都是自包含且正确的。

我可以使用HEAD ^从尖端返回一个,但是有一个“我从哪里前进”树木?也就是说,如果我有

o aaabbbccc (tip)
|
o abcdefabc
|
o fedcbafed
|
o abcdabcde
|
o deadbeefe (root)

我想这样做:

git checkout deadbeefe
build and test
git checkout current+1
<up two, return>
<up two, return>

但我无法弄清楚“当前+ 1”的树木。

1 个答案:

答案 0 :(得分:4)

Git不存储父母与孩子之间的联系;只有从孩子到父母的链接。要查找提交的子项,您必须从存储库中的最少提交(分支提示,标记,HEAD等)开始,然后沿着父项链向上,直到您到达根节点或找到有问题的提交。 / p>

如果您的提交DAG是线性的,tip是对最常见提交的引用,您可以执行以下操作来查找修订版deadbeefe的子提交:

git rev-list deadbeefe..tip | tail -n 1

这会导致Git从tip开始走到它到达deadbeefe或根目录并打印出它遇到的所有提交。然后将输出传送到tail以选择上次访问的提交,如果提交历史是线性的,则提交将是deadbeefe的子项。

HEAD是指当前已检出的提交,因此如果您需要当前提交的子项而不是deadbeefe,请使用HEAD。如果未指定,则需要提交的命令默认为HEAD,因此您可以执行以下操作:

git rev-list ..tip | tail -n 1

同样,这只适用于DAG是线性的。如果提交历史记录不是线性的,则可以使用--ancestry-path参数rev-list

每次想要移动到下一次提交时执行上述操作将是O(n ^ 2),但是Git是如此之快以至于在实践中通常无关紧要。如果你需要它是O(n),我会做以下事情:

git rev-list --reverse tip | while IFS= read -r rev; do
    git checkout "${rev}" || handle_checkout_error_here
    # build and test here
done

而且@ knittl是正确的 - 你想要的术语是提交,而不是树状。一些术语:

  • 'treeish'可以像文件系统树一样(例如,索引,工作目录,工作目录中的子目录,提交,提交内的子目录等)。
  • 'Revision'的定义不如提交,但它通常意味着标识提交的东西(提交自身,指向提交的带注释的标记,以及引用提交的引用)。
  • 'reference'是指向Git对象或另一个引用的指针(在这种情况下,它被称为'符号引用')。引用通常指向提交或带注释的标记对象,但它可以指向任何内容。人们通常会在他们想要一般性地引用HEAD,标签和/或分支时说出参考。