我有两个分支:master和develop.当更改develop完成后,它们将合并到master.
此时,分支应该同步.但是,我注意到一个文件丢失了,master但是在develop分支上.(看起来它以某种方式被删除但我无法使用git log -- myfile.txt命令找到任何证据.
我试图合并develop,master但它说没有什么可以合并.
> git checkout master
> git merge --no-ff develop
Already up-to-date
Run Code Online (Sandbox Code Playgroud)
如何将我们develop分支中的一个丢失文件重新合并到我们的master分支中?
你根本不合并这个;相反,您只需从分支中提取所需的文件develop并将其提交到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
Run Code Online (Sandbox Code Playgroud)
因为这种签出“通过”索引写入,所以新文件现在已暂存并准备好提交到分支master。
下面讨论。
合并实际上并不同步分支(更具体地说,这并不意味着它们将具有相同的工作树,无论如何)。所有git merge要做的就是查看提交历史记录,看看应该合并哪些更改(如果有)。这意味着它必须找到最近的共同历史。让我们绘制一些提交图片段来说明这一点。
git checkout master
Run Code Online (Sandbox Code Playgroud)
选择一些特定的提交,然后:
git merge <sha1-or-other-identifier-like-develop>
Run Code Online (Sandbox Code Playgroud)
告诉 git 从识别的 SHA-1 开始并查看该分支最后“与”一起的位置master。这是“合并基础”的 SHA-1:
...-o-*-o-o-o <-- master
\
o-o <-- develop
Run Code Online (Sandbox Code Playgroud)
合并基础是*此处标记的提交,并且*在由 标识的行上有develop不在由 标识的行上的提交master,因此这个序列需要合并。
然而:
...-o-*-o-o-o <-- master
`---___
`---- develop
Run Code Online (Sandbox Code Playgroud)
在这里,develop直接指向提交*(再次是合并基础)。从那时起,就没有develop在下面找不到的提交了master。所以这是Already up-to-date。同样对于:
...-o-o-o-M <-- master
\ /
o-* <-- develop
Run Code Online (Sandbox Code Playgroud)
如果是最近合并的话,您会看到这种情况develop:在 上有一个合并提交master,我已将其标记为M。合并基础仍然是 commit *;开发直接指向该提交,合并提交也是如此M。因此,再次没有任何内容可以合并(没有develop尚未提交的提交master,由 merge-commit 提供M)。
如果(git认为)需要合并,git会将基础(*提交)与当前分支(的尖端master)上的最新提交进行比较,并将基础与您要求合并的提交进行比较(在此情况下,)的尖端develop。然后(实质上)它会查看两个差异,获取第二个差异中第一个差异中未包含的任何更改,并将它们应用到工作树中。
如果一切顺利,git 通常会在此时进行合并提交(尽管您可以抑制它)。如果没有,它会因合并冲突而停止,并让您自己解决问题,然后您自己执行“git commit”来提交合并。
合并提交的工作树由 git 自动解析的任何内容组成,加上您之后暂存的任何内容(如果您手动进行提交)。一旦合并提交本身存在,提交图将使得 git 认为不需要后续合并(develop例如,直到添加更多提交)。
如果(git 认为)不需要合并,它当然不会执行任何操作。
最后两张插图:
...-*-----M1--M2 <-- master
\ / /
A-B-C-D <-- develop
Run Code Online (Sandbox Code Playgroud)
这种模式是在执行两次git merge --no-ff developinto后出现的master,并且没有中间提交master:
第一次合并开始于*作为公共合并基础(M1并且M2还不存在),因此它发现了*和之间的更改B。之间没有任何更改*,因此合并很容易:git 将这些更改添加到*(提供与 中相同的工作树B)并进行合并提交M1。
第二次合并以提交B作为合并基础(M2尚不存在)开始。B所以它取了和之间的差异M1,即没有;B和之间的区别D,这是新的发展develop。然后,它将这些差异组合起来,将它们应用到树中M1,并进行新的合并提交M2。的树与M2的树相同D。
然而,这有点不同:
...-*-o---M1--M2 <-- master
\ / /
A-B-C-D <-- develop
Run Code Online (Sandbox Code Playgroud)
在这种情况下,共同基础与*以前一样,但有所不同*并且o可能产生了一些东西。比较*并B显示分支上发生的情况develop。Git 通过将第二组更改应用于 的工作树来组合这两者o,以进行合并提交M1。for 的工作树M1很可能与 for 的工作树不同B,因为它还包含提交时发生的任何事情o。但它可能是相同的,因为 git “组合”了这些更改。
o具体来说,如果从到的差异B 包含与从到 的差异相同的更改,则M1 的树将与 的树匹配。如果没有,就不会。也就是说,git 仅保留相同更改的一份副本。(“相同”在这里的意思是“据 git 所知”:它不是特别聪明。如果一个更改是添加“闪亮的金属”一词,另一个更改是添加“闪亮的金属”一词,git 认为这些是不同的。)*oB
无论如何,第二次合并都会重复该模式:比较BvsM1和Bvs的工作树D。无论第二个中发现第一个中尚未包含的更改,都将这些更改应用于 的工作树M1,并使用结果来创建 的工作树M2。
| 归档时间: |
|
| 查看次数: |
3255 次 |
| 最近记录: |