使用参考存储库对拉取请求检查器有意义吗?
Does using reference repos makes sense for pull request checkers?
缩短 Jenkins 作业执行时间的方法之一是 use reference repo during clone。
然后该作业依赖于参考存储库,它是经常更新(例如,由另一个作业)的远程存储库的本地镜像(缓存)。
如果我 运行 使用参考存储库拉取请求检查器并且最新的提交尚未缓存,会发生什么情况? Jenkins 会获取丢失的提交吗?
What happens if I run pull request checker using reference repo and the newest commit has not been cached yet? Will Jenkins fetch missing commits?
是的。 参考资料库的目的是充当快速后备缓存。
可选阅读:这是如何工作的
在下文中,“您的Git”是指您的机器上运行的Git软件,为Jenkins创建新的克隆,“他们的Git”是指Git 软件在托管存储库 cloned 的机器上运行,“reference Git”指的是 Jenkins 机器上的存储库(它必须在同一台机器)。
还请记住,哈希 ID(无论是提交哈希 ID 还是任何其他内部 object 哈希 ID)对于该特定数据来说是 唯一的 .也就是说,每个存储库中的每个提交的哈希 ID 与每个其他存储库中的每个提交不同不同 146=],因为每个提交本身都是唯一的。关于提交哈希 ID 唯一性的规则的一个例外是,如果这实际上是 相同的提交: 如果存储库 A 具有提交 a123456...
,并且存储库 B 获得该提交 from 存储库 A,存储库 B 现在也调用该提交 a123456...
。如果存储库 C 从 A 或 B 获得该特定提交,存储库 C 也将其称为 a123456...
,依此类推。
因此:您的 Git 调用了他们的 Git。他们的 Git 列出了一些分支和标签以及其他类似的名称。每个名称对应一 (1) 个哈希 ID。
您的 Git 现在对这些名称进行挑选:您的 Git 想要哪些?根据您的克隆是否是 --single-branch
,它将需要其中的 所有,或者只需要其中的 一个。它挑选出它想要的那些,将这些哈希 ID 放入哈希 ID 池中。
如果没有参考克隆,您的 Git 现在会发送它们的 Git 所有 的哈希 ID,并附上“想要”消息。他们的 Git 将这些哈希 ID 添加到通缉名单并查找那些 object。如果那些 objects 是提交 objects——通常它们是,但如果你正在获取标签,其中一些可能是 tag objects —他们的 Git 现在必须 提供 parent 提交哈希 ID 到您的 Git。 (如果他们是标签 objects,他们的 Git 必须提供提交哈希 ID。)您的 Git 将这些添加到其想要的 ID 池中,并发送带有“想要”消息的那些出色地。然后他们会列出 那些 的 parent,而你的 Git“想要”那些,等等。
使用--depth
稍微调整一下这个过程:两个Git同意在这种遍历的某个深度,两个人会说“这就够了parent”他们会阻止整个 offer/want 的事情。如果没有 --depth
,两个 Git 会继续枚举提交,直到他们提供为止,并且您的 Git 已经“想要”, 每个 提交。
他们的 Git 现在没有更多的提交可以提供,因此他们开始打包 to-be-sent 提交,以及这些提交所需的所有支持 object。 (如果您以实时克隆的方式执行此操作,则会在此处看到“计数”“压缩”消息。)他们向您发送 Git 这个包,您的 Git 打开并解包并存储该包在你的克隆中,现在你有了一个克隆。
稍后,您的 Git 可以使用 git fetch
再次调用他们的 Git。他们的 Git 将再次列出他们的名字和哈希 ID。您的 Git 将检查您 已经有哪些提交 ,对于这些提交,告诉他们 Git: 不,谢谢,我 对于你 没有 的提交,你的 Git 会告诉他们的 Git 你想要他们,然后他们将像以前一样提供提交的 parents。这个对话一直持续到你的 Git 和他们的 Git 就你 已经 和你 需要 [=146] 的提交达成一致=].他们的 Git 现在计数和压缩等等——而且,因为你 已经有 提交和他们的支持 object,他们的 Git 可以避免 发送你那些提交的任何东西。因此,在第一个 git clone
git fetch
之后使用 git fetch
获取的包裹要小得多并且更容易交付。
当您使用 --reference
克隆时,同样的程序适用。然而,这一次,当他们的 Git 列出提交哈希 ID 时,你的 Git 检查 两个 地方:
- 我已经有这个提交了吗? (对于初始克隆,答案总是“否”,但对于后续
git fetch
操作,答案通常是“是”)。
- 我的参考克隆有这个提交吗?
如果 其中一个 有提交,你的 Git 会说 不,谢谢,我已经有那个了 。如果没有,你的 Git 说它想要那个,他们的 Git 现在有义务提供那个提交的parent 次提交。
由于提交哈希 ID 全局唯一,您的 Git 只有在字面上 相同[=146= 时才具有这些提交中的任何一个] 作为另一个 Git 的提交提交。无论是在您自己的存储库中,还是在您的参考存储库中,它都是相同的提交。
这个克隆或获取过程的最终结果与没有--reference
的克隆的最终结果相同:你的Git现在拥有所有他们提供的承诺,您的 Git 需要并因此接受。不同之处在于,当他们提供一些提交哈希 ID,例如 a123456...
时,您的 Git 会在 两个 位置查找:它自己的存储库数据库和参考存储库的数据库。
--dissociate
选项
还有一个 可选 区别。当您的 Git 查看两个数据库并发现它们提供的提交在参考数据库中时,您的 Git 可以:
- 让它留在那儿,假设它将来会继续在那里,或者
- 假设参考副本可能会消失,将其复制到自己的私有数据库中
默认是将其保留在参考副本中:当两套都数据库文件在同一台主机上。但是,如果您计划在将来 删除或以其他方式清除 参考副本,您可能希望此时强制您的 git clone --reference
操作制作副本。为此,请使用 --dissociate
选项。
请注意,此选项与 --reference
一样,仅在初始克隆期间可用,在 git fetch
期间不可用。如果你:
- 使用
--reference
而不是 --dissociate
进行克隆;
- 然后用
git fetch
更新该克隆,可能需要很多天或几个月的时间
一些内部 objects in 那个克隆仍然真的只是存储在参考克隆中,但只有那些 did 最初来自参考,在初始克隆期间,仍然来自参考克隆。 这里没有git fetch
选项来停止使用参考克隆。如果您想要或需要销毁参考克隆,请参阅下文。
“撤消”参考克隆
因为 --dissociate
仅在 git clone
期间可用,要“撤消”引用克隆(然后允许您销毁原始引用),您现在必须“克隆克隆”。也就是说,您将 运行 git clone
将 source 存储库作为使用引用的克隆。在此处 添加--dissociate
标记,以便现有clone-that-depends-on-a-reference-clone 的new 克隆生成完整副本。否则,您的 clone-of-existing-clone 将只使用对参考克隆的引用。
您很可能想使用 --mirror
来制作此 clone-of-a-clone,因此“撤消引用”操作实际上是:
git clone --mirror <clone> --dissociate <new-clone>
--mirror
选项意味着 --bare
,所以如果你不想要一个裸克隆,要么不要使用 --mirror
(而是使用 --mirror
暗示),或将裸镜像克隆转换为 non-bare 克隆:参见,例如 How do I convert a bare git repository into a normal one (in-place)? 您可能还想输入克隆并使用 git remote remove origin
删除 origin
远程,因为你打算删除或以其他方式销毁它。
缩短 Jenkins 作业执行时间的方法之一是 use reference repo during clone。
然后该作业依赖于参考存储库,它是经常更新(例如,由另一个作业)的远程存储库的本地镜像(缓存)。
如果我 运行 使用参考存储库拉取请求检查器并且最新的提交尚未缓存,会发生什么情况? Jenkins 会获取丢失的提交吗?
What happens if I run pull request checker using reference repo and the newest commit has not been cached yet? Will Jenkins fetch missing commits?
是的。 参考资料库的目的是充当快速后备缓存。
可选阅读:这是如何工作的
在下文中,“您的Git”是指您的机器上运行的Git软件,为Jenkins创建新的克隆,“他们的Git”是指Git 软件在托管存储库 cloned 的机器上运行,“reference Git”指的是 Jenkins 机器上的存储库(它必须在同一台机器)。
还请记住,哈希 ID(无论是提交哈希 ID 还是任何其他内部 object 哈希 ID)对于该特定数据来说是 唯一的 .也就是说,每个存储库中的每个提交的哈希 ID 与每个其他存储库中的每个提交不同不同 146=],因为每个提交本身都是唯一的。关于提交哈希 ID 唯一性的规则的一个例外是,如果这实际上是 相同的提交: 如果存储库 A 具有提交 a123456...
,并且存储库 B 获得该提交 from 存储库 A,存储库 B 现在也调用该提交 a123456...
。如果存储库 C 从 A 或 B 获得该特定提交,存储库 C 也将其称为 a123456...
,依此类推。
因此:您的 Git 调用了他们的 Git。他们的 Git 列出了一些分支和标签以及其他类似的名称。每个名称对应一 (1) 个哈希 ID。
您的 Git 现在对这些名称进行挑选:您的 Git 想要哪些?根据您的克隆是否是 --single-branch
,它将需要其中的 所有,或者只需要其中的 一个。它挑选出它想要的那些,将这些哈希 ID 放入哈希 ID 池中。
如果没有参考克隆,您的 Git 现在会发送它们的 Git 所有 的哈希 ID,并附上“想要”消息。他们的 Git 将这些哈希 ID 添加到通缉名单并查找那些 object。如果那些 objects 是提交 objects——通常它们是,但如果你正在获取标签,其中一些可能是 tag objects —他们的 Git 现在必须 提供 parent 提交哈希 ID 到您的 Git。 (如果他们是标签 objects,他们的 Git 必须提供提交哈希 ID。)您的 Git 将这些添加到其想要的 ID 池中,并发送带有“想要”消息的那些出色地。然后他们会列出 那些 的 parent,而你的 Git“想要”那些,等等。
使用--depth
稍微调整一下这个过程:两个Git同意在这种遍历的某个深度,两个人会说“这就够了parent”他们会阻止整个 offer/want 的事情。如果没有 --depth
,两个 Git 会继续枚举提交,直到他们提供为止,并且您的 Git 已经“想要”, 每个 提交。
他们的 Git 现在没有更多的提交可以提供,因此他们开始打包 to-be-sent 提交,以及这些提交所需的所有支持 object。 (如果您以实时克隆的方式执行此操作,则会在此处看到“计数”“压缩”消息。)他们向您发送 Git 这个包,您的 Git 打开并解包并存储该包在你的克隆中,现在你有了一个克隆。
稍后,您的 Git 可以使用 git fetch
再次调用他们的 Git。他们的 Git 将再次列出他们的名字和哈希 ID。您的 Git 将检查您 已经有哪些提交 ,对于这些提交,告诉他们 Git: 不,谢谢,我 对于你 没有 的提交,你的 Git 会告诉他们的 Git 你想要他们,然后他们将像以前一样提供提交的 parents。这个对话一直持续到你的 Git 和他们的 Git 就你 已经 和你 需要 [=146] 的提交达成一致=].他们的 Git 现在计数和压缩等等——而且,因为你 已经有 提交和他们的支持 object,他们的 Git 可以避免 发送你那些提交的任何东西。因此,在第一个 git clone
git fetch
之后使用 git fetch
获取的包裹要小得多并且更容易交付。
当您使用 --reference
克隆时,同样的程序适用。然而,这一次,当他们的 Git 列出提交哈希 ID 时,你的 Git 检查 两个 地方:
- 我已经有这个提交了吗? (对于初始克隆,答案总是“否”,但对于后续
git fetch
操作,答案通常是“是”)。 - 我的参考克隆有这个提交吗?
如果 其中一个 有提交,你的 Git 会说 不,谢谢,我已经有那个了 。如果没有,你的 Git 说它想要那个,他们的 Git 现在有义务提供那个提交的parent 次提交。
由于提交哈希 ID 全局唯一,您的 Git 只有在字面上 相同[=146= 时才具有这些提交中的任何一个] 作为另一个 Git 的提交提交。无论是在您自己的存储库中,还是在您的参考存储库中,它都是相同的提交。
这个克隆或获取过程的最终结果与没有--reference
的克隆的最终结果相同:你的Git现在拥有所有他们提供的承诺,您的 Git 需要并因此接受。不同之处在于,当他们提供一些提交哈希 ID,例如 a123456...
时,您的 Git 会在 两个 位置查找:它自己的存储库数据库和参考存储库的数据库。
--dissociate
选项
还有一个 可选 区别。当您的 Git 查看两个数据库并发现它们提供的提交在参考数据库中时,您的 Git 可以:
- 让它留在那儿,假设它将来会继续在那里,或者
- 假设参考副本可能会消失,将其复制到自己的私有数据库中
默认是将其保留在参考副本中:当两套都数据库文件在同一台主机上。但是,如果您计划在将来 删除或以其他方式清除 参考副本,您可能希望此时强制您的 git clone --reference
操作制作副本。为此,请使用 --dissociate
选项。
请注意,此选项与 --reference
一样,仅在初始克隆期间可用,在 git fetch
期间不可用。如果你:
- 使用
--reference
而不是--dissociate
进行克隆; - 然后用
git fetch
更新该克隆,可能需要很多天或几个月的时间
一些内部 objects in 那个克隆仍然真的只是存储在参考克隆中,但只有那些 did 最初来自参考,在初始克隆期间,仍然来自参考克隆。 这里没有git fetch
选项来停止使用参考克隆。如果您想要或需要销毁参考克隆,请参阅下文。
“撤消”参考克隆
因为 --dissociate
仅在 git clone
期间可用,要“撤消”引用克隆(然后允许您销毁原始引用),您现在必须“克隆克隆”。也就是说,您将 运行 git clone
将 source 存储库作为使用引用的克隆。在此处 添加--dissociate
标记,以便现有clone-that-depends-on-a-reference-clone 的new 克隆生成完整副本。否则,您的 clone-of-existing-clone 将只使用对参考克隆的引用。
您很可能想使用 --mirror
来制作此 clone-of-a-clone,因此“撤消引用”操作实际上是:
git clone --mirror <clone> --dissociate <new-clone>
--mirror
选项意味着 --bare
,所以如果你不想要一个裸克隆,要么不要使用 --mirror
(而是使用 --mirror
暗示),或将裸镜像克隆转换为 non-bare 克隆:参见,例如 How do I convert a bare git repository into a normal one (in-place)? 您可能还想输入克隆并使用 git remote remove origin
删除 origin
远程,因为你打算删除或以其他方式销毁它。