簡體   English   中英

git commit 和 git commit 有什么區別<file>和 git commit --only?

[英]what"s the difference between git commit <file> and git commit --only?

在此處輸入圖片說明

在此處輸入圖片說明

似乎這兩個選項的功能相同。

也許他們之間有我看不到的區別,因為我的英語閱讀能力很差。

你能告訴我真相嗎?

有三種使用git commit (無論如何都沒有--amend ):

  • git commit ,不命名任何文件:這意味着提交當前索引。

  • git commit --only file1 ... fileN ,您可以在其中命名一些文件使用--only選項。 稍后我們將對此進行描述。

  • git commit --include file1 ... fileN ,您可以在其中命名一些文件使用--include選項。 我們稍后也將對此進行描述。

如果您選擇列出一些非零數量的文件,但省略--only選項,Git采用--only選項。 如果你不希望--only選項,則必須指定--include選項。 如果你選擇在命令行中列出一些文件,你必須選擇這兩個選項之一,如果你選擇失敗,Git 會為你選擇。 所以--only僅僅是相反--include

索引及其在提交中的作用

要正確理解所有三種操作模式,您需要了解 Git 從索引構建提交。 通常它使用索引 這是上面列出的第一個模式: git commit ,沒有任何文件名,現在使用索引中的任何內容。

索引本身是一種有點隱藏的數據結構。 它有三個名稱,要么反映了它的重要性,要么反映了相當糟糕的初始名稱,即“索引”。 第二個名字是臨時區域,因為該指數的作用是充當可以在其中構建,或階段性-the下次提交你會做的地方。 這個東西的第三個名字——這個索引或暫存區——是緩存

索引開始時保存當前提交所有文件的副本,這些副本是在您運行git checkout branch時提取的。 這些文件從分支提示提交復制索引/暫存區,也復制到工作樹中,您可以在其中處理它們。 名稱索引來自於索引跟蹤工作樹的事實:它索引它。 (請參閱此處動詞定義。)

定期提交的工作原理

當你運行git commit在正常模式下,Git的封裝了所有索引右邊的文件,然后,一切都在提交簽出,與文件,您的文件git add -ed覆蓋從工作文件-樹。 這些文件成為新的快照。 Git 會寫出快照本身、您作為提交作者的姓名和電子郵件地址,以及您的其他元數據,例如您的日志消息。 它將新提交的父級設置為分支的前一個提示,然后將新提交的哈希 ID 寫入當前分支名稱,這樣新提交現在就是當前提交。

由於 Git 剛剛索引構建了新的提交,新的、當前的提交和索引匹配。 因此,通過修改工作樹文件並將它們復制到索引中,一切都為您可能進行的下一次提交做好了准備。

如何--only--include工作

要使用--include構建新提交,Git 本質上只是將文件添加到索引並提交。 1這非常簡單:看起來好像您運行了git add file1 ... fileN然后運行了git commit 新提交是從這個修改后的索引構建的,現在索引,因為它現在匹配新的當前提交。

然而,對於--only ,Git 有問題。 指數常規one-也很可能被修改,可能不再匹配當前提交。 因此,實際上 Git 所做的是將當前提交提取到臨時索引中,使用git add將工作樹文件復制到該臨時索引中,然后從臨時索引構建提交。 這部分並不復雜:新提交被從索引建成,它只是沒有索引 但是一旦完成,Git 又回到了問題上:真正的索引——你可能修改過的索引——與 Git 剛剛做出的新提交不匹配,並且可能與之前的提交不匹配。 它不匹配任何東西,這是一個大混亂。

在成功提交之后,此時 Git 所做的是將那些相同的文件復制到實際索引,以便索引中的file1 ... fileN更新以匹配您剛剛提交的內容。 同時,實際索引中的所有剩余文件仍然存在,但是它們在您運行git commit --only之前看起來是git commit --only

請注意,您在實際索引中仔細暫存的文件(例如,使用git add --patch既不匹配工作樹也不匹配舊的(不再是當前的)提交可能仍然是您暫存它們的方式。 但是,如果您其中一個文件命名--only文件之一,那么精心設計的版本現在就消失了! 由於提交后git add它已被替換為工作樹版本。 2


1 在內部,它更復雜:Git 仍然構建一個臨時索引,就像它為--only所做的--only 但是,如果提交成功,臨時索引將成為常規索引。 所以這比--only 請注意,這個“本質上”的短語掩蓋了許多錯誤:例如,如果文件對git是全新的,那么--include部分至少在某些版本的 Git 中會失敗,而直接git add會起作用。

這里至少一些,因為我剛剛在 Git 2.24.0 中測試了它,這是非常最新的,這可能意味着它在所有版本中都失敗了; 但這似乎是一個錯誤,因此它可能會在未來版本的 Git 中得到修復。 特別可怕的是,它只是默默地忽略新文件! 您可以獲得不包含您命名的文件的提交。 這似乎不僅是一個錯誤,而且是一個糟糕的錯誤。

2git commit --include ,這有一些粗糙的邊緣,尤其是在當前不在索引中的文件的情況下。 但是,至少在 Git 2.24 中的行為稍微好一些,因為 Git 會在此處生成錯誤消息,而不是默默地忽略該文件。

答案在您列出的文檔片段中:

--only

通過獲取命令行上指定路徑的更新工作樹內容進行提交,忽略已為其他路徑暫存的任何內容。 如果命令行上給出了任何路徑,則這是git commit的默認操作模式,在這種情況下,可以省略此選項。

當您在命令行中添加文件路徑時, --only不會向命令添加任何內容,並且您在問題中描述的第二個選項所描述的語義適用。

另一方面,正如--only的其余描述所解釋的那樣,如果它與--allow-empty --amend一起使用,則索引的內容(暫存文件)將被忽略。

git commit --amend通過添加當前暫存文件並更改其提交消息git commit --amend修改當前提交。 使用--only ,不會修改提交的內容(忽略暫存文件),只會更新提交消息。

我不清楚--only如何改變git commit --allow-empty的行為。

但是,-- --allow-empty在 Git 的日常工作中沒有任何用處。 添加它是為了幫助將其他 VCS-es 的存儲庫自動轉換為 Git。 Fe 當一個分支被創建時,Subversion 會創建一個從 Git 的角度來看是空的新提交。 --allow-empty允許git-svn在將 Subversion 存儲庫轉換為 Git 時創建這樣的空提交。

git commit -- 從給定文件中獲取提交消息。 在參數中,您應該輸入您想要從存儲庫中獲取的文件的名稱。

git commit --only 是 git commit 的默認操作模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM