繁体   English   中英

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

[英]Git: Get all changed files since the last push

我正在编写一个 Gitlab CI 管道,我正在尝试查找自上次推送到远程 git 存储库以来已更改的所有文件。

我知道如何获取上次提交中更改的所有文件,但是如果同时推送了多个提交,我仍然只能找到最后一个的更改。

确保在推送中覆盖所有提交的最佳方法是编写一个预接收钩子,它可以访问每次推送中的所有提交。 如果您必须考虑历史重写可能发生,这一点尤其重要。

但是,如果您必须使用管道作业来执行此操作,一种方法是缓存(或以其他方式存储/检索)最后一次看到的提交 ref 并将其用作您的参考。

这种方法不会像预接收钩子那样健壮(但可以变得健壮),因为除其他问题外:

  1. 管道可以在旧的提交哈希上重新运行
  2. 克隆深度可能不够大,无法检索必要的提交(您可以使用GIT_DEPTH修复此问题,但这是一个考虑因素)
  3. 历史可以改写
  4. 具有较旧时间戳的提交可以在具有较新时间戳的提交之后推送(时间戳也有些随意,因为它们可以由提交者设置)
  5. 不同的分支可能有不同/不同的历史
  6. 在各种情况下都可以跳过管道

但是这个一般想法的实现可能看起来像这样:

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

这是未经测试的,因此可能存在小错误,但总体思路就在那里。

要解决git本身不跟踪推送事件的问题,另一种选择可能是依靠GitLab 项目事件 API来查找触发管道的推送之前的最后一次推送,但您可能必须整理出一个大量数据,包括推送到其他分支。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM