之前git常用命令是放在一篇文章中的,但是学习的东西越来越多,导致文章的阅读行变差,于是决定将其拆分开。
场景
git rebase和git merge的作用有相似之处,在多分支开发中,经常会碰到分支代码合并的情况,而merge和rebase都可以实现这类需求。
举个栗子
创建分支
接下来我们创建两个分支funA和funB。1
2 git checkout -b funA
git checkout -b funB
在A分支产生多次commit记录
然后我们再切回到A分支上,模拟产生多个commit。1
2
3
4
5
6
7 git checkout funA
vim a.txt
git add .
git commit -m "功能A第一次提交"
vim a.txt
git add .
git commit -m "功能A第二次提交"
这个时候A分支上产生了2个commit记录。
在B分支产生多次commit记录
接着我们再切回到B分支上,模拟产生多个commit。1
2
3
4
5
6
7 git checkout funB
vim b.txt
git add .
git commit -m "功能B第一次提交"
vim b.txt
git add .
git commit -m "功能B第二次提交"
这个时候B分支上也产生了2个commit记录。这个时候git仓库的commit记录是这个样子的。
接下来我们保持这个状态然后copy一份文件出来,分别测试git merge和git rebase两个命令。
git merge
我们将funB分支上的代码merge到funA分支上。1
2 git checkout funA
git merge funB
merge操作产生了一个新的commit。这个时候git仓库的commit记录是这个样子的。
git rebase
看完了merge,我们再来将funA分支上的代码rebase到funB分支上。1
2 git checkout funA
git rebase funB
rebase操作并不像merge操作产生一个新的commit,它会将某个分支上commit都复制一份然后拼接在指定分支后面。这个时候git仓库的commit记录是这个样子的。
冲突
上面只是简单的模拟了一下merge和rebase,但是实际开发过程中,肯定会遇到两个分支修改了相同文件的情况,这个时候我们就需要解决冲突。
git merge
我们来看看如果两个分支修改了相同的文件,在merge的时候会出现什么。
可以看到在终端中提示有冲突,这个时候我们打开a.txt文件进行查看。
这个时候我们需要将冲突的地方解决后重新提交就可以了。
git rebase
而git rebase对于解决冲突来说比merge要稍微复杂一点点。我们在两个分支上修改了同一个文件,然后执行rebase命令,发现终端有如下的提示。
而这个时候不在任何一个分支上,我们可以通过git branch查看当前的分支状态。
正如终端所说,你有两种选择
- 修改冲突文件,然后使用git rebase –continue继续rebase操作;
- 使用git rebase –abort终止rebase操作。
我们解决完冲突后,使用git add将修改添加,继续git rebase –continue操作,然后就rebase成功了。
异同
- git rebase和git merge都可以将多个分支的commit合并到同一个分支上;
- rebase操作首先会复制当前分支上的每个commit,然后再拼接到另外的分支上;而merge会生成一个新的commit,它包含了待merge分支的所有commit,然后再拼接到分支上。
更加复杂的场景
这里就不赘述了,直接给一张图自行理解提交记录,这里有三个分支master,server,client。
假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改,因为它们还需要经 过更全面的测试。 这时,你就可以使用 git rebase 命令的 –onto 选项,选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放。1
git rebase --onto master server client
这个命令的意思是:“取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然 后把它们在 master 分支上重放一遍”。 这理解起来有一点复杂,不过效果非常酷。
余生没那么长,不要一味的付出去惯哪些得寸进尺的人,请忠于自己,活的像最初的模样~