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

名稱

git-receive-pack - 接收推送至版本庫的內容

概要

git receive-pack <git-dir>

描述

git send-pack 調用,並使用遠端傳送的資訊更新版本庫。

此指令通常不直接由終端使用者調用。該協定的使用者介面位於 git send-pack 端,這對程式旨在用於將更新推送至遠端版本庫。關於拉取操作,請參閱 git-fetch-pack[1]

此指令允許在遠端建立及快轉 (fast-forward) sha1 參考(heads/tags)(嚴格來說,它是 git-receive-pack 運行的本地端,但對於坐在 send-pack 端的使用者來說,它是在更新遠端。困惑了嗎?)。

在 Documentation/howto 目錄中可以找到使用 update 和 post-update 鉤子的其他實際案例。

git-receive-pack 會遵守 receive.denyNonFastForwards 設定選項,該選項告知若對參考的更新不是快轉(fast-forward)時,是否應拒絕該更新。

還有許多其他的 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

--skip-connectivity-check

繞過驗證可達物件傳遞閉包中所有物件是否存在性的連通性檢查。此選項旨在供伺服器營運商使用,他們希望在 Git 之外實現自己的物件連通性驗證。這在伺服器端已知關於 Git 使用方式的額外資訊,從而可以依賴某些保證來更有效地計算 Git 本身無法做出的物件連通性時很有用。在沒有可靠的外部機制來確保完整可達物件連通性的情況下使用此選項,有損壞版本庫的風險,因此不應在一般情況下使用。

PRE-RECEIVE 鉤子

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

sha1-old SP sha1-new SP refname LF

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

當接受簽署過的推送(參見 git-push[1])時,簽署過的推送憑證會儲存在 blob 中,並可查詢環境變數 GIT_PUSH_CERT 以取得其物件名稱。有關範例,請參見 post-receive 鉤子的描述。此外,憑證會使用 GPG 驗證,結果會透過以下環境變數導出:

GIT_PUSH_CERT_SIGNER

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

GIT_PUSH_CERT_KEY

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

GIT_PUSH_CERT_STATUS

推送憑證的 GPG 驗證狀態,使用與 git log 指令系列(參見 git-log[1])的 %G? 格式相同的助憶碼。

GIT_PUSH_CERT_NONCE

該進程要求簽署者在推送憑證中包含的 nonce 字串。如果這與推送憑證上 "nonce" 標頭中記錄的值不符,則可能表示憑證是從另一個 "git push" 工作階段重放(replay)的有效憑證。

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 與我們現在要求發送的不同,但在之前的會話中曾使用過。參見 GIT_PUSH_CERT_NONCE_SLOP 環境變數。

GIT_PUSH_CERT_NONCE_SLOP

"git push --signed" 發送的 nonce 與我們現在要求發送的不同,但來自於一個開始時間與當前會話相差這麼多秒的另一個會話。只有當 GIT_PUSH_CERT_NONCE_STATUSSLOP 時才有意義。另請閱讀 git-config[1] 中的 receive.certNonceSlop 變數。

此鉤子在更新任何參考名稱之前,以及在執行任何快轉(fast-forward)檢查之前被調用。

如果 pre-receive 鉤子以非零狀態退出,則不會執行任何更新,且 update、post-receive 和 post-update 鉤子也不會被調用。如果更新不被支援,這對於快速終止處理非常有用。

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

UPDATE 鉤子

在每個參考更新之前,如果 $GIT_DIR/hooks/update 檔案存在且可執行,它會對每個參考調用一次,帶有三個參數:

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

refname 參數是相對於 $GIT_DIR 的;例如,對於 master head,這是 "refs/heads/master"。兩個 sha1 引數是更新前後該參考名稱的物件名稱。請注意,鉤子是在參考名稱更新之前被調用的,因此 sha1-old 要麼是 0{40}(表示尚無此參考),要麼應該符合 refname 中所記錄的內容。

如果鉤子想要拒絕更新命名的參考,它應該以非零狀態退出。否則,它應該以零狀態退出。

此鉤子成功執行(零退出狀態)並不保證參考一定會被更新,這僅是一個先決條件。因此,不建議從此鉤子發送通知(例如電子郵件)。請考慮改用 post-receive 鉤子。

POST-RECEIVE 鉤子

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

sha1-old SP sha1-new SP refname LF

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

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

使用此鉤子,可以輕鬆產生描述版本庫更新的郵件。此範例指令碼為每個參考發送一封郵件,列出推送至版本庫的提交,並將具有有效簽名的已簽署推送的憑證記錄到記錄服務中。

#!/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

此鉤子調用的退出碼會被忽略,但非零的退出碼會產生錯誤訊息。

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

POST-UPDATE 鉤子

在所有其他處理完成後,如果至少有一個參考被更新,且 $GIT_DIR/hooks/post-update 檔案存在且可執行,那麼 post-update 將會被調用,並帶有已更新的參考列表。這可用於執行任何與版本庫範圍相關的清理任務。

此鉤子調用的退出碼會被忽略;此時 git-receive-pack 剩下唯一要做的就是它自己退出。

例如,如果版本庫已打包並透過啞傳輸(dumb transport)提供服務,此鉤子可用於執行 git update-server-info

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

隔離環境

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

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

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

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

  3. pre-receive 鉤子絕不能將任何參考更新指向隔離的物件。存取版本庫的其他程式將無法看到這些物件(如果 pre-receive 鉤子失敗,這些參考將變得損壞)。為了安全起見,來自 pre-receive 內部的任何參考更新都會被自動拒絕。

GIT

git[1] 套件的一部分