Git 从浅克隆中查找自 <ref> 以来修改过的文件

Git find modified files since <ref> from a shallow clone

我正在进行 CI 盒子 运行 测试。为了加快速度,我只是做了一个浅层克隆:

git clone --depth 1 git@github.com:JoshCheek/some_repo.git

假设所有测试都通过,我想触发管道中的下一步。触发什么是基于哪些文件在最后一个 d 部署(ref d123456)和我刚刚测试的 current ref 之间发生了变化(参考 c123456)。如果我做了一个普通的克隆,我会发现这样的:

git diff --name-only d123456 c123456

但是我的克隆很浅,所以它不知道那些提交。我看到我可以使用 git fetch --depth=n 来获取更多的历史记录,但我只知道 SHA,不知道 SHA 的深度。这里有一组可能可以回答这个问题的方法:

# hypothetical remote diff
git diff --name-only origin/d123456 origin/c123456

# hypothetical ref based fetch
git fetch --shallow-through d123456
git diff --name-only d123456 c123456

# hypothetical way to find the depth I need
depth=`git remote depth-to d123456`
git fetch --depth "$depth"
git diff --name-only d123456 c123456

否则我可能不得不编写一个循环并继续调用 --deepen 直到我的历史包含提交。这看起来很痛苦(意思是编写/维护很烦人)而且很昂贵(意思是很慢,记住浅克隆的目的是降低这个成本)。

Otherwise it seems like I might have to write a loop and keep invoking --deepen until my history contains the commit. That seems painful ...

痛苦的(而且很慢,你稍后会注意到)。

现代 Git(自版本 2.11 起)确实有一个新的 git fetch 选项:

--shallow-exclude=<revision>

    Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. This option can be specified multiple times.

我没试过这个;目前尚不清楚它是否允许哈希 ID(测试使用名称),并且在任何情况下您都可以指定要深化的提交的 parent(s),而不是提交你想获得。但这可能就足够了。

(我真的认为更好的方法是保留可以借用的参考克隆。)

除了浅克隆之外,还有几种可能的解决方案可以减少克隆时间和space。

1.git clone <url> -b <branch> --single-branch

这仅获取 <branch> 可访问的数据。不如 --depth=1 有效,但仍优于完整克隆。当 repo 有许多不同的分支时它工作正常。

2.git init;git fetch <url> <tag>

同样,它只获取 <tag> 可达的数据。

3.Create 并使用镜像仓库。

git clone <url> --mirror -- /foo/mirror/foo/mirror 是镜像仓库。假设您的 CI 系统同时启动多个实例。通过 git clone <url> --reference=/foo/mirror -- <instanceN> 克隆每个。在每次克隆中,只有在镜像仓库中找不到的数据才会从远程仓库中下载。您可以在作业完成后删除实例以保存 space。但只需根据远程仓库的更新频率定期 git fetch 保持和更新镜像仓库即可。例如每天半夜一次,或每周一次周日。

4.Use git worktree.

制作一个克隆,保留它并在每个 CI 实例启动时首先更新它。使用 git worktree 将修订检出到每个实例的不同工作树中。

我遇到了同样的问题并使用了这个

git clone --shallow-since=<date>

我不仅要存储上次部署的 SHA,还要存储上次部署的日期,但在其他方面效果很好。