网站公告

本次更新:没啥更新的

“钱塘江上潮信起,今日方知我是我”

Skip to content

分支与合并 ​

字数: 0 字 时长: 0 分钟

1.什么是分支 ​

分支(Branch)可以理解成:从某个版本开始,拉出一条独立的开发线。

官话:

分支是指向某个提交(Commit)的可移动指针,用于在不影响主线代码的情况下进行独立开发。

人话:

就是从当前代码复制出一条“平行时间线”,你可以在这条线上随便改,改完再决定要不要合回主分支。

例如:

这里:

  • main:主分支
  • feature-login:功能分支
  • D、E:在新分支上的提交

开发完后可以合并:

一句话记:

分支 = 独立开发线,用来隔离不同功能、Bug 修复或版本开发。

2.查看分支 ​

bash
git branch
git branch -a
命令作用人话
git branch查看本地分支只看我电脑上的分支
git branch -a查看所有分支本地分支 + 远程分支都看
只看我电脑上的分支

看看是否有远程分支,因为我并没有放在远程仓库里,所以。】

3. 创建分支 ​

bash
git branch dev

创建一个叫 dev 的分支。

再次查看分支

就能看到俩了。

然后查看日志

其实就是这俩分支是一模一样的,因为刚刚复制过来

4. 切换分支 ​

切换前先查看分支

发现是 master 当前,因为前面有个*号。

同时只能编辑一个分支,就是每次修改只能选择同一个分支。不能说 master和 dev一起编辑。

接下来我们用 switch 命令切换

bash
git switch dev
git checkout dev
命令作用说明
git switch dev切换到 dev 分支新命令,专门用于分支切换,语义更清晰
git checkout dev切换到 dev 分支老命令,除了切分支还能恢复文件,功能更多但更容易混淆

先用 switch 试试

可以看到是 dev 了

接下来 q 退出切换用 checkout

5. 创建并切换 ​

bash
git switch -c prod

其实可以创建并切换的,如果嫌麻烦的话可以一键生成新的分支并切换。这个 -c 就是英文 create 的意思。

命令作用人话
git switch dev切换到已有的 dev 分支这个分支已经有了,我过去
git switch -c prod创建并切换到 prod 分支新建一个分支,然后马上切过去

可以看到现在*号是在 prod 分支的。

6. 删除分支 ​

bash
git branch -d dev
git branch -D prod
命令作用人话
git branch -d dev安全删除 dev 分支如果分支还有没合并的提交,Git 会阻止删除
git branch -D prod强制删除 prod 分支不管有没有未合并提交,直接删
可以记成:
bash
-d = delete       安全删
-D = force delete 强制删

所以一般优先用:git branch -d dev

确认这个分支真的不要了,再用:git branch -D dev

下面做一个命令行实验。

先切换到 master 分支,因为你在当前分支是无法删除的。

然后在看看,就发现只剩一个了。

7. merge(合并分支) ​

bash
git merge dev

7.1 合并概念 ​

将 dev 分支的修改合并到当前分支。

这里的 dev 可以理解为开发分支,开发人员通常在自己的功能分支或开发分支上写代码;main / master 一般作为主分支,通常保存相对稳定、可发布的代码。

实际团队开发中,通常不会直接在本地把代码合进主分支,而是先提交到远程仓库,再通过 Pull Request / Merge Request 发起合并,由其他开发人员或负责人进行 Code Review,审核通过后再合并。

分支一般作用说明
dev开发分支用于日常开发和功能联调,可以理解为开发人员工作的分支
main / master主分支一般保存相对稳定、可发布的代码,不建议直接随意修改
feature/*功能分支针对某个具体功能单独开发,例如 feature/login
fix/* / hotfix/*修复分支用于修复 Bug 或线上紧急问题
merge 不是两种命令,而是同一个合并过程可能有两种结果:无冲突合并、发生冲突的合并。
情况说明结果
正常合并两个分支修改的内容不冲突Git 自动完成合并
冲突合并两个分支修改了同一位置,Git 无法判断该保留谁需要人工处理冲突后再提交
例如:
bash
master: file001.txt = 01
dev:    file001.txt = 02

如果只有 dev 改了,master 没改:

bash
git switch master
git merge dev

Git 一般可以自动合并。

但如果:

bash
master 把 01 改成 03
dev    把 01 改成 02

再执行:git merge dev 就可能出现冲突 。这时候你需要手动决定保留了。

7.2 准备工作 ​

先创建两个分支,现在一共是 3 个分支。

查看

然后查看 master 主分支的内容

可以看到 file 是 count = 01

然后切换 dev 分支,更新一下为 count = 02

准备编辑一下为 02

7.3 合并操作(正常合并) ​

下面进入真正的合并操作。

先在 dev 分支提交修改

然后为切换到 master 分支,也就是主分支。

把 dev 合并进 master

现在看到已经合并成功了。

7.4 合并操作(冲突合并) ​

先把 master 改成 03,把 dev 改成 04

可以看到master 是 03,dev 是 04 了,下一步进行提交一下。

切换到 master 进行合并操作

就能看到是报了冲突的,需要手工处理选择 dev 还是 master

可以用到一下命令查看区别

bash
git diff

其实就是单词Different缩写

可以看到是一个 03 一个 04

因为我们目前就在 master,所以ours = master``theirs = dev。字面意思

ours 就是我们当前的 theirs 就是他们的

命令如下

bash
git checkout --ours file001.txt
git add file001.txt
git commit
命令作用人话
git checkout --ours file001.txt使用当前分支版本解决该文件冲突这个文件先保留 master 的版本
git add file001.txt标记该文件冲突已解决告诉 Git:这个文件我处理好了
git commit完成本次合并提交把这次冲突解决后的结果正式保存

冲突已经解决了、如果同一个文件,各要一行呢?

7.5手动选择冲突内容 ​

当多个分支修改了同一位置时,不能简单使用 --ours 或 --theirs,因为可能只想保留每个分支中的部分内容。

例如:

text
master:
update count = 5

dev:
update count = 6
update count = 7

prod:
update count = 8
update count = 9
## rebase

```bash
git rebase master

最终希望从每个分支选择部分内容,例如:

bash
update count = 5
update count = 6
update count = 8

这时直接使用 vim 手动编辑冲突文件解决了,或者 VSCode、idea 有更高级的工具可视化处理。

8. rebase ​

bash
git rebase
git rebase --continue
git rebase --abort
git rebase --skip
命令作用人话
git rebase --continue解决当前冲突后继续 rebase这次冲突处理完了,继续往后搬
git rebase --abort取消整个 rebase不弄了,恢复到 rebase 之前
git rebase --skip跳过当前这个提交这个提交不要了,直接处理下一个

rebase:把当前分支自己的提交,重新接到目标分支最新提交的后面,让历史看起来像是一条直线。

比如原来:

bash
A---B---C  master
     \
      D---E  dev

你现在在 dev:

bash
git rebase master

相当于把 dev 的 D、E 先拿下来,再接到 master 最新的 C 后面:

bash
A---B---C---D'---E'  dev

人话就是:

我原来是基于旧版 master 开发的,现在把我的修改“搬到”最新版 master 后面继续排队。

图解:

做一个实验:

先在 master 制造一个新提交

bash
git switch master
echo "master new" >> master.txt 
git add . 
git commit -m "master new commit"

在 dev 也制造几个自己的提交

bash
git switch dev 
echo "dev 1" >> dev.txt 
git add . 
git commit -m "dev commit 1"

在提交一些

看 rebase 前的历史

当前在 dev,把 dev 的提交搬到最新 master 后面

成功。

对比第一张:rebase 前第二张:rebase 后
master 最新提交d627af7d627af7,没变
dev commit 1b307a70381aa33
dev commit 204b485721d4f87
分支关系dev 和 master 分叉dev 接到了最新 master 后面
原来
bash
       D---E  dev
      /
-----B
      \
       C---F  master

rebase 后:

bash
-----C---F---D'---E'  dev
          ↑
        master

Noctiflorous Garden · MIT License