[英]Git: Get all changed files since the last push
I am writing a Gitlab CI pipeline and I am trying to find all files that have changed since the last push to the remote git repository.我正在编写一个 Gitlab CI 管道,我正在尝试查找自上次推送到远程 git 存储库以来已更改的所有文件。
I know how to get all files that were changed in the last commit but if more than one commit was pushed at the same time I can still only find the changes of the last one.我知道如何获取上次提交中更改的所有文件,但是如果同时推送了多个提交,我仍然只能找到最后一个的更改。
The best way to ensure you're covering all commits in a push would be to write a pre-receive hook, which will have access to all commits in every push.确保在推送中覆盖所有提交的最佳方法是编写一个预接收钩子,它可以访问每次推送中的所有提交。 This is especially important if you must consider that it's possible for history rewrites to happen.
如果您必须考虑历史重写可能发生,这一点尤其重要。
But if you must use a pipeline job to do this, one way would be to cache (or otherwise store/retrieve) the last seen commit ref and use that as your reference.但是,如果您必须使用管道作业来执行此操作,一种方法是缓存(或以其他方式存储/检索)最后一次看到的提交 ref 并将其用作您的参考。
This approach will not be as robust (but could be made to be robust) as a pre-receive hook because, among other issues:这种方法不会像预接收钩子那样健壮(但可以变得健壮),因为除其他问题外:
GIT_DEPTH
, but it's a consideration)GIT_DEPTH
修复此问题,但这是一个考虑因素)But an implementation of this general idea may look something like this:但是这个一般想法的实现可能看起来像这样:
my_job:
cache:
key: last-push # or consider keying on `CI_COMMIT_BRANCH` or similar
paths:
- "last-push.txt"
rules:
- if: "$CI_COMMIT_BRANCH"
script:
- |
if [[ -f "last-push.txt" ]]; then
source last-push.txt
else
echo "LAST_CI_COMMIT_SHA=${CI_COMMIT_SHA}" > last-push.txt
echo "LAST_CI_COMMIT_TIMESTAMP=${CI_COMMIT_TIMESTAMP}" >> last-push.txt
exit 0 # there is no cache, so this is the first pipeline to populate the cache
# nothing to do. Alternatively, consider entire history/all files
fi
last_date=$(date -d "$LAST_CI_COMMIT_TIMESTAMP" +%s)
this_date=$(date -d "$CI_COMMIT_TIMESTAMP" +%s)
if [[ this_date <= last_date ]]; then
exit 0 # current HEAD is older than last known HEAD. Someone may have re-run a pipeline on an older commit; exit to avoid giving the cache a bad value... there's probably a better way to handle this
fi
# show all commit SHAs since last push
# hope the clone depth was large enough to get this!
git log --since="$LAST_CI_COMMIT_TIMESTAMP" --pretty=%H
# get files that have changed since then
# hope the clone depth was large enough to get this!
git diff --name-only HEAD "${LAST_CI_COMMIT_SHA}"
# finally, store the current HEAD into the cache:
echo "LAST_CI_COMMIT_SHA=${CI_COMMIT_SHA} > last-push.txt
echo "LAST_CI_COMMIT_TIMESTAMP=${CI_COMMIT_TIMESTAMP}" >> last-push.txt
This is untested, so there may be minor bugs, but the general idea is there.这是未经测试的,因此可能存在小错误,但总体思路就在那里。
To resolve the issue in fact that git
does not itself track push events, an alternative option may be to rely on the GitLab Project Events API to find the last push before the push that triggered the pipeline, but you would have to potentially sort out a lot of data, including pushes to other branches.要解决
git
本身不跟踪推送事件的问题,另一种选择可能是依靠GitLab 项目事件 API来查找触发管道的推送之前的最后一次推送,但您可能必须整理出一个大量数据,包括推送到其他分支。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.