Git
英文 ▾ 主題 ▾ 最新版本 ▾ git-interpret-trailers 最後更新於 2.45.0

名稱

git-interpret-trailers - 在提交訊息中新增或解析結構化資訊

概要

git interpret-trailers [--in-place] [--trim-empty]
			[(--trailer (<key>|<key-alias>)[(=|:)<value>])…​]
			[--parse] [<file>…​]

描述

在提交訊息的自由格式部分的結尾,新增或解析類似於 RFC 822 電子郵件標頭的結尾行。例如,在以下提交訊息中

subject

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Signed-off-by: Alice <alice@example.com>
Signed-off-by: Bob <bob@example.com>

以 "Signed-off-by" 開頭的最後兩行是結尾。

如果沒有指定 <file>,此命令會從 <file> 參數或標準輸入讀取提交訊息。如果指定了 --parse,則輸出會包含來自輸入的已解析結尾,而不會受到任何命令列選項或組態變數的影響。

否則,此命令會將 trailer.* 組態變數(可能新增新的結尾,以及重新定位它們)以及任何可以覆寫組態變數的命令列參數(例如 --trailer=...,也可以新增新的結尾)套用到每個輸入檔案。結果會輸出到標準輸出。

此命令也可以對 git-format-patch[1] 的輸出進行操作,這比單純的提交訊息更為詳盡。也就是說,此類輸出包含提交訊息(如上所示)、"---" 分隔線和修補程式部分。對於這些輸入,分隔線和修補程式部分不會由此命令修改,並按原樣輸出,除非指定了 --no-divider

某些組態變數會控制如何將 --trailer 參數套用到每個輸入,以及如何變更輸入中的任何現有結尾。它們也允許自動新增某些結尾。

預設情況下,只有在最後一個結尾具有不同的 (<key>, <value>) 對時(或如果沒有現有結尾),才會將使用 --trailer 提供的 <key>=<value><key>:<value> 參數附加到現有結尾之後。<key> 和 <value> 部分會被修剪以移除開頭和結尾的空白,並且修剪後的 <key> 和 <value> 會以這種方式出現在輸出中

key: value

這表示修剪後的 <key> 和 <value> 會以 ': '(一個冒號後跟一個空格)分隔。

為了方便起見,可以設定 <key-alias>,讓在命令列上使用 --trailer 時可以縮短輸入時間。可以使用 trailer.<key-alias>.key 組態變數來設定。<keyAlias> 必須是完整 <key> 字串的前置詞,雖然大小寫不敏感。例如,如果您有

trailer.sign.key "Signed-off-by: "

在您的設定中,您只需要在命令列上指定 --trailer="sign: foo",而不是 --trailer="Signed-off-by: foo"

預設情況下,新的結尾會出現在所有現有結尾的結尾。如果沒有現有結尾,新的結尾會出現在輸入的結尾。如果沒有空白行,則會在新的結尾之前新增空白行。

從輸入中擷取現有結尾的方法是尋找一組或多組行,這些行 (i) 全部都是結尾,或 (ii) 包含至少一個 Git 產生或使用者設定的結尾,並且包含至少 25% 的結尾。該組必須以一個或多個空白(或僅包含空白)行開頭。該組必須位於輸入的結尾,或者是以 --- 開頭(後面跟著空格或行尾)的行之前的最後一個非空白行。

讀取結尾時,<key> 前面或內部不能有任何空白,但 <key> 和分隔符號之間允許有任意數量的常規空格和 Tab 字元。<value> 前面、內部或後面可以有空白。<value> 可以分割成多行,每後續一行都以至少一個空白開頭,如同 RFC 822 中的「摺疊」。範例

key: This is a very long value, with spaces and
  newlines in it.

請注意,結尾不遵循(也不打算遵循)RFC 822 標頭的許多規則。例如,它們不遵循編碼規則。

選項

--in-place

就地編輯檔案。

--trim-empty

如果任何結尾的 <value> 部分僅包含空白,則整個結尾將從輸出中移除。這適用於現有結尾和新結尾。

--trailer <key>[(=|:)<value>]

指定應該作為結尾套用到輸入的 (<key>, <value>) 對。請參閱此命令的描述。

--where <placement>
--no-where

指定所有新的結尾將被新增到哪裡。使用 --where 提供的設定會覆寫 trailer.where 和任何適用的 trailer.<keyAlias>.where 組態變數,並套用到所有 --trailer 選項,直到下一個出現 --where--no-where。遇到 --no-where 時,清除之前使用 --where 的任何效果,使得相關的組態變數不再被覆寫。可能的位置是 afterbeforeendstart

--if-exists <action>
--no-if-exists

指定當輸入中已經有至少一個具有相同 <key> 的結尾時,將執行什麼動作。使用 --if-exists 提供的設定會覆寫 trailer.ifExists 和任何適用的 trailer.<keyAlias>.ifExists 組態變數,並套用到所有 --trailer 選項,直到下一個出現 --if-exists--no-if-exists。遇到 '--no-if-exists' 時,清除之前使用 '--if-exists' 的任何效果,使得相關的組態變數不再被覆寫。可能的動作是 addIfDifferentaddIfDifferentNeighboraddreplacedoNothing

--if-missing <action>
--no-if-missing

指定當輸入中沒有其他具有相同 <key> 的結尾時,將執行什麼動作。使用 --if-missing 提供的設定會覆寫 trailer.ifMissing 和任何適用的 trailer.<keyAlias>.ifMissing 組態變數,並套用到所有 --trailer 選項,直到下一個出現 --if-missing--no-if-missing。遇到 '--no-if-missing' 時,清除之前使用 '--if-missing' 的任何效果,使得相關的組態變數不再被覆寫。可能的動作是 doNothingadd

--only-trailers

僅輸出結尾,不輸出輸入的任何其他部分。

--only-input

僅輸出輸入中存在的結尾;不從命令列新增任何結尾或套用 trailer.* 組態變數。

--unfold

如果結尾的值跨越多行(又稱「摺疊」),請將值重新格式化為單行。

--parse

--only-trailers --only-input --unfold 的方便別名。這讓您更容易只看到來自輸入的結尾,而不受任何命令列選項或組態變數的影響,同時也使用 --unfold 使輸出對機器友善。

--no-divider

請勿將 --- 視為提交訊息的結尾。當您確定您的輸入僅包含提交訊息本身(而非電子郵件或 git format-patch 的輸出)時,請使用此選項。

組態變數

trailer.separators

此選項指定哪些字元會被視為 trailer 分隔符號。預設情況下,只有: 會被視為 trailer 分隔符號,但為了與其他 git 命令相容,命令列上始終接受 =

此選項指定的第一個字元將會是在此 trailer 的組態中未指定其他分隔符號時,所使用的預設字元。

例如,如果此選項的值為「%=$」,那麼只有使用 <key><sep><value> 格式的行,且 <sep> 包含 %=$,然後接空格,才會被視為 trailer。而 % 將會是預設使用的分隔符號,因此預設情況下,trailer 會像這樣顯示:<key>% <value>(key 和 value 之間會出現一個百分比符號和一個空格)。

trailer.where

此選項指定新 trailer 將會被加入的位置。

這可以是 end(預設值)、startafterbefore

如果是 end,則每個新 trailer 將會出現在現有 trailer 的末尾。

如果是 start,則每個新 trailer 將會出現在現有 trailer 的開頭,而不是末尾。

如果是 after,則每個新 trailer 將會出現在具有相同 <key> 的最後一個 trailer 之後。

如果是 before,則每個新 trailer 將會出現在具有相同 <key> 的第一個 trailer 之前。

trailer.ifexists

此選項可以選擇當輸入中已經至少有一個具有相同 <key> 的 trailer 時,將要執行的動作。

此選項的有效值為:addIfDifferentNeighbor(預設值)、addIfDifferentaddreplacedoNothing

使用 addIfDifferentNeighbor,只有在新 trailer 將被加入的行的上方或下方,沒有具有相同(<key>、<value>)配對的 trailer 時,才會加入新的 trailer。

使用 addIfDifferent,只有在輸入中沒有具有相同(<key>、<value>)配對的 trailer 時,才會加入新的 trailer。

使用 add,即使輸入中已經存在一些具有相同(<key>、<value>)配對的 trailer,也會加入新的 trailer。

使用 replace,會刪除現有具有相同 <key> 的 trailer,並加入新的 trailer。被刪除的 trailer 會是與新 trailer 將加入的位置最接近(具有相同 <key>)的 trailer。

使用 doNothing,則什麼都不會做;也就是說,如果輸入中已經存在一個具有相同 <key> 的 trailer,則不會加入新的 trailer。

trailer.ifmissing

此選項可以選擇當輸入中尚未存在具有相同 <key> 的 trailer 時,將要執行的動作。

此選項的有效值為:add(預設值)和 doNothing

使用 add,將會加入新的 trailer。

使用 doNothing,則什麼都不會做。

trailer.<keyAlias>.key

為 <key> 定義一個 <keyAlias>。<keyAlias> 必須是 <key> 的前綴(大小寫不拘)。例如,在 git config trailer.ack.key "Acked-by" 中,「Acked-by」是 <key>,「ack」是 <keyAlias>。此組態允許在命令列上使用較短的 --trailer "ack:..." 呼叫,使用「ack」<keyAlias> 而不是較長的 --trailer "Acked-by:..."

在 <key> 的結尾,可以出現一個分隔符號,然後是一些空格字元。預設情況下,唯一有效的分隔符號是 :,但是可以使用 trailer.separators 組態變數來更改此設定。

如果 key 中存在分隔符號,則在加入 trailer 時,它會覆蓋預設分隔符號。

trailer.<keyAlias>.where

此選項採用與 trailer.where 組態變數相同的值,並且會覆蓋該選項針對具有指定 <keyAlias> 的 trailer 所指定的設定。

trailer.<keyAlias>.ifexists

此選項採用與 trailer.ifexists 組態變數相同的值,並且會覆蓋該選項針對具有指定 <keyAlias> 的 trailer 所指定的設定。

trailer.<keyAlias>.ifmissing

此選項採用與 trailer.ifmissing 組態變數相同的值,並且會覆蓋該選項針對具有指定 <keyAlias> 的 trailer 所指定的設定。

trailer.<keyAlias>.command

已棄用,請改用 trailer.<keyAlias>.cmd。此選項的行為與 trailer.<keyAlias>.cmd 相同,只是它不會將任何內容作為引數傳遞給指定的命令。相反地,子字串 $ARG 的第一次出現會被將作為引數傳遞的 <value> 所取代。

請注意,使用者命令中的 $ARG 只會被取代一次,並且原始的 $ARG 取代方式並不安全。

當針對相同的 <keyAlias> 同時給定 trailer.<keyAlias>.cmdtrailer.<keyAlias>.command 時,會使用 trailer.<keyAlias>.cmd,而忽略 trailer.<keyAlias>.command

trailer.<keyAlias>.cmd

此選項可用於指定一個 shell 命令,該命令會被呼叫一次,以自動加入具有指定 <keyAlias> 的 trailer,然後在每次指定 --trailer <keyAlias>=<value> 引數時呼叫,以修改此選項將產生的 trailer 的 <value>。

當第一次呼叫指定的命令以加入具有指定 <keyAlias> 的 trailer 時,其行為就像是在 "git interpret-trailers" 命令的開頭加入了特殊的 --trailer <keyAlias>=<value> 引數一樣,其中 <value> 會被視為命令的標準輸出,並刪除任何開頭和結尾的空格。

如果也在命令列上傳遞了一些 --trailer <keyAlias>=<value> 引數,則會針對每個具有相同 <keyAlias> 的引數再次呼叫該命令。而這些引數的 <value> 部分(如果有的話),將會作為其第一個引數傳遞給該命令。這樣,命令就可以根據 --trailer <keyAlias>=<value> 引數中傳遞的 <value> 來產生計算出的 <value>。

範例

  • 使用 Signed-off-by key 組態一個 sign trailer,然後將這兩個 trailer 加入到提交訊息檔案中

    $ git config trailer.sign.key "Signed-off-by"
    $ cat msg.txt
    subject
    
    body text
    $ git interpret-trailers --trailer 'sign: Alice <alice@example.com>' --trailer 'sign: Bob <bob@example.com>' <msg.txt
    subject
    
    body text
    
    Signed-off-by: Alice <alice@example.com>
    Signed-off-by: Bob <bob@example.com>
  • 使用 --in-place 選項來就地編輯提交訊息檔案

    $ cat msg.txt
    subject
    
    body text
    
    Signed-off-by: Bob <bob@example.com>
    $ git interpret-trailers --trailer 'Acked-by: Alice <alice@example.com>' --in-place msg.txt
    $ cat msg.txt
    subject
    
    body text
    
    Signed-off-by: Bob <bob@example.com>
    Acked-by: Alice <alice@example.com>
  • 將最後一次提交提取為 patch,並向其加入 CcReviewed-by trailer

    $ git format-patch -1
    0001-foo.patch
    $ git interpret-trailers --trailer 'Cc: Alice <alice@example.com>' --trailer 'Reviewed-by: Bob <bob@example.com>' 0001-foo.patch >0001-bar.patch
  • 使用一個命令組態一個 sign trailer,該命令會自動加入 'Signed-off-by: ' 以及作者資訊,但前提是還沒有 'Signed-off-by: ',並展示其運作方式

    $ cat msg1.txt
    subject
    
    body text
    $ git config trailer.sign.key "Signed-off-by: "
    $ git config trailer.sign.ifmissing add
    $ git config trailer.sign.ifexists doNothing
    $ git config trailer.sign.cmd 'echo "$(git config user.name) <$(git config user.email)>"'
    $ git interpret-trailers --trailer sign <msg1.txt
    subject
    
    body text
    
    Signed-off-by: Bob <bob@example.com>
    $ cat msg2.txt
    subject
    
    body text
    
    Signed-off-by: Alice <alice@example.com>
    $ git interpret-trailers --trailer sign <msg2.txt
    subject
    
    body text
    
    Signed-off-by: Alice <alice@example.com>
  • 組態一個 fix trailer,其 key 包含一個 #,並且此字元後面沒有空格,並展示其運作方式

    $ git config trailer.separators ":#"
    $ git config trailer.fix.key "Fix #"
    $ echo "subject" | git interpret-trailers --trailer fix=42
    subject
    
    Fix #42
  • 使用一個腳本 glog-find-author 組態一個 help trailer,該腳本會從 git 儲存庫的 git log 中搜尋指定的作者身份,並展示其運作方式

    $ cat ~/bin/glog-find-author
    #!/bin/sh
    test -n "$1" && git log --author="$1" --pretty="%an <%ae>" -1 || true
    $ cat msg.txt
    subject
    
    body text
    $ git config trailer.help.key "Helped-by: "
    $ git config trailer.help.ifExists "addIfDifferentNeighbor"
    $ git config trailer.help.cmd "~/bin/glog-find-author"
    $ git interpret-trailers --trailer="help:Junio" --trailer="help:Couder" <msg.txt
    subject
    
    body text
    
    Helped-by: Junio C Hamano <gitster@pobox.com>
    Helped-by: Christian Couder <christian.couder@gmail.com>
  • 使用一個腳本 glog-grep 組態一個 ref trailer,該腳本會從 git 儲存庫的 git log 中 grep 出最後一個相關的提交,並展示其運作方式

    $ cat ~/bin/glog-grep
    #!/bin/sh
    test -n "$1" && git log --grep "$1" --pretty=reference -1 || true
    $ cat msg.txt
    subject
    
    body text
    $ git config trailer.ref.key "Reference-to: "
    $ git config trailer.ref.ifExists "replace"
    $ git config trailer.ref.cmd "~/bin/glog-grep"
    $ git interpret-trailers --trailer="ref:Add copyright notices." <msg.txt
    subject
    
    body text
    
    Reference-to: 8bc9a0c769 (Add copyright notices., 2005-04-07)
  • 使用一個命令組態一個 see trailer,該命令會顯示相關的提交主旨,並展示其運作方式

    $ cat msg.txt
    subject
    
    body text
    
    see: HEAD~2
    $ cat ~/bin/glog-ref
    #!/bin/sh
    git log -1 --oneline --format="%h (%s)" --abbrev-commit --abbrev=14
    $ git config trailer.see.key "See-also: "
    $ git config trailer.see.ifExists "replace"
    $ git config trailer.see.ifMissing "doNothing"
    $ git config trailer.see.cmd "glog-ref"
    $ git interpret-trailers --trailer=see <msg.txt
    subject
    
    body text
    
    See-also: fe3187489d69c4 (subject of related commit)
  • 使用一些具有空值的 trailer(使用 sed 來顯示並保留 trailer 末尾的尾隨空格)組態一個提交範本,然後組態一個 commit-msg hook,該 hook 使用 git interpret-trailers 來刪除具有空值的 trailer,並加入一個 git-version trailer

    $ cat temp.txt
    ***subject***
    
    ***message***
    
    Fixes: Z
    Cc: Z
    Reviewed-by: Z
    Signed-off-by: Z
    $ sed -e 's/ Z$/ /' temp.txt > commit_template.txt
    $ git config commit.template commit_template.txt
    $ cat .git/hooks/commit-msg
    #!/bin/sh
    git interpret-trailers --trim-empty --trailer "git-version: \$(git describe)" "\$1" > "\$1.new"
    mv "\$1.new" "\$1"
    $ chmod +x .git/hooks/commit-msg

GIT

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

scroll-to-top