在尝试理解actions/checkout@version
操作时,我遇到了this answer,其中说明了执行相同操作时会发生什么:
正在执行的默认步骤为:
1.正在其中触发工作流的当前存储库将被克隆。
1.根据已定义的事件(如推送或拉取请求):
对于推送事件,它运行下面的命令,其中$GITHUB_REF
指向工作流中推送事件的指定分支上的最新提交:git fetch --depth 1 $GITHUB_REF
我不明白的是,为什么最新的提交是在仓库刚刚被克隆之后获取的,因此已经是最新的了。
3条答案
按热度按时间ix0qys7i1#
运行此命令的两个示例原因:
$GITHUB_REF
可以是引用或标签以外的内容;例如,github管理名为refs/pull/<id>/head
的引用以指向pull请求的最新提交,并且这些引用不会被默认的git clone
下载首先运行
git fetch ... $GITHUB_REF
是确保该操作在所有可能的条件下都有效的一种方法。vmdwslir2#
你的报价中提到的第一步是不正确的(强调我的):
1.触发工作流的当前存储库被克隆。
查看了操作的代码[GitHub]后,这里是它执行的检查引用的步骤:
1.如果git不存在,使用API下载代码并返回
1.否则,如果存在git,则初始化一个空的git存储库
1.为该空存储库添加一个指向要使用的存储库的遥控器
1.获取并检出所需的特定参考文件
您可以注意到,存储库实际上并没有被克隆,而是在新初始化的空存储库上配置了一个远程。因此,运行
fetch
是非常必要的,因为它实际上还没有提交。注意:我跳过了代码执行的一些与问题无关的其他步骤。
vtwuwzda3#
虽然看起来 "只" 克隆git仓库就足够了,但你必须记住git是分布式版本控制。
所以git-clone(1)会小心地克隆实际的仓库(或者操作失败),但是如果你仔细考虑一下,仓库的内容可能在克隆它的时候已经改变了(只举一个例子)。
在这里真正考虑一下分布式计算机系统。涉及网络(是的,传输确实会失败)。时间(是的,时间会倒流)。
接下来,让我们假设克隆操作没有失败,而是成功了,我们在这里走上了幸福的道路。
现在,下一个工作是获取可操作的具体修订。我们去拿吧。因为git-fetch(1)会告诉我们它是否工作。
所以...
...而git-clone(1)足以验证远程存储库是可访问的并且可以被克隆...
... git-fetch(1)是获取("fetch")感兴趣的特定版本号的正确操作(在操作的上下文中)。
这两个操作都需要做。后者,在逻辑上更重要的一个(工作在 * 那个 * 修订版),只能在仓库已经被克隆(引导,初始化)的情况下才能完成。
我希望这回答了你的问题,听起来不像是在取笑你的问题,因为这很容易被错过。我经常只是克隆一个仓库,我不需要去获取正确的版本号,因为 * 它已经在那里了 *。使用git-clone(1)的Git已经足够聪明,可以理解我在寻找什么(例如:一个分支名称),然后它的头,这就是我的意思。
然而,当我们自动化构建时,我们希望特别确保(Assert)我们可以并且确实构建了一个非常独特的修订版本。
GITHUB_REF
、CI_COMMIT
、BUILD_REVISION
、REVISION
--根据运行它的(专有)平台,有许多名称。在一天结束的时候,这是对git中由SHA1散列标识的提交的引用,即修订版。这些参数中的任何一个都只是引用它,git-fetch(1)确保它获取它(以及所有必要的文件/树/对象)。这就是我们使用版本控制系统的目的。当然,它需要首先获取此修订版。
所有这些分支或标记名称都只是随着时间的推移而消失,它们是象征性的,给孩子一个名称来发布它,但可以随时被覆盖。对克隆来说很好,但你不想在此基础上建立。首先获取实际修订版本。
这又需要设置远程并克隆它。(这是用git-clone(1)一步完成的,用于所有的引导。)
快乐编码,让构建运行!
练习:
而不是
action/checkout[@<revision>]
你可以只是run:
git clone
和git fetch
,git checkout
....较早的是一个JavaScript Package 器,用于您所要求的这些确切的shell命令(但显然他们的文档没有分享实现的基本原理,否则您就不会要求它,对吗?).因此,如果你喜欢实验,可以通过bash shell中的
run:
克隆git存储库,并探索在Github运行的Microsoft基础设施中git实际上是如何 * 克隆的环境(因此也是你的工作流程)。为此,学习如何使用
gh
命令行界面并创建一个(临时)存储库(在另一个存储库之后)以触发操作运行,然后在查看结果后删除临时存储库。