我有一个包含许多分支的大型 git 存储库(通常,我只使用其中的一小部分,与我的团队拥有的功能相关)。假设我有一个提交的哈希值(例如,从拉取请求中复制)。此提交可能已合并到我感兴趣的分支之一中,也可能未合并。它可能被直接合并,或者被挑选或重新定位。在后两种情况下,它在日志中的哈希是不同的(因为它现在实际上是一个全新的提交,尽管具有相同的差异)。
如果我知道原始提交的哈希值,我如何找到直接包含它或以精选或重定基形式包含它的所有分支?
如果我知道原始提交的哈希值,我如何找到直接包含它或以精选或重定基形式包含它的所有分支?
好消息是,您绝对可以做到所有这些(在一两个假设下,我将在稍后描述)。"直接包含它">变体是最简单的:git branch --containshash
产生答案。
"或...在樱桃采摘或变基形式中,部分是需要假设的部分,坏消息是"如何"部分可能非常混乱。 或者这可能真的很容易!
有一个 Git 命令,git patch-id
,它接受git diff
输出(由git diff
直接生成,或者更方便地由git show
生成)并计算补丁 ID,它本质上是去除行号和空格后差异的校验和。 (有关详细信息,请参阅链接的文档页面,或运行git help patch-id
。 例如:
$ git show HEAD | git patch-id
869f23f0e8b4813c88cb853fa2b4d415d25dc32c 8dca754b1e874719a732bc9ab7b0e14b21b1bc10
第二个哈希(如果出现第二个哈希)是提交的哈希 ID:
$ git rev-parse HEAD
8dca754b1e874719a732bc9ab7b0e14b21b1bc10
因此,您可以在原始提交上运行git show
并获取其补丁 ID,然后在每个可疑提交上运行git show
,并查看补丁 ID 是否匹配。
这是困难的方法(但对于单个提交来说很容易做到)。简单的方法是让 Git 告诉你"相等提交"。git cherry
命令及其更灵活但更难使用的配套git rev-list --cherry-mark
,通过在一组提交中的每个提交上运行git show | git patch-id
,在另一组提交中的每个提交上运行git show | git patch-id
,并告诉您第一集中的哪些提交与第二集中的哪些提交匹配。
要使用git rev-list
,你必须选择一个对称差分运算,即使用带有三个点的A...B
语法。 Git 将计算可从 A 但不能从 B 访问的所有提交的补丁 ID,并将其与可从 B 但不能从 A 访问的所有提交的所有补丁 ID 进行比较。git cherry
命令执行大致相同的操作,但具有不同的语法和不同的输出格式。 有关详细信息,请参阅两个文档页面。
需要注意的是:补丁 ID 基于 diff 减去行号和(一些)空格。 但有时在挑选或变基期间,必须更改差异以使其适合。 在这种情况下,修补程序 ID 将不匹配,并且此类检测将失败。 对此你无能为力。