git merge表示已经是最新的,但是有';这两个分支之间确实存在差异
我有两个分支:git merge表示已经是最新的,但是有';这两个分支之间确实存在差异,git,git-merge,Git,Git Merge,我有两个分支:master和developer。当develop中的更改最终确定后,它们将合并到master中 此时,应该同步分支。但是,我注意到,master中缺少一个文件,但它位于develope分支上。(它看起来像是被删除了,但是我使用git log--myfile.txt命令找不到任何证据 我试图将develope合并到master,但它说没有什么可以合并的 > git checkout master > git merge --no-ff develop Already u
master
和developer
。当develop
中的更改最终确定后,它们将合并到master
中
此时,应该同步分支。但是,我注意到,master
中缺少一个文件,但它位于develope
分支上。(它看起来像是被删除了,但是我使用git log--myfile.txt
命令找不到任何证据
我试图将develope
合并到master
,但它说没有什么可以合并的
> git checkout master
> git merge --no-ff develop
Already up-to-date
如何将
develope
分支中缺少的文件重新合并到master
分支中?您根本不合并此文件;相反,您只需从develope
分支中提取所需的文件,并将其提交到master
分支上。(我假设“缺少”文件)文件从未合并,可能是由于上次合并的人的错误,但可能是任何合并,也可能是故意的。)要从另一个分支提取文件,请在master
:
# run "git status" here to make sure you're on master
# and have no other changes you want to commit first!
git checkout develop -- path/to/file
因为这种签出“通过”索引写入,所以新文件现在处于暂存状态,并准备提交到分支主
讨论如下
合并实际上并不同步分支(更具体地说,它并不意味着它们将以任何方式具有相同的工作树).git merge所做的一切就是查看提交历史记录,看看应该合并哪些更改(如果有)。这意味着它必须找到最新的公共历史记录。让我们绘制一些提交图片段来说明这一点
git checkout master
获取一些特定的提交,然后:
git merge <sha1-or-other-identifier-like-develop>
合并基础是此处标记为*
的提交,并且*
之后的提交位于develope
标识的行上,但不在master
标识的行上,因此此序列需要合并
然而:
...-o-*-o-o-o <-- master
`---___
`---- develop
如果develope
是最近合并的,您就会看到这种情况:在master
上有一个合并提交,我已经标记了M
。合并基础仍然是commit*
;develope直接指向该提交,就像合并提交M
一样。因此,同样没有要合并的内容(由于合并提交M
,未在master
上提交的develope
)
如果(git认为)需要合并,git会将基础(*
提交)与当前分支上的最新提交(主的提示)区分开来,并将基础与您请求合并的提交(在本例中是开发
的提示)区分开来。然后(本质上)查看这两个差异,在第二个差异中进行第一个差异中尚未进行的任何更改,并将其应用于工作树
如果一切顺利,git通常会在此时进行合并提交(尽管您可以抑制它)。如果没有,它会以合并冲突停止,并让您自己解决问题,然后您自己进行“git提交”以提交合并
合并提交的工作树包括git自动解析的内容,以及在手动执行提交后所暂存的内容。一旦合并提交本身存在,提交图将使git认为不需要后续合并(例如,在develope
中添加更多提交之前)
如果(git认为)不需要合并,那么它当然不会做任何事情
最后两个插图:
...-*-----M1--M2 <-- master
\ / /
A-B-C-D <-- develop
在这种情况下,公共基础与以前一样是*
,但是diffing*
和o
可能产生了一些结果。diffing*
和B
显示了分支develop
上发生的情况。Git通过对o
的工作树应用第二组更改,将这两者结合起来,使合并为mmitM1
。M1
的工作树很可能与B
的工作树不同,因为它也包含在提交o
时发生的任何事情。但它可能是相同的,因为git“组合”了这些更改
具体来说,如果从o
到B
的差异包含与从*
到o
的差异相同的更改,M1的树将与B
的树匹配。如果不匹配,则不会匹配。也就是说,git只保留一个相同更改的副本。(“相同”在这里的意思是“尽git所能告诉的”:这不是特别聪明。如果一个改动是添加“闪亮的金属”,另一个改动是添加“闪亮的金属”,git认为这是不同的。)
在任何情况下,第二次合并都会重复这种模式:比较B
与M1
的工作树,以及B
与D
的工作树。无论在第二次合并中发现了哪些第一次合并中尚未包含的更改,都将这些更改应用于M1
的工作树,并使用结果生成M2
的工作树
...-o-o-o-M <-- master
\ /
o-* <-- develop
...-*-----M1--M2 <-- master
\ / /
A-B-C-D <-- develop
...-*-o---M1--M2 <-- master
\ / /
A-B-C-D <-- develop