[英]Are git branches squashed or replayed when merging?
給定具有母版和功能分支的存儲庫,並通過以下方式提交C0
至C5
:
C0 <-- C1 <-- C2 <------ ??? master
\ /
C3 <-- C4 <-- C5 feature
當我合並時, ???
點?
我是否得到一個提交C6
,即作為單個提交的合並的“壓扁”:
C0 <-- C1 <-- C2 <------ C6 master
\ /
C3 <-- C4 <-- C5 feature
或“重播”,即C6 <-- C3' <-- C4' <-- C5'
(帶有'
因為這些提交現在也包含C2
):
C0 <-- C1 <-- C2 <------ C6 <-- C3' <-- C4' <-- C5' master
\ /
C3 <-- C4 <-- C5 feature
合並來自同一倉庫的分支機構的盒裝標准拉取請求時,在GitHub上是否相同?
假設您使用不帶 --squash
選項的git merge
命令,則發生的情況是Git創建了一個C6
提交,稱為merge commit
,這類似於合並了它們的內容之后的跟蹤文件的快照 。 默認策略是遞歸,它通過考慮C5
和C1
之間以及C2
和C1
之間的變化進行合並。
由於這是合並提交,因此其父級將為C5
和C2
。
您可能會因為沒有考慮什么是提交而感到困惑:它們只是指向文件樹狀態的指針。 它們不存儲差異(為簡單起見,由gc進行跳過壓縮),而是存儲state 。 因此,Git會合並您的文件,保存它們,對它們進行哈希處理並創建一個哈希(表示一個樹對象),該哈希使我們能夠重建該狀態,這就是C6
提交將指向的狀態。 從內而外的Git在解釋整個過程方面做得非常出色。
另一方面,如果您使用了git merge --squash
,那么Git還會在合並后創建一個狀態為commit的提交,但是生成的提交就像沒有兩個父級的普通提交一樣。 請參閱Git:壓扁還是不壓扁? 欲獲得更多信息。
最后,此“重播”過程是通過rebase
完成的,而不是以您描述的方式進行的。 閱讀合並與衍合 ,看看如何merge
和rebase
不同。
您得到的既不是壓榨也不是提交的重播。
要獲得壁球,可以使用--squash
選項進行merge
。 那你就會
C0 <-- C1 <-- C2 <-- C3C4C5 master
\
C3 <-- C4 <-- C5 feature
其中C3C4C5
是一個提交的單親,其父級與C2
的差異等於C5
與C1
的差異(除非沖突)。
從分支重播更改,您可以執行重新基准操作。 這可能會產生
C0 <-- C1 <-- C2 <-- C3' <-- C4' <-- C5' master featurE_ref
\
C3 <-- C4 <-- C5 feature_ref_used_to_be_here
(或某些變化,具體取決於您的工作)。 在這種情況下,提交C3'
與C2
完全不同,就像C3
與C1
不同, C3
類推。
但是在合並的情況下,您不會獲得任何一個。 你得到
C0 <-- C1 <-- C2 <------ M master
\ /
C3 <-- C4 <-- C5 feature
“ M”是一次提交,但不同於壁球中的C3C4C5
, M
具有兩個父級。 它的TREE
(內容)與C2
不同,就像C5
的TREE
與C1
不同一樣,因此它類似於南瓜。 但通常將其解釋為不引入更改(除非合並沖突或惡意合並); 相反,這標志着此時C5
及其祖先的更改已引入到master
中。 因此,默認情況下, git log
不顯示M
的補丁,但包含提交C3
, C4
和C5
您不會兩者都...直接。
首先,git中的合並是這樣工作的:
C1
C2
和C5
作為公共父級 git merge --squash
可以壓扁( git merge --squash
)。 這是一個很好的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.