如何在 Dockerfile 中的特定提交处签出?

Posted

技术标签:

【中文标题】如何在 Dockerfile 中的特定提交处签出?【英文标题】:How to checkout at particular commit in Dockerfile? 【发布时间】:2022-01-21 17:05:12 【问题描述】:

我正在为我的项目编写一个 Dockerfile,例如

RUN git clone https://github.com/CNA/contract.git --depth 1 --branch 20.0 /opt/CNA-contract

我想在特定提交时冻结代码。在 Docker 中做这样的事情的最佳实践是什么? 我认为在类似的扩建中相当容易

git clone https://github.com/CNA/contract.git --depth 1 --branch 20.0 /opt/CNA-contract commit-SHA

【问题讨论】:

请注意,如果您可以在源存储库中设置 标签,那么无论您的 Git 有多旧,--depth 1 --branch <tag-name> 都能做到这一点。你会得到一个分离的 HEAD 克隆,但这应该没问题。 谢谢,但是这不能用你不拥有的 repos 来完成吗? @BrIndSoftsBrazil 是的,下面的my answer 可以使用您不拥有的(公共)存储库来完成。 对。只是注意 if 你可以做 X (创建标签)你可以得到 Y (你想要的效果,“免费”)。如果您不能做 X ... 请参阅 VonC 的回答 :-)(还有 David Maze 的,正如他所说,这有其自身的优势) 【参考方案1】:

如果您不在 Dockerfile 中而是在主机上运行 git clone,那么您可以签出并构建您想要的任何提交。

# on the host, not in a Dockerfile
git clone https://github.com/CNA/contract.git
cd contract
git checkout 20.0
docker build -t cna/contract:20.0 .
git checkout main
docker build -t cna/contract:$(git rev-parse --short HEAD)

这种方法还避免了一些关于获取适当凭据以运行git clone 命令的危险问题(该存储库不是公开的;您可以使用docker run 从映像中取回私钥吗?),它支持构建实际上并没有提交到源代码控制的东西,它避免了 Docker 层缓存的一些问题,即使存储库发生了变化,Docker 也不会重复 git clone 命令。

【讨论】:

【参考方案2】:

最好在您的RUN 中添加一些步骤,如“How to shallow clone a specific commit with depth 1?”中所述,假设是最新版本的 Git 2.24 或 mroe:

RUN \
mkdir repo && \
cd repo && \
git init . && \
git remote add origin <url> && \\
git fetch --depth 1 origin <sha1> && \\ 
git checkout FETCH_HEAD

这样,你只获取你需要的提交。

【讨论】:

以上是关于如何在 Dockerfile 中的特定提交处签出?的主要内容,如果未能解决你的问题,请参考以下文章

在 Jenkins 中,如何将项目签出到特定目录中(使用 GIT)

如何从命令行签出特定的 Subversion 版本?

Git如何签出提交进行一些更改并将其推送回相同的提交

从 github 签出项目时,Eclipse 中的团队菜单中没有提交按钮

如何更新CSV文件中的特定位置?

带有背景渐变的CSS子菜单覆盖内容