我对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