3. 记录的提交和合并

本节课我们来学习不同分支的记录提交和合并。

本小节我将学习 git merge 命令。

命令
说明
git merge
合并两个或多个分支的记录。

上节课我们在原有 my_project 项目中添加了 myb1 分支,加上原有的默认分支 master 共有两个分支。本节课我们模拟不同的需求,在两个分支上分别添加功能并提交,然后合并两个分支中的修改记录合并到主分支中形成一个提交。

前面的章节中使用 git commit 命令可以将当前暂存区中的修改记录提交到当前分支中形成新的提交对象。提交的同时会移动当前分支指针指向最新生成的提交对象。

需要注意的是在不同的分支上进行提交时,需要使用 git switch 命令切换某个分支到当前分支。

假设我们现在要改写 my_project 项目的功能。为了不影响主分支的开发进度,我们最后要将此次修改提交到 myb1 分支,待修改完成后再将新加入的功能合并到主分支。

我们切换当前分支为 myb1 分支,然后在创建一个新文件 function1.txt 写入一行文件文字 新功能1的实现代码,然后再修改 website.txt 文件,在最末尾加入一行 https://weimingze.com/c/

文件:function1.txt 内容如下:

新功能1的实现代码

文件:website.txtt 内容如下:

https://weimingze.com
https://weimingze.com/c/

最后提交到 myb1 分支,我的操作如下:

weimingze@mzstudio:~/my_project$ git switch myb1
Switched to branch 'myb1'
weimingze@mzstudio:~/my_project$ git branch
  master
* myb1
weimingze@mzstudio:~/my_project$ ls
README.md  website.txt
weimingze@mzstudio:~/my_project$ echo -e -n "新功能1的实现代码\r\n" > function1.txt
weimingze@mzstudio:~/my_project$ echo -e -n "https://weimingze.com/c/\r\n" >> website.txt
weimingze@mzstudio:~/my_project$ git add website.txt function1.txt
weimingze@mzstudio:~/my_project$ git commit -m "完成了功能1"
[myb1 8e7f7c7] 完成了功能1
 2 files changed, 2 insertions(+)
 create mode 100644 function1.txt
weimingze@mzstudio:~/my_project$ ls
README.md  function1.txt  website.txt

此时在 myb1 上新创建了一个提交对象 8e7f7c7,这个提交对象记录了新增功能1的状态。 仓库结构如下:

              .--------.
              | master |
              `--------`
                  |
+-------+     +-------+
|8cb34d1| <-- |5dcccb0|
+-------+     +-------+
                  ^
                  |         +-------+
                  `-------- |8e7f7c7|
                            +-------+
                               |
                            .--------.
                            |  myb1  |
                            `--------`
                                |
                               HEAD

下面我们在主分支master 上完成一个新功能2的代码并提交。

我们切换当前分支为 master 分支,然后在创建一个新文件 function2.txt 写入一行文件文字 新功能2的实现代码,然后在修改 website.txt 文件,在最末尾加入一行 https://weimingze.com/git/(需要注意此时 website.txt 文件的内容应当只有一行,不存在分支 myb1 中的 https://weimingze.com/c/ 这一行)。

文件:function2.txt 内容如下:

新功能2的实现代码

文件:website.txtt 内容如下:

https://weimingze.com
https://weimingze.com/git/

完成上述编写后提交到 master 分支,操作如下:

weimingze@mzstudio:~/my_project$ git switch master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
weimingze@mzstudio:~/my_project$ ls
README.md  website.txt
weimingze@mzstudio:~/my_project$ echo -e -n "新功能2的实现代码\r\n" > function2.txt
weimingze@mzstudio:~/my_project$ echo -e -n "https://weimingze.com/git/\r\n" >> website.txt
weimingze@mzstudio:~/my_project$ cat website.txt
https://weimingze.com
https://weimingze.com/git/
weimingze@mzstudio:~/my_project$ cat function2.txt
新功能2的实现代码
weimingze@mzstudio:~/my_project$ git add function2.txt website.txt
weimingze@mzstudio:~/my_project$ git commit -m "完成了功能2"
[master 9d3b213] 完成了功能2
 Date: Wed Jan 14 15:07:32 2026 +0800
 2 files changed, 2 insertions(+)
 create mode 100644 function2.txt
weimingze@mzstudio:~/my_project$ ls
README.md  function2.txt  website.txt

此时在 master 分支上新创建了一个提交对象 9d3b213,这个提交对象记录了新增功能2的状态。 仓库结构如下:

                               HEAD
                                |
                            .--------.
                            | master |
                            `--------`
                               |
+-------+     +-------+     +-------+
|8cb34d1| <-- |5dcccb0| <-- |9d3b213|
+-------+     +-------+     +-------+
                  ^
                  |         +-------+
                  `-------- |8e7f7c7|
                            +-------+
                               |
                            .--------.
                            |  myb1  |
                            `--------`

到现在为止,master 分支最后的提交状态时有三个文件 README.mdwebsite.txtfunction2.txt, myb1 分支最后的提交状态也有三个文件 README.mdwebsite.txtfunction1.txt, 但 master 分支和 myb1 分支中的 website.txt 文件的内容是不同的。

合并分支

现在 master 分支中新增了功能2myb1 分支中新增了 功能1。现在我们希望这个项目同时使用 功能1功能2 两个功能。这个时候有两个比较方便的选择:第一种方法是将 myb1 合并到 master 分支中,形成一个新的提交对象,此提交对象中将 myb1 的修改内容添加进来,最后发布 master 分支的功能。第二种方法就是将 master 分支的修改合并到 myb1 分支中。

在 Git 中,分支都是平等的。如何操作分支取决于实际开发需求。

以下讲解 将 myb1 合并到 master 分支中的方法。合并分支需要使用 git merge 命令。

git merge 命令

作用: 将两个或两个以上分支的最终提交对象合并到当前分支并提交。

命令格式

git merge [选项] 分支名1 分支名2 分支名3 ...

git merge 的常用选项

选项
说明
-m "提交说明信息"
合并的提交说明。
--no-commit
仅合并,不提交。
--commit
合并后自动提交。
--tool=<工具命令名>-t 工具命令名
使用指定合并工具,如 meld、vimdiff 等。
--abort
取消本次合并。

注意:

如果两个分支有共同修改的文件,则合并过程中可能会产生冲突,需要解决冲突问题,然后再使用 git commit 命令提交合并的结果。

示例:

上述两个提交中 master 分支和 myb1 分支都修改了 website.txt 中的内容,因此两个分支的 website.txt 合并时就会产生冲突。当产生冲突时,合并工作会中断,此时需要使用编辑软件对冲突的文件进行手动合并。当然也可以使用 git mergetool 命令调用可视化的工具进行手动合并。待合并完成后需要使用 git commit 来手动提交合并结果。

myb1分支中的 website.txt 内容如下:

https://weimingze.com
https://weimingze.com/c/

master分支中的 website.txt 内容如下:

https://weimingze.com
https://weimingze.com/git/

我们希望合并后的 website.txt是:

https://weimingze.com
https://weimingze.com/c/
https://weimingze.com/git/

合并时要注意一下几个可能引发合并失败的问题:

  1. 将要并入的分支作为当前分支。
  2. 确保工作区是干净的状态。
  3. 工作区必须是当前分支的最新版本的状态。

具体操作如下:

weimingze@mzstudio:~/my_project$ git branch
* master
  myb1
weimingze@mzstudio:~/my_project$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
weimingze@mzstudio:~/my_project$ git merge myb1
Auto-merging website.txt
CONFLICT (content): Merge conflict in website.txt
Automatic merge failed; fix conflicts and then commit the result.
weimingze@mzstudio:~/my_project$ ls
README.md  function1.txt  function2.txt  website.txt

此时已经完成了合并,合并的结果存放在当前工作区,可见其中的四个文件 README.mdfunction1.txtfunction2.txtwebsite.txt 其中提示了 Auto-merging website.txt 说明 website.txt 文件产生了冲突,并已经自动合并。当前文件内容如下:

https://weimingze.com
<<<<<<< HEAD
https://weimingze.com/git/
=======
https://weimingze.com/c/
>>>>>>> myb1

其中 <<<<<<< HEAD======= 之间的内容是当前 HEAD 指向的分支 master 中的内容。而 =======>>>>>>> myb1 之间是 myb1 分支中 mywebsite.txt 的内容。

手动改写 website.txt 内容如下:

https://weimingze.com
https://weimingze.com/c/
https://weimingze.com/git/

至此 myb1master 分支的最终结果已经合并到工作区,我们将所有文件加入到暂存区,然后提交到 master 分支。操作如下:

weimingze@mzstudio:~/my_project$ git add *
weimingze@mzstudio:~/my_project$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
    new file:   function1.txt
    modified:   website.txt

weimingze@mzstudio:~/my_project$ git commit -m "将功能1合并到 master分支"
[master 11caedf] 将功能1合并到 master分支
weimingze@mzstudio:~/my_project$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

可见在 master 分支上又创建了一个提交对象 11caedf,此提交对象是 9d3b2138e7f7c7 合并后的结果。这两个提交对象也称之为 11caedf 的父对象。

此时的仓库内的结构如下:

                                             HEAD
                                              |
                                          .--------.
                                          | master |
                                          `--------`
                                             |
+-------+     +-------+     +-------+     +-------+
|8cb34d1| <-- |5dcccb0| <-- |9d3b213| <-- |11caedf|
+-------+     +-------+     +-------+     +-------+
                  ^                         |
                  |         +-------+  <----+
                  `-------- |8e7f7c7|
                            +-------+
                               |
                            .--------.
                            |  myb1  |
                            `--------`

使用 git log --graph --abbrev-commit --oneline 命令查看日志可以看到如下分支结构:

weimingze@mzstudio:~/my_project$ git log --graph --abbrev-commit
*   11caedf (HEAD -> master) 将功能1合并到 master分支
|\
| * 8e7f7c7 (myb1) 完成了功能1
* | 9d3b213 完成了功能2
|/
* 5dcccb0 (origin/master) 魏明择在当前项目中修改了 README.md 文件,并添加了 website.txt 文件
* 8cb34d1 魏明择在当前项目中添加了 README.md文件

上述合并后 my_project项目 可以点击此处进行下载

实验:

  1. master 分支的功能2 在合并到 myb1 分支中,形成一个新的提交对象。
  2. 查看 master 分支的提交日志。
  3. 查看 myb1 分支的提交日志。
  4. 删除 myb1 分支。