簡體   English   中英

如何在Git中壓縮提交?

[英]How to squash commits in Git?

我正在嘗試壓縮提交並將分支合並到master中,成為一個提交。 這就是我正在嘗試的。 我切換到主分支,然后我做

git merge --squash <branch_name>

我得到

Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD

之后,我承諾。 但是,這就是我得到的

$ git commit -m "Resolved"
On branch master
nothing to commit, working tree clean

由於某些原因,更改未得到反映,並且我沒有收到任何要提交的消息。 我已經遍歷了很多帖子和問題,但到目前為止沒有任何幫助。

對我來說,還不是很清楚您正在壓榨什么提交內容,因此為什么要得到這個結果。 您可以清除了自己的第一個問題(它不會真正幫助很多,因為我沒有提交):

git log --decorate --oneline --graph --boundary master...<branch-name>

(請注意此處的三個點)。 這將顯示您現在在master上具有哪些提交,以及將通過這兩個分支的合並基礎提交從<branch-name>引入哪些提交。

不過無論如何,我可以做出一個很好的猜測,因為git merge工作方式是將合並基礎與兩個分支技巧進行比較。 這是進行合並之前的示例圖形片段(此時,這是常規合並還是南瓜合並都沒有關系):

...--B--C--D   <-- master (HEAD)
      \
       E--F--G   <-- feature

每個大寫字母代表一個提交(其真實ID是a9f3c72類的Git哈希ID)。 這里的合並基礎提交是提交B :它是同時從masterfeature開始並向后工作(在此圖的左側)的提交鏈。 提交B ,換句話說,是最新的承諾是在兩個分支master 分支feature 這就是使其成為合並基礎提交的原因。

現在,Git實際上將運行:

git diff B D   # see what "we" did on branch master
git diff B G   # see what "they" did on branch feature

然后,Git必須結合這些更改:如果我們更改了README以便在末尾添加一行,則Git應該將此多余的行添加到末尾。 如果他們以某種方式更改了foo.py (可能添加了一行並刪除了另一行),則Git應該將其更改更改為foo.py 但是,如果我們都做完全相同的事情 ,Git應該只取一份該更改的副本 例如,如果我們在master上對foo.py進行了相同的更改, foo.py我們根本不需要它們的更改:它已包含在我們的更改中。

假設我們更改了README並且我們和他們都在foo.py修復了相同的問題,但是他們也更改了doc.txtmain.py 因此,最后一組更改是將添加的行保留在README ,保留foo.py更改,並選擇doc.txtmain.py更改。 結果是Git將所有這些都應用於合並基礎提交B的內容。 這為我們提供了新提交H的內容。 (請注意H因為它可能會再次困擾我們。)Git將索引(下一次提交的位置)和工作樹(我們可以看到將要或將要提交的位置)更新到這個新位置內容,准備提交。

現在,常規與壁球合並突然變得很重要,因為如果Git要進行常規合並提交,它將執行以下操作:

...--B--C--D---H   <-- master (HEAD)
      \       /
       E--F--G   <-- feature

這個新的合並提交 H將提交CD完成的所有工作與提交EFG完成的所有工作組合在一起,將指向既是 master的前一個提交D ,又是提交到G的前一個仍是當前的G feature

但是,如果Git要進行壁球提交,那么它會在說出以下內容后停止:

Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD
$ 

它使我們做出承諾。 一旦我們做出這個承諾,我們得到了新的提交H ,但這次回指向兩個 D G 這次,新提交H 指向D

...--B--C--D---H   <-- master (HEAD)
      \
       E--F--G   <-- feature

假設這一切都按應有的方式進行 ,實際上我們確實進行了commit H 這引起了我認為最有可能發生的情況。

可能的情況

讓我們看看如果再次運行git merge --squash feature會發生什么。

通過找到合並基礎,Git與以前一樣開始:分支masterfeature連接的點。 再次提交B

現在,Git對比了兩個分支技巧。 這次, master的尖端是H ,所以兩個差異是:

git diff B H
git diff B G

現在,Git 結合了這些更改。 這次,我們更改了READMEfoo.pydoc.txtmain.py (請記住,這些都是我們說我們得到了通過合並的一切變化。)與此同時,他們(在feature )改變foo.py我們做同樣的方式,改變了doc.txt我們也做了同樣的方式,並改變main.py以同樣的方式我們做到了。

因此,Git承擔了我們所有的更改,而沒有任何更改。 結果與提交H完全匹配 Git現在停止並顯示與以前相同的消息。

這次,當我們運行時:

git commit

為了完成任務,Git將索引(我們為提交准備的階段)與HEAD提交進行比較,發現它們完全完全相同,完全相同。 我們已經擁有來自feature所有工作。 Git表示“沒有要提交的內容”和“工作樹清除的內容”,因為沒有要提交的內容,並且工作樹與索引匹配。

可能性較小

我們可以在這里獲得相同效果的另一種方法,而無需先執行壁球提交H ,就是如果提交系列EFG足以“撤消自身”而沒有關系。 例如,假設F是對foo.py的匹配更改(也許是提交C的副本),但是提交G是提交E的還原。 現在,而不是感人的doc.txtmain.py ,從變化的總和BG 包含在我們原來的B至- D的變化。 git merge --squash承諾要合並,但是對最終的源代碼樹也沒有影響。 我們的索引和工作樹將匹配提交Ggit commit根本不會產生新的提交H

在“提交差異”方面,這與以前的情況相同:任何更改(如果有的話)都會引入另一個分支,我們已經有了。 但是這次我們並沒有通過壁球合並得到它:反正我們已經有了它。

如果要壓縮提交,請轉到HEAD(last)提交,然后執行以下操作:

git reset --soft HEAD~2 && git commit

輸入此命令后,將要求您將提交消息寫入新的提交。
該命令將使用您編寫的新提交消息將最后兩個提交壓縮為一個。

然后合並你的分支它是如何描述在這里

暫無
暫無

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

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