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,还要存储上次部署的日期,但在其他方面效果很好。
我正在进行 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,还要存储上次部署的日期,但在其他方面效果很好。