关于git:Git-合并分支

5次阅读

共计 3440 个字符,预计需要花费 9 分钟才能阅读完成。

在日常开发工作中,人人都会应用 git merge <branch> 命令来合并分支。但简直没有人会关怀合并分支的细节,本文将具体解说 git mergegit rebase命令的细节以及应用场景。

git merge

日常开发中,常常应用 git merge <branch>,有三种场景不一样。

1. 快进 – 无抵触

假如分支 master 有三次提交记录:B0、B1、B2

B0---B1---B2(master)

因为须要紧急修复线上问题,于是新建了分支 fix,并且在分支 fix 上提交了两次提交记录:B3、B4

            B3---B4(fix)
           /
B0---B1---B2(master)

当在分支 fix 上的工作完结,切换到分支 master,而后把分支 fix 合并到分支 master:

git merge fix

Updating 4f6316b..2c975d7
Fast-forward
 footer.js | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 footer.js

因为分支 fix 最新提交记录(B4)是 master 分支最新提交记录(B2)的后继,因而 Git 会间接将指针向前挪动(由 B2 挪动到 B4)。换句话说,当试图合并两个分支时,如果顺着一个分支走上来可能达到另一个分支,那么 Git 在合并两者的时候,只会简略的将指针向前推动(指针右移),因为这种状况下的合并操作没有须要解决的一致————这就叫做“快进”(fast-forward)。

合并后果如下:

B0---B1---B2---B3---B4(master)

合并分支 fix 之后,曾经不再须要该分支,能够删除该分支了。

git branch -d fix

tips: 当不想应用快进合并时,使每次合并都有一个总结性的提交记录,能够应用git merge <branch> --no-ff

2. 非“快进”,批改不同文件。(无抵触)

假如分支 master 有三次提交记录:B0、B1、B2

B0---B1---B2(master)

因为须要紧急修复线上问题,于是新建了分支 fix,并且在分支 fix 上提交了两次提交记录(与分支 master 代码无抵触):B3、B4

            B3---B4(fix)
           /
B0---B1---B2(master)

当在分支 fix 上开发时,另一位开发人员开发了新性能,并且曾经合并入分支 master,增加了提交记录(与分支 master、分支 fix 代码都无抵触):B5

            B3---B4(fix)
           /
B0---B1---B2---B5(master)

当在分支 fix 上的工作完结,切换到分支 master,而后把分支 fix 合并到分支 master:

git merge fix

Merge made by the 'ort' strategy.
 footer.js | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 footer.js

因为分支 master 最新提交 B5 不是分支 fix 最新提交 B4 的间接先人,所以 Git 无奈做“快进”(fast-forward)合并。

Git 会应用两个分支的最新提交(B4 和 B5)以及这两个分支的最新公共提交(B2),做一个简略的三方合并。并且把合并后果在分支 master 上创立一个新的提交(B6)。提交 B3 和 B4 的批改内容都体现在提交 B6。

            B3----B4(fix)
           /        \
B0---B1---B2---B5---B6(master)

合并分支 fix 之后,曾经不再须要该分支,能够删除该分支了。

git branch -d fix

3. 非“快进”,批改雷同文件。(有抵触)

假如分支 master 有三次提交提交记录:B0、B1、B2

B0---B1---B2(master)

因为须要紧急修复线上问题,于是新建了分支 fix,并且在分支 fix 上提交了两次提交记录:B3,B4

            B3---B4(fix)
           /
B0---B1---B2(master)

当在分支 fix 上开发时,另一位开发人员开发了新性能,并且曾经合并入分支 master,增加了提交记录(与分支 fix 代码有抵触):B5

            B3---B4(fix)
           /
B0---B1---B2---B5(master)

当在分支 fix 上的工作完结,切换到分支 master,而后把分支 fix 合并到分支 master:

git merge fix

Auto-merging footer.js
CONFLICT (add/add): Merge conflict in footer.js
Automatic merge failed; fix conflicts and then commit the result.

因为分支 master 最新提交 B5 与分支 fix 最新提交 B4 存在批改同一个文件的同一处代码,所以 Git 无奈主动合并,须要开发者本人解决抵触并且提交后果。

关上有抵触的文件,Git 曾经标记出代码抵触:

<<<<<<< HEAD
B5
=======
B3
B4
>>>>>>> fix

手动整顿该局部代码,解决抵触。

B3
B4
B5

增加该文件到暂存区,随后增加到分支 master。

git add footer.js
git commit -m 'B6'

合并后果如下:

            B3----B4(fix)
           /        \
B0---B1---B2---B5---B6(master)

合并分支 fix 之后,曾经不再须要该分支,能够删除该分支了。

git branch -d fix

git rebase

当本地分支合并近程分支时,在无奈快进合并时,就会产生一个合并提交记录。该合并提交记录,并非开发时产生的,而是合并流程中产生的。为了让分支的提交记录看起来连贯无分叉,rebase 合并形式进去了。

介绍

扭转以后分支的基底,并且把差别代码利用在新的基底上。从而实现分支提交记录的无分叉成果。

命令git rebase <branch>

具体步骤:

  1. 找到以后分支(fix)与被合并分支(master)之间的最新公共先人提交记录(B2)。

             B3---B4(fix)
            /
    B0---B1---B2---B5(master)
  2. 在分支 fix 中,从提交记录 B2 之后的提交记录 B3 开始到最新的提交记录 B4 都勾销掉,并且把这些提交记录长期保留为补丁(patch)。

    B0---B1---B2(fix)
  3. 把分支 fix 更新为分支 master,最初把 patch 利用到分支 fix 上,失去提交记录 B3和 B4(与提交分支 B3 和 B4 的 commit id 不一样)。

    B0---B1---B2---B5(fix)
    
    B0---B1---B2---B5---B3`---B4`(fix)

通过比照 git merge 能够看出,git rebase 合并后果无分叉。

应用场景

因为 git rebase 合并命令会扭转以后分支的基底。因而对多人应用的公共分支,为了防止已提交的记录被扭转,不倡议应用 git rebase 扭转分支的基底。

本地分支合并近程分支

当多个开发者在一个分支上开发,在合并近程分支时。为了防止产生多余的合并提交记录,能够应用 git rebase 变更本地分支的基底,再把本地开发的提交记录一一增加到新基底上。

B0---B1---B2---B5(origin/feature-1)

B0---B1---B2---B3---B4(local/feature-1)

利用 git pull origin feature-1 --rebase 之后:

B0---B1---B2---B5---B3`---B4`(local/feature-1)

tips: 当合并有抵触时,须要先解决抵触、git add、git commit,而后再执行 git rebase --continue 持续合并流程。

本地分支合并公共分支

本地的开发分支在向远端主分支提交 merge request 之前,为了防止产生多余的合并提交记录,能够应用 git rebase 变更本地分支的基底,再把本地开发的提交记录一一增加到新基底上。

B0---B1---B2---B5(origin/master)

B0---B1---B2---B3---B4(local/feature-1)

利用 git rebase master 之后:

B0---B1---B2---B5---B3`---B4`(local/feature-1)

总结

  1. 当分支 master 之类的骨干分支合并其余分支时,须要针对每次的合并有一个总结性的提交记录,能够应用命令git merge <branch> --no-ff
  2. 当本地开发分支合并公共分支之前,能够应用命令git rebase <branch>,扭转本地分支的基底,防止产生非必要的合并提交记录。
正文完
 0