简体   繁体   English

Git:获取自上次推送以来所有更改的文件

[英]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:这种方法不会像预接收钩子那样健壮(但可以变得健壮),因为除其他问题外:

  1. Pipelines can be rerun on old commit hashes管道可以在旧的提交哈希上重新运行
  2. The clone depth may not be large enough to retrieve the necessary commits (you can fix this with GIT_DEPTH , but it's a consideration)克隆深度可能不够大,无法检索必要的提交(您可以使用GIT_DEPTH修复此问题,但这是一个考虑因素)
  3. History can be rewritten历史可以改写
  4. commits with older timestamps can be pushed after commits with newer timestamps (timestamps are also somewhat arbitrary since they can be set by the committer)具有较旧时间戳的提交可以在具有较新时间戳的提交之后推送(时间戳也有些随意,因为它们可以由提交者设置)
  5. Different branches may have different/diverged histories不同的分支可能有不同/不同的历史
  6. Pipelines can be skipped in a variety of circumstances在各种情况下都可以跳过管道

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.

相关问题 如何判断自上次git pull或git push之后我更改过的git pull将覆盖哪些文件? - How to tell what files would be over written by a git pull that I've changed since the last git pull or git push? 我怎样才能获得自从我上次使用Git以来在远程服务器上更改的唯一文件列表 - How can I get JUST a unique list of files that changed on remote server since my last pull with Git 自上次使用git / gerrit在Jenkins / Hudson中生成以来,如何获取已更改文件的列表 - How to get list of changed files since last build in Jenkins/Hudson with git/gerrit 获取自上次标记以来的所有git提交 - Get all git commits since last tag Gitlab CI:获取自上次运行以来更改的文件列表 - Gitlab CI: get list of files changed since last run 自从在git中创建分支以来如何获取已更改文件的列表 - How to get the list of changed files since the creation of a branch in git libgit2sharp 获取自上次推送以来的所有提交 - libgit2sharp get all commits since the last push 由于在jGit中进行了某些提交,如何获取所有更改的文件? - How to get all changed files since some commit in jGit? 自上次推送以来撤消git中的更改? - Undo changes in git since the last push? 如何判断自上次git pull以来远程存储库上的哪些文件发生了变化? - How to tell what files on remote repository changed since last git pull?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM