簡體   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