簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-receive-pack 最後更新於 2.50.0

名稱

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

概要

git receive-pack <git-dir>

描述

git send-pack 呼叫,並用從遠端端接收到的資訊更新倉庫。

此命令通常不由終端使用者直接呼叫。協議的使用者介面在 git send-pack 端,而這個程式對旨在推送更新到遠端倉庫。對於拉取操作,請參閱 git-fetch-pack[1]

該命令允許在遠端端建立和快進 sha1 引用(heads/tags)(嚴格來說,是執行 git-receive-pack 的本地端,但對於坐在 send-pack 端使用者來說,它正在更新遠端。感到困惑嗎?)

在 Documentation/howto 目錄中可以找到其他實際使用 update 和 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

--skip-connectivity-check

繞過連線性檢查,這些檢查會驗證可達物件傳遞閉包中所有物件的存在性。此選項旨在供伺服器管理員使用,他們希望在 Git 之外實現自己的物件連線性驗證。在這種情況下,當伺服器端知道 Git 的使用方式以及因此可以依賴某些保證來更有效地計算 Git 本身無法實現的 Git 物件連線性時,此選項很有用。在沒有可靠的外部機制來確保完整可達物件連線性的情況下使用此選項,存在損壞儲存庫的風險,一般情況下不應使用。

PRE-RECEIVE HOOK

在任何引用被更新之前,如果 $GIT_DIR/hooks/pre-receive 檔案存在且可執行,它將被呼叫一次,不帶任何引數。hook 的標準輸入將是每行一條待更新的引用資訊。

sha1-old SP sha1-new SP refname LF

refname 值是相對於 $GIT_DIR 的;例如,對於 master 頭,它是 "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 頭,它是 "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 頭,它是 "refs/heads/master"。每個 refname 前面的兩個 sha1 值是更新前後的 refname 的物件名稱。被建立的引用將具有 sha1-old 等於 0{40},而被刪除的引用將具有 sha1-new 等於 0{40},否則 sha1-old 和 sha1-new 應該是儲存庫中的有效物件。

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

使用此 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

QUARANTINE ENVIRONMENT

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

這有幾個使用者可見的影響和注意事項:

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

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

  3. pre-receive hook **必須**不要將任何引用指向隔離的物件。其他訪問儲存庫的程式將無法看到這些物件(如果 pre-receive hook 失敗,這些引用將損壞)。為安全起見,來自 pre-receive 內部的任何引用更新都會被自動拒絕。

GIT

Git[1] 套件的一部分