如何使用 Git 合并
总结:要将一个开发分支合并到当前分支,使用“git merge dev-branch-name”。如果您收到有关合并的冲突警告,请使用“git merge --abort”退出合并,或编辑受影响的文件然后提交它们。
Git 使用分支来隔离开发流,以防止稳定版本分支被污染。将分支中的工作纳入主流意味着合并分支。这是你如何做的。
什么是 Git 中的合并?
Git 旨在使分支变得简单和快速。与其他版本控制系统相比,在 Git 上创建分支是一件小事。特别是在多开发者项目中,分支是 Git 的核心组织工具之一。
分支沙箱新的开发工作,以便可以修改或添加代码而不影响其他分支中的代码,尤其是主分支或主分支。这通常包含代码库的稳定版本。
将这些更改与稳定代码版本隔离是非常有意义的。但是新代码迟早会经过测试、审查和加盖橡皮图章,以便被纳入 master 分支。此时,您需要将您的分支合并到 master 分支中。
实际上,分支可以有子分支,因此您可能会将您的分支合并到其他分支而不是主分支。请记住,合并总是采用一个分支并将其合并到一个目标分支中,无论该分支是什么。如果你想将你的 master 分支合并到另一个分支,你甚至可以这样做。
与 Git 中的大多数操作一样,您在本地存储库中执行合并并将它们推送到远程存储库。
准备在 Git 中合并一个分支
我们有一个带有本地 Git 存储库和远程 Git 存储库的小型开发项目。我们从“master”分支创建了一个名为“bugfix14”的分支,并致力于解决一个错误。
这项工作已经完成,我们已经测试了我们的代码。一切都按预期工作。我们希望将这些更改滚动到 master 分支中,以便我们的修复成为软件下一版本的一部分。
在我们执行合并之前需要做一些准备工作。我们需要确保目标分支——在本例中为“主”分支——以及我们要合并到其中的分支都是最新的。
为此,我们将使用 git status
命令。
git status
- 在分支 bugfix14 上:这是我们当前的分支。
- 您的分支是最新的“origin/bugfix”:我们本地存储库中的分支与远程存储库中的分支具有相同的提交历史。这意味着它们是相同的。
- nothing to commit 暂存区域中没有未提交的更改。
- working tree clean:工作目录中没有未暂存的更改。
所有这些都表明该分支是最新的,我们可以继续进行。如果其中任何一个表明存在更改,我们就需要暂存它们、提交它们并将它们推送到远程。如果其他人处理过这些文件,我们可能需要从远程存储库中提取他们的更改。
检查我们要合并到的分支可以简化合并过程。它还允许我们验证它是最新的。让我们看看 master 分支。
git checkout master
git status
我们得到相同的确认,即“master”分支是最新的。
执行合并
在我们合并之前,我们的提交看起来像这样。
“bugfix14”分支是从“master”分支分支出来的。在创建“bugfix14”分支后,已经提交到“master”分支。 “bugfix14”分支有几个提交。
我们已经确保我们的两个分支是最新的,并且我们已经检查了“master”分支。我们可以发出命令将“bugfix14”分支合并到“master”分支。
git merge bugfix14
合并发生。 “bugfix14”分支仍然存在,但现在在该分支中所做的更改已合并到“master”分支中。
在这种情况下,合并命令执行三向合并。只有两个分支,但涉及三个提交。它们是任一分支的负责人,以及代表合并操作本身的第三次提交。
要更新我们的远程存储库,我们可以使用 git push 命令。
git push
有些人喜欢在合并后删除分支。其他人则小心翼翼地保存它们,作为项目真实发展历史的记录。
如果要删除分支,可以使用带有 -d
(删除)选项的 git branch
命令来执行此操作。
git branch -d bugfix14
要删除远程存储库中的分支,请使用以下命令:
git push origin --delete bugfix14
你会有一个线性的提交历史,但它不会是真实的历史。
在 Git 中执行快进合并
如果您还没有对“master”分支进行任何提交,您的历史记录将如下所示。如果您重新设置开发分支的基线,使其附加到“master”分支的末尾,它也会看起来像这样。
因为“master”分支中没有提交,要合并“bugfix15”分支,Git 所要做的就是将“master”头指针指向“bugfix15”分支的最后一次提交。
我们可以使用通常的 git merge
命令:
git merge bugfix15
这给了我们这个结果。
这与此相同:
这与此相同:
Git 会在可能的时候执行快进合并。如果提交到“master”分支意味着快进合并是不可能的,Git 将使用三向合并。
你不能强制进行快进合并——毕竟这可能是不可能的——但你可以声明它是快进合并或什么都不做。有一个选项指示 Git 在可能的情况下使用快进合并,但如果不能则不进行三向合并。选项是 --ff-only
(仅快进合并)。
这会将“bugfix15”分支合并到“master”分支,但前提是可以进行快进合并。
git merge --ff-only bugfix15
如果不可能,Git 会抱怨并退出。
git merge --ff-only bugfix16
在这种情况下,已经有提交到“master”分支,所以快进合并是不可能的。
如何解决 Git 中的合并冲突
如果在两个分支中更改了同一文件的相同部分,则无法合并分支。需要人工交互来解决冲突的编辑。
在这里,我们对名为“bugfix17”的分支中名为“rot.c”的文件进行了更改,我们希望将其合并到“master”分支。但是“rot.c”在“master”分支中也发生了变化。
git merge bugfix17
当我们尝试合并它时,我们会收到一条警告,提示存在冲突。 Git 列出了冲突的文件,并告诉我们合并失败。我们可以使用 --abort
选项完全退出:
git merge --abort
但是解决合并并不像听起来那么可怕。 Git 已经做了一些工作来帮助我们。如果我们编辑其中一个冲突文件——在我们的例子中,我们只有一个——我们会发现冲突的代码部分为我们突出显示。
每个冲突都由七个小于字符“<<<<<<<
”和七个大于字符“>>>>>>>
”限定,其中它们之间有七个等号“=======
”。
- 等号上方的代码来自您要合并到的分支。
- 等号下面的代码是您要合并的分支的代码。
您可以轻松地搜索一组七个字符中的一组,并在整个文件中从冲突转移到冲突。对于每个冲突,您需要选择要保留的编辑集。您必须编辑掉您拒绝的代码,以及 Git 添加的七个字符的行。
我们将保留“bugfix17”分支中的代码。编辑后,我们的文件看起来像这样。
我们现在可以继续进行合并。但请注意,我们使用 commit
命令来执行此操作,而不是 merge
命令。
我们通过暂存文件并照常提交来提交更改。我们将在进行最终提交之前检查状态。
git add rot.c
git status
git commit -m "Merged bugfix17"
合并完成。我们现在可以将其推送到我们的远程存储库。
一切最终合并
最终,所有分支都需要合并,这样它们中的更改就不会成为孤立的和被遗忘的。
合并分支很容易,但在繁忙的大型团队中处理冲突可能会变得复杂。解决冲突可能需要每个开发人员的输入,只是为了解释他们的代码做了什么以及他们为什么进行更改。您需要了解这一点,然后才能就保留哪些编辑做出明智的决定。
遗憾的是,Git 对此无能为力。