在Git中,合并是一个连接分叉历史的过程。它将两个或多个开发历史连接在一起。git merge命令可以帮助你把git分支创建的数据整合到一个分支中。git merge会将一系列的提交关联到一个统一的历史。一般来说,git merge 用来合并两个分支。
它被用来维护不同的开发线;在某个阶段,你想把这些变化合并到一个分支中。了解Git中的合并工作是非常重要的。
在上图中,有两个分支 master 和 feature。我们可以看到,我们在功能和主干分支都做了一些提交,并将它们合并。它就像一个指针。它将在各分支之间找到一个共同的基础提交。一旦 Git 找到一个共同的基础提交,它就会创建一个新的 “合并提交”。它结合了每个排队的合并提交序列的变化。
git merge命令
git merge命令用来合并分支。
git merge命令的语法如下。
$ git merge <query>
它可以在各种情况下使用。一些情况如下。
场景1:将指定的提交合并到当前活动分支
使用下面的命令,将指定的提交合并到当前活动分支。
$ git merge <commit>
上述命令将把指定的提交合并到当前的活动分支。你也可以通过在<commit>
中传入分支名称,将指定的提交合并到指定的分支。让我们看看如何提交到当前的活动分支。
请看下面的例子。我在项目的文件newfile1.txt中做了一些修改,并在test分支中提交。
把你想合并的特定提交复制到活动分支上,然后执行合并操作。请看下面的输出。
在上面的输出中,我们已经将之前的提交合并到了活动分支test2中。
场景2:将提交的内容合并到主分支
要把一个指定的提交合并到主站,首先要发现其提交ID。使用 log 命令来查找特定的提交 ID。
$git log
请看下面的输出。
要把这些提交合并到主分支,请切换到主分支。
$ git checkout master
现在,切换到分支 “master”,对一个提交进行合并操作。使用git merge命令和主分支名称。其语法如下。
$ git merge master
请看下面的输出。
如上图所示,提交号为 2852e020909dfe705707695fd6d715cd723f9540 的提交已经合并到主分支。主分支中有两个文件发生了变化。不过,我们是在测试分支中做的这个提交。所以,任何一个分支中的任何一个提交都可以合并。
打开新文件,你会发现,我们提交到测试分支的新行现在已经复制到了主分支上。
场景3:Git合并分支
Git 允许将整个分支合并到另一个分支中。假设你在一个分支上做了很多改动,想一次把所有的都合并起来。Git允许你这样做。请看下面的例子。
在给出的输出中,我在测试分支的 newfile1 中做了修改。现在,我已经在测试分支中提交了这一修改。
现在,切换到你想要合并的那个分支。在给定的例子中,我已经切换到了主分支。执行下面的命令,将整个分支合并到活动分支。
$ git merge <branchname>
从给定的输出中可以看到,分支test2的全部提交已经合并到了分支master。
Git Merge冲突
当两个分支试图合并时,如果这两个分支在同一时间和同一文件中被编辑,Git将无法识别哪个版本的修改。这种情况被称为合并冲突。如果这种情况发生,它会在合并提交前停止,这样你就可以手动解决冲突。
让我们通过一个例子来理解它。
假设我的远程版本库被我的两个团队成员 user1 和 user2 克隆了。用户1在我的项目索引文件中做了如下修改。
在git add命令的帮助下,在本地存储库中更新它。
现在提交修改,并在远程版本库中更新它。请看下面的输出。
现在,我的远程版本库将看起来像这样。
它将显示文件的状态,如由谁编辑和何时编辑。
现在,在同一时间,用户2也更新索引文件,如下所示。
用户2在本地版本库中添加并提交了修改。但当他试图将其推送到远程服务器时,会出现错误。请看下面的输出。
在上面的输出中,服务器知道该文件已经被更新,并且没有与其他分支合并。所以,推送请求被远程服务器拒绝。它将抛出一条错误信息,如[rejected]
未能推送一些 refs 到 <remote URL>
。它将建议你在推送前先拉出版本库。请看下面的命令
在给定的输出中,git rebase命令被用来从远程URL拉取版本库。这里,它将显示错误信息,如<filename>
的合并冲突
解决冲突
为了解决冲突,有必要了解冲突是否发生以及发生的原因。Git的合并工具命令被用来解决冲突。合并命令的使用方法如下。
$ git mergetool
在我的存储库中,它将导致。
上面的输出显示了冲突文件的状态。要解决冲突,只需按I键进入插入模式,并按你的要求进行修改。按Esc键,从插入模式中出来。在编辑器的底部键入:w!以保存并退出修改。要接受这些变化,请使用rebase命令。它的使用方法如下。
$ git rebase --continue
因此,冲突已经解决。请看下面的输出。
在上面的输出中,冲突已经解决,本地版本库与远程版本库同步。
要想知道哪个是你文件中合并冲突的第一个编辑过的文本,请搜索附有冲突标记的文件<<<<<<<。