当我两次克隆存储库时,例如:
git clone <repo_X> --depth 1 clone1
git clone <repo_X> --depth 1 clone2
然后进行差异
diff -r clone1 clone2
这显示出差异:
Binary files clone1/.git/index and clone2/.git/index differ
...
diff -r clone1/.git/logs/HEAD clone2/.git/logs/HEAD
...
diff -r clone1/.git/logs/refs/remotes/origin/HEAD
...
似乎在文件中记录了克隆的时间。
我想向Docker映像添加一些存储库。当文件未更改时,Docker将使用其缓存。不幸的是,在克隆之后,Docker总是由于更改的文件而使缓存无效。
是否可以在完全相同的文件中包含两个仓库的克隆结果? (注意:我不想删除.git目录,因为我希望能够在图像内部使用git来检查存储库的版本。)
在进行缓存时,是否可以让Docker忽略.git文件夹(请注意,仍然必须将.git文件夹添加到映像中,所以.dockerignore不是一个选择吗?)
答案 0 :(得分:1)
您可以使用新的 Docker 的 BuildKit 功能 --mount=cache
。 Dockerfile 的玩具示例:
FROM ubuntu
RUN --mount=type=cache,target=/var/cache/apt \
apt update && apt upgrade -y && apt install -yq git
RUN echo A00
RUN --mount=type=cache,target=/tmp/git_cache/ \
git clone --depth=1 https://github.com/qtox/qtox/ /tmp/git_cache/qtox/; \
cd /tmp/git_cache/qtox/ && git pull && cp -r ./ /tmp/my_qtox/
RUN echo B00
以上dockerfile可以通过命令构建:
sudo env DOCKER_BUILDKIT=1 docker build -f Dockerfile .
注意 DOCKER_BUILDKIT=1
环境变量的存在,有必要在 docker build 中启用所有 BuildKit 的功能。您可以阅读有关 BuildKit 的功能here。
例如,我克隆了上面的 qTox 存储库,因为它非常庞大。
--mount=cache
功能会自动创建用于缓存的临时目录,并将其挂载到容器内的 /tmp/git_cache/
(目标)中。如果之前的一些图层发生了变化,例如echo A00
更改为 echo A01
则此克隆会立即完成,没有延迟,因为它只是从缓存中取出。
此外,根据您的要求,使用此缓存将使克隆存储库完全相同。只有当新提交出现在存储库中时,git pull
才会完成并且存储库更改。除非有新的提交,否则这个缓存的存储库将保持不变。因此,每次再次运行 docker build 时,您都会拥有相同的 git repo。
如果缓存目录长时间不使用或磁盘可用空间不足,Docker 很少会自动删除它。
正如您从上面的 docker-file 中看到的,最终的 git repo 将出现在容器的 /tmp/my_qtox/
文件夹中。您可以将此路径更改为您的案例所需的任何内容。
您也可能已经注意到,我在安装 APT 包时使用了相同的缓存机制。这非常方便,因为在重建映像时,所有软件包都不会从远程 Ubuntu 服务器重新下载,而是从缓存目录中获取。当 apt install 之前的先前 docker 层发生更改或将新的 apt 包添加到安装列表时,这很有用,在这两种情况下,apt install 都会非常快地重新运行。
答案 1 :(得分:1)
不要使用git-clone(1)
,而是使用git-archive(1)
(至少在最后)。它还包含已存档的修订,您可以在包含修订的文件中添加标记,例如创建一个标志文件。
对于需要完整克隆的存储库,请同时进行克隆(或将克隆后的元数据更改为基线)。
通常完全克隆应该不是特别必要的。如果,您还可以考虑在过程中使用 tar-pipe,在此过程中注意简化结果,以便缓存保持有效(仅在需要时失效)。