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

名稱

git-commit - 記錄對倉庫的變更

概要

git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]
	   [--dry-run] <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. 透過在 commit 命令中使用 -a 開關,自動“新增”所有已知檔案(即索引中已列出的所有檔案)的變更,並自動“移除”已從工作樹中刪除的檔案,然後執行實際的提交;

  5. 透過在 commit 命令中使用 --interactive--patch 開關,在最終操作之前,逐一決定哪些檔案或塊應作為提交的一部分,除了索引中的內容。有關如何操作這些模式的詳細資訊,請參閱 git-add[1] 的“互動模式”部分。

可以使用 --dry-run 選項,透過提供相同的引數集(選項和路徑),獲取下次提交將包含哪些內容的摘要。

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

選項

-a
--all

自動暫存已修改和刪除的檔案,但不影響未告知 Git 的新檔案。

-p
--patch

使用互動式補丁選擇介面來選擇要提交的變更。詳見 git-add[1]

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

使用現有 <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!”提交中修改後的日誌訊息替換。如果“amend!”提交的日誌訊息為空,除非指定了 --allow-empty-message,否則會報錯。

--fixup=reword:<commit>--fixup=amend:<commit> --only 的簡寫。它建立一個只有日誌訊息的“amend!”提交(忽略索引中任何已暫存的變更)。當被 git rebase --autosquash 壓縮時,它會替換 <commit> 的日誌訊息而不會進行任何其他變更。

“fixup!”和“amend!”提交在被 git rebase --autosquash 應用時都不會改變 <commit> 的作者資訊。詳見 git-rebase[1]

--squash=<commit>

構造用於 git rebase --autosquash 的提交訊息。提交訊息標題取自指定提交,並加上字首“squash! ”。可與額外提交訊息選項(-m/-c/-C/-F)一起使用。詳見 git-rebase[1]

--reset-author

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

--short

在試執行時,以短格式輸出。詳見 git-status[1]。隱含 --dry-run

--branch

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

--porcelain

在試執行時,以“瓷器”友好格式輸出。詳見 git-status[1]。隱含 --dry-run

--long

在試執行時,以長格式輸出。隱含 --dry-run

-z
--null

顯示 shortporcelain 狀態輸出時,按字面列印檔名並以 NUL 終止條目,而不是 LF。如果未給出格式,則隱含 --porcelain 輸出格式。如果沒有 -z 選項,帶有“不尋常”字元的檔名將按照配置變數 core.quotePath 的說明進行引用(參見 git-config[1])。

-F <file>
--file=<file>

<file> 中讀取提交訊息。使用 - 從標準輸入讀取訊息。

--author=<author>

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

--date=<date>

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

-m <msg>
--message=<msg>

使用 <msg> 作為提交訊息。如果給出了多個 -m 選項,它們的值將作為單獨的段落連線。

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

-t <file>
--template=<file>

編輯提交訊息時,使用 <file> 中的內容啟動編輯器。commit.template 配置變數通常用於隱式地向命令提供此選項。此機制可用於希望指導參與者如何按順序編寫訊息的專案。如果使用者在未編輯訊息的情況下退出編輯器,則提交將被中止。當透過其他方式提供訊息時,例如透過 -m-F 選項,此功能無效。

-s
--signoff
--no-signoff

在提交日誌訊息末尾新增提交者的 Signed-off-by 尾部資訊。簽名的含義取決於您提交的專案。例如,它可能證明提交者有權根據專案許可證提交作品,或同意某些貢獻者宣告,如開發者原創證書。(有關 Linux 核心和 Git 專案使用的證書,請參閱 https://developercertificate.org)。請查閱您所貢獻專案的文件或領導層,以瞭解該專案中如何使用簽名。

可以使用 --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-commitcommit-msg 鉤子。另見 githooks[5]

--allow-empty

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

--allow-empty-message

建立一個空提交訊息的提交,而無需使用 git-commit-tree[1] 等底層命令。與 --allow-empty 類似,此命令主要用於外部 SCM 介面指令碼。

--cleanup=<mode>

確定在提交之前如何清理提供的提交訊息。<mode> 可以是 stripwhitespaceverbatimscissorsdefault

strip

去除開頭和結尾的空行、尾隨空格、註釋併合並連續的空行。

whitespace

strip 相同,但 #註釋不被移除。

verbatim

完全不改變訊息。

scissors

whitespace 相同,但如果訊息要被編輯,則從(包括)以下行開始的所有內容都被截斷。“#”可以透過 core.commentChar 自定義。

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

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

預設值可以透過 commit.cleanup 配置變數更改(參見 git-config[1])。

-e
--edit

允許使用者進一步編輯從 <file> 處透過 -F <file> 獲取的訊息,從命令列透過 -m <message> 獲取的訊息,以及從 <commit> 處透過 -C <commit> 獲取的訊息。

--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] 中的“從上游 rebase 恢復”一節。)

--no-post-rewrite

繞過 post-rewrite 鉤子。

-i
--include

在從已暫存內容建立提交之前,也暫存命令列上給定的路徑內容。這通常不是您想要的,除非您正在結束一個衝突的合併。

-o
--only

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

--pathspec-from-file=<file>

<file> 中傳遞路徑規範,而不是命令列引數。如果 <file> 恰好是 -,則使用標準輸入。路徑規範元素由 LFCR/LF 分隔。路徑規範元素可以按照配置變數 core.quotePath 的說明進行引用(參見 git-config[1])。另見 --pathspec-file-nul 和全域性 --literal-pathspecs

--pathspec-file-nul

僅在使用 --pathspec-from-file 時有意義。路徑規範元素用 NUL 字元分隔,所有其他字元都按字面解釋(包括換行符和引號)。

-u[<mode>]
--untracked-files[=<mode>]

顯示未跟蹤檔案。

<mode> 引數是可選的(預設為 all),用於指定未跟蹤檔案的處理方式;當不使用 -u 時,預設值為 normal,即顯示未跟蹤檔案和目錄。

可能的選項有

no

不顯示未跟蹤檔案

normal

顯示未跟蹤檔案和目錄

all

也顯示未跟蹤目錄中的單個檔案。

所有通常表示布林值 true 的拼寫都被視為 normalfalse 被視為 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[<key-id>]
--gpg-sign[=<key-id>]
--no-gpg-sign

使用 GPG 簽名提交。<key-id> 是可選的,預設為提交者身份;如果指定,它必須緊跟在選項後,不能有空格。--no-gpg-sign 對於抵消 commit.gpgSign 配置變數和之前指定的 --gpg-sign 都很有用。

--

不再將任何後續引數解釋為選項。

<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 編碼。這適用於樹物件、索引檔案、引用名稱,以及命令列引數、環境變數和配置檔案(.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 選項的預設值。當您總是希望在日誌訊息中保留以註釋字元(core.commentChar,預設為 #)開頭的行時,更改預設值會很有用,在這種情況下,您可以執行 git config commit.cleanup whitespace(請注意,如果您這樣做,您將必須自己刪除提交日誌模板中以註釋字元開頭的幫助行)。

commit.gpgSign

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

commit.status

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

commit.template

指定一個檔案路徑,用作新提交訊息的模板。

commit.verbose

一個布林值或整數,用於指定 git commit 的詳細程度。

鉤子

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

檔案

$GIT_DIR/COMMIT_EDITMSG

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

GIT

Git[1] 套件的一部分

scroll-to-top