# git-commit
> 原文: [https://git-scm.com/docs/git-commit](https://git-scm.com/docs/git-commit)
## 名稱
git-commit - 記錄對存儲庫的更改
## 概要
```
git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
[--dry-run] [(-c | -C | --fixup | --squash) <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] [-S[<keyid>]] [--] [<file>…?]
```
## 描述
創建一個新的提交,其中包含索引的當前內容和描述更改的給定日志消息。新提交是HEAD的直接子代,通常是當前分支的尖端,并且分支被更新為指向它(除非沒有分支與工作樹相關聯,在這種情況下HEAD是“分離的”,如 [git-checkout [1]](https://git-scm.com/docs/git-checkout) )。
要提交的內容可以通過以下幾種方式指定:
1. 通過使用 [git-add [1]](https://git-scm.com/docs/git-add) 在使用 _commit_ 命令之前逐步“添加”對索引的更改(注意:甚至修改后的文件必須“添加”);
2. 通過使用 [git-rm [1]](https://git-scm.com/docs/git-rm) 從工作樹和索引中刪除文件,再次使用 _commit_ 命令之前;
3. 通過將文件列為 _commit_ 命令的參數(沒有--interactive或--patch switch),在這種情況下,提交將忽略索引中暫存的更改,而是記錄列出的文件的當前內容(必須已經為Git所知);
4. 通過使用-a開關和 _commit_ 命令自動“添加”來自所有已知文件的更改(即已在索引中列出的所有文件)并自動“rm”索引中的文件已從工作樹中刪除,然后執行實際提交;
5. 通過使用--interactive或--patch開關和 _commit_ 命令,在完成操作之前,逐個確定哪些文件或數據庫應該是提交的一部分,以及索引中的內容。請參閱 [git-add [1]](https://git-scm.com/docs/git-add) 的“交互模式”部分,了解如何操作這些模式。
`--dry-run`選項可用于通過提供相同的參數集(選項和路徑)來獲取上述任何內容對下一次提交所包含內容的摘要。
如果你提交然后在那之后立即發現錯誤,你可以使用 _git reset_ 從中恢復。
## OPTIONS
```
-a
```
```
--all
```
告訴命令自動暫存已修改和刪除的文件,但是沒有告訴Git的新文件不會受到影響。
```
-p
```
```
--patch
```
使用交互式修補程序選擇界面選擇要提交的更改。有關詳細信息,請參閱 [git-add [1]](https://git-scm.com/docs/git-add) 。
```
-C <commit>
```
```
--reuse-message=<commit>
```
獲取現有提交對象,并在創建提交時重用日志消息和作者信息(包括時間戳)。
```
-c <commit>
```
```
--reedit-message=<commit>
```
與 _-C_ 類似,但是使用`-c`調用編輯器,以便用戶可以進一步編輯提交消息。
```
--fixup=<commit>
```
構造一個與`rebase --autosquash`一起使用的提交消息。提交消息將是指定提交的主題行,前綴為“fixup!”。有關詳細信息,請參閱 [git-rebase [1]](https://git-scm.com/docs/git-rebase) 。
```
--squash=<commit>
```
構造一個與`rebase --autosquash`一起使用的提交消息。提交消息主題行取自指定的提交,前綴為“squash!”。可與其他提交消息選項一起使用(`-m` / `-c` / `-C` / `-F`)。有關詳細信息,請參閱 [git-rebase [1]](https://git-scm.com/docs/git-rebase) 。
```
--reset-author
```
當與-C / -c / - 修改選項一起使用時,或者在沖突的挑選之后提交時,聲明生成的提交的作者現在屬于提交者。這也更新了作者的時間戳。
```
--short
```
進行干運行時,請以短格式輸出。有關詳細信息,請參閱 [git-status [1]](https://git-scm.com/docs/git-status) 。意味著`--dry-run`。
```
--branch
```
即使是短格式顯示分支和跟蹤信息。
```
--porcelain
```
進行干運行時,請以瓷質格式輸出。有關詳細信息,請參閱 [git-status [1]](https://git-scm.com/docs/git-status) 。意味著`--dry-run`。
```
--long
```
進行干運行時,請以長格式輸出。意味著`--dry-run`。
```
-z
```
```
--null
```
顯示`short`或`porcelain`狀態輸出時,逐字打印文件名并使用NUL而不是LF終止輸入。如果沒有給出格式,則表示`--porcelain`輸出格式。如果沒有`-z`選項,則會按照配置變量`core.quotePath`的說明引用帶有“異常”字符的文件名(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
```
-F <file>
```
```
--file=<file>
```
從給定文件中獲取提交消息。使用 _-_ 從標準輸入讀取信息。
```
--author=<author>
```
覆蓋提交作者。使用標準`A U Thor <author@example.com>`格式指定顯式作者。否則< author>假定是一種模式,用于搜索該作者的現有提交(即rev-list --all -i --author =< author>);然后從找到的第一個這樣的提交中復制提交作者。
```
--date=<date>
```
覆蓋提交中使用的作者日期。
```
-m <msg>
```
```
--message=<msg>
```
使用給定的< msg>作為提交消息。如果給出了多個`-m`選項,則它們的值將作為單獨的段落連接在一起。
`-m`選項與`-c`,`-C`和`-F`互斥。
```
-t <file>
```
```
--template=<file>
```
編輯提交消息時,使用給定文件中的內容啟動編輯器。 `commit.template`配置變量通常用于向命令隱式提供此選項。希望引導參與者提供有關在消息中以什么順序寫入內容的一些提示的項目可以使用此機制。如果用戶在不編輯消息的情況下退出編輯器,則中止提交。當通過其他方式給出消息時,例如,這沒有效果。使用`-m`或`-F`選項。
```
-s
```
```
--signoff
```
在提交日志消息的末尾由提交者添加逐行簽名。簽收的含義取決于項目,但它通常證明提交者有權在同一許可下提交此作品并同意開發者原產地證書(參見 [http://developercertificate.org/](http://developercertificate.org/) ] 欲獲得更多信息)。
```
-n
```
```
--no-verify
```
此選項繞過pre-commit和commit-msg掛鉤。另見 [githooks [5]](https://git-scm.com/docs/githooks) 。
```
--allow-empty
```
通常記錄與其唯一父提交具有完全相同的樹的提交是錯誤的,并且該命令阻止您進行此類提交。此選項繞過安全性,主要供外部SCM接口腳本使用。
```
--allow-empty-message
```
與--allow-empty類似,此命令主要供外部SCM接口腳本使用。它允許您使用空提交消息創建提交,而不使用 [git-commit-tree [1]](https://git-scm.com/docs/git-commit-tree) 等管道命令。
```
--cleanup=<mode>
```
此選項確定在提交之前應如何清除提供的提交消息。 _< mode>_ 可以是`strip`,`whitespace`,`verbatim`,`scissors`或`default`。
```
strip
```
剝去前導和尾隨空行,尾隨空格,注釋和折疊連續的空行。
```
whitespace
```
與`strip`相同,但不刪除#commentary。
```
verbatim
```
根本不要更改消息。
```
scissors
```
與`whitespace`相同,但是如果要編輯消息,則截斷下面找到的行的所有內容(包括)都將被截斷。 “`#`”可以使用core.commentChar進行自定義。
```
# ------------------------ >8 ------------------------
```
```
default
```
如果要編輯消息,則與`strip`相同。否則`whitespace`。
可以通過`commit.cleanup`配置變量更改默認值(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
```
-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]](https://git-scm.com/docs/git-rebase) 中的“從上游重新恢復”部分。)
```
--no-post-rewrite
```
繞過重寫后的鉤子。
```
-i
```
```
--include
```
在到目前為止提交暫存內容之前,還要在命令行上分配路徑的內容。這通常不是您想要的,除非您得出沖突的合并。
```
-o
```
```
--only
```
通過獲取命令行上指定的路徑的更新工作樹內容進行提交,忽略已為其他路徑暫存的任何內容。如果在命令行上給出了任何路徑,這是 _git commit_ 的默認操作模式,在這種情況下,可以省略此選項。如果此選項與`--amend`一起指定,則不需要指定任何路徑,這可以用于修改最后一次提交而不提交已經暫存的更改。如果與`--allow-empty`一起使用,則也不需要路徑,并且將創建空提交。
```
-u[<mode>]
```
```
--untracked-files[=<mode>]
```
顯示未跟蹤的文件。
mode參數是可選的(默認為 _all_ ),用于指定未跟蹤文件的處理;當-u未使用時,默認為_正常_,即顯示未跟蹤的文件和目錄。
可能的選擇是:
* _沒有_ - 顯示沒有未跟蹤的文件
* _正常_ - 顯示未跟蹤的文件和目錄
* _全部_ - 還顯示未跟蹤目錄中的單個文件。
可以使用 [git-config [1]](https://git-scm.com/docs/git-config) 中記錄的status.showUntrackedFiles配置變量更改默認值。
```
-v
```
```
--verbose
```
顯示HEAD提交與提交消息模板底部提交的內容之間的統一差異,以幫助用戶通過提醒提交的更改來描述提交。請注意,此diff輸出的行前綴不是_#_。此差異不會是提交消息的一部分。請參見 [git-config [1]](https://git-scm.com/docs/git-config) 中的`commit.verbose`配置變量。
如果指定了兩次,則另外顯示將提交的內容與worktree文件之間的統一差異,即對跟蹤文件的未分級更改。
```
-q
```
```
--quiet
```
禁止提交摘要消息。
```
--dry-run
```
不要創建提交,而是顯示要提交的路徑列表,具有未提交的本地更改的路徑以及未跟蹤的路徑。
```
--status
```
使用編輯器準備提交消息時,在提交消息模板中包含 [git-status [1]](https://git-scm.com/docs/git-status) 的輸出。默認為on,但可用于覆蓋配置變量commit.status。
```
--no-status
```
使用編輯器準備默認提交消息時,請勿在提交消息模板中包含 [git-status [1]](https://git-scm.com/docs/git-status) 的輸出。
```
-S[<keyid>]
```
```
--gpg-sign[=<keyid>]
```
GPG簽名提交。 `keyid`參數是可選的,默認為提交者標識;如果指定,它必須粘在沒有空格的選項上。
```
--no-gpg-sign
```
Countermand `commit.gpgSign`配置變量,設置為強制每個提交都被簽名。
```
--
```
不要將任何更多的參數解釋為選項。
```
<file>…?
```
在命令行上提供文件時,該命令將提交指定文件的內容,而不記錄已暫存的更改。這些文件的內容也會在之前的演出之上進行下一次提交。
## 日期格式
`GIT_AUTHOR_DATE`,`GIT_COMMITTER_DATE`環境變量和`--date`選項支持以下日期格式:
```
Git internal format
```
它是`<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`字符。
| 注意 | 此外,日期部分以下列格式接受:`YYYY.MM.DD`,`MM/DD/YYYY`和`DD.MM.YYYY`。 |
## 例子
錄制自己的作品時,工作樹中已修改文件的內容會暫時存儲到名為“索引”的暫存區域,并帶有 _git add_ 。一個文件只能在索引中但不能在工作樹中恢復為使用`git reset HEAD -- <file>`的最后一次提交的文件,這會有效地恢復 _git add_ 并阻止對該文件的更改參與下一次提交。在使用這些命令逐步構建要提交的狀態之后,`git commit`(沒有任何路徑名參數)用于記錄到目前為止已經暫存的內容。這是命令的最基本形式。一個例子:
```
$ edit hello.c
$ git rm goodbye.c
$ git add hello.c
$ git commit
```
您可以告訴`git commit`注意在工作樹中跟蹤其內容的文件的更改,并為您執行相應的`git add`和`git rm`,而不是在每次更改后暫存文件。也就是說,如果您的工作樹中沒有其他更改,則此示例與前面的示例相同:
```
$ edit hello.c
$ rm goodbye.c
$ git commit -a
```
命令`git commit -a`首先查看您的工作樹,注意您已修改了hello.c并刪除了goodbye.c,并為您執行必要的`git add`和`git rm`。
在對多個文件進行暫存更改后,您可以通過為`git commit`提供路徑名來更改記錄更改的順序。給出路徑名時,該命令進行提交,僅記錄對命名路徑所做的更改:
```
$ edit hello.c hello.h
$ git add hello.c hello.h
$ edit Makefile
$ git commit Makefile
```
這使得提交記錄了對`Makefile`的修改。 `hello.c`和`hello.h`暫掛的更改不包含在生成的提交中。然而,他們的變化并沒有丟失 - 他們仍然上演并且只是被阻止。完成上述步驟后,如果您這樣做:
```
$ git commit
```
第二次提交將按預期記錄對`hello.c`和`hello.h`的更改。
合并后(由 _git merge_ 或 _git 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`選項)。
## 討論
雖然不是必需的,但最好使用一個簡短(小于50個字符)的行來概括更改,然后是空白行,然后是更詳盡的描述。提交消息中第一個空白行的文本被視為提交標題,并且該標題在整個Git中使用。例如, [git-format-patch [1]](https://git-scm.com/docs/git-format-patch) 將提交轉換為電子郵件,它使用主題行上的標題和正文中的其余提交。
Git在某種程度上是字符編碼不可知的。
* blob對象的內容是未解釋的字節序列。核心級別沒有編碼轉換。
* 路徑名以UTF-8規范化形式C編碼。這適用于樹對象,索引文件,ref名稱,以及命令行參數,環境變量和配置文件中的路徑名(`.git/config`(參見 [git) -config [1]](https://git-scm.com/docs/git-config) ), [gitignore [5]](https://git-scm.com/docs/gitignore) , [gitattributes [5]](https://git-scm.com/docs/gitattributes) 和 [gitmodules [5]](https://git-scm.com/docs/gitmodules) )。
請注意,核心級別的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瓷器都不是為了強制項目使用UTF-8。如果特定項目的所有參與者發現使用遺留編碼更方便,Git不會禁止它。但是,有一些事情需要牢記。
1. _git commit_ 和 _git commit-tree_ 發出警告,如果提供給它的提交日志消息看起來不像有效的UTF-8字符串,除非你明確說你的項目使用了遺產編碼。說這個的方法是在`.git/config`文件中使用i18n.commitencoding,如下所示:
```
[i18n]
commitEncoding = ISO-8859-1
```
使用上述設置創建的提交對象在其`encoding`標題中記錄`i18n.commitEncoding`的值。這是為了幫助其他人以后再看。缺少此標頭意味著提交日志消息以UTF-8編碼。
2. _git log_ , _git show_ , _git 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]](https://git-scm.com/docs/git-var) 。
## 掛鉤
該命令可以運行`commit-msg`,`prepare-commit-msg`,`pre-commit`,`post-commit`和`post-rewrite`掛鉤。有關詳細信息,請參閱 [githooks [5]](https://git-scm.com/docs/githooks) 。
## FILES
```
$GIT_DIR/COMMIT_EDITMSG
```
此文件包含正在進行的提交的提交消息。如果在創建提交之前由于錯誤而退出`git commit`,則用戶提供的任何提交消息(例如,在編輯器會話中)將在此文件中可用,但將在下一次調用[COD1時]覆蓋]。
## 也可以看看
[git-add [1]](https://git-scm.com/docs/git-add) , [git-rm [1]](https://git-scm.com/docs/git-rm) , [git-mv [1]](https://git-scm.com/docs/git-mv) , [git-merge [1]](https://git-scm.com/docs/git-merge) , [git-commit-tree [1]](https://git-scm.com/docs/git-commit-tree)
## GIT
部分 [git [1]](https://git-scm.com/docs/git) 套件
- git
- git-config
- git-help
- git-init
- git-clone
- git-add
- git-status
- git-diff
- git-commit
- git-reset
- git-rm
- git-mv
- git-branch
- git-checkout
- git-merge
- git-mergetool
- git-log
- git-stash
- git-tag
- git-worktree
- git-fetch
- git-pull
- git-push
- git-remote
- git-submodule
- git-show
- git-log
- git-shortlog
- git-describe
- git-apply
- git-cherry-pick
- git-rebase
- git-revert
- git-bisect
- git-blame
- git-grep
- gitattributes
- giteveryday
- gitglossary
- githooks
- gitignore
- gitmodules
- gitrevisions
- gittutorial
- gitworkflows
- git-am
- git-format-patch
- git-send-email
- git-request-pull
- git-svn
- git-fast-import
- git-clean
- git-gc
- git-fsck
- git-reflog
- git-filter-branch
- git-instaweb
- git-archive
- git-bundle
- git-daemon
- git-update-server-info
- git-cat-file
- git-check-ignore
- git-checkout-index
- git-commit-tree
- git-count-objects
- git-diff-index
- git-for-each-ref
- git-hash-object
- git-ls-files
- git-merge-base
- git-read-tree
- git-rev-list
- git-rev-parse
- git-show-ref
- git-symbolic-ref
- git-update-index
- git-update-ref
- git-verify-pack
- git-write-tree