Git
English ▾ 主題 ▾ 最新版本 ▾ git-commit 最後更新於 2.46.1

名稱

git-commit - 記錄對儲存庫的變更

概要

git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
	   [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]
	   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]
	   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]
	   [--date=<date>] [--cleanup=<mode>] [--[no-]status]
	   [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]
	   [(--trailer <token>[(=|:)<value>])…​] [-S[<keyid>]]
	   [--] [<pathspec>…​]

描述

建立一個新的提交,包含索引的目前內容和描述變更的指定記錄訊息。新的提交是 HEAD 的直接子節點,通常是目前分支的頂端,並且分支會更新以指向它(除非沒有分支與工作樹相關聯,在這種情況下,HEAD 會如 git-checkout[1] 中所述的「分離」)。

要提交的內容可以用幾種方式指定

  1. 在 使用 commit 命令之前,先使用 git-add[1] 逐步將變更「加入」到索引中(注意:即使是修改過的文件也必須「加入」);

  2. 在 使用 commit 命令之前,先使用 git-rm[1] 從工作樹和索引中移除檔案;

  3. 將檔案列為 commit 命令的引數(沒有 --interactive 或 --patch 參數),在這種情況下,提交會忽略在索引中暫存的變更,而是記錄列出的檔案的目前內容(必須已為 Git 所知);

  4. 將 -a 參數與 commit 命令一起使用,以自動「加入」所有已知檔案(即索引中已列出的所有檔案)中的變更,並自動「rm」索引中已從工作樹中移除的檔案,然後執行實際的提交;

  5. 將 --interactive 或 --patch 參數與 commit 命令一起使用,以決定除了索引中的內容之外,哪些檔案或區塊應成為提交的一部分,然後再完成操作。請參閱 git-add[1] 的「互動模式」章節,以了解如何操作這些模式。

--dry-run 選項可用於取得摘要,其中包含任何上述內容在下一次提交時所包含的內容,方法是提供相同的參數組(選項和路徑)。

如果您進行提交,然後立即發現錯誤,可以使用 git reset 從中恢復。

選項

-a
--all

告訴命令自動暫存已修改和刪除的檔案,但您尚未告知 Git 的新檔案不會受到影響。

-p
--patch

使用互動式修補程式選取介面,選擇要提交的變更。有關詳細資訊,請參閱 git-add[1]

-C <commit>
--reuse-message=<commit>

取得現有的提交物件,並在建立提交時重複使用記錄訊息和作者資訊(包括時間戳記)。

-c <commit>
--reedit-message=<commit>

-C 類似,但是使用 -c 時會叫用編輯器,以便使用者可以進一步編輯提交訊息。

--fixup=[(amend|reword):]<commit>

建立一個新的提交,該提交在與 git rebase --autosquash 一起套用時「修正」<commit>。普通的 --fixup=<commit> 會建立一個「fixup!」提交,該提交會變更 <commit> 的內容,但使其記錄訊息保持不變。--fixup=amend:<commit> 類似,但會建立一個「amend!」提交,該提交也會將 <commit> 的記錄訊息替換為「amend!」提交的記錄訊息。--fixup=reword:<commit> 會建立一個「amend!」提交,該提交會將 <commit> 的記錄訊息替換為其自己的記錄訊息,但不會對 <commit> 的內容進行任何變更。

普通的 --fixup=<commit> 所建立的提交具有一個主題,該主題由「fixup!」加上來自 <commit> 的主題行組成,並且會被 git rebase --autosquash 特別辨識。-m 選項可以用於補充所建立提交的記錄訊息,但是一旦「fixup!」提交被 git rebase --autosquash 壓縮到 <commit> 中,額外的註解就會被丟棄。

--fixup=amend:<commit> 所建立的提交類似,但是其主題改為以「amend!」作為前綴。<commit> 的記錄訊息會複製到「amend!」提交的記錄訊息中,並在編輯器中開啟,以便可以進一步修改。當 git rebase --autosquash 將「amend!」提交壓縮到 <commit> 中時,<commit> 的記錄訊息將被「amend!」提交中修改過的記錄訊息取代。除非指定了 --allow-empty-message,否則「amend!」提交的記錄訊息為空是錯誤的。

--fixup=reword:<commit>--fixup=amend:<commit> --only 的簡寫。它會建立一個僅具有記錄訊息的「amend!」提交(忽略索引中暫存的任何變更)。當被 git rebase --autosquash 壓縮時,它會取代 <commit> 的記錄訊息,而不會進行任何其他變更。

git rebase --autosquash 套用時,「fixup!」和「amend!」提交都不會變更 <commit> 的作者身分。有關詳細資訊,請參閱 git-rebase[1]

--squash=<commit>

建構一個提交訊息,以與 rebase --autosquash 一起使用。提交訊息主題行取自指定的提交,並以「squash! 」作為前綴。 可以與其他提交訊息選項 (-m/-c/-C/-F) 一起使用。 有關詳細資訊,請參閱 git-rebase[1]

--reset-author

當與 -C/-c/--amend 選項一起使用時,或在有衝突的 cherry-pick 之後進行提交時,宣告結果提交的作者身分現在屬於提交者。這也會更新作者時間戳記。

--short

在進行 dry-run 時,以短格式給出輸出。有關詳細資訊,請參閱 git-status[1]。表示 --dry-run

--branch

即使在短格式中,也顯示分支和追蹤資訊。

--porcelain

在進行 dry-run 時,以適合瓷器(porcelain-ready)的格式給出輸出。有關詳細資訊,請參閱 git-status[1]。表示 --dry-run

--long

在進行 dry-run 時,以長格式給出輸出。表示 --dry-run

-z
--null

當顯示 shortporcelain 狀態輸出時,會逐字印出檔名,並以 NUL 字元而非 LF 字元終止條目。如果沒有給定格式,則表示使用 --porcelain 輸出格式。若沒有 -z 選項,具有「不尋常」字元的檔名會如同組態變數 core.quotePath 所說明的方式加上引號(請參閱 git-config[1])。

-F <檔案>
--file=<檔案>

從指定的檔案取得提交訊息。使用 - 從標準輸入讀取訊息。

--author=<作者>

覆寫提交作者。使用標準 A U Thor <author@example.com> 格式明確指定作者。否則,<作者> 會被視為模式,並用於搜尋該作者的現有提交(例如:rev-list --all -i --author=<作者>);然後會從找到的第一個此類提交複製提交作者。

--date=<日期>

覆寫提交中使用的作者日期。

-m <訊息>
--message=<訊息>

使用給定的 <訊息> 作為提交訊息。如果給定多個 -m 選項,它們的值將會串聯成個別的段落。

-m 選項與 -c-C-F 選項互斥。

-t <檔案>
--template=<檔案>

當編輯提交訊息時,使用指定檔案中的內容啟動編輯器。commit.template 組態變數通常用於隱式地將此選項提供給命令。專案可以使用此機制來引導參與者,說明要在訊息中依序寫入哪些提示。如果使用者在未編輯訊息的情況下退出編輯器,提交會中止。當訊息透過其他方式給定時,例如透過 -m-F 選項時,此選項無效。

-s
--signoff
--no-signoff

在提交記錄訊息的結尾,由提交者新增一個 Signed-off-by 尾部。簽署的意義取決於您要提交的專案。例如,它可能證明提交者有權根據專案的授權提交工作,或同意某些貢獻者聲明,例如開發人員原產地證明。(請參閱 https://developercertificate.org,瞭解 Linux 核心和 Git 專案使用的證明。)請查閱您貢獻的專案的文件或領導層,以瞭解簽署在該專案中如何使用。

--no-signoff 選項可以用於反制命令列上較早的 --signoff 選項。

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

指定一個 (<token>、<value>) 對,應該將其作為尾部套用。(例如:git commit --trailer "Signed-off-by:C O Mitter \ <committer@example.com>" --trailer "Helped-by:C O Mitter \ <committer@example.com>" 會將 "Signed-off-by" 尾部和 "Helped-by" 尾部新增到提交訊息。)trailer.* 組態變數(git-interpret-trailers[1])可以用於定義是否省略重複的尾部、每個尾部在尾部執行順序中的顯示位置,以及其他詳細資訊。

-n
--[no-]verify

預設情況下,會執行 pre-commit 和 commit-msg 鉤子。當給定 --no-verify-n 其中之一時,會略過這些鉤子。另請參閱 githooks[5]

--allow-empty

通常,記錄一個與其唯一父提交具有完全相同樹的提交是一個錯誤,而此命令會阻止您進行這樣的提交。此選項會略過安全檢查,主要供外部 SCM 介面指令碼使用。

--allow-empty-message

--allow-empty 類似,此命令主要供外部 SCM 介面指令碼使用。它允許您建立具有空提交訊息的提交,而無需使用如 git-commit-tree[1] 的底層命令。

--cleanup=<模式>

此選項決定在提交之前,應該如何清理提供的提交訊息。<模式> 可以是 stripwhitespaceverbatimscissorsdefault

strip

移除開頭和結尾的空白行、結尾空白字元、註解並摺疊連續的空白行。

whitespace

strip 相同,只是不移除 #註解。

verbatim

完全不變更訊息。

scissors

whitespace 相同,只是如果訊息要編輯,則會從下方找到的行開始(包括該行)截斷所有內容。"#" 可以使用 core.commentChar 自訂。

# ------------------------ >8 ------------------------
default

如果要編輯訊息,則與 strip 相同。否則,與 whitespace 相同。

預設值可以使用 commit.cleanup 組態變數變更(請參閱 git-config[1])。

-e
--edit

從檔案使用 -F、從命令列使用 -m 以及從提交物件使用 -C 取得的訊息,通常會直接用作提交記錄訊息。此選項允許您進一步編輯從這些來源取得的訊息。

--no-edit

使用選取的提交訊息,而不啟動編輯器。例如,git commit --amend --no-edit 會修改提交,而不會變更其提交訊息。

--amend

透過建立新的提交來取代目前分支的頂端。記錄的樹會照常準備(包括 -i-o 選項以及明確路徑規格的影響),而且當沒有透過命令列選項(例如 -m-F-c 等)指定其他訊息時,會使用原始提交的訊息作為起點,而不是空訊息。新的提交與目前的提交具有相同的父項和作者(--reset-author 選項可以反制此設定)。

它大致等效於

	$ git reset --soft HEAD^
	$ ... do something else to come up with the right tree ...
	$ git commit -c ORIG_HEAD

但可以用於修改合併提交。

如果您修改了已經發佈的提交,您應該瞭解重寫歷史的影響。(請參閱 git-rebase[1] 中的「從上游重新設定基準復原」一節。)

--no-post-rewrite

略過 post-rewrite 鉤子。

-i
--include

在從目前已暫存的內容進行提交之前,也暫存命令列上給定的路徑的內容。除非您要結束衝突的合併,否則通常這不是您想要的操作。

-o
--only

透過採用命令列上指定的路徑的已更新工作樹內容來進行提交,而忽略已為其他路徑暫存的任何內容。如果命令列上給定了任何路徑,這是 git commit 的預設操作模式,在這種情況下,可以省略此選項。如果此選項與 --amend 一起指定,則不需要指定任何路徑,這可以用於修改最後一次提交,而無需提交已經暫存的變更。如果與 --allow-empty 一起使用,則也不需要路徑,並且會建立一個空的提交。

--pathspec-from-file=<檔案>

路徑規格會傳遞到 <檔案> 中,而不是命令列引數。如果 <檔案> 正好是 -,則會使用標準輸入。路徑規格元素會以 LF 或 CR/LF 分隔。路徑規格元素可以如同組態變數 core.quotePath 所說明的方式加上引號(請參閱 git-config[1])。另請參閱 --pathspec-file-nul 和全域 --literal-pathspecs

--pathspec-file-nul

僅對 --pathspec-from-file 有意義。路徑規格元素會以 NUL 字元分隔,且所有其他字元都會按字面意義採用(包括換行符號和引號)。

-u[<模式>]
--untracked-files[=<模式>]

顯示未追蹤的檔案。

模式參數是選用的(預設為 all),用於指定未追蹤檔案的處理方式;當未使用 -u 時,預設值為 normal,也就是顯示未追蹤的檔案和目錄。

可能的選項為

  • no - 不顯示未追蹤的檔案

  • normal - 顯示未追蹤的檔案和目錄

  • all - 也顯示未追蹤目錄中的個別檔案。

布林值 true 的所有常用拼寫都會被視為 normal,而 false 則會被視為 no。預設值可以使用 git-config[1] 中記載的 status.showUntrackedFiles 組態變數變更。

-v
--verbose

顯示 HEAD 提交與提交訊息範本底端將要提交的內容之間的統一差異,以幫助使用者描述提交內容,提醒使用者此提交有哪些變更。請注意,此差異輸出行的開頭沒有 #。此差異不會是提交訊息的一部分。請參閱 git-config[1] 中的 commit.verbose 組態變數。

如果指定兩次,則額外顯示將要提交的內容與工作樹檔案之間的統一差異,也就是追蹤檔案的未暫存變更。

-q
--quiet

抑制提交摘要訊息。

--dry-run

不建立提交,而是顯示要提交的路徑清單、將保持未提交的本地變更路徑,以及未追蹤的路徑。

--status

在使用編輯器準備提交訊息時,將 git-status[1] 的輸出包含在提交訊息範本中。預設為開啟,但可以用來覆寫組態變數 commit.status。

--no-status

在使用編輯器準備預設提交訊息時,不要將 git-status[1] 的輸出包含在提交訊息範本中。

-S[<keyid>]
--gpg-sign[=<keyid>]
--no-gpg-sign

使用 GPG 簽署提交。keyid 引數是選擇性的,預設為提交者身分;如果指定,則必須緊接在選項之後,中間沒有空格。--no-gpg-sign 可用來反制 commit.gpgSign 組態變數,以及先前的 --gpg-sign

--

不要將任何其他引數解譯為選項。

<pathspec>…​

當在命令列上給定 pathspec 時,提交符合 pathspec 的檔案內容,而不記錄已新增至索引的變更。這些檔案的內容也會為了下一次提交而暫存,且會加在先前已暫存的內容之上。

如需更多詳細資訊,請參閱 gitglossary[7] 中的 *pathspec* 條目。

範例

當記錄您自己的工作時,工作樹中修改的檔案內容會使用 git add 暫時儲存到名為「索引」的暫存區。可以使用 git restore --staged <file> 將檔案還原回最後一次提交時的狀態,僅在索引中還原,而不是在工作樹中,這會有效地還原 git add,並防止此檔案的變更參與下一次提交。使用這些命令逐步建立要提交的狀態後,可以使用 git commit (不帶任何路徑名稱參數) 來記錄目前已暫存的內容。這是命令最基本的形式。一個範例

$ edit hello.c
$ git rm goodbye.c
$ git add hello.c
$ git commit

您可以不用在每次個別變更後都暫存檔案,而是告知 git commit 注意工作樹中內容已追蹤的檔案變更,並為您執行對應的 git addgit rm。也就是說,如果工作樹中沒有其他變更,此範例會執行與先前範例相同的操作

$ edit hello.c
$ rm goodbye.c
$ git commit -a

git commit -a 命令會先查看您的工作樹,注意到您已修改 hello.c 並移除 goodbye.c,然後為您執行必要的 git addgit rm

在暫存許多檔案的變更後,您可以透過將路徑名稱提供給 git commit 來變更記錄變更的順序。當提供路徑名稱時,命令會建立一個提交,只會記錄對指定路徑所做的變更

$ edit hello.c hello.h
$ git add hello.c hello.h
$ edit Makefile
$ git commit Makefile

這會建立一個提交,記錄對 Makefile 的修改。為 hello.chello.h 暫存的變更不會包含在結果提交中。但是,它們的變更並未遺失,它們仍然會被暫存並暫時保留。在上述順序之後,如果您執行

$ git commit

第二個提交會如預期記錄對 hello.chello.h 的變更。

在合併 (由 git mergegit pull 起始) 因為衝突而停止後,已乾淨合併的路徑已暫存以供您提交,而發生衝突的路徑則保持在未合併狀態。您必須先使用 git status 檢查哪些路徑發生衝突,並在您的工作樹中手動修正後,像往常一樣使用 git add 暫存結果

$ git status | grep unmerged
unmerged: hello.c
$ edit hello.c
$ git add hello.c

在解決衝突並暫存結果後,git ls-files -u 將不再提及發生衝突的路徑。完成後,請執行 git commit 以最終記錄合併

$ git commit

與記錄您自己變更的情況相同,您可以使用 -a 選項來節省輸入。一個不同之處在於,在合併解決期間,您無法使用帶有路徑名稱的 git commit 來變更提交變更的順序,因為合併應該記錄為單一提交。事實上,當提供路徑名稱時,該命令會拒絕執行 (但請參閱 -i 選項)。

提交資訊

作者和提交者資訊取自下列環境變數 (如果已設定)

GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE

(注意:「<」、「>」和「\n」會被移除)

作者和提交者名稱依照慣例是某種形式的個人名稱 (也就是其他人類稱呼您的名稱),儘管 Git 不會強制或要求任何特定形式。可以使用任意 Unicode,但需遵守上述限制。此名稱對驗證沒有任何影響;如需相關資訊,請參閱 git-config[1] 中的 credential.username 變數。

如果 (部分) 這些環境變數未設定,則資訊取自組態項目 user.nameuser.email,或者,如果不存在,則取自環境變數 EMAIL,或者,如果未設定,則取自系統使用者名稱和用於寄出郵件的主機名稱 (取自 /etc/mailname,如果該檔案不存在,則會回復為完整的主機名稱)。

如果設定了 author.namecommitter.name 及其對應的電子郵件選項,它們會覆寫 user.nameuser.email,並且它們本身會被環境變數覆寫。

典型的用法是只設定 user.nameuser.email 變數;其他選項提供給更複雜的使用案例。

日期格式

GIT_AUTHOR_DATEGIT_COMMITTER_DATE 環境變數支援下列日期格式

Git 內部格式

它是 <unix-timestamp> <time-zone-offset>,其中 <unix-timestamp> 是自 UNIX 紀元以來的秒數。<time-zone-offset> 是與 UTC 的正或負時區偏移量。例如,CET (比 UTC 快 1 小時) 為 +0100

RFC 2822

RFC 2822 所述的標準日期格式,例如 Thu, 07 Apr 2005 22:13:13 +0200

ISO 8601

ISO 8601 標準指定的日期和時間,例如 2005-04-07T22:13:13。剖析器也接受空格來代替 T 字元。秒的分數部分將會被忽略,例如 2005-04-07T22:13:13.019 將會被視為 2005-04-07T22:13:13

注意
此外,日期部分接受下列格式:YYYY.MM.DDMM/DD/YYYYDD.MM.YYYY

除了辨識上述所有日期格式之外,--date 選項也會嘗試理解其他更人性化的日期格式,例如相對日期,像是「昨天」或「上週五中午」。

討論

雖然不是必要的,但最好在提交訊息的開頭使用一行簡短 (不超過 50 個字元) 的文字來總結變更,後面接著一個空白行,然後再加入更詳細的描述。提交訊息中第一個空白行之前的文字會被視為提交標題,而且該標題會用於整個 Git 中。例如,git-format-patch[1] 會將提交轉換為電子郵件,並且會在主旨行中使用標題,而在本文中使用提交的其餘部分。

Git 在某種程度上不考量字元編碼。

  • Blob 物件的內容是未解譯的位元組序列。在核心層級沒有編碼轉換。

  • 路徑名稱以 UTF-8 正規化形式 C 編碼。這適用於樹狀結構物件、索引檔案、ref 名稱,以及命令列引數、環境變數和組態檔案 (.git/config (請參閱 git-config[1])、gitignore[5]gitattributes[5]gitmodules[5]) 中的路徑名稱。

    請注意,在核心層級,Git 只是將路徑名稱視為非 NUL 位元組的序列,沒有路徑名稱編碼轉換 (Mac 和 Windows 除外)。因此,即使在使用舊版延伸 ASCII 編碼的平台和檔案系統上,使用非 ASCII 路徑名稱也大多可以正常運作。但是,在此類系統上建立的存放庫無法在以 UTF-8 為基礎的系統 (例如 Linux、Mac、Windows) 上正常運作,反之亦然。此外,許多以 Git 為基礎的工具都只是假設路徑名稱是 UTF-8,並且無法正確顯示其他編碼。

  • 提交記錄訊息通常以 UTF-8 編碼,但也支援其他延伸 ASCII 編碼。這包括 ISO-8859-x、CP125x 和許多其他編碼,但 *不* 包括 UTF-16/32、EBCDIC 和 CJK 多位元組編碼 (GBK、Shift-JIS、Big5、EUC-x、CP9xx 等)。

雖然我們鼓勵以 UTF-8 編碼提交記錄訊息,但核心和 Git Porcelain 的設計目的不是在專案上強制使用 UTF-8。如果特定專案的所有參與者發現使用舊版編碼更方便,Git 不會禁止這樣做。但是,有幾件事需要記住。

  1. 如果提供給 git commitgit commit-tree 的提交記錄訊息看起來不像有效的 UTF-8 字串,它們會發出警告,除非您明確聲明您的專案使用舊版編碼。宣告的方式是在 .git/config 檔案中加入 i18n.commitEncoding,如下所示

    [i18n]
    	commitEncoding = ISO-8859-1

    使用上述設定建立的提交物件會在它們的 encoding 標頭中記錄 i18n.commitEncoding 的值。這是為了幫助稍後查看它們的其他人員。缺少此標頭表示提交記錄訊息是以 UTF-8 編碼。

  2. git loggit showgit blame 和相關命令會查看提交物件的 encoding 標頭,並嘗試將記錄訊息重新編碼為 UTF-8,除非另有指定。您可以在 .git/config 檔案中使用 i18n.logOutputEncoding 指定所需的輸出編碼,如下所示

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果您沒有此組態變數,則會改用 i18n.commitEncoding 的值。

請注意,我們刻意選擇在建立提交時不重新編碼提交記錄訊息以強制在提交物件層級使用 UTF-8,因為重新編碼為 UTF-8 不一定是一個可逆的操作。

環境和組態變數

用於編輯提交記錄訊息的編輯器會依序從 GIT_EDITOR 環境變數、core.editor 組態變數、VISUAL 環境變數或 EDITOR 環境變數中選擇。如需詳細資訊,請參閱 git-var[1]

此章節中此行以上的所有內容都不會包含在 git-config[1] 文件中。接下來的內容與在那裡找到的內容相同

commit.cleanup

此設定會覆寫 git commit--cleanup 選項的預設值。詳情請參閱 git-commit[1]。當您總是想在日誌訊息中保留以註解字元 # 開頭的行時,變更預設值可能會很有用,在這種情況下,您可以執行 git config commit.cleanup whitespace (請注意,如果您這樣做,您必須自己移除提交日誌範本中以 # 開頭的說明行)。

commit.gpgSign

一個布林值,用於指定是否所有提交都應使用 GPG 簽署。在執行 rebase 等操作時使用此選項可能會導致大量提交被簽署。使用代理程式可能很方便,以避免多次輸入 GPG 密碼。

commit.status

一個布林值,用於在編輯器中準備提交訊息時,啟用/停用在提交訊息範本中包含狀態資訊。預設值為 true。

commit.template

指定一個檔案的路徑名稱,以用作新提交訊息的範本。

commit.verbose

一個布林值或整數,用於指定 git commit 的詳細程度。請參閱 git-commit[1]

HOOKS

此命令可以執行 commit-msgprepare-commit-msgpre-commitpost-commitpost-rewrite hooks。有關更多資訊,請參閱 githooks[5]

FILES

$GIT_DIR/COMMIT_EDITMSG

此檔案包含正在進行中的提交的提交訊息。如果 git commit 因為錯誤而退出,在建立提交之前,使用者提供的任何提交訊息(例如,在編輯器會話中)都將在此檔案中可用,但在下次調用 git commit 時將被覆寫。

GIT

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

scroll-to-top