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
的工作树应用第二组更改,将这两者结合起来,使合并为mmit
M1
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