Git合并命令会添加所有提交记录还是只添加最后一个提交记录?

4

我一直在使用 git merge,但我不明白它是否会将合并的分支中的所有提交都添加到当前分支,还是只添加最后一个提交。

例如,如果我有一个分支 A 和一个分支 B

  • A 包含提交:1 2 5

  • B 包含提交:3 4

那么,如果我在分支 A 中执行 git merge B,会发生什么?

如果我在分支 B 中执行 git merge A,会发生什么?

我最想知道的是合并完成后会发生什么,所有提交都添加到当前分支还是只添加最后一个提交?


你要合并到哪个分支?换句话说,当你“运行”合并时,当前的分支是哪个?这样可以根据你的示例分支/提交来回答你。 - skyboyer
你对于“引擎盖下正在发生什么?”,“我的历史记录是如何改变的?”或者“我的工作树(文件和代码内部)正在发生什么?”感兴趣吗?每个主题都会导致很大的答案,因此最好只选择一个项目。 Context: This is a question in the context of programming, asking if the person is interested in learning about the inner workings of the code they are working on. - skyboyer
我最感兴趣的是合并完成后会发生什么,所有提交都会添加到当前分支还是只有最后一个提交。 - Mohamed Benkedadra
2个回答

5
你可以很容易地自行进行实验(需要使用终端)
在命令行中进入你喜欢的文件夹:
创建一个空仓库。
mkdir test-repo
cd test-repo
git init

添加一些内容(我们将创建一个文件,在每次提交时更改该内容)

echo 0 > file.txt
git add file.txt
git commit -m '0'

创建分支A

git checkout -b A
echo 1 > file.txt; git add file.txt; git commit -m '1'
echo 2 > file.txt; git add file.txt; git commit -m '2'
echo 3 > file.txt; git add file.txt; git commit -m '3'
git log --graph --oneline --all

创建B分支。
git checkout master
git checkout -b B
echo 4 > file.txt; git add file.txt; git commit -m '4'
echo 5 > file.txt; git add file.txt; git commit -m '5'
git log --graph --oneline --all

在分支A中,我们有一个数字为3的文件,在B中有一个数字为5的文件 让我们将A合并到B中(当前分支是B,请记住)

git merge B

你将看到一个易于解决的冲突。
cat file.txt

<<<<<<< HEAD
5
=======
3
>>>>>>> A

修复和提交:

git commit
git log --graph --oneline --all

历史记录将类似于: enter image description here 这里发生的情况是,您只需创建一个新提交,将A链接到B,该提交具有2个分支之间的冲突解决。并且您仍然在B分支上。
这意味着您可以删除此提交,并返回到先前状态,只需删除此提交即可:
git reset --hard HEAD~1
git log

现在让我们反过来,切换到分支A并将B合并到A中。

git checkout A
git merge B

修复一个看起来相似但并非完全相同的冲突。
cat file.txt


<<<<<<< HEAD
3
=======
5
>>>>>>> B

修复冲突后,您应该处于相同的状态,但从技术上讲并不是:) 您现在处于B分支。
git commit
git log --graph --oneline --all 

在这里输入图片描述

那么它们有什么区别呢?冲突的顺序是不同的,但更重要的是你所在分支的最终分支名。

因此,合并会创建另一个提交来将一个分支的不同历史链接到另一个分支中(这就是为什么在这个示例中提交0不会重复出现的原因)。

如果您喜欢干净的历史记录,其中最终历史记录类似于:在这里输入图片描述

您应该使用rebase。但这超出了本问题的范围。

如果您想从一个分支创建一个单独的提交以添加到另一个分支,您可以使用squashrebase

当您通过实践学习时,Git会变得更加容易。经常检查您的git log。学习如何使用git reflog来增强信心(这就是git伟大的原因),并给git rebase命令一个机会。然后与您的团队交流并决定最佳工作流程。


2
  1. 提交并不是被“移动”到分支中的。
  2. Git 中的每个提交都存储着指向父提交的链接。
  3. 合并提交有两个或更多个父提交(它们通常是相应分支的 HEAD)。
  4. 由于这些提交仍然保留了它们的父提交,合并操作实际上将“将所有不同的提交(在当前分支之前不存在)带入当前分支”。虚拟意味着一旦您使用 git reset 或 git revert 删除合并提交,您将从当前分支中“删除”它们。

相反地:

a. 进行变基会通过复制所有“不同”的提交来将它们带入当前分支;它们最初将“表现”得就像为当前分支创建的本机提交一样。

b. 摘录会复制单个提交(如果您使用分支名称作为参数,则是最后一个提交);但您可以指定一个范围。


1
好的回答。我正好在寻找“virtually”这个词来回答我所有关于这个问题的问题。另一个证据是:尽管有分支AB的混合提交,但是如果您尝试使用git restore --source=HEAD~n file.txt,当n增加时,您只会看到当前分支的更改,而不是合并分支的更改。它们只是在日志中虚拟存在。 - S.B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接