我不喜欢用3路方式从两个分支创建文件的合并版本,但是我不知道如何。
答案 0 :(得分:1)
创建一个新分支
git branch new_branch
git checkout new_branch
git merge old_branch1
git merge old_branch2
new_branch现在包含合并的版本,而old_branch1和old_branch2包含以前的版本。
答案 1 :(得分:1)
在当前分支中,创建一个新分支:
<div class="card-white">
<div class="footer">
<ul>
<li>
<a href="https://www.facebook.com/alexandre.auriol/" target="_blank"><i class="fab fa-facebook-square"></i>Facebook</a>
</li>
<li>
<a href="https://www.instagram.com/alexandre.auriol/" target="_blank"><i class="fab fa-instagram"></i>Instagram</a>
</li>
</ul>
</div>
</div>
之后,与另一个分支合并:
git checkout -b new_branch
答案 2 :(得分:0)
请记住,合并是关于合并工作。我认为,例如,如果您认为合并是有帮助的,
Alice对她的文件做了一些工作,而Bob对他的文件做了一些工作,现在Alice,Bob甚至是第三人Carol想要将这两个结合起来工作范围。
Git通常一次处理整个 commits ,而不处理单个文件。如果运行git merge
,则将合并 commits ,而不是 files 。也就是说,您可以git checkout
进行Alice的最新提交,然后运行git merge Bob
,Git会找到Alice和Bob的起始位置,查看他们对所有文件进行了什么处理,然后合并全部。
如果您确实想对仅一个文件进行三向合并,则需要获取该文件的三个版本。毕竟,这就是三向合并的含义:每个要合并的文件都获得三个版本,然后使用这三个输入版本得出最终的合并版本。
文件级合并操作的三个输入是:
文件的--ours
版本。如果您要git checkout Alice
(进入Alice分支),那将是Alice的最新消息。
文件的--theirs
版本。如果您要运行git merge Bob
(从Bob的分支合并),那将是Bob的最新消息。
文件的合并基础版本。那是Alice和Bob都开始使用的文件的版本。这是困难的部分:爱丽丝和鲍勃都从哪个版本的文件 did 开始?
查找合并基础,并让该合并基础用于所有文件,而不只是一个,git merge
会为您服务。当您运行git merge
时,Git使用历史记录(存储库中的提交)来找到合并基础 commit ,即两个分支上共享最好的提交。如果我们记得每次提交都会自动记住自己的父母,那么我们可以看到它是如何工作的:
o--o--A <-- alice
/
...--o--o--*
\
o--o--B <-- bob
Alice和Bob都从提交*
开始。此后,爱丽丝在 her 分支上进行了3次提交,鲍勃在 his 上进行了3次提交。我在这里将Alice的最新标签为提交A
,将Bob的最新标签为提交B
,尽管这两个标签(当然也包括提交*
)都具有一些难看的哈希ID作为他们的真实姓名。
提交*
在两个分支上,并且由于它是共享提交,并且提交是 all 文件,很明显,当时Alice和Bob在每个文件中都有相同的内容。因此,git merge
命令将从提交*
中获取每个文件,并将每个此类文件与提交A
中的每个文件进行比较。无论这里发生了什么变化,爱丽丝都发生了变化。然后,Git将比较*
中的每个文件与提交B
中的每个文件。无论这里发生了什么变化,鲍勃都发生了变化。
对于与git merge
相比在A
或B
中进行了更改的每个文件,{em}都将使用*
命令更改每个文件。也就是说,如果Alice和Bob 两者都更改了README.md
,则Git将合并这些更改。如果Alice更改了alice.txt
,而Bob没有更改,则Git只会接受Alice的更改。如果Bob更改了blue.py
而Alice没有更改,那么Git只会接受Bob的更改。
已将所有这些更改组合在一起(假设将所有工作组合在一起),Git会将组合的更改应用于*
中的所有内容。生成的文件现在适合进行 new 提交。新的提交是 merge commit ,这是特殊的,因为它有两个父母而不是通常的父母:而不是记住我的父母是commit A 或 my父是提交B ,新提交会记住这两个:
o--o--A
/ \
...--o--o--* M
\ /
o--o--B
新的提交M
进入您现在已签出的任何分支。如果是分支alice
,则结果为:
o--o--A
/ \
...--o--o--* M <-- alice (HEAD)
\ /
o--o--B <-- bob
如果您首先创建一个 new 分支(例如carol
),则 还要指向首先提交A
:
o--o--A <-- alice, carol (HEAD)
/
...--o--o--*
\
o--o--B <-- bob
然后新的提交M
将名称carol
更改为指向M
:
o--o--A <-- alice
/ \
...--o--o--* M <-- carol (HEAD)
\ /
o--o--B <-- bob
请记住,M
中的 all 个文件是合并 all 所做的更改的结果。棘手的部分是查找更改,因为提交是快照,而这样做的技巧是找到快照*
(合并基础)。然后,Git将快照*
与快照A
进行了比较:
git diff --find-renames <hash-of-*> <hash-of-A> # what Alice changed
并针对快照B
重复此操作:
git diff --find-renames <hash-of-*> <hash-of-B> # what Bob changed
然后合并将三个快照中所有所有文件的这些更改组合起来,以构建合并提交M
,该合并提交进入当前分支:带有HEAD
的分支附加到它。
要合并A
和B
中的 all 个文件而不影响任何其他分支,可以创建一个 new 分支以指向任一提交A
或提交B
,然后使用指定两次提交中的另一个的任何名称或哈希ID运行git merge
。如果合并成功,则新的合并提交M
将指向A
和B
,并且将分别位于新分支上。
要合并A
和B
中的所有文件,同时将新的合并提交放入分支alice
(当前提交A
)或bob
(当前提交B
),签出所需的分支并使用另一个分支的名称运行git merge
。如果合并成功,您的新合并提交M
将同时指向A
和B
,就像其他情况一样,但是这次合并提交将位于{{1 }}或alice
,而不是位于您未创建的新分支上。
如果您确实只想合并提交bob
和A
中的一个文件,则不能使用B
来做到这一点:它做得太多了;它将合并所有文件。有一个Git命令可以合并一个文件:
git merge
将完成这项工作。但它需要三个输入文件。它需要您要合并其更改的文件的合并基础版本。找到合并的基本版本,以及您要合并的其他两个版本。将它们放入三个文件中,例如git merge-file
,file.base
和file.mine
。然后运行:
file.theirs
Git会将git merge-file file.mine file.base file.theirs
与file.base
进行比较以查看您所更改的,并将file.mine
与file.base
进行比较以查看其 已更改。然后它将尝试合并这两个更改,将合并的更改应用于file.theirs
,然后将结果写入file.base
。
这当然是file.mine
对每个文件所做的工作。 git merge
只是为您找到了三个 文件,并自动完成了所有工作。