如何以编程方式确定较早或较晚的提交?
How to determine earlier or later commits programatically?
是否可以比较 git 以编程方式提交或与其整数十六进制值进行比较?后面的提交是否比前一个提交的整数大?
因此,例如,如果我们可以在伪代码
中获取哈希值
int commit_a = myrepo.getCurrentCommit();
int commit_b = myrepo.getPreviousCommit();
if(commit_a > commit_b)
printf("Commit A is later than Commit B");
else
printf("Commit B is later than Commit A");
注意:我已经编辑了我的问题,询问是否有 git 库可以执行上述示例。或者如何实现我自己的。
提交由它们的 "sha" 标识,最好不要将其视为整数,而应将其视为不透明的二进制值。它不会递增,也不能直接与另一个提交进行比较。
但是,每个提交中固有的信息足以确定该提交的历史,因此您可以想象根据历史比较提交。关于如何做到这一点已经有一个非常可靠的问题和答案:How can I tell if one commit is a descendant of another commit?
Git 中的提交形成有向无环图或 DAG。
在任何图中,我们都有一个邻接表(因为图定义为 G = (V, E) 其中 V 和 E 分别是顶点和边集):图中任何给定的顶点/节点是要么离其他顶点一跳,通过一些边,要么更远,要么根本没有连接:
C--D
/
B------E G--H
\ /
A F
节点 A 连接到 B(反之亦然),B 连接到 C 和 E,依此类推。 G 和 H 相互连接,但不连接到图的其余部分,因此该图由两个不相交的子图组成。 (这些边没有方向。)
在有向图中,有predecessor和successor的概念连接有一个箭头:
A->B->C
|
v
D
这里A连接到B,B连接到C和D。所以B是A的后继者,C和D都是B的后继者(但彼此不连接)。就前辈而言,A是B的前辈,B是C和D的前辈
如果图没有环——无环——我们可以使用predecessor/successor操作执行传递闭包操作。 Git 的图都是有向 和 非循环的——它是一个 DAG——所以我们可以用 Git.
来做这个
在Git内部,箭头实际上是向后的(出于实现原因),但我们仍然执行相同的传递闭包。当我们这样做时,我们发现 A 是 B、C 和 D 的祖先:
A <-B <-C
^
|
D
因为我们可以从这些提交中的任何一个开始,然后回到 A。B 是 C 和 D 的祖先。相反的关系是 后代: D 是一个A.
的后裔
这里必须要小心一点。 C和D之间没有祖先或后代关系,即C不是D的祖先,但C也不是D的后代。你不能只说 "not ancestor therefore descendant":两者可能根本不相关。如果 DAG 具有不相交的子图,则对于某些提交也是如此,这是允许的:
A <-B <-C <-- master1
D <-E <-- master2
虽然 D 是 E 的祖先,但 D 与 A、B 或 C 中的任何一个都没有关系。
无论如何,测试"ancestor-ness"的Git命令是:
git merge-base --is-ancestor
它采用两个提交哈希 ID(或其他提交说明符)和答案,作为真或假查询(通过退出状态,0 表示 "yes, is an ancestor"),问题:是第一个命名的提交参数由第二个命名的提交的祖先。即:
hash1=$(git rev-parse $thing1^{commit}) || die "$thing1 does not name a git commit"
hash2=$(git rev-parse $thing2^{commit}) || die "$thing2 does not name a git commit"
if git merge-base --is-ancestor $hash1 $hash2; then
echo "$thing1 is an ancestor of $thing2"
else
if git merge-base --is-ancestor $hash2 $hash1; then
echo "$thing1 is a descendant of $thing2"
else
echo "$thing1 and $thing2 are not relatable"
fi
fi
出现 "not relatable" 答案是因为,正如我们在上面看到的,我们从 predecessor/successor 的概念中只得到一个 partial order, not a total order。
(出于 Git 的目的,提交是它自己的祖先,因此 git merge-base --is-ancestor $hash1 $hash1
始终为真。)
是否可以比较 git 以编程方式提交或与其整数十六进制值进行比较?后面的提交是否比前一个提交的整数大? 因此,例如,如果我们可以在伪代码
中获取哈希值int commit_a = myrepo.getCurrentCommit();
int commit_b = myrepo.getPreviousCommit();
if(commit_a > commit_b)
printf("Commit A is later than Commit B");
else
printf("Commit B is later than Commit A");
注意:我已经编辑了我的问题,询问是否有 git 库可以执行上述示例。或者如何实现我自己的。
提交由它们的 "sha" 标识,最好不要将其视为整数,而应将其视为不透明的二进制值。它不会递增,也不能直接与另一个提交进行比较。
但是,每个提交中固有的信息足以确定该提交的历史,因此您可以想象根据历史比较提交。关于如何做到这一点已经有一个非常可靠的问题和答案:How can I tell if one commit is a descendant of another commit?
Git 中的提交形成有向无环图或 DAG。
在任何图中,我们都有一个邻接表(因为图定义为 G = (V, E) 其中 V 和 E 分别是顶点和边集):图中任何给定的顶点/节点是要么离其他顶点一跳,通过一些边,要么更远,要么根本没有连接:
C--D
/
B------E G--H
\ /
A F
节点 A 连接到 B(反之亦然),B 连接到 C 和 E,依此类推。 G 和 H 相互连接,但不连接到图的其余部分,因此该图由两个不相交的子图组成。 (这些边没有方向。)
在有向图中,有predecessor和successor的概念连接有一个箭头:
A->B->C
|
v
D
这里A连接到B,B连接到C和D。所以B是A的后继者,C和D都是B的后继者(但彼此不连接)。就前辈而言,A是B的前辈,B是C和D的前辈
如果图没有环——无环——我们可以使用predecessor/successor操作执行传递闭包操作。 Git 的图都是有向 和 非循环的——它是一个 DAG——所以我们可以用 Git.
来做这个在Git内部,箭头实际上是向后的(出于实现原因),但我们仍然执行相同的传递闭包。当我们这样做时,我们发现 A 是 B、C 和 D 的祖先:
A <-B <-C
^
|
D
因为我们可以从这些提交中的任何一个开始,然后回到 A。B 是 C 和 D 的祖先。相反的关系是 后代: D 是一个A.
的后裔这里必须要小心一点。 C和D之间没有祖先或后代关系,即C不是D的祖先,但C也不是D的后代。你不能只说 "not ancestor therefore descendant":两者可能根本不相关。如果 DAG 具有不相交的子图,则对于某些提交也是如此,这是允许的:
A <-B <-C <-- master1
D <-E <-- master2
虽然 D 是 E 的祖先,但 D 与 A、B 或 C 中的任何一个都没有关系。
无论如何,测试"ancestor-ness"的Git命令是:
git merge-base --is-ancestor
它采用两个提交哈希 ID(或其他提交说明符)和答案,作为真或假查询(通过退出状态,0 表示 "yes, is an ancestor"),问题:是第一个命名的提交参数由第二个命名的提交的祖先。即:
hash1=$(git rev-parse $thing1^{commit}) || die "$thing1 does not name a git commit"
hash2=$(git rev-parse $thing2^{commit}) || die "$thing2 does not name a git commit"
if git merge-base --is-ancestor $hash1 $hash2; then
echo "$thing1 is an ancestor of $thing2"
else
if git merge-base --is-ancestor $hash2 $hash1; then
echo "$thing1 is a descendant of $thing2"
else
echo "$thing1 and $thing2 are not relatable"
fi
fi
出现 "not relatable" 答案是因为,正如我们在上面看到的,我们从 predecessor/successor 的概念中只得到一个 partial order, not a total order。
(出于 Git 的目的,提交是它自己的祖先,因此 git merge-base --is-ancestor $hash1 $hash1
始终为真。)