我對git
索引包含的內容有一個模糊的想法,其中一個是git-add
s和git-commit
s,但我不知道在執行git-merge
時這些內容會發生什麼。我特別有興趣瞭解合併失敗時(例如,由於某種衝突)索引所持有的內容。合併期間git索引的內容如何演變(合併失敗後索引內容是什麼)?
回答
對於任何給定的路徑,索引中最多有四個「版本號」,編號爲0(零)至3.我將它們稱爲「插槽」,就好像它們實際上存在於每個條目中一樣,然後容易索引(這使得它們更易於思考),但實際上只有在需要時纔會動態引入額外的版本。這些「虛擬插槽」可以是「空的」,這意味着該文件不存在。 (實際上,一旦在索引中創建了一個條目,如果需要,它將被標記爲CE_REMOVED
,這樣會變得毛茸茸,因爲整個目錄中充滿了文件可以標記爲「已刪除」,然後文件可以是我們只是假裝我們有固定的插槽,而不是空的,而是:-))
插槽#0是「正常的」,沒有衝突的,全部入圍。它包含一堆緩存數據,路徑名和存儲在存儲庫中的文件的blob-ID(SHA-1)。
當合併成功時,它都是「一切照舊」,所以唯一的特例是衝突合併。當插槽1,2和/或3不爲空時,合併是「衝突的」。跳過大部分機制,會發生什麼呢?合併使用所有插槽的「最新」名稱,並且:
- 插槽零爲空(您不能「提交」,直到您解決衝突,此時該插槽不會爲空除非你真的想要刪除文件)。
- 插槽1(「基本」)填充了共同的祖先版本。如果文件是新的(在兩個版本中),則此插槽爲空。
- 插槽2(「我們的」)填充目標(
HEAD
,除非您手動調用某些底層合併機器)版本。如果該文件在HEAD
/合併目標中被刪除,則此槽爲空。 - 插槽3(「他們」)充滿了正在合併的版本。如果文件在正在合併版本中被刪除,則此插槽爲空。
一旦你解決了衝突和「git add」,#0插槽被填充任何你「添加」,擦除#1到#3的條目 - 或者,如果你「git rm」衝突的文件,其他階段條目仍然被刪除,但現在#0插槽保持空白,這也解決了衝突。
更具體,那麼,假設你有一個有(其中包括)共同祖先的這兩個文件:
gronk
flibby
你分支cleanup
,你已經改名gronk
到breem
,都編輯那和flibby
。你決定git merge work
,他們修改gronk
但沒有重命名它,並刪除flibby
。一些其他文件乾淨地合併。
該指數將包含bleem
三個版本和flibby
兩個版本:
$ git checkout cleanup
Switched to branch 'cleanup'
$ git merge work
CONFLICT (modify/delete): flibby deleted in work and modified
in HEAD. Version HEAD of flibby left in tree.
Auto-merging bleem
CONFLICT (content): Merge conflict in bleem
Automatic merge failed; fix conflicts and then commit the result.
$ git ls-files --stage
100644 4362aba7f3b7abf2da0d0ed558cbf5bc0d12e4b0 1 bleem
100644 49db92a61392e9fd691c4af6e1221f408452a128 2 bleem
100644 04b399c8fe321902ce97a1538248878756678ca2 3 bleem
100644 366b52546711401122b791457793a38c033838dd 1 flibby
100644 6fecb1480f45faaabc31b18c91262d03d3767cde 2 flibby
100644 7129c6edb96d08bb44ca1025eb5ae41d41be8903 0 x.txt
你可以看到bleem
原始(基地)版本git show :1:bleem
。這在基礎版本中被稱爲gronk
(在這種情況下也是work
),但現在它被稱爲bleem
,因爲git認爲您已將gronk
更名爲bleem
,cleanup
。 (GIT發現合併基礎和HEAD
之間的重命名,然後應用同樣的命名規則,以work
如果必要的,因爲在這種情況下)。
同樣,你可以看到work
版本git show :3:bleem
或git show work:gronk
,並且HEAD
版本與以下任何一個:git show HEAD:bleem
,git show cleanup:bleem
或git show :2:bleem
(時隙2包含HEAD
又名cleanup
版本,並且根據HEAD
中的名稱命名)。
對於flibby
,雖然它在work
中被刪除,但沒有「他們」(插槽3)版本。
要解決衝突,您只需要告訴git add
或git rm
更新插槽零條目並刪除1至3條目。當然,對於git add
,到的插槽0是什麼在工作目錄現在,所以你通常必須先編輯文件。
順便提一下,我在上面標記了「我們」和「他們的」的插槽2和3。這也是git checkout
對待它們的原因(git checkout --ours
和git checkout --theirs
可讓您將第2版或第3版寫入第0號槽;與大多數結賬一樣,此結賬「擦除」其他槽,從而解決衝突)。然而,在一個rebase中,HEAD
分支實際上是分支正在重新分配,而「他們的」分支是分支重新分配。因此,我認爲我們的/他們的術語並不是那麼棒:在重新綁定期間很容易讓它倒退。
我還應該注意到,git checkout -m
如果您處於衝突合併的中間,將通過擦除插槽0和根據需要「復活」插槽1-3中的版本來「重新創建」合併衝突(並將衝突的合併文件寫入工作目錄,並遵守merge.conflictstyle
設置中的任何更改)。
這是一個非常好的答案。 –
- 1. 合併索引
- 2. 什麼是內容級別合併?
- 3. PANDAS將多個單元格的內容與索引合併
- 4. 合併內容
- 5. git:「致命:執行內部合併失敗」是什麼意思?
- 6. TYPO3索引搜索引擎 - 並非所有的頁面內容被索引
- 7. 索引搜索與合併
- 8. 爲什麼Lucene會合並索引?
- 9. WebDeploy:合併內容
- 10. 在最短時間內合併大小爲60GB和10GB的索引索引的最佳方法是什麼?
- 11. 合併內容,如果環
- 12. 索引內容在Wordpress中消失
- 13. Lucene中的合併索引
- 14. 在SOLR上合併(合併)索引,而不是DIH中的內部連接表
- 15. git,合併後不要這麼容易
- 16. 如何在相同索引下隨機混合列表內容
- 17. 如何閱讀Nutch索引的內容?
- 18. 如何查看Oracle索引的內容?
- 19. 如何索引pdf的內容與SolrJ?
- 20. 顯示mongodb索引內容
- 21. TYPO3爬蟲索引內容
- 22. 內容搜索引擎
- 23. pdf內容的索引和搜索
- 24. 如何通過索引選擇List <>並返回內容?
- 25. mysql索引合併問題
- 26. SQLAlchemy設置索引合併
- 27. 合併行基於索引
- 28. Zend Lucene索引合併
- 29. 如何防止內容索引從CelerySearchIndex
- 30. CONFLICT(內容):合併衝突
合併和rebase在某些點上是相似的。也許你可以通過'git rebase -i'來看看會發生什麼,並用'edit'替換所有的'pick',然後觀察.git修改 – Asenar
@Asenar:相似性的出現是因爲'rebase'是一系列'cherry-pick'內部操作,並且對於每個櫻桃選擇的提交,git使用合併機制來應用該提交所隱含的更改。 – torek
謝謝你的精度:) – Asenar