Git
English ▾ 主題 ▾ 最新版本 ▾ git-receive-pack 最後更新於 2.43.0

名稱

git-receive-pack - 接收推送到儲存庫的內容

概要

git receive-pack <git-dir>

描述

git send-pack 呼叫,並使用來自遠端饋送的資訊更新儲存庫。

此命令通常不由終端使用者直接呼叫。協定的使用者介面在 git send-pack 端,而該程式配對旨在用於將更新推送至遠端儲存庫。對於提取操作,請參閱 git-fetch-pack[1]

此命令允許在遠端(嚴格來說,是執行 git-receive-pack 的本機端,但對於坐在 send-pack 端的使用者來說,它是更新遠端。搞混了嗎?)上建立和快轉 sha1 參考 (heads/tags)。

在 Documentation/howto 目錄中可以找到使用更新和 post-update hook 的其他實際範例。

git-receive-pack 會遵守 receive.denyNonFastForwards 配置選項,該選項會告知它如果對參考的更新不是快轉,是否應該拒絕。

還有許多其他 receive.* 配置選項可用於調整其行為,請參閱 git-config[1]

選項

<git-dir>

要同步的儲存庫。

--http-backend-info-refs

git-http-backend[1] 用於服務 $GIT_URL/info/refs?service=git-receive-pack 請求。請參閱 git-upload-pack[1] 中的 --http-backend-info-refs

pre-receive hook

在任何參考更新之前,如果 $GIT_DIR/hooks/pre-receive 檔案存在且可執行,則會呼叫它一次,不帶任何參數。hook 的標準輸入將是每行一個要更新的參考

sha1-old SP sha1-new SP refname LF

refname 值相對於 $GIT_DIR;例如,對於 master head,它是 "refs/heads/master"。每個 refname 前面的兩個 sha1 值是更新前後 refname 的物件名稱。要建立的參考的 sha1-old 等於 0{40},而要刪除的參考的 sha1-new 等於 0{40},否則 sha1-old 和 sha1-new 應該是儲存庫中的有效物件。

接受簽名的推送(請參閱 git-push[1])時,簽名的推送憑證會儲存在 blob 中,並且可以查詢環境變數 GIT_PUSH_CERT 以取得其物件名稱。請參閱 post-receive hook 的描述以取得範例。此外,憑證會使用 GPG 進行驗證,並且會使用以下環境變數匯出結果

GIT_PUSH_CERT_SIGNER

簽署推送憑證的金鑰擁有者的名稱和電子郵件地址。

GIT_PUSH_CERT_KEY

簽署推送憑證的金鑰的 GPG 金鑰 ID。

GIT_PUSH_CERT_STATUS

推送憑證的 GPG 驗證狀態,使用與 git log 系列命令的 %G? 格式中相同的助記符(請參閱 git-log[1])。

GIT_PUSH_CERT_NONCE

該程序要求簽署者在推送憑證中包含的 nonce 字串。如果此值與推送憑證中「nonce」標頭上記錄的值不符,則可能表示憑證是有效的憑證,並且正在從單獨的「git push」會話中重新播放。

GIT_PUSH_CERT_NONCE_STATUS
UNSOLICITED

當我們沒有要求時,「git push --signed」發送了一個 nonce。

MISSING

「git push --signed」沒有發送任何 nonce 標頭。

BAD

「git push --signed」發送了一個偽造的 nonce。

OK

「git push --signed」發送了我們要求它發送的 nonce。

SLOP

「git push --signed」發送的 nonce 與我們現在要求它發送的 nonce 不同,但在先前的會話中。請參閱 GIT_PUSH_CERT_NONCE_SLOP 環境變數。

GIT_PUSH_CERT_NONCE_SLOP

「git push --signed」發送的 nonce 與我們現在要求它發送的 nonce 不同,但在不同會話中,該會話的開始時間與目前會話相差這麼多秒。僅當 GIT_PUSH_CERT_NONCE_STATUS 表示 SLOP 時才有意義。另請閱讀 git-config[1] 中的 receive.certNonceSlop 變數。

此 hook 會在更新任何 refname 之前以及執行任何快轉檢查之前呼叫。

如果 pre-receive hook 以非零結束狀態退出,則不會執行任何更新,並且也不會呼叫 update、post-receive 和 post-update hook。如果不想支援更新,這對於快速跳出很有用。

請參閱下方關於隔離環境的注意事項。

UPDATE HOOK

在更新每個參考之前,如果 $GIT_DIR/hooks/update 檔案存在且可執行,則會針對每個參考呼叫一次,並帶有三個參數

$GIT_DIR/hooks/update refname sha1-old sha1-new

refname 參數相對於 $GIT_DIR;例如,對於 master head,它是 "refs/heads/master"。兩個 sha1 引數是更新前後 refname 的物件名稱。請注意,hook 是在更新 refname 之前呼叫的,因此 sha1-old 要嘛是 0{40}(表示還沒有這樣的參考),要嘛它應該符合 refname 中記錄的內容。

如果 hook 想要禁止更新指定的參考,則應該以非零結束狀態退出。否則,它應該以零退出。

成功執行此 hook(零結束狀態)並不能確保參考實際會被更新,它只是一個先決條件。因此,不建議從此 hook 發送通知(例如電子郵件)。請考慮改用 post-receive hook。

POST-RECEIVE HOOK

在所有參考都已更新(或嘗試更新)之後,如果任何參考更新成功,並且如果 $GIT_DIR/hooks/post-receive 檔案存在且可執行,則會呼叫它一次,不帶任何參數。hook 的標準輸入將是每個成功更新的參考一行

sha1-old SP sha1-new SP refname LF

refname 值相對於 $GIT_DIR;例如,對於 master head,它是 "refs/heads/master"。每個 refname 前面的兩個 sha1 值是更新前後 refname 的物件名稱。已建立的參考的 sha1-old 等於 0{40},而已刪除的參考的 sha1-new 等於 0{40},否則 sha1-old 和 sha1-new 應該是儲存庫中的有效物件。

在接受簽名的推送後,可以檢查 GIT_PUSH_CERT* 環境變數,就像在 pre-receive hook 中一樣。

使用此 hook,可以輕鬆產生描述儲存庫更新的郵件。此範例腳本為每個參考發送一封郵件,其中列出推送到儲存庫的提交,並將具有良好簽名的簽名推送的推送憑證記錄到記錄器服務

#!/bin/sh
# mail out commit update information.
while read oval nval ref
do
	if expr "$oval" : '0*$' >/dev/null
	then
		echo "Created a new ref, with the following commits:"
		git rev-list --pretty "$nval"
	else
		echo "New commits:"
		git rev-list --pretty "$nval" "^$oval"
	fi |
	mail -s "Changes to ref $ref" commit-list@mydomain
done
# log signed push certificate, if any
if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G
then
	(
		echo expected nonce is ${GIT_PUSH_NONCE}
		git cat-file blob ${GIT_PUSH_CERT}
	) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain
fi
exit 0

會忽略此 hook 呼叫的結束代碼,但是非零結束代碼會產生錯誤訊息。

請注意,此 hook 執行時,refname 可能沒有 sha1-new。如果另一個使用者在 git-receive-pack 更新參考之後,但在 hook 能夠評估它之前修改了參考,則可能會很容易發生這種情況。建議 hook 依賴 sha1-new,而不是 refname 的目前值。

POST-UPDATE HOOK

在所有其他處理完成之後,如果至少有一個參考已更新,並且如果 $GIT_DIR/hooks/post-update 檔案存在且可執行,則將使用已更新的參考清單呼叫 post-update。這可用於實作任何儲存庫範圍的清除任務。

會忽略此 hook 呼叫的結束代碼;在那個時間點 git-receive-pack 剩下的唯一事情是退出它本身。

例如,如果儲存庫已封裝並且透過啞傳輸提供服務,則可以使用此 hook 來執行 git update-server-info

#!/bin/sh
exec git update-server-info

隔離環境

receive-pack 接收物件時,它們會被放置在 $GIT_DIR/objects 目錄內的暫時「隔離」目錄中,並且僅在 pre-receive hook 完成後才會移轉到主物件儲存區。如果推送在此之前失敗,則會完全移除臨時目錄。

這有一些使用者可見的影響和注意事項

  1. 由於傳入的封裝、遺失的物件或 pre-receive hook 的問題而失敗的推送不會留下任何磁碟上的資料。這通常有助於防止重複失敗的推送填滿您的磁碟,但會使除錯更具挑戰性。

  2. pre-receive hook 建立的任何物件都將在隔離目錄中建立(並且僅在成功時才移轉)。

  3. pre-receive hook(預先接收掛鉤)絕對**不能**更新任何引用(refs)指向被隔離的物件。存取此儲存庫的其他程式將無法看到這些物件(並且如果 pre-receive 掛鉤失敗,這些引用將會損毀)。為了安全起見,來自 pre-receive 內的任何引用更新都會被自動拒絕。

GIT

屬於 git[1] 套件的一部分

scroll-to-top