将 Git 分支合并到 Master 的最佳方法

Sharad Dixit 2023年1月30日
  1. 先决条件
  2. 在 Git 中准备合并
  3. 使用 Git 中的 merge 方法将分支合并到 Master 中
  4. 使用 rebase 方法将分支合并到 Master
  5. 结论
将 Git 分支合并到 Master 的最佳方法

git 最强大的功能之一是分支创建和合并操作。Git 允许用户创建一个新分支并将它们合并到开发代码中。此功能通过鼓励更具体、更小和更精细的任务来改进多个项目的开发流程工作流。

在本教程文章中,我们将讨论将 git 功能分支合并到 master 的不同方法。

git 的主要优点是它的分支系统。GIT 的所有魔力都在这些分支上!主分支将进行所有修改。因此,目标不是直接在这个分支上进行修改,而是在其他分支上进行修改,经过各种测试后,将它们集成到主分支上。

在我们的教程中,为简单起见,我们假设有两个分支,master 分支和称为 feature-1 的特性分支。主分支是包含生产代码的主分支,第二个分支是执行修改或实现新功能的地方。最后,如果一个功能或错误被批准,它将被合并到 master

Initial_Repository

下面开始用一个真实的例子来演示两个分支的合并。首先,我们需要以下内容。

先决条件

在 GitHub 上创建仓库

可以按照 Github 中的介绍创建初始仓库

接下来,使用仓库页面上的添加文件按钮在 Master 分支上添加两个文件。文件名如下。

  • file1.txt
  • file2.txt

在本例中,以下文本内容分别添加到 file1.txtfile 2.txt

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

克隆仓库

接下来,将你新创建的仓库从 GitHub 克隆到你的系统以创建代码的本地副本。克隆 URL 可以从代码按钮中检索,如下所示。

Clone_Repository

使用以下命令进行克隆。

$ git clone git@github.com:project/demorepo.git

克隆成功后,使用以下命令显示并验证 master 分支文件的内容:

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

创建特征分支

$ git branch feature-1

此命令会创建一个新分支,并且不会在 git 上创建新的提交。

检出功能分支

之前,我们使用 git branch feature-1 创建了一个新分支。但是,活动分支是 master 分支。要激活新分支,请在终端中使用以下命令:

$ git checkout feature-1
Switched to branch 'feature-1'

上面的命令会将活动分支从 master 切换到 feature-1。现在,这个分支已经可以进行单独开发了。

修改功能分支中的文件

我们将在 feature-1 分支中添加一些提交或添加新行。在这种情况下,file2.txt 将在本地修改,然后合并回主分支。

对于到目前为止的更改,我们的提交图如下所示。A 和 E 都代表 masterfeature-1 分支状态。目前,提交 AE 相同,因为在切换期间没有更改任何文件。

A  ← master
   \
     E  ← feature-1

现在,file1.txt 更新为新文本。使用此命令更新内容。

$ echo "file update in feature branch" > file1.txt

现在,file2.txt 具有以下内容。

$ cat file2.txt
This is dummy test in 2nd file

file1.txt 中新旧内容之间的差异可以使用以下命令进行验证。

$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch

现在,暂存此文件并通过以下命令创建本地提交。

$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
 1 file changed, 1 insertion(+), 2 d

提交树的当前快照如下所示。这里 F 是在上一步中创建的新提交。

A  ← master
  \
    E --- F ← feature-1

为了演示一个真实的例子,远程 master 也被其他开发人员同时更改,这些更改作为提交 C 和提交 D 推送到 master。

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

以下是 master 分支的 Github 仓库中 file1.txt 的更新内容。请注意,第 2 行已更新,第 3 行和第 4 行是新创建的。

文件 1_内容

这也可以通过使用以下命令在命令 shell 中实时可视化你的分支历史记录来本地验证。

$ git fetch
$ git log --all --decorate --oneline --graph

Commit_Graph

在 Git 中准备合并

使用 Git,我们有两种可能性将我们的功能分支更改与远程 master 分支合并:

  1. merge 方法
    Git merge 是一个将更改提交到另一个分支的命令。它允许开发人员从功能分支中获取他们独立的代码行,并通过 git 合并工具将它们集成到 master 上的单个分支中。

  2. rebase 方法
    Git rebase 是另一个用于基本相同目的的命令,只是它的执行方式非常不同。

让我们详细了解这两种方式:

使用 Git 中的 merge 方法将分支合并到 Master 中

merge 旨在将 featuremaster 分支合并到保留所有相关分支内容的提交中。Git 实现了这一点,即所谓的合并提交。这也意味着 merge 操作多个分支。

当分支分叉时,即一个不是另一个的祖先。Git 可以通过进行具有多个父项的新附加提交来实现合并。在下图中,如果你在不同的分支中有提交 D 和提交 F 并混合分支(通过 git merge),结果是提交 G,其父项是 BE

A --- B --- C --- D ---	
  \				         \  
    \					  G  ← master
      E --- F --------- /	

在上图中,G 是一个新创建的提交,完全由 git 创建。这个提交有两个父节点!他们有一个命令:

  • 第一个父节点是 D,之前是 master
  • 第二个父节点是 F,之前是 feature-1

这种类型的提交称为合并提交。

现在切换回我们的仓库示例并将新创建的 feature-1 分支合并到 master

首先,检查主分支。

$ git checkout master

现在,将远程 master 更改拉到本地的 master

$ git pull origin master

From github.com:repo/demorepo

 * branch            master     -> FETCH_HEAD
   Updating 17cc6b4..a802b6b
   Fast-forward
    file1.txt | 5 ++++-
    1 file changed, 4 insertions(+), 1 deletion(-)

之后,使用以下命令将功能分支,即 feature-1 合并到当前活动的分支。

$ git merge feature-1

如果此步骤成功完成,feature-1 分支将与 master 分支完全合并。但是,如果 git 不能自动解决这些合并冲突,它将失败并显示合并冲突错误。

这是一个非常典型的场景;当两个分支修改文件的同一部分并且 git 无法解析要使用的部分时,就会发生这种情况。这正是我们示例中发生的情况。下面通过 git 显示了这种情况。

Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

每当 git 遇到冲突时,它都会添加 <<<<<<< & ======== 以突出显示导致冲突的部分,这需要手动解决。

File1_MergeConflict

一旦决定将哪个部分保留在文件的最终主版本中,个人必须删除不相关的代码(包括冲突指示符)。最后,将更改推送到远程分支,如下所示。

$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push

这样 feature-1 分支成功合并到远程 master

接下来,我们将使用以下命令再次验证分支历史记录。

git log --all --decorate --oneline --graph

Merge_Graph

我们可以验证 git merge 是否创建了一个 Merge Commit,commit-id 为 1acce69 以将 feature-1 分支与 origin/master 合并。

使用 rebase 方法将分支合并到 Master

再次考虑我们的 feature 和 master 分支不同步需要合并的情况。让我们还回顾一下之前显示这种情况的图示。

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

作为合并的替代方法,你可以使用 rebase 选项将分支 feature-1 合并到分支 masterrebase 通过简单地将来自 feature 分支的提交放在 master 分支的前面来统一所涉及的分支。

这将通过以下命令实现,

git checkout master
git pull
git checkout feature-1
git rebase master

运行 rebase 后,我们可以得到如下图所示。

A --- B --- C --- D----(operation rebase)----- E--------F   ← master

从上图可以看出,rebase 所做的一些好事是产生线性、更清晰、更易于阅读的提交历史。通过合并,它也不会产生额外的奇怪的 merge commit

这种方法的缺点是 rebase 改变了所涉及分支的整个结构,包括重写这些分支的提交历史。由于 rebase 不会创建 merge commit,你无法获得两个分支何时合并的可追溯性,因为 rebase 在流程结束时生成一个线性分支。

结论

这两个命令都非常有用;但是,在不同的情况下,双方各有优势。

Git rebase

  • 简化复杂的历史。
  • 避免在具有繁忙分支的仓库中合并提交噪音。
  • 如果使用不当,则有风险,因为它不会保存历史。

Git merge

  • 使用简单。
  • 由于每次都会创建一个额外的合并提交,它会导致提交历史看起来混乱和肮脏。
  • 保留完整的历史和时间顺序。

相关文章 - Git Merge