如何使用 Git 合并

已发表: 2023-01-03
在绿草如茵的公园里,两条人行道合二为一。
大师之手/Shutterstock.com
要将开发分支合并到当前分支,请使用“git merge dev-branch-name”。 如果您收到有关合并的冲突警告,请使用“git merge --abort”退出合并,或编辑受影响的文件然后提交它们。

Git 使用分支来隔离开发流,以防止稳定版本分支被污染。 将分支中的工作纳入主流意味着合并分支。 这是你如何做的。

目录

什么是 Git 中的合并?
准备在 Git 中合并一个分支
执行合并
在 Git 中执行快进合并
如何解决 Git 中的合并冲突
一切最终合并

什么是 Git 中的合并?

Git 旨在使分支变得简单和快速。 与其他版本控制系统相比,在 Git 上创建分支是一件小事。 特别是在多开发者项目中,分支是 Git 的核心组织工具之一。

分支沙箱新的开发工作,以便可以修改或添加代码而不影响其他分支中的代码,尤其是主分支或主分支。 这通常包含代码库的稳定版本。

将这些更改与稳定代码版本隔离是非常有意义的。 但是新代码迟早会经过测试、审查和加盖橡皮图章,以便被纳入 master 分支。 此时,您需要将您的分支合并到 master 分支中。

Git 分支如何工作?
相关Git 分支如何工作?

实际上,分支可以有子分支,因此您可能会将您的分支合并到其他分支而不是主分支。 请记住,合并总是采用一个分支并将其合并到目标分支中,无论该分支是什么。 如果你想将你的 master 分支合并到另一个分支,你甚至可以这样做。

与 Git 中的大多数操作一样,您在本地存储库中执行合并并将它们推送到远程存储库。

准备在 Git 中合并一个分支

我们有一个带有本地 Git 存储库和远程 Git 存储库的小型开发项目。 我们从“master”分支创建了一个名为“bugfix14”的分支,并致力于解决一个错误。

这项工作已经完成,我们已经测试了我们的代码。 一切都按预期工作。 我们希望将这些更改滚动到 master 分支中,以便我们的修复成为软件下一版本的一部分。

在我们执行合并之前需要做一些准备工作。 我们需要确保目标分支——在本例中为“主”分支——以及我们要合并到其中的分支都是最新的。

为此,我们将使用git status命令。

 混帐状态

使用 git status 查看分支的状态

  • 在分支 bugfix14 上:这是我们当前的分支。
  • Your branch is up to date with 'origin/bugfix' :我们本地存储库中的分支与远程存储库中的分支具有相同的提交历史。 这意味着它们是相同的。
  • nothing to commit暂存区中没有未提交的更改。
  • 工作树清理:工作目录中没有未暂存的更改。

所有这些都表明该分支是最新的,我们可以继续进行。 如果其中任何一个表明存在更改,我们就需要暂存它们、提交它们并将它们推送到远程。 如果其他人处理过这些文件,我们可能需要从远程存储库中提取他们的更改。

检查我们要合并到的分支可以简化合并过程。 它还允许我们验证它是最新的。 让我们看看主分支。

 git结帐大师
混帐状态

检查 master 分支并使用 git status 查看其状态

我们得到相同的确认,即“master”分支是最新的。

相关:如何选择适合您团队的 Git 工作流和分支模型

执行合并

在我们合并之前,我们的提交看起来像这样。

分支合并前的提交历史

“bugfix14”分支是从“master”分支分支出来的。 在创建“bugfix14”分支后,已经提交到“master”分支。 “bugfix14”分支有几个提交。

我们已经确保我们的两个分支是最新的,并且我们已经检查了“master”分支。 我们可以发出命令将“bugfix14”分支合并到“master”分支。

 git 合并 bugfix14 

使用 git merge 命令合并一个分支

合并发生。 “bugfix14”分支仍然存在,但现在在该分支中所做的更改已合并到“master”分支中。

分支合并后的提交历史

在这种情况下,合并命令执行三向合并。 只有两个分支,但涉及三个提交。 它们是任一分支的负责人,以及代表合并操作本身的第三次提交。

要更新我们的远程存储库,我们可以使用git push命令。

将更改推送到远程存储库

有些人喜欢在合并后删除分支。 其他人则小心翼翼地保存它们,作为项目真实发展历史的记录。

如果要删除分支,可以使用带有-d (删除)选项的git branch命令。

 git branch -d bugfix14 

删除本地仓库中的分支

要删除远程存储库中的分支,请使用以下命令:

 git push origin --delete bugfix14 

删除远程仓库中的分支

您将拥有线性提交历史记录,但它不会是真实的历史记录。

相关:如何删除本地和远程存储库上的 Git 分支

在 Git 中执行快进合并

如果您还没有对“master”分支进行任何提交,您的历史记录将如下所示。 如果您重新设置了开发分支的基础,它也会看起来像这样,以便它附加到“master”分支的末尾。

快进合并前的提交历史

因为“master”分支中没有提交,要合并“bugfix15”分支,Git 所要做的就是将“master”头指针指向“bugfix15”分支的最后一次提交。

我们可以使用通常的git merge命令:

 git 合并 bugfix15

这给了我们这个结果。

查看快进合并结果的一种方法

这与此相同:

查看快进合并结果的另一种方法

这与此相同:

另一种查看快进合并结果的方法

只要有可能,Git 就会执行快进合并。 如果提交到“主”分支意味着快进合并是不可能的,Git 将使用三向合并

您不能强制执行快进合并 — 毕竟这可能是不可能的 — 但您可以声明它是快进合并或什么都不是。 有一个选项指示 Git 在可能的情况下使用快进合并,但在不能的情况下不进行三向合并。 该选项是--ff-only (仅快进合并)。

这会将“bugfix15”分支合并到“master”分支,但前提是可以进行快进合并。

 git merge --ff-only bugfix15 

如果无法进行快进合并,则使用 --ff-only 选项防止使用三向合并

如果不可能,Git 会抱怨并退出。

 git merge --ff-only bugfix16 

Git 不执行任何合并,因为快进合并是不可能的,并且使用了 --ff-only 选项

在这种情况下,已经有提交到“master”分支,所以快进合并是不可能的。

如何解决 Git 中的合并冲突

如果在两个分支中更改了同一文件的相同部分,则无法合并分支。 需要人工交互来解决冲突的编辑。

在这里,我们对名为“bugfix17”的分支中名为“rot.c”的文件进行了更改,我们希望将其合并到“master”分支。 但是“rot.c”在“master”分支中也发生了变化。

 git 合并 bugfix17 

获取报告冲突并停止合并

当我们尝试合并它时,我们会收到一条警告,提示存在冲突。 Git 列出了冲突的文件,并告诉我们合并失败。 我们可以使用--abort选项完全退出:

 git 合并 --abort

但是解决合并并不像听起来那么可怕。 Git 已经做了一些工作来帮助我们。 如果我们编辑其中一个冲突文件——在我们的例子中,我们只有一个——我们会发现冲突的代码部分为我们突出显示。

git 如何识别文件中的冲突

每个冲突由七个小于字符“ <<<<<<< ”和七个大于字符“ >>>>>>> ”界定,它们之间有七个等号“ ======= ” .

  • 等号上方的代码来自您要合并的分支。
  • 等号下面的代码是您要合并的分支的代码。

您可以轻松地搜索一组七个字符中的一组,并在整个文件中从冲突转移到冲突。 对于每个冲突,您需要选择要保留的编辑集。 您必须编辑掉您拒绝的代码,以及 Git 添加的七字符行。

我们将保留“bugfix17”分支中的代码。 编辑后,我们的文件看起来像这样。

编辑后的文本,解决合并冲突

我们现在可以继续进行合并。 但请注意,我们使用commit命令来执行此操作,而不是merge命令。

我们通过暂存文件并照常提交来提交更改。 我们将在进行最终提交之前检查状态。

 git 添加 rot.c
 混帐状态
git commit -m "合并 bugfix17" 

解决冲突后使用 commit 命令完成合并

合并完成。 我们现在可以将其推送到我们的远程存储库。

相关:如何修复、编辑或撤消 Git 提交(更改 Git 历史)

一切最终合并

最终,所有分支都需要合并,这样它们中的更改就不会成为孤立的和被遗忘的。

合并分支很容易,但在繁忙的大型团队中处理冲突可能会变得复杂。 解决冲突可能需要每个开发人员的输入,只是为了解释他们的代码做了什么以及他们为什么进行更改。 您需要了解这一点,然后才能就保留哪些编辑做出明智的决定。

遗憾的是,Git 对此无能为力。

相关:您应该使用 GUI Git 客户端吗?